@@ -740,64 +740,136 @@ private ConcurrentBag<Declaration> FindEventHandlers(IEnumerable<Declaration> de
740
740
return new ConcurrentBag < Declaration > ( handlers ) ;
741
741
}
742
742
743
- public IEnumerable < Declaration > GetDeclarationsAccessibleToScope ( Declaration target , IEnumerable < Declaration > declarations )
743
+
744
+ public IEnumerable < Declaration > GetAccessibleDeclarations ( Declaration target )
744
745
{
745
746
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 ) ;
746
753
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 ( ) ;
754
755
}
755
756
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 )
757
806
{
758
807
return candidateDeclaration . ParentScope == scopingDeclaration . ParentScope ;
759
808
}
760
809
761
- private bool IsDeclarationChildOfTheScope ( Declaration candidateDeclaration , Declaration scopingDeclaration )
810
+ private bool IsChildOfScopeMethodOrProperty ( Declaration candidateDeclaration , Declaration scopingDeclaration )
762
811
{
763
- return scopingDeclaration == candidateDeclaration . ParentDeclaration ;
812
+ if ( IsMethodOrProperty ( scopingDeclaration ) )
813
+ {
814
+ return scopingDeclaration == candidateDeclaration . ParentDeclaration ;
815
+ }
816
+ return false ;
764
817
}
765
818
766
- private bool IsModuleLevelDeclarationOfTheScope ( Declaration candidateDeclaration , Declaration scopingDeclaration )
819
+ private bool IsDeclarationInSameModuleScope ( Declaration candidateDeclaration , Declaration scopingDeclaration )
767
820
{
768
- if ( candidateDeclaration . ParentDeclaration = = null )
821
+ if ( candidateDeclaration . ParentDeclaration ! = null )
769
822
{
770
- return false ;
823
+ return candidateDeclaration . ComponentName == scopingDeclaration . ComponentName
824
+ && ( candidateDeclaration . ParentDeclaration . DeclarationType == DeclarationType . ClassModule
825
+ || candidateDeclaration . ParentDeclaration . DeclarationType == DeclarationType . ProceduralModule ) ;
771
826
}
772
- return candidateDeclaration . ComponentName == scopingDeclaration . ComponentName
773
- && ! IsDeclaredWithinMethodOrProperty ( candidateDeclaration . ParentDeclaration . Context ) ;
827
+ else
828
+ return false ;
774
829
}
775
830
776
- private bool IsProjectGlobalDeclaration ( Declaration candidateDeclaration , Declaration scopingDeclaration )
831
+ private bool IsMethodOrProperty ( Declaration declaration )
777
832
{
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 ) ;
781
840
}
782
841
783
- private bool IsPublicInOtherModule ( Declaration candidateDeclaration , Declaration scopingDeclaration )
842
+ private Declaration GetModuleDeclaration ( Declaration declaration )
784
843
{
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 ;
790
855
}
791
856
792
- private bool IsDeclaredWithinMethodOrProperty ( RuleContext procedureContextCandidate )
857
+ private Declaration RetrieveDeclarationType ( Declaration start , DeclarationType goalType )
793
858
{
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 ; }
795
865
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 ;
801
873
}
802
874
}
803
875
}
0 commit comments