Rubberduck: Can I add attributes to items with conditional compilation?

Created on 28 Jun 2019  路  7Comments  路  Source: rubberduck-vba/Rubberduck

I'm trying to add '@Description attributes to api declarations with conditional compilation, like this:

'@Description("API: Destination and Source can be byVal pointers or byRef variables, length is LenB(dataType)")
#If Win64 Then
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
#Else
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
#End If

The inspections detect it fine but the quickfix does nothing, is this sort of thing supported?

antlr bug edge-case feature-annotations hacktoberfest

Most helpful comment

For those who like a horror show....

image

All 7 comments

Rubberduck is only seeing the "live" code (IIRC with whitespace in place of the "dead" code), so stuff around conditionally compiled code is always going to be a rough edge.

Does it work better if you put the annotation inside the conditionally compiled block?

#If Win64 Then
    '@Description("API: Destination and Source can be byVal pointers or byRef variables, length is LenB(dataType)")
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
#Else
    '@Description("API: Destination and Source can be byVal pointers or byRef variables, length is LenB(dataType)")
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
#End If

I thought that might be the case. No, that change doesn't solve the problem; I'm getting errors in the log like this one:

2019-06-28 14:46:41.1293;ERROR-2.4.1.4694;Rubberduck.UI.Inspections.InspectionResultsViewModel;System.NullReferenceException: Object reference not set to an instance of an object.
   at Rubberduck.Parsing.VBA.AttributesUpdater.AddAttribute(IRewriteSession rewriteSession, Declaration declaration, String attribute, IReadOnlyList`1 values) in C:\projects\rubberduck\Rubberduck.Parsing\VBA\AttributesUpdater.cs:line 99
   at Rubberduck.Inspections.QuickFixes.AddMissingAttributeQuickFix.Fix(IInspectionResult result, IRewriteSession rewriteSession) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\QuickFixes\AddMissingAttributeQuickFix.cs:line 31
   at Rubberduck.Inspections.QuickFixes.QuickFixProvider.FixInProject(IQuickFix fix, QualifiedSelection selection, Type inspectionType, IEnumerable`1 results) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\QuickFixes\QuickFixProvider.cs:line 177
   at Rubberduck.UI.Inspections.InspectionResultsViewModel.ExecuteQuickFixInProjectCommand(Object parameter) in C:\projects\rubberduck\Rubberduck.Core\UI\Inspections\InspectionResultsViewModel.cs:line 580
   at Rubberduck.UI.Command.DelegateCommand.OnExecute(Object parameter) in C:\projects\rubberduck\Rubberduck.Core\UI\Command\DelegateCommand.cs:line 29
   at Rubberduck.UI.Command.CommandBase.Execute(Object parameter) in C:\projects\rubberduck\Rubberduck.Core\UI\Command\CommandBase.cs:line 60;System.NullReferenceException: Object reference not set to an instance of an object.
   at Rubberduck.Parsing.VBA.AttributesUpdater.AddAttribute(IRewriteSession rewriteSession, Declaration declaration, String attribute, IReadOnlyList`1 values) in C:\projects\rubberduck\Rubberduck.Parsing\VBA\AttributesUpdater.cs:line 99
   at Rubberduck.Inspections.QuickFixes.AddMissingAttributeQuickFix.Fix(IInspectionResult result, IRewriteSession rewriteSession) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\QuickFixes\AddMissingAttributeQuickFix.cs:line 31
   at Rubberduck.Inspections.QuickFixes.QuickFixProvider.FixInProject(IQuickFix fix, QualifiedSelection selection, Type inspectionType, IEnumerable`1 results) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\QuickFixes\QuickFixProvider.cs:line 177
   at Rubberduck.UI.Inspections.InspectionResultsViewModel.ExecuteQuickFixInProjectCommand(Object parameter) in C:\projects\rubberduck\Rubberduck.Core\UI\Inspections\InspectionResultsViewModel.cs:line 580
   at Rubberduck.UI.Command.DelegateCommand.OnExecute(Object parameter) in C:\projects\rubberduck\Rubberduck.Core\UI\Command\DelegateCommand.cs:line 29
   at Rubberduck.UI.Command.CommandBase.Execute(Object parameter) in C:\projects\rubberduck\Rubberduck.Core\UI\Command\CommandBase.cs:line 60

...when I try the quickfix.

I also tried getting rid of the 1st '@Description (I'm 32 bit system)

#If Win64 Then
    Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
#Else
    '@Description("API: Destination and Source can be byVal pointers or byRef variables, length is LenB(dataType)")
    Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)
#End If

but still no luck

I will have to test this case. It might be that the attribute gets added outside the procedure, which would cause the VBE to ignore it.

Another possibility is that it gets added in the wrong branch of the conditional compilation.

I think part of the problem is that we require annotations to be above the member and the VBE demands attributes to be inside or right below the member.

Hm, looking at the stack trace, there is definitely a bug. I will have to find some time to look into this.

The problem is not the conditional compilation. That works just fine.

The problem here is that the attribute annotation is on a declare statement. AFAIK, that is not legal; we do not collect the corresponding context from the attributes pass.

So, from my point of view the problem here is that there was an inspection result for the missing attribute in the first place instead of one for an illegal annotation.

FWIW, it seems to me we can at least add a description to the Declare statements.

Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Attribute Sleep.VB_Description = "Can I haz a description?"

image

image

Note that the description doesn't show up right away but does after an import (and perhaps after restart?)

For those who like a horror show....

image

Was this page helpful?
0 / 5 - 0 ratings