|
1 | 1 | using System.Collections.Generic;
|
2 | 2 | using System.Linq;
|
| 3 | +using Antlr4.Runtime; |
3 | 4 | using Rubberduck.CodeAnalysis.Inspections.Abstract;
|
4 | 5 | using Rubberduck.CodeAnalysis.Inspections.Extensions;
|
5 | 6 | using Rubberduck.Inspections.CodePathAnalysis;
|
@@ -112,35 +113,47 @@ private static bool IsAssignmentOfNothing(IdentifierReference reference)
|
112 | 113 |
|
113 | 114 | private static bool DisqualifiedByResumeOrGoToStatements(IdentifierReference resultCandidate, DeclarationFinder finder)
|
114 | 115 | {
|
115 |
| - var relevantLabels = finder.DeclarationsWithType(DeclarationType.LineLabel) |
116 |
| - .Where(label => resultCandidate.ParentScoping.Equals(label.ParentDeclaration)); |
| 116 | + var jumpCtxts = (resultCandidate.ParentScoping.Context.GetDescendents<VBAParser.ResumeStmtContext>().Cast<ParserRuleContext>()) |
| 117 | + .Concat(resultCandidate.ParentScoping.Context.GetDescendents<VBAParser.GoToStmtContext>().Cast<ParserRuleContext>()); |
117 | 118 |
|
118 |
| - if (!relevantLabels.Any()) |
119 |
| - { |
120 |
| - return false; |
121 |
| - } |
| 119 | + if (!jumpCtxts.Any()) { return false; } |
122 | 120 |
|
123 |
| - var lineNumbersForNonAssignmentReferencesOfResultCandidateDeclaration = |
| 121 | + var lineNumbersForNonAssignmentReferences = |
124 | 122 | resultCandidate.Declaration.References
|
125 | 123 | .Where(rf => !rf.IsAssignment)
|
126 | 124 | .Select(rf => rf.Context.Stop.Line);
|
127 | 125 |
|
128 |
| - if (!lineNumbersForNonAssignmentReferencesOfResultCandidateDeclaration.Any()) |
| 126 | + if (!lineNumbersForNonAssignmentReferences.Any()) { return false; } |
| 127 | + |
| 128 | + //The jumped-to-line is after the resultCandidate and before a use of the variable |
| 129 | + return AllJumpToLines(resultCandidate, jumpCtxts, finder) |
| 130 | + .Any(jumpToLine => resultCandidate.Context.Start.Line > jumpToLine |
| 131 | + && lineNumbersForNonAssignmentReferences.Max() >= jumpToLine); |
| 132 | + } |
| 133 | + |
| 134 | + private static IEnumerable<int> AllJumpToLines(IdentifierReference resultCandidate, IEnumerable<ParserRuleContext> jumpCtxts, DeclarationFinder finder) |
| 135 | + { |
| 136 | + var jumpToLineNumbers = new List<int>(); |
| 137 | + var jumpToLabels = new List<string>(); |
| 138 | + foreach (var ctxt in jumpCtxts) |
129 | 139 | {
|
130 |
| - return false; |
| 140 | + var target = ctxt.children[2].GetText(); |
| 141 | + if (int.TryParse(target, out var line)) |
| 142 | + { |
| 143 | + jumpToLineNumbers.Add(line); |
| 144 | + } |
| 145 | + jumpToLabels.Add(target); |
131 | 146 | }
|
132 | 147 |
|
133 |
| - var labelReferencesAffectingExecutionPath = relevantLabels.SelectMany(d => d.References) |
134 |
| - .Where(labelReference => LabelReferencedByJumpStatementAfterResultCandidateAssignment(labelReference, resultCandidate)); |
| 148 | + var relevantLabelLineNumbers = finder.DeclarationsWithType(DeclarationType.LineLabel) |
| 149 | + .Where(label => resultCandidate.ParentScoping.Equals(label.ParentDeclaration) |
| 150 | + && jumpToLabels.Contains(label.IdentifierName)) |
| 151 | + .Select(d => d.Context.Start.Line); |
135 | 152 |
|
136 |
| - return labelReferencesAffectingExecutionPath.Any(labelReference => labelReference.Declaration.Context.Stop.Line < resultCandidate.Context.Start.Line |
137 |
| - && labelReference.Declaration.Context.Start.Line < lineNumbersForNonAssignmentReferencesOfResultCandidateDeclaration.Max()); |
138 |
| - } |
| 153 | + jumpToLineNumbers.AddRange(relevantLabelLineNumbers); |
139 | 154 |
|
140 |
| - private static bool LabelReferencedByJumpStatementAfterResultCandidateAssignment(IdentifierReference labelReference, IdentifierReference resultCandidate) |
141 |
| - => labelReference.Context.Start.Line > resultCandidate.Context.Stop.Line |
142 |
| - && (labelReference.Context.TryGetAncestor<VBAParser.ResumeStmtContext>(out _) |
143 |
| - || labelReference.Context.TryGetAncestor<VBAParser.GoToStmtContext>(out _)); |
| 155 | + return jumpToLineNumbers; |
| 156 | + } |
144 | 157 |
|
145 | 158 | protected override string ResultDescription(IdentifierReference reference)
|
146 | 159 | {
|
|
0 commit comments