patternMinor
Ugly workaround to get the vbext_ProcKind of a procedure is breaking encapsulation
Viewed 0 times
uglytheencapsulationprocedurebreakinggetworkaroundvbext_prockind
Problem
This is a follow up to Extending the VBAExtensibility Library. It turns out that code had a really nasty bug. Anytime
To clarify, this is a dangerous call.
My solution was to parse the code module line by line checking for some keywords so I could determine what
I already posted this code as an answer, but I would like to have it reviewed. I'm posting the entirety of both classes here, but I'm particularly interested in
The full project is over at GitHub.
vbeCodeModule
```
' requires Microsoft Visual Basic for Applications Extensibility 5.3 library
Option Explicit
Private mCodeModule As CodeModule
Private mVbeProcedures As vbeProcedures
Public Property Get CodeModule() As CodeModule
Set CodeModule = mCodeModule
End Property
Public Property Let CodeModule(ByRef codeMod As CodeModule)
Me.Initialize codeMod
End Property
Public Property Get vbeProcedures()
Set vbeProcedures = mVbeProcedures
End Property
Public Sub Insert(Comp
vbeProcedure.StartLine got called, I was running the risk of hitting runtime error 35 because CodeModule.ProcStartLine has to be told what kind of procedure it's looking for. Everything blows up when you call it with vbext_pk_proc, but you're really looking for a class property.To clarify, this is a dangerous call.
CodeModule.ProcStartLine(procedureName, vbext_pk_proc)My solution was to parse the code module line by line checking for some keywords so I could determine what
vbext_ProcKind to pass it. I have one huge issue with how I've fixed it: vbeCodeModule now knows more about what it means to be a procedure than I like. I feel like I'm breaking encapsulation. In my original version, vbeCodeModule knew just enough to create a list of procedures. That's it. VbeProcedures were responsible for reporting information about themselves. My concerns are deepened by the difficulty I'm having in testing this code. If it was part of VbeProcedure, I could expose it publicly and testing would be a breeze. As part of VbeCodeModule, I don't really want it to be public.I already posted this code as an answer, but I would like to have it reviewed. I'm posting the entirety of both classes here, but I'm particularly interested in
IsSignature, GetProcedureType, and GetProcedures in the vbeCodeModule class.The full project is over at GitHub.
vbeCodeModule
```
' requires Microsoft Visual Basic for Applications Extensibility 5.3 library
Option Explicit
Private mCodeModule As CodeModule
Private mVbeProcedures As vbeProcedures
Public Property Get CodeModule() As CodeModule
Set CodeModule = mCodeModule
End Property
Public Property Let CodeModule(ByRef codeMod As CodeModule)
Me.Initialize codeMod
End Property
Public Property Get vbeProcedures()
Set vbeProcedures = mVbeProcedures
End Property
Public Sub Insert(Comp
Solution
Your
If I make a function with an argument named
For example:
There's other minor cases you should watch out for; there could be extra spaces between
IsSignature relies on IsDeclaration, which doesn't take variable names of functions into account.If I make a function with an argument named
maxDimensions, your code fails to identify the function as a function.For example:
Public Sub Initialize(maxDimensions as Integer) for some kind of data structure object (multi-dimensional array?). You call GetProcedures, hit IsSignature, and because the line contains the word Dim (maxDimensions), it's seen as a variable and not a function or procedure.There's other minor cases you should watch out for; there could be extra spaces between
Property and Get/Set/Let. Also, End Function, End Sub and End Property could have a space on the end. Lines containing End Function like If IsDeclaration Then Exit Function could also cause problems if they have a space on the end. I suggest you trim excess spaces.Context
StackExchange Code Review Q#63815, answer score: 6
Revisions (0)
No revisions yet.