Skip to content

Commit e5e692f

Browse files
authored
Merge pull request #2772 from retailcoder/rd-next
resolver / inspection fixes
2 parents 222198a + 6a84c09 commit e5e692f

11 files changed

+93
-14
lines changed

RetailCoder.VBE/Inspections/ImplicitByRefParameterInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public ImplicitByRefParameterInspection(RubberduckParserState state)
2323
public override IEnumerable<InspectionResultBase> GetInspectionResults()
2424
{
2525
var interfaceMembers = UserDeclarations.FindInterfaceImplementationMembers();
26-
var builtinEventHandlers = State.DeclarationFinder.FindBuiltinEventHandlers();
26+
var builtinEventHandlers = State.DeclarationFinder.FindEventHandlers();
2727

2828
var issues = State.DeclarationFinder
2929
.UserDeclarations(DeclarationType.Parameter)

RetailCoder.VBE/Inspections/ParameterCanBeByValInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
3333

3434
var eventMembers = declarations.Where(item => !item.IsBuiltIn && item.DeclarationType == DeclarationType.Event).ToList();
3535
var formEventHandlerScopes = State.FindFormEventHandlers().Select(handler => handler.Scope);
36-
var eventHandlerScopes = State.DeclarationFinder.FindBuiltinEventHandlers().Concat(declarations.FindUserEventHandlers()).Select(e => e.Scope);
36+
var eventHandlerScopes = State.DeclarationFinder.FindEventHandlers().Concat(declarations.FindUserEventHandlers()).Select(e => e.Scope);
3737
var eventScopes = eventMembers.Select(s => s.Scope)
3838
.Concat(formEventHandlerScopes)
3939
.Concat(eventHandlerScopes);

RetailCoder.VBE/Inspections/ParameterNotUsedInspection.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System.Collections.Generic;
22
using System.Linq;
3-
using Rubberduck.Common;
43
using Rubberduck.Inspections.Abstract;
54
using Rubberduck.Inspections.Resources;
65
using Rubberduck.Inspections.Results;
@@ -29,7 +28,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
2928
var interfaceMembers = State.DeclarationFinder.FindAllInterfaceMembers();
3029
var interfaceImplementationMembers = State.DeclarationFinder.FindAllInterfaceImplementingMembers();
3130

32-
var builtInHandlers = State.DeclarationFinder.FindBuiltinEventHandlers();
31+
var handlers = State.DeclarationFinder.FindEventHandlers();
3332

3433
var parameters = State.DeclarationFinder
3534
.UserDeclarations(DeclarationType.Parameter)
@@ -39,7 +38,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
3938
&& parameter.ParentDeclaration.DeclarationType != DeclarationType.LibraryFunction
4039
&& parameter.ParentDeclaration.DeclarationType != DeclarationType.LibraryProcedure
4140
&& !interfaceMembers.Contains(parameter.ParentDeclaration)
42-
&& !builtInHandlers.Contains(parameter.ParentDeclaration))
41+
&& !handlers.Contains(parameter.ParentDeclaration))
4342
.ToList();
4443

4544
var issues = from issue in parameters

RetailCoder.VBE/Inspections/ProcedureCanBeWrittenAsFunctionInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
4343
}
4444

4545
var userDeclarations = UserDeclarations.ToList();
46-
var builtinHandlers = State.DeclarationFinder.FindBuiltinEventHandlers().ToList();
46+
var builtinHandlers = State.DeclarationFinder.FindEventHandlers().ToList();
4747

4848
var contextLookup = userDeclarations.Where(decl => decl.Context != null).ToDictionary(decl => decl.Context);
4949

RetailCoder.VBE/Inspections/ProcedureNotUsedInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
4141
var handlers = State.DeclarationFinder.UserDeclarations(DeclarationType.Control)
4242
.SelectMany(control => declarations.FindEventHandlers(control)).ToList();
4343

44-
var builtInHandlers = State.DeclarationFinder.FindBuiltinEventHandlers();
44+
var builtInHandlers = State.DeclarationFinder.FindEventHandlers();
4545
handlers.AddRange(builtInHandlers);
4646

4747
var withEventFields = State.DeclarationFinder.UserDeclarations(DeclarationType.Variable).Where(item => item.IsWithEvents).ToList();

RetailCoder.VBE/Inspections/UseMeaningfulNameInspection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public override IEnumerable<InspectionResultBase> GetInspectionResults()
4242
var settings = _settings.Load(new CodeInspectionSettings()) ?? new CodeInspectionSettings();
4343
var whitelistedNames = settings.WhitelistedIdentifiers.Select(s => s.Identifier).ToArray();
4444

45-
var handlers = State.DeclarationFinder.FindBuiltinEventHandlers();
45+
var handlers = State.DeclarationFinder.FindEventHandlers();
4646

4747
var issues = UserDeclarations
4848
.Where(declaration => !string.IsNullOrEmpty(declaration.IdentifierName) &&

RetailCoder.VBE/Root/RubberduckModule.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,9 @@ private IMenuItem GetRefactoringsParentMenu()
466466
var items = new IMenuItem[]
467467
{
468468
KernelInstance.Get<CodePaneRefactorRenameCommandMenuItem>(),
469+
#if DEBUG
469470
KernelInstance.Get<RefactorExtractMethodCommandMenuItem>(),
471+
#endif
470472
KernelInstance.Get<RefactorReorderParametersCommandMenuItem>(),
471473
KernelInstance.Get<RefactorRemoveParametersCommandMenuItem>(),
472474
KernelInstance.Get<RefactorIntroduceParameterCommandMenuItem>(),

Rubberduck.Parsing/Symbols/BoundExpressionVisitor.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Rubberduck.Parsing.Annotations;
22
using Rubberduck.Parsing.Binding;
3+
using Rubberduck.Parsing.Grammar;
34
using Rubberduck.VBEditor;
45

56
namespace Rubberduck.Parsing.Symbols
@@ -47,6 +48,13 @@ private void Visit(
4748
bool isAssignmentTarget,
4849
bool hasExplicitLetStatement)
4950
{
51+
if (isAssignmentTarget && expression.Context.Parent is VBAParser.IndexExprContext && !expression.ReferencedDeclaration.IsArray)
52+
{
53+
// 'SomeDictionary' is not the assignment target in 'SomeDictionary("key") = 42'
54+
// ..but we want to treat array index assignment as assignment to the array itself.
55+
isAssignmentTarget = false;
56+
}
57+
5058
var callSiteContext = expression.Context;
5159
var identifier = expression.Context.GetText();
5260
var callee = expression.ReferencedDeclaration;

Rubberduck.Parsing/Symbols/DeclarationFinder.cs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public DeclarationFinder(IReadOnlyList<Declaration> declarations, IEnumerable<IA
6464
_parametersByParent = declarations.Where(declaration => declaration.DeclarationType == DeclarationType.Parameter)
6565
.GroupBy(declaration => declaration.ParentDeclaration).ToConcurrentDictionary();
6666
_userDeclarationsByType = declarations.Where(declaration => !declaration.IsBuiltIn).GroupBy(declaration => declaration.DeclarationType).ToConcurrentDictionary();
67-
_builtinEvents = new Lazy<ConcurrentBag<Declaration>>(() => FindBuiltInEventHandlers(declarations), true);
67+
_eventHandlers = new Lazy<ConcurrentBag<Declaration>>(() => FindEventHandlers(declarations), true);
6868

6969
_projects = _projects = new Lazy<ConcurrentBag<Declaration>>(() => new ConcurrentBag<Declaration>(declarations.Where(d => d.DeclarationType == DeclarationType.Project)), true);
7070
_classes = new Lazy<ConcurrentBag<Declaration>>(() => new ConcurrentBag<Declaration>(declarations.Where(d => d.DeclarationType == DeclarationType.ClassModule)), true);
@@ -165,12 +165,12 @@ public IEnumerable<Declaration> FindDeclarationsWithNonBaseAsType()
165165
}
166166
}
167167

168-
private readonly Lazy<ConcurrentBag<Declaration>> _builtinEvents;
169-
public IEnumerable<Declaration> FindBuiltinEventHandlers()
168+
private readonly Lazy<ConcurrentBag<Declaration>> _eventHandlers;
169+
public IEnumerable<Declaration> FindEventHandlers()
170170
{
171171
lock (ThreadLock)
172172
{
173-
return _builtinEvents.Value;
173+
return _eventHandlers.Value;
174174
}
175175
}
176176

@@ -695,7 +695,23 @@ private IEnumerable<Declaration> FindAllInReferencedProjectByPriority(Declaratio
695695
}
696696
}
697697

698-
public ConcurrentBag<Declaration> FindBuiltInEventHandlers(IEnumerable<Declaration> declarations)
698+
private IEnumerable<Declaration> FindFormControlHandlers(IReadOnlyList<Declaration> declarations)
699+
{
700+
var controls = declarations
701+
.Where(declaration => declaration.DeclarationType == DeclarationType.Control);
702+
var handlerNames = declarations
703+
.Where(declaration => declaration.IsBuiltIn && declaration.DeclarationType == DeclarationType.Event)
704+
.SelectMany(e => controls.Select(c => c.IdentifierName + "_" + e.IdentifierName));
705+
if (!_userDeclarationsByType.ContainsKey(DeclarationType.Procedure))
706+
{
707+
return Enumerable.Empty<Declaration>();
708+
}
709+
var handlers = _userDeclarationsByType[DeclarationType.Procedure]
710+
.Where(procedure => handlerNames.Contains(procedure.IdentifierName));
711+
return handlers;
712+
}
713+
714+
private ConcurrentBag<Declaration> FindEventHandlers(IEnumerable<Declaration> declarations)
699715
{
700716
var declarationList = declarations.ToList();
701717

@@ -725,7 +741,9 @@ public ConcurrentBag<Declaration> FindBuiltInEventHandlers(IEnumerable<Declarati
725741
(!item.IsBuiltIn &&
726742
item.DeclarationType == DeclarationType.Procedure &&
727743
handlerNames.Contains(item.IdentifierName))
728-
);
744+
)
745+
.Concat(_handlersByWithEventsField.Value.SelectMany(kvp => kvp.Value))
746+
.Concat(FindFormControlHandlers(declarationList));
729747

730748
return new ConcurrentBag<Declaration>(handlers);
731749
}

RubberduckTests/Grammar/ResolverTests.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,30 @@ End Sub
902902
&& !item.IsAssignment));
903903
}
904904

905+
[TestMethod]
906+
public void SubscriptWrite_IsNotAssignmentReferenceToObjectDeclaration()
907+
{
908+
var code = @"
909+
Public Sub DoSomething()
910+
Dim foo As Object
911+
Set foo = CreateObject(""Scripting.Dictionary"")
912+
foo(""key"") = 42
913+
End Sub
914+
";
915+
// act
916+
var state = Resolve(code);
917+
918+
// assert
919+
var declaration = state.AllUserDeclarations.Single(item =>
920+
item.DeclarationType == DeclarationType.Variable
921+
&& item.IdentifierName == "foo");
922+
923+
Assert.IsNotNull(declaration.References.SingleOrDefault(item =>
924+
item.ParentScoping.DeclarationType == DeclarationType.Procedure
925+
&& item.ParentScoping.IdentifierName == "DoSomething"
926+
&& !item.IsAssignment));
927+
}
928+
905929
[TestMethod]
906930
public void ArraySubscriptWrite_IsAssignmentReferenceToArrayDeclaration()
907931
{

0 commit comments

Comments
 (0)