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.92k stars 302 forks source link

Synchronizing attributes escapes backslashes, which keeps the annotation de-synchronized #5742

Closed daFreeMan closed 3 years ago

daFreeMan commented 3 years ago

Rubberduck version information The info below can be copy-paste-completed from the first lines of Rubberduck's log or the About box:

Rubberduck version 2.5.2.5824 loading:  (NOTE: Problem also exists in .5834)
Operating System: Microsoft Windows NT 10.0.18363.0 x64
Host Product: Microsoft Office 2016 x64
Host Version: 16.0.5110.1000
Host Executable: MSACCESS.EXE;

Description Selecting the Adjust attribute value(s) | Selected occurrence quick fix for the noted inspection does not actually apply the fix. The problem lies in the literal string text \\server or \share where the \ before \share seems to be treated as an escape code instead of part of the literal string and is dropped in the comparison routine to see if the two match.

To Reproduce Steps to reproduce the behavior:

  1. Create a method documentation annotation:
'@Description "Recursive function that builds as much of 'FullPath' as is necessary, all the way back to root, if need be. Will trim a filename from the end of the path, if one is provided. Works fine with a mapped drive, hasn't been tested with a UNC, but should work unless either the \\server or \share are missing"
  1. Parse the project

  2. Select the quick fix to correct the attribute value

  3. Parse the project

  4. The inspection remains. See this log file: RubberduckLog.txt

  5. Change the annotation to read:

    '@Description "Recursive function that builds as much of 'FullPath' as is necessary, all the way back to root, if need be. Will trim a filename from the end of the path, if one is provided. Works fine with a mapped drive, hasn't been tested with a UNC, but should work unless either the \\server or the share are missing"
  6. Parse the project

  7. Execute the quick fix

  8. The inspection result is no longer listed. See this log file (Note, it's a continuation of the log above, so ignore the initial part): RubberduckLog.txt

Expected behavior Since the '@Description text is a literal string, it should be treated as such, and any occurrences of \ should be escaped with a leading \ to avoid them being treated as escape codes.

Screenshots N/A

Logfile Above

Additional context With the @Description containing the string \\server or \share, exporting the module to a .bas file shows the VB_Description attribute with \\server or share, hence my substitution of the for the \ - I needed to make sure it was quite distinct.

Also note that there are quite a number of:

2021-04-22 10:00:12.4729;ERROR-2.5.2.5824;Rubberduck.UI.Command.MenuItems.CommandBars.AppCommandBarBase;Assignment of CommandBarButton.Caption or .TooltipText for ContextDescriptionLabelMenuItem threw an exception.;System.ArgumentException: Value does not fall within the expected range.
   at Microsoft.Office.Core.CommandBarControl.set_TooltipText(String pbstrTooltip)
   at Rubberduck.VBEditor.SafeComWrappers.Office12.CommandBarButton.set_TooltipText(String value) in C:\projects\rubberduck\Rubberduck.VBEditor.VBA\SafeComWrappers\Office\CommandBarButton.cs:line 236
   at Rubberduck.UI.Command.MenuItems.CommandBars.AppCommandBarBase.LocalizeInternal(KeyValuePair`2 item, KeyValuePair`2 kvp) in C:\projects\rubberduck\Rubberduck.Core\UI\Command\MenuItems\CommandBars\AppCommandBarBase.cs:line 77
2021-04-22 10:00:12.5299;ERROR-2.5.2.5824;Rubberduck.UI.Command.MenuItems.CommandBars.AppCommandBarBase;Assignment of CommandBarButton.Caption or .TooltipText for ContextDescriptionLabelMenuItem threw an exception.;System.ArgumentException: Value does not fall within the expected range.
   at Microsoft.Office.Core.CommandBarControl.set_TooltipText(String pbstrTooltip)
   at Rubberduck.VBEditor.SafeComWrappers.Office12.CommandBarButton.set_TooltipText(String value) in C:\projects\rubberduck\Rubberduck.VBEditor.VBA\SafeComWrappers\Office\CommandBarButton.cs:line 236
   at Rubberduck.UI.Command.MenuItems.CommandBars.AppCommandBarBase.LocalizeInternal(KeyValuePair`2 item, KeyValuePair`2 kvp) in C:\projects\rubberduck\Rubberduck.Core\UI\Command\MenuItems\CommandBars\AppCommandBarBase.cs:line 77

and at least one

2021-04-22 10:06:18.0416;WARN-2.5.2.5824;Rubberduck.CodeAnalysis.Inspections.Logistics.Inspector;System.ArgumentException: Unsupported operation (Is) passed to Evaluate function
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeExpressionEvaluator.Evaluate(IParseTreeValue LHS, IParseTreeValue RHS, String opSymbol) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeExpressionEvaluator.cs:line 39
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitBinaryOpEvaluationContext(QualifiedModuleName module, ParserRuleContext context, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 209
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.Visit(QualifiedModuleName module, ParserRuleContext parserRuleContext, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 104
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, ParserRuleContext context, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 294
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.Visit(QualifiedModuleName module, ParserRuleContext parserRuleContext, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 93
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, ParserRuleContext context, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 294
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.Visit(QualifiedModuleName module, ParserRuleContext parserRuleContext, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 91
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, IRuleNode node, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 65
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, IRuleNode ruleNode, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 50
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseInspection.ResultsForContext(QualifiedContext`1 qualifiedSelectCaseStmt, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseInspection.cs:line 177
   at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseInspection.<>c__DisplayClass9_0.<DoGetInspectionResults>b__1(Declaration module) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseInspection.cs:line 158
   at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Rubberduck.CodeAnalysis.Inspections.Abstract.InspectionBase.GetInspectionResults(CancellationToken token) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Abstract\InspectionBase.cs:line 82
   at Rubberduck.CodeAnalysis.Inspections.Logistics.Inspector.RunInspection(IInspection inspection, ConcurrentBag`1 allIssues, CancellationToken token) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Logistics\Inspector.cs:line 175;System.ArgumentException: Unsupported operation (Is) passed to Evaluate function
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeExpressionEvaluator.Evaluate(IParseTreeValue LHS, IParseTreeValue RHS, String opSymbol) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeExpressionEvaluator.cs:line 39
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitBinaryOpEvaluationContext(QualifiedModuleName module, ParserRuleContext context, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 209
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.Visit(QualifiedModuleName module, ParserRuleContext parserRuleContext, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 104
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, ParserRuleContext context, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 294
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.Visit(QualifiedModuleName module, ParserRuleContext parserRuleContext, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 93
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, ParserRuleContext context, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 294
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.Visit(QualifiedModuleName module, ParserRuleContext parserRuleContext, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 91
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, IRuleNode node, IMutableParseTreeVisitorResults knownResults, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 65
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseEvaluation.ParseTreeValueVisitor.VisitChildren(QualifiedModuleName module, IRuleNode ruleNode, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseEvaluation\ParseTreeValueVisitor.cs:line 50
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseInspection.ResultsForContext(QualifiedContext`1 qualifiedSelectCaseStmt, DeclarationFinder finder) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseInspection.cs:line 177
   at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Rubberduck.CodeAnalysis.Inspections.Concrete.UnreachableCaseInspection.<>c__DisplayClass9_0.<DoGetInspectionResults>b__1(Declaration module) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Concrete\UnreachableCaseInspection.cs:line 158
   at System.Linq.Enumerable.<SelectManyIterator>d__17`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Rubberduck.CodeAnalysis.Inspections.Abstract.InspectionBase.GetInspectionResults(CancellationToken token) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Abstract\InspectionBase.cs:line 82
   at Rubberduck.CodeAnalysis.Inspections.Logistics.Inspector.RunInspection(IInspection inspection, ConcurrentBag`1 allIssues, CancellationToken token) in C:\projects\rubberduck\Rubberduck.CodeAnalysis\Inspections\Logistics\Inspector.cs:line 175

errors/warnings reported in the log. I do not know if they're related or not

retailcoder commented 3 years ago

Failed to get host document Quarterly Report.Form_GenQuarterlyRpt;System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.

I don't think it's a bug with the quick-fix.

retailcoder commented 3 years ago

Ok the exceptions are unrelated, but there is something about escapes being ...escaped:

image

daFreeMan commented 3 years ago

Failed to get host document Quarterly Report.Form_GenQuarterlyRpt;System.Runtime.InteropServices.InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used.

May well have been a one-off issue. After closing Access, reopening, parsing and applying the quick fix, I've not seen a recurrence of that in the log.

I noted it as an exception because I came across it and wasn't sure if it was related or not.

MDoerner commented 3 years ago

I have investigated this. The error is not in our code, but in the COM interop library or even the VBE API itself.

The problem is that string literals do not properly round-trip when exporting an imported component. In the reexported file, backslashes in front of most other characters are missing. Exceptions seem to be the backslash itself, r and n.

Since there does not seem to be a way to round-trip a single backslash followed by most characters, I think we will not be able to fix this.