Skip to content

Commit f27427f

Browse files
authored
Merge pull request #5363 from MDoerner/FixUndeclaredVariableScopingInResolver
Generate distinct unresolved variable declarations in Get Set and Let
2 parents 5d7369a + 58e8e15 commit f27427f

File tree

2 files changed

+83
-8
lines changed

2 files changed

+83
-8
lines changed

Rubberduck.Parsing/VBA/DeclarationCaching/DeclarationFinder.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class DeclarationFinder
3030

3131
private readonly IReadOnlyDictionary<QualifiedModuleName, IFailedResolutionStore> _failedResolutionStores;
3232
private readonly ConcurrentDictionary<QualifiedModuleName, IMutableFailedResolutionStore> _newFailedResolutionStores;
33-
private readonly ConcurrentDictionary<QualifiedMemberName, ConcurrentBag<Declaration>> _newUndeclared;
33+
private readonly ConcurrentDictionary<(QualifiedMemberName memberName, DeclarationType declarationType), ConcurrentBag<Declaration>> _newUndeclared;
3434

3535
private IDictionary<(QualifiedModuleName module, int annotatedLine), List<IParseTreeAnnotation>> _annotations;
3636
private IDictionary<Declaration, List<ParameterDeclaration>> _parametersByParent;
@@ -78,7 +78,7 @@ public DeclarationFinder(
7878
_failedResolutionStores = failedResolutionStores;
7979

8080
_newFailedResolutionStores = new ConcurrentDictionary<QualifiedModuleName, IMutableFailedResolutionStore>();
81-
_newUndeclared = new ConcurrentDictionary<QualifiedMemberName, ConcurrentBag<Declaration>>();
81+
_newUndeclared = new ConcurrentDictionary<(QualifiedMemberName memberName, DeclarationType declarationType), ConcurrentBag<Declaration>>();
8282

8383
var collectionConstructionActions = CollectionConstructionActions(declarations, annotations);
8484
ExecuteCollectionConstructionActions(collectionConstructionActions);
@@ -986,13 +986,14 @@ public Declaration OnUndeclaredVariable(Declaration enclosingProcedure, string i
986986
null,
987987
!isReDimVariable);
988988

989-
var hasUndeclared = _newUndeclared.ContainsKey(enclosingProcedure.QualifiedName);
989+
var enclosingScope = (enclosingProcedure.QualifiedName, enclosingProcedure.DeclarationType);
990+
var hasUndeclared = _newUndeclared.ContainsKey(enclosingScope);
990991
if (hasUndeclared)
991992
{
992993
ConcurrentBag<Declaration> undeclared;
993-
while (!_newUndeclared.TryGetValue(enclosingProcedure.QualifiedName, out undeclared))
994+
while (!_newUndeclared.TryGetValue(enclosingScope, out undeclared))
994995
{
995-
_newUndeclared.TryGetValue(enclosingProcedure.QualifiedName, out undeclared);
996+
_newUndeclared.TryGetValue(enclosingScope, out undeclared);
996997
}
997998
var inScopeUndeclared = undeclared.FirstOrDefault(d => d.IdentifierName == identifierName);
998999
if (inScopeUndeclared != null)
@@ -1003,7 +1004,7 @@ public Declaration OnUndeclaredVariable(Declaration enclosingProcedure, string i
10031004
}
10041005
else
10051006
{
1006-
_newUndeclared.TryAdd(enclosingProcedure.QualifiedName, new ConcurrentBag<Declaration> { undeclaredLocal });
1007+
_newUndeclared.TryAdd(enclosingScope, new ConcurrentBag<Declaration> { undeclaredLocal });
10071008
}
10081009
return undeclaredLocal;
10091010
}
@@ -1067,14 +1068,16 @@ public Declaration OnBracketedExpression(string expression, ParserRuleContext co
10671068
Debug.Assert(hostApp != null, "Host application project can't be null. Make sure VBA standard library is included if host is unknown.");
10681069

10691070
var qualifiedName = hostApp.QualifiedName.QualifiedModuleName.QualifyMemberName(expression);
1071+
var declarationType = DeclarationType.BracketedExpression;
1072+
var undeclaredScope = (qualifiedName, declarationType);
10701073

1071-
if (_newUndeclared.TryGetValue(qualifiedName, out var undeclared))
1074+
if (_newUndeclared.TryGetValue(undeclaredScope, out var undeclared))
10721075
{
10731076
return undeclared.SingleOrDefault();
10741077
}
10751078

10761079
var item = new Declaration(qualifiedName, hostApp, hostApp, Tokens.Variant, string.Empty, false, false, Accessibility.Global, DeclarationType.BracketedExpression, context, null, context.GetSelection(), true, null);
1077-
_newUndeclared.TryAdd(qualifiedName, new ConcurrentBag<Declaration> { item });
1080+
_newUndeclared.TryAdd(undeclaredScope, new ConcurrentBag<Declaration> { item });
10781081
return item;
10791082
}
10801083

RubberduckTests/Grammar/ResolverTests.cs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7300,5 +7300,77 @@ End Function
73007300
Assert.AreEqual(expectedReferenceText, enumMemberReference.IdentifierName);
73017301
}
73027302
}
7303+
7304+
[Category("Grammar")]
7305+
[Category("Resolver")]
7306+
[Test]
7307+
public void OneUndeclaredVariablePerMemberAndUndeclaredIdentifier_DifferentMemberName()
7308+
{
7309+
var moduleCode = @"
7310+
Private Sub Foo
7311+
bar = 42 + 23
7312+
bar = bar + bar
7313+
bar = bar * bar
7314+
fooBar = 42
7315+
End Sub
7316+
7317+
Private Sub DoSomething
7318+
bar = 42 + 23
7319+
bar = bar + bar
7320+
bar = bar * bar
7321+
fooBaz = 42
7322+
End Sub
7323+
";
7324+
7325+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(moduleCode, out _);
7326+
7327+
using (var state = Resolve(vbe.Object))
7328+
{
7329+
var finder = state.DeclarationFinder;
7330+
var module = finder.UserDeclarations(DeclarationType.ProceduralModule)
7331+
.Single();
7332+
var undeclared = finder.Members(module.QualifiedModuleName)
7333+
.Where(declaration => declaration.IsUndeclared)
7334+
.ToList();
7335+
7336+
Assert.AreEqual(4, undeclared.Count);
7337+
}
7338+
}
7339+
7340+
[Category("Grammar")]
7341+
[Category("Resolver")]
7342+
[Test]
7343+
public void OneUndeclaredVariablePerMemberAndUndeclaredIdentifier_DifferentDeclarationType()
7344+
{
7345+
var moduleCode = @"
7346+
Private Property Get Foo() As Variant
7347+
bar = 42 + 23
7348+
bar = bar + bar
7349+
bar = bar * bar
7350+
fooBar = 42
7351+
End Property
7352+
7353+
Private Property Let Foo(arg As Variant)
7354+
bar = 42 + 23
7355+
bar = bar + bar
7356+
bar = bar * bar
7357+
fooBaz = 42
7358+
End Property
7359+
";
7360+
7361+
var vbe = MockVbeBuilder.BuildFromSingleStandardModule(moduleCode, out _);
7362+
7363+
using (var state = Resolve(vbe.Object))
7364+
{
7365+
var finder = state.DeclarationFinder;
7366+
var module = finder.UserDeclarations(DeclarationType.ProceduralModule)
7367+
.Single();
7368+
var undeclared = finder.Members(module.QualifiedModuleName)
7369+
.Where(declaration => declaration.IsUndeclared)
7370+
.ToList();
7371+
7372+
Assert.AreEqual(4, undeclared.Count);
7373+
}
7374+
}
73037375
}
73047376
}

0 commit comments

Comments
 (0)