Skip to content

Commit 67be186

Browse files
committed
Modified to leverage AccessibilityCheck class
1 parent e9050d8 commit 67be186

File tree

4 files changed

+189
-84
lines changed

4 files changed

+189
-84
lines changed

RetailCoder.VBE/Inspections/QuickFixes/AssignedByValParameterMakeLocalCopyQuickFix.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public AssignedByValParameterMakeLocalCopyQuickFix(Declaration target, Qualified
2727
_target = target;
2828
_dialogFactory = dialogFactory;
2929
_parserState = parserState;
30-
_forbiddenNames = parserState.DeclarationFinder.GetDeclarationsAccessibleToScope(target, parserState.AllUserDeclarations).Select(n => n.IdentifierName);
30+
_forbiddenNames = parserState.DeclarationFinder.GetDeclarationsWithIdentifiersToAvoid(target).Select(n => n.IdentifierName);
3131
_localCopyVariableName = ComputeSuggestedName();
3232
}
3333

RetailCoder.VBE/Refactorings/Rename/RenameRefactoring.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,12 @@ public void Refactor(Declaration target)
101101

102102
private void Rename()
103103
{
104-
var declaration = _state.DeclarationFinder.GetDeclarationsAccessibleToScope(_model.Target, _model.Declarations)
104+
var declaration = _state.DeclarationFinder.GetDeclarationsWithIdentifiersToAvoid(_model.Target)
105105
.Where(d => d.IdentifierName.Equals(_model.NewName, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();
106106
if (declaration != null)
107107
{
108108
var message = string.Format(RubberduckUI.RenameDialog_ConflictingNames, _model.NewName,
109-
declaration.IdentifierName);
109+
declaration);
110110
var rename = _messageBox.Show(message, RubberduckUI.RenameDialog_Caption, MessageBoxButtons.YesNo,
111111
MessageBoxIcon.Exclamation);
112112

Rubberduck.Parsing/Symbols/DeclarationFinder.cs

Lines changed: 105 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -740,64 +740,136 @@ private ConcurrentBag<Declaration> FindEventHandlers(IEnumerable<Declaration> de
740740
return new ConcurrentBag<Declaration>(handlers);
741741
}
742742

743-
public IEnumerable<Declaration> GetDeclarationsAccessibleToScope(Declaration target, IEnumerable<Declaration> declarations)
743+
744+
public IEnumerable<Declaration> GetAccessibleDeclarations(Declaration target)
744745
{
745746
if (target == null) { return Enumerable.Empty<Declaration>(); }
747+
748+
var declarations = GetAllDeclarations();
749+
750+
//declarations based on Accessibility
751+
var projectDeclaration = RetrieveDeclarationType(target, DeclarationType.Project);
752+
var moduleDeclaration = GetModuleDeclaration(target);
746753
return declarations
747-
.Where(candidateDeclaration =>
748-
(
749-
IsDeclarationInTheSameProcedure(candidateDeclaration, target)
750-
|| IsDeclarationChildOfTheScope(candidateDeclaration, target)
751-
|| IsModuleLevelDeclarationOfTheScope(candidateDeclaration, target)
752-
|| IsProjectGlobalDeclaration(candidateDeclaration, target)
753-
)).Distinct();
754+
.Where(callee => AccessibilityCheck.IsAccessible(projectDeclaration, moduleDeclaration, target.ParentDeclaration, callee)).ToList();
754755
}
755756

756-
private bool IsDeclarationInTheSameProcedure(Declaration candidateDeclaration, Declaration scopingDeclaration)
757+
public IEnumerable<Declaration> GetDeclarationsWithIdentifiersToAvoid(Declaration target)
758+
{
759+
if (target == null) { return Enumerable.Empty<Declaration>(); }
760+
761+
var accessibleDeclarations = GetAccessibleDeclarations(target);
762+
763+
//Filter accessible declarations to those that would result in name collisions or hiding
764+
var possibleConflictDeclarations = accessibleDeclarations.Where(dec =>
765+
IsInProceduralModule(dec)
766+
|| IsDeclarationInSameModuleScope(dec, target)
767+
|| IsDeclarationInSameProcedureScope(dec, target)
768+
|| dec.DeclarationType == DeclarationType.Project
769+
|| dec.DeclarationType == DeclarationType.ClassModule
770+
|| dec.DeclarationType == DeclarationType.ProceduralModule
771+
|| dec.DeclarationType == DeclarationType.UserForm
772+
).ToList();
773+
774+
//Add local variables when the target is a method or property
775+
if (IsMethodOrProperty(target))
776+
{
777+
var declarations = GetAllDeclarations();
778+
var localVariableDeclarations = declarations.Where(dec => target == dec.ParentDeclaration).ToList();
779+
possibleConflictDeclarations.AddRange(localVariableDeclarations.ToList());
780+
}
781+
782+
return possibleConflictDeclarations;
783+
}
784+
785+
private IEnumerable<Declaration> GetAllDeclarations()
786+
{
787+
List<Declaration> declarations = new List<Declaration>();
788+
foreach (var Key in _declarationsByName.Keys)
789+
{
790+
ConcurrentBag<Declaration> theDeclarations;
791+
_declarationsByName.TryGetValue(Key, out theDeclarations);
792+
declarations.AddRange(theDeclarations);
793+
}
794+
return declarations;
795+
}
796+
797+
private bool IsInProceduralModule(Declaration candidateDeclaration)
798+
{
799+
var candidateModuleDeclaration = GetModuleDeclaration(candidateDeclaration);
800+
if (null == candidateModuleDeclaration) { return false; }
801+
802+
return (candidateModuleDeclaration.DeclarationType == DeclarationType.ProceduralModule);
803+
}
804+
805+
private bool IsDeclarationInSameProcedureScope(Declaration candidateDeclaration, Declaration scopingDeclaration)
757806
{
758807
return candidateDeclaration.ParentScope == scopingDeclaration.ParentScope;
759808
}
760809

761-
private bool IsDeclarationChildOfTheScope(Declaration candidateDeclaration, Declaration scopingDeclaration)
810+
private bool IsChildOfScopeMethodOrProperty(Declaration candidateDeclaration, Declaration scopingDeclaration)
762811
{
763-
return scopingDeclaration == candidateDeclaration.ParentDeclaration;
812+
if (IsMethodOrProperty(scopingDeclaration))
813+
{
814+
return scopingDeclaration == candidateDeclaration.ParentDeclaration;
815+
}
816+
return false;
764817
}
765818

766-
private bool IsModuleLevelDeclarationOfTheScope(Declaration candidateDeclaration, Declaration scopingDeclaration)
819+
private bool IsDeclarationInSameModuleScope(Declaration candidateDeclaration, Declaration scopingDeclaration)
767820
{
768-
if (candidateDeclaration.ParentDeclaration == null)
821+
if (candidateDeclaration.ParentDeclaration != null)
769822
{
770-
return false;
823+
return candidateDeclaration.ComponentName == scopingDeclaration.ComponentName
824+
&& (candidateDeclaration.ParentDeclaration.DeclarationType == DeclarationType.ClassModule
825+
|| candidateDeclaration.ParentDeclaration.DeclarationType == DeclarationType.ProceduralModule);
771826
}
772-
return candidateDeclaration.ComponentName == scopingDeclaration.ComponentName
773-
&& !IsDeclaredWithinMethodOrProperty(candidateDeclaration.ParentDeclaration.Context);
827+
else
828+
return false;
774829
}
775830

776-
private bool IsProjectGlobalDeclaration(Declaration candidateDeclaration, Declaration scopingDeclaration)
831+
private bool IsMethodOrProperty(Declaration declaration)
777832
{
778-
return candidateDeclaration.ProjectName == scopingDeclaration.ProjectName
779-
&& !(candidateDeclaration.ParentScopeDeclaration is ClassModuleDeclaration)
780-
&& (IsPublicInOtherModule(candidateDeclaration, scopingDeclaration));
833+
if (declaration == null) { return false; }
834+
835+
return (declaration.DeclarationType == DeclarationType.PropertyGet)
836+
|| (declaration.DeclarationType == DeclarationType.PropertySet)
837+
|| (declaration.DeclarationType == DeclarationType.PropertyLet)
838+
|| (declaration.DeclarationType == DeclarationType.Procedure)
839+
|| (declaration.DeclarationType == DeclarationType.Function);
781840
}
782841

783-
private bool IsPublicInOtherModule(Declaration candidateDeclaration, Declaration scopingDeclaration)
842+
private Declaration GetModuleDeclaration(Declaration declaration)
784843
{
785-
return candidateDeclaration.ComponentName != scopingDeclaration.ComponentName
786-
&& (candidateDeclaration.Accessibility == Accessibility.Public
787-
|| (candidateDeclaration.Accessibility == Accessibility.Implicit)
788-
&& (candidateDeclaration.ParentScopeDeclaration is ProceduralModuleDeclaration)
789-
&& !(candidateDeclaration.DeclarationType == DeclarationType.ModuleOption));
844+
var classDeclaration = RetrieveDeclarationType(declaration, DeclarationType.ClassModule);
845+
if (null != classDeclaration)
846+
{
847+
return classDeclaration;
848+
}
849+
var moduleDeclaration = RetrieveDeclarationType(declaration, DeclarationType.ProceduralModule);
850+
if (null != moduleDeclaration)
851+
{
852+
return moduleDeclaration;
853+
}
854+
return null;
790855
}
791856

792-
private bool IsDeclaredWithinMethodOrProperty(RuleContext procedureContextCandidate)
857+
private Declaration RetrieveDeclarationType(Declaration start, DeclarationType goalType)
793858
{
794-
if (procedureContextCandidate == null) { return false; }
859+
if (start.DeclarationType == goalType) { return start; }
860+
861+
var next = start.ParentDeclaration;
862+
for (var idx = 0; idx < 10; idx++)
863+
{
864+
if (next == null) { return null; }
795865

796-
return (procedureContextCandidate is VBAParser.SubStmtContext)
797-
|| (procedureContextCandidate is VBAParser.FunctionStmtContext)
798-
|| (procedureContextCandidate is VBAParser.PropertyLetStmtContext)
799-
|| (procedureContextCandidate is VBAParser.PropertyGetStmtContext)
800-
|| (procedureContextCandidate is VBAParser.PropertySetStmtContext);
866+
if (next.DeclarationType == goalType)
867+
{
868+
return next;
869+
}
870+
next = next.ParentDeclaration;
871+
}
872+
return null;
801873
}
802874
}
803875
}

0 commit comments

Comments
 (0)