Skip to content

Commit 32a0a49

Browse files
committed
WIP - new name collision detection design
Rather than finding all possible conflicts first, now it looks for the proposed new name and works with any name matches.
1 parent 4c7a658 commit 32a0a49

File tree

1 file changed

+81
-76
lines changed

1 file changed

+81
-76
lines changed

Rubberduck.Parsing/Symbols/DeclarationFinder.cs

Lines changed: 81 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,96 +1030,101 @@ private IEnumerable<Declaration> GetAccessibleUserDeclarations(Declaration targe
10301030
callee));
10311031
}
10321032

1033-
public IEnumerable<Declaration> NewDeclarationNameConflictsWithExisting(string newName, Declaration renameTarget)
1033+
public IEnumerable<Declaration> FindNewDeclarationNameConflicts(string newName, Declaration renameTarget)
10341034
{
1035-
bool hasConflict = false;
1036-
var identifierMatches = MatchName(newName);//.ToList();
1035+
if (newName.Equals(renameTarget.IdentifierName))
1036+
{
1037+
return new List<Declaration>();
1038+
}
10371039

1038-
if (!identifierMatches.Any() || newName.Equals(renameTarget.IdentifierName))
1040+
var identifierMatches = MatchName(newName);
1041+
if (!identifierMatches.Any())
10391042
{
1040-
return new List<Declaration>();// identifierMatches;
1043+
return new List<Declaration>();
10411044
}
10421045

1043-
if (renameTarget.DeclarationType == DeclarationType.EnumerationMember
1044-
|| renameTarget.DeclarationType == DeclarationType.UserDefinedTypeMember)
1046+
if (IsEnumOrUDTMemberDeclaration(renameTarget))
10451047
{
1046-
identifierMatches = identifierMatches.Where(nc => nc.ParentDeclaration == renameTarget.ParentDeclaration); //.ToList();
1048+
identifierMatches = identifierMatches.Where(idm =>
1049+
IsEnumOrUDTMemberDeclaration(idm) && idm.ParentDeclaration == renameTarget.ParentDeclaration);
10471050
if (identifierMatches.Any())
10481051
{
10491052
return identifierMatches;
10501053
}
10511054
}
1052-
else
1053-
{
1054-
identifierMatches = identifierMatches
1055-
.Where(nc => !(nc.DeclarationType == DeclarationType.EnumerationMember
1056-
|| nc.DeclarationType == DeclarationType.UserDefinedTypeMember));
1057-
1058-
//if (accessible.Any())
1059-
//{
1060-
// return accessible;
1061-
//}
1062-
//if (IsSubroutineOrProperty(renameTarget))
1063-
//{
1064-
// //identifierMatches = identifierMatches.Where(idm => idm.ParentDeclaration == renameTarget);
1065-
// //retain member variables of the module
1066-
// identifierMatches = identifierMatches.Where(dec => ReferenceEquals(renameTarget.ParentDeclaration, dec.ParentDeclaration));
1067-
// //identifierMatches = identifierMatches.Where(dec => ((ParserRuleContext)dec.Context).GetAncestor)
1068-
//}
1069-
var localConflicts = identifierMatches.Where(idm => renameTarget.References.Any(rt => rt.ParentScoping == idm.ParentDeclaration)
1070-
|| renameTarget.References.Any(tref => idm == tref.ParentScoping)
1071-
|| renameTarget == idm.ParentDeclaration);
1072-
if (localConflicts.Any())
1073-
{
1074-
return localConflicts;
1075-
}
10761055

1077-
identifierMatches = identifierMatches.Where(callee =>
1078-
AccessibilityCheck.IsAccessible(
1079-
Declaration.GetProjectParent(renameTarget),
1080-
Declaration.GetModuleParent(renameTarget),
1081-
renameTarget.ParentDeclaration,
1082-
callee));
1083-
//return identifierMatches.Where(callee =>
1084-
// AccessibilityCheck.IsAccessible(
1085-
// Declaration.GetProjectParent(renameTarget),
1086-
// Declaration.GetModuleParent(renameTarget),
1087-
// renameTarget.ParentDeclaration,
1088-
// callee));
1089-
// || AccessibilityCheck.IsAccessible(
1090-
// Declaration.GetProjectParent(callee),
1091-
// Declaration.GetModuleParent(callee),
1092-
// callee.ParentDeclaration,
1093-
// renameTarget));
1094-
//if (identifierMatches.Any())
1095-
//{
1096-
// return identifierMatches;
1097-
//}
1056+
identifierMatches = identifierMatches.Where(nc => !IsEnumOrUDTMemberDeclaration(nc));
1057+
#if DEBUG
1058+
foreach (var idMatch in identifierMatches)
1059+
{
1060+
var predicate1 = renameTarget.References.Any(renameTargetRef => renameTargetRef.ParentScoping == idMatch.ParentDeclaration);
1061+
var predicate2 = renameTarget.References.Any(renameTargetRefs => renameTarget.ParentDeclaration.DeclarationType != DeclarationType.ClassModule
1062+
&& idMatch == renameTargetRefs.ParentScoping
1063+
&& !UsesScopeResolution(renameTargetRefs.Context.Parent));
1064+
var predicate3 = renameTarget.References
1065+
.Any(renameTargetRef => idMatch.References
1066+
.Any(idmRefs => idmRefs.ParentScoping == renameTargetRef.ParentScoping
1067+
&& !UsesScopeResolution(renameTargetRef.Context.Parent)));
1068+
var predicate4 = RenameTargetReferencedInConflictingNameDeclaringModule(renameTarget, idMatch);
1069+
var predicate5 = renameTarget == idMatch.ParentDeclaration;
1070+
var isLocalConflict = predicate1 || predicate2 || predicate3 || predicate4 || predicate5;
1071+
}
1072+
#endif
1073+
var referenceConflicts = identifierMatches.Where(idm => renameTarget.References.Any(renameTargetRef => renameTargetRef.ParentScoping == idm.ParentDeclaration)
1074+
|| renameTarget.References.Any(renameTargetRef => renameTarget.ParentDeclaration.DeclarationType != DeclarationType.ClassModule
1075+
&& idm == renameTargetRef.ParentScoping
1076+
&& !UsesScopeResolution(renameTargetRef.Context.Parent))
1077+
|| renameTarget.References
1078+
.Any(renameTargetRef => idm.References
1079+
.Any(idmRefs => idmRefs.ParentScoping == renameTargetRef.ParentScoping
1080+
&& !UsesScopeResolution(renameTargetRef.Context.Parent)))
1081+
|| RenameTargetReferencedInConflictingNameDeclaringModule(renameTarget, idm)
1082+
|| renameTarget == idm.ParentDeclaration);
1083+
if (referenceConflicts.Any())
1084+
{
1085+
return referenceConflicts;
10981086
}
10991087

1100-
//if (identifierMatches.Any())
1101-
//{
1102-
// //var accessible = GetAccessibleUserDeclarations(renameTarget);
1103-
// //foreach (var conflictDec in conflicts)
1104-
// //{
1105-
// //if (accessible.Any(ad => ad.Equals(conflictDec)))
1106-
// //{
1107-
// // hasConflict = true;
1108-
// //}
1109-
// return identifierMatches.Where(idms => identifierMatches.Any(ad => ad.Equals(idms))
1110-
// || IsSubroutineOrProperty(renameTarget) && idms.ParentDeclaration == renameTarget);
1111-
// //var accessible = GetAccessibleUserDeclarations(renameTarget);
1112-
// //if (accessible.Contains(conflictDec))
1113-
// //{
1114-
// // hasConflict = true;
1115-
// //}
1116-
// //if (!hasConflict && IsSubroutineOrProperty(renameTarget))
1117-
// //{
1118-
// // hasConflict = conflictDec.ParentDeclaration == renameTarget;
1119-
// //}
1120-
// //}
1121-
//}
1122-
return identifierMatches;
1088+
var renameTargetModule = Declaration.GetModuleParent(renameTarget);
1089+
var declarationConflicts = identifierMatches.Where(idm =>
1090+
AccessibilityCheck.IsAccessible(
1091+
Declaration.GetProjectParent(renameTarget),
1092+
renameTargetModule,
1093+
renameTarget.ParentDeclaration,
1094+
idm)
1095+
&& IsConflictingMember(renameTarget, renameTargetModule, idm));
1096+
1097+
return declarationConflicts;
1098+
}
1099+
1100+
private bool IsEnumOrUDTMemberDeclaration(Declaration candidate)
1101+
{
1102+
return candidate.DeclarationType == DeclarationType.EnumerationMember
1103+
|| candidate.DeclarationType == DeclarationType.UserDefinedTypeMember;
1104+
}
1105+
1106+
public bool IsConflictingMember(Declaration renameTarget, Declaration renameTargetModule, Declaration candidate)
1107+
{
1108+
var candidateModule = Declaration.GetModuleParent(candidate);
1109+
return renameTargetModule == candidateModule //member of same module
1110+
|| renameTargetModule.DeclarationType.HasFlag(DeclarationType.ProceduralModule)
1111+
&& candidate.Accessibility != Accessibility.Private
1112+
&& candidateModule.DeclarationType.HasFlag(DeclarationType.ProceduralModule)
1113+
;
1114+
}
1115+
1116+
public bool RenameTargetReferencedInConflictingNameDeclaringModule(Declaration renameTarget, Declaration conflictCandidate)
1117+
{
1118+
if (conflictCandidate.DeclarationType != DeclarationType.Variable)
1119+
{
1120+
return false;
1121+
}
1122+
var candidateModule = Declaration.GetModuleParent(conflictCandidate);
1123+
if (candidateModule != conflictCandidate.ParentDeclaration)
1124+
{
1125+
return false;
1126+
}
1127+
return renameTarget.References.Any(renameTargetRef => renameTargetRef.QualifiedModuleName == candidateModule.QualifiedModuleName);
11231128
}
11241129

11251130
public IEnumerable<Declaration> GetDeclarationsWithIdentifiersToAvoid(Declaration target)

0 commit comments

Comments
 (0)