rubberduck-vba / Rubberduck

Every programmer needs a rubberduck. COM add-in for the VBA & VB6 IDE (VBE).
https://rubberduckvba.com
GNU General Public License v3.0
1.91k stars 299 forks source link

Annotation for Shared/Static members of a Predeclared class #3859

Open ThunderFrame opened 6 years ago

ThunderFrame commented 6 years ago

Having a Predeclared class with a factory method, or with members that are intended to be used as Shared/Static members, it would be useful to annotate those members as being '@Shared.

Once RD knows which members are Shared, it could:

@retailcoder: that would make UserForm1.Show much less friendly all of a sudden

'Class Foo
Private counter As Long
Public Sub Increment
  counter = counter + 1
End Sub

'@Shared
Public Function Create() As Foo
  'Return a new Foo
  Set Create = New Foo
End Function
bclothier commented 6 years ago

As a reminder:

In earlier days of RD, we would have used an annotation to mark a class as predeclared ID. Of course this was problematic due to needing to read from the attribute pass, so we no longer do that.

However, we can use the Type Library API to tell us whether a class is predeclared or not, since the @Shared annotation wouldn't work if the class isn't predeclared (and that can be its own inspection to warn the user to fix it). However that I think requires updating (I assume) the resolver so that it will extract that attribute (as well as others) during the parse.

retailcoder commented 6 years ago

@bclothier but the resolver already knows about the attributes of a module. Good catch warning about using the annotation without a predeclared id :+1:

MDoerner commented 6 years ago

Just as a side note: Shared is a keyword in VBA, which is specified to be meaningless.

retailcoder commented 6 years ago

Huh, TIL. Did MS intend to support "shared" classes and members at one point?

bclothier commented 6 years ago

@retailcoder @MDoerner That keyword is used for low file IO.

MDoerner commented 6 years ago

Oh, there is a second use. I have been refereeing to Shared in instance and local variable declarations. There, it exists purely for compatibility with other basic dialects.

BTW, in the Open statement the lock is optional and defaults to Shared.

bclothier commented 6 years ago

Ah, I see. Now I TIL'd too.

(For others, the reference is section 5.2.3.1) - So this is legal code:

Public Shared x As Boolean

but VBE will automatically strip the Shared out once inserted. This seems to apply only to the module-level variables.