@@ -1015,79 +1015,78 @@ private List<Declaration> FindAllEventHandlers()
1015
1015
return handlers . ToList ( ) ;
1016
1016
}
1017
1017
1018
- public IEnumerable < Declaration > GetAccessibleUserDeclarations ( Declaration target )
1018
+ /// <summary>
1019
+ /// Finds declarations that would be in conflict with the target declaration if renamed.
1020
+ /// </summary>
1021
+ /// <returns>Zero or more declarations that would be in conflict if the target declaration is renamed.</returns>
1022
+ public IEnumerable < Declaration > FindNewDeclarationNameConflicts ( string newName , Declaration renameTarget )
1019
1023
{
1020
- if ( target == null )
1024
+ if ( newName . Equals ( renameTarget . IdentifierName ) )
1021
1025
{
1022
1026
return Enumerable . Empty < Declaration > ( ) ;
1023
1027
}
1024
1028
1025
- return _userDeclarationsByType . AllValues ( )
1026
- . Where ( callee => AccessibilityCheck . IsAccessible (
1027
- Declaration . GetProjectParent ( target ) ,
1028
- Declaration . GetModuleParent ( target ) ,
1029
- target . ParentDeclaration ,
1030
- callee ) ) ;
1031
- }
1032
-
1033
- public IEnumerable < Declaration > GetDeclarationsWithIdentifiersToAvoid ( Declaration target )
1034
- {
1035
- if ( target == null )
1029
+ var identifierMatches = MatchName ( newName ) ;
1030
+ if ( ! identifierMatches . Any ( ) )
1036
1031
{
1037
1032
return Enumerable . Empty < Declaration > ( ) ;
1038
1033
}
1039
1034
1040
- List < Declaration > declarationsToAvoid = GetNameCollisionDeclarations ( target ) . ToList ( ) ;
1041
-
1042
- declarationsToAvoid . AddRange ( GetNameCollisionDeclarations ( target . References ) ) ;
1043
-
1044
- return declarationsToAvoid . Distinct ( ) ;
1045
- }
1046
-
1047
- private IEnumerable < Declaration > GetNameCollisionDeclarations ( Declaration declaration )
1048
- {
1049
- if ( declaration == null )
1035
+ if ( IsEnumOrUDTMemberDeclaration ( renameTarget ) )
1050
1036
{
1051
- return Enumerable . Empty < Declaration > ( ) ;
1037
+ var memberMatches = identifierMatches . Where ( idm =>
1038
+ IsEnumOrUDTMemberDeclaration ( idm ) && idm . ParentDeclaration == renameTarget . ParentDeclaration ) ;
1039
+ if ( memberMatches . Any ( ) )
1040
+ {
1041
+ return memberMatches ;
1042
+ }
1052
1043
}
1053
1044
1054
- //Filter accessible declarations to those that would result in name collisions or hiding
1055
- var declarationsToAvoid = GetAccessibleUserDeclarations ( declaration ) . Where ( candidate =>
1056
- ( IsAccessibleInOtherProcedureModule ( candidate , declaration )
1057
- || candidate . DeclarationType == DeclarationType . Project
1058
- || candidate . DeclarationType . HasFlag ( DeclarationType . Module )
1059
- || IsDeclarationInSameProcedureScope ( candidate , declaration )
1060
- ) ) . ToHashSet ( ) ;
1061
-
1062
- //Add local variables when the target is a method or property
1063
- if ( IsSubroutineOrProperty ( declaration ) )
1045
+ identifierMatches = identifierMatches . Where ( nc => ! IsEnumOrUDTMemberDeclaration ( nc ) ) ;
1046
+ var referenceConflicts = identifierMatches . Where ( idm =>
1047
+ renameTarget . References
1048
+ . Any ( renameTargetRef => renameTargetRef . ParentScoping == idm . ParentDeclaration
1049
+ || renameTarget . ParentDeclaration . DeclarationType != DeclarationType . ClassModule
1050
+ && idm == renameTargetRef . ParentScoping
1051
+ && ! UsesScopeResolution ( renameTargetRef . Context . Parent )
1052
+ || idm . References
1053
+ . Any ( idmRef => idmRef . ParentScoping == renameTargetRef . ParentScoping
1054
+ && ! UsesScopeResolution ( renameTargetRef . Context . Parent ) ) )
1055
+ || idm . DeclarationType . HasFlag ( DeclarationType . Variable )
1056
+ && idm . ParentDeclaration . DeclarationType . HasFlag ( DeclarationType . Module )
1057
+ && renameTarget . References . Any ( renameTargetRef => renameTargetRef . QualifiedModuleName == idm . ParentDeclaration . QualifiedModuleName ) ) ;
1058
+
1059
+ if ( referenceConflicts . Any ( ) )
1064
1060
{
1065
- var localVariableDeclarations = _declarations . AllValues ( )
1066
- . Where ( dec => ReferenceEquals ( declaration , dec . ParentDeclaration ) ) ;
1067
- declarationsToAvoid . UnionWith ( localVariableDeclarations ) ;
1061
+ return referenceConflicts ;
1068
1062
}
1069
1063
1070
- return declarationsToAvoid ;
1064
+ var renameTargetModule = Declaration . GetModuleParent ( renameTarget ) ;
1065
+ var declarationConflicts = identifierMatches . Where ( idm =>
1066
+ renameTarget == idm . ParentDeclaration
1067
+ || AccessibilityCheck . IsAccessible (
1068
+ Declaration . GetProjectParent ( renameTarget ) ,
1069
+ renameTargetModule ,
1070
+ renameTarget . ParentDeclaration ,
1071
+ idm )
1072
+ && IsConflictingMember ( renameTarget , renameTargetModule , idm ) ) ;
1073
+
1074
+ return declarationConflicts ;
1071
1075
}
1072
1076
1073
- private IEnumerable < Declaration > GetNameCollisionDeclarations ( IEnumerable < IdentifierReference > references )
1077
+ private bool IsEnumOrUDTMemberDeclaration ( Declaration candidate )
1074
1078
{
1075
- var declarationsToAvoid = new HashSet < Declaration > ( ) ;
1076
- foreach ( var reference in references )
1077
- {
1078
- if ( ! UsesScopeResolution ( reference . Context . Parent ) )
1079
- {
1080
- declarationsToAvoid . UnionWith ( GetNameCollisionDeclarations ( reference . ParentNonScoping ) ) ;
1081
- }
1082
- }
1083
- return declarationsToAvoid ;
1079
+ return candidate . DeclarationType == DeclarationType . EnumerationMember
1080
+ || candidate . DeclarationType == DeclarationType . UserDefinedTypeMember ;
1084
1081
}
1085
1082
1086
- private bool IsAccessibleInOtherProcedureModule ( Declaration candidate , Declaration declaration )
1083
+ private bool IsConflictingMember ( Declaration renameTarget , Declaration renameTargetModule , Declaration candidate )
1087
1084
{
1088
- return IsInProceduralModule ( declaration )
1089
- && IsInProceduralModule ( candidate )
1090
- && candidate . Accessibility != Accessibility . Private ;
1085
+ var candidateModule = Declaration . GetModuleParent ( candidate ) ;
1086
+ return renameTargetModule == candidateModule
1087
+ || renameTargetModule . DeclarationType . HasFlag ( DeclarationType . ProceduralModule )
1088
+ && candidate . Accessibility != Accessibility . Private
1089
+ && candidateModule . DeclarationType . HasFlag ( DeclarationType . ProceduralModule ) ;
1091
1090
}
1092
1091
1093
1092
private bool UsesScopeResolution ( RuleContext ruleContext )
@@ -1096,25 +1095,6 @@ private bool UsesScopeResolution(RuleContext ruleContext)
1096
1095
|| ( ruleContext is VBAParser . MemberAccessExprContext ) ;
1097
1096
}
1098
1097
1099
- private bool IsInProceduralModule ( Declaration candidateDeclaration )
1100
- {
1101
- var candidateModuleDeclaration = Declaration . GetModuleParent ( candidateDeclaration ) ;
1102
-
1103
- return candidateModuleDeclaration ? . DeclarationType == DeclarationType . ProceduralModule ;
1104
- }
1105
-
1106
- private bool IsDeclarationInSameProcedureScope ( Declaration candidateDeclaration , Declaration scopingDeclaration )
1107
- {
1108
- return candidateDeclaration . ParentScope == scopingDeclaration . ParentScope ;
1109
- }
1110
-
1111
- private static bool IsSubroutineOrProperty ( Declaration declaration )
1112
- {
1113
- return declaration . DeclarationType . HasFlag ( DeclarationType . Property )
1114
- || declaration . DeclarationType == DeclarationType . Function
1115
- || declaration . DeclarationType == DeclarationType . Procedure ;
1116
- }
1117
-
1118
1098
/// <summary>
1119
1099
/// Creates a dictionary of identifier references, keyed by module.
1120
1100
/// </summary>
0 commit comments