New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support attributes? #25
Comments
My concern is that it could get messy with having support for VB.NET attributes, RubberDuck attributes, and also the old style Attribute VB_* attributes. I'll leave this open for discussion though, as I'm not technically opposed to it. It might be that we can "auto-correct" the three forms into a single authoritative form. |
FWIW, I am in favor not having multiple ways of doing the same and "auto-correct" into a canonical form sounds like the best solution especially considering that the I am somewhat ambivalent about the idea of having the equivalent of VB.NET attributes. It's important to note that those exist primarily for the reflection purpose. By itself, it does nothing useful. However, it can be used as some kind of "compiler directive". One good use I found for Rubberduck project is to prefer this version over the latter version:
vs.
I will refer the readers to this excellent blog which explains why the former form is a superior solution over the latter. Suffice to say that the former ensures that the unused branch still gets validated by the compiler and thus prevent the source code from becoming incorrect as things changes. TBH I can't imagine doing any useful metaprogramming without the attributes but my imagination might be too constrained by my familiarity with .NET and lack of familiarity with Lisp. 😆 So to summarize, if twinBASIC has plans for reflection & metaprogramming, it may need to solve how it will handle the metadata that is useful only for reflection/metaprogramming. As the example above shows, there's value in having the metaprogramming be also code as opposite to a 2nd "language" superimposed as is the case with current compiler directives. One additional consideration, however, is that in .NET, the attributes are shipped as metadata with the assembly. Since twinBASIC is unmanaged, it probably can make use of the One thing I'm sure about, though is that I very much dislike VB.NET's syntax for attributes. 😄 |
I concur: nothing against attributes per se, but needs a proper reflection API to be useful, and I will actively boycott the feature if it involves |
Heh, I think we can agree that VB6\VBA attributes are of the form
Perhaps we could devise a syntax that acts as an alias to these existing forms, and also provides capabilities for the future. For example:
would be treated as exactly equivalent to:
But in the future, the syntax would also allow:
EDIT: VB_Name is a poor example, as modules are named explicitly in tB. Updated to VB_Description. |
The other thing to bear in mind is that we will be supporting external CLS/BAS files, so we need to be mindful that the solution we choose should keep the source backwards compatible with VB6. Rubberduck style annotations, being inside code comments would definitely fulfill that criteria. I wonder whether we could hide the VB6 style attributes in the editor, and display them in a more friendly manner via CodeLens? So they would still be authoritative, but the user doesn't have to deal with them directly. Thoughts? |
I thought the goal for compatibility was that tB should be able to compile all existing VB6 code without changes. I.e. VB6 is forward-compatible with tB, and tB is a superset of VB6. There are many changes already that would make tB code not compile in the VB6 IDE (generics, overloads). I see this as just being another such case - a new syntax that is only available in tB? |
True, however it feels a little uncomfortable to have tB effectively trash a CLS/BAS file just by opening it and having it auto-correct everything to an unsupported syntax (in VB6s eyes). At least making changes such as overloads and generics are an active choice made by the programmer. I'm not against the syntax bring suggested at all by the way... Just trying to be as considerate to the old file formats as much as possible. It's a discussion for another day, but it could be that we want to restrict the new VB6-incompatible features to just TWIN files anyway. |
So there's classic-VB attributes, using the Then there's Rubberduck's This syntax poses a number of problems. It's difficult to annotate a particular method parameter, for example; Rubberduck may eventually extend its annotation parameterization to take a parameter name, but then annotations quickly stack up on top of procedures, and soon you have more magic-syntax comments than actual code. Square-bracket attributes à la C# would be similar to Rubberduck annotations, but they wouldn't be a comment syntax and they could be interleaved between parameter declarations, making it possible and relatively much easier to support attributes like If/when non-comment actual custom attributes are supported, twinBASIC should offer to "translate" both the legacy
That way there would be One Clear Way of doing things the twinBASIC way, while legacy statements and comments retain their legacy meaning and functionality. |
Ah yes sorry I see, I didn't explain myself correctly. I was proposing that either VB6 form or the new form would be acceptable syntax to tB. No auto-correction, it would be a manual and conscious decision to change to the new form if desired. |
Heh, @retailcoder said it much better than me :-) |
Ah I see. Sorry, probably my fault, as there was talk of auto-correct etc. Manual changes that break VB6 back compat in fine with 😀 |
I agree that when handling a bas/cls file there should be no autocorrection, but it sounds like it would significantly complicate the mapping. Example: Import a I am not familiar with CodeLen so not sure how that will help. I do think we need one canonical way of doing attributes. |
I would suggest that it should continue to display |
The old VBIDE behaviour of hiding things was deeply unhelpful IMO - I prefer my IDE to show every line of text in the source file (just with folding and intellisense etc) |
I like the idea of not changing the syntax with the option to change it to modern syntax. That becomes an explicit choice on the user's part while simplifying the compiler's job of parsing the legacy code. |
CodeLens is a bit like the inline parameter hints, but shown immediately above the definition, where you can show the number of references etc. In this case we'd have it show the aggregated attributes from the Rubberduck annotations and the VB6 style attributes, in our nice [] style, whilst hiding the Rubberduck annotations and the VB6 style attributes. But on the other hand I do agree that hiding bits of the source file seems like a step backwards. |
So the consensus seems to be to introduce the square bracket (third) syntax, and then have the old two syntax forms become legacy supported with recommendations and quick fixes to change to the new syntax? |
What you mean with magic value? Public Function NewEnum() As IEnumVARIANT However, the -4 is not magic. It maps to DISPID_NEWENUM. Or do you mean something different? |
Yeah. I can see CodeLen being useful in displaying the legacy syntax as that has the additional advantage of not accidentally modifying it in code. That can be then fixed with a quickfix to convert into modern syntax. The thing is that if someone then adds the modern syntax, it should override the original syntax to avoid having conflicting values.
That's exactly what we mean by magic numbers. I'd rather read |
I guess it does raise the question of whether the canonical form should be |
@mansellan shouldn't it be |
But if we're mapping to the old form, I guess it would need to be done for all known VB_ attributes. That's a valid approach, given that this is a brand new syntax. But it does mean that these attribute names become "reserved", and would not be available to a later reflection-based system. |
Hm, I was thinking |
Yes, agreed. But if we're looking to treat legacy VB6/VBA attributes as freely interchangeable with their modern equivalents, then certain attribute names need to have special effect. In a future world with tB reflection, attributes would be defined in code. But they wouldn't be able to use the same names as the legacy-mapped attributes, as those are special-cased. |
Which might be an argument for keeping the legacy |
Nah, not concerned because those will be different syntax. canonical tB:
vs. (imported from VB6/VBA):
In tB, we would have the option of converting the legacy |
But what happens if a user wants to do this:
Oops, there's already a built-in attribute called |
You're assuming that twinBASIC parser can't tell a difference between a procedure named |
For the sake of consistency and simplicity, I stand by the comments I made in the I get that it would be convenient to not have define an interface but the problem with the
I would much rather not have to add the OERN block. Furthermore, it wouldn't help with the methods that does NOT return a That said, maybe this may be possible --- support preserving the signature at the call site not just at the definition of the interface:
This removes the need to wrap error handling but the downside is that it requires making assumptions about how the method is actually defined (e.g. |
I am not sure if the OERN block would be necessary. I assume it would be similar to like |
I'm not sure I'm following. Why do we need to add the OERN? If we expect that the callee returns S_FALSE, then there is no change to error handling, we can just read For
We can't really have attributes inside procedure blocks, as the square brackets are allowed as symbol identifiers. |
Maybe I'm working on wrong assumptions. Right now in VBx world, if one calls a method that returns a |
S_OK and S_FALSE are both success code. So no error. No OERN needed. |
All positive HRESULTs are ignored as they are not errors. |
One more consideration. As mentioned, this assumes that the return value of the method is a |
No that won't happen. |
I find Maybe |
The german translator messed it up. It's |
Out of curiosity, does that depend on having a type library to infer that it's a EDIT: to clarify why I'm asking --- I'm looking at implementing undocumented interfaces and I would need to define it so in twinBASIC. But |
Yes, internally we have a HasHRESULT flag on each member, which gets picked up from the type library. For any interface members defined internally in your project, they will always have that flag, until we support |
@bclothier HRESULT shenanigans happen on method/props only. It's hard not to return HRESULT from dual/dispinterfaces because these non-HRESULT methods cannot be called through IDispatch. JFYI, a VB |
Right but in my case, I'm implementing an interface that comes from DLL with no type library and converting C++ code into a tB compatible interface. Truth be told, it'd be easier if I had a type library because it's easier to see whether there's a |
|
Just out of curiosity, will the access to the |
Yes, thread-aware and thread-safe. The two new properties, |
Will the |
|
@bclothier this should probably move to lang-design and (IMO) be closed. Attributes are now supported, which is the OP, and are a pretty big discussion area. Could probably do with a tag to use when specific new attributes (or discussion around custom attributes) is raised. |
I understand where you are going with the suggestion. We already have other issues on the attribute subject. However, I didn’t close the issue because we still have outstanding items to implement and didn’t transfer because adding new attributes isn’t a change in language. |
I dislike the .net syntax. it does look like a cruel mix of BASIC and HTML spiced up by c :/ A more basic like style would be using the # syntax of conditional defines. And in this case i suggest to use '# to keep backward copability. Otherwise we have a nice #if #endif mess. It would be in any case handy if the IDE let us the choice what we want to see. I would love to have the ability to hide "dead" code by #if and friends as well as to get rid normal coments as well as conditioonal defines. It makes the algorithm often very unreadble. |
Discussion: should twinBASIC support attributes?
Describe the solution you'd like
VB.Net (and C#) allow attributes to be attached to various declarations, which can then be used at runtime. These can be useful for scenarios like serialisation, display, decoration etc.
Describe alternatives you've considered
Rubberduck works around the lack of attributes by using a convention-based comment format. Whilst this works well, it requires explicit tooling support for each scenario and is not user-extensible.
Additional context
This might be opening a can of worms, as attributes are only useful if they can be reflectively retrieved at runtime.
If support were to be implemented, it should probably syntactically follow the format used in VB.Net.EDIT: Dropped suggestion to follow VB.Net syntax
The text was updated successfully, but these errors were encountered: