HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Ugly workaround to get the vbext_ProcKind of a procedure is breaking encapsulation

Submitted by: @import:stackexchange-codereview··
0
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 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 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.