From a23f1b3f077e91c7d289009b4ef4dc8366bb86b0 Mon Sep 17 00:00:00 2001 From: comintern Date: Wed, 6 Mar 2019 19:38:06 -0600 Subject: [PATCH] Split Documents into subclass of ClassModuleDeclaration --- .../Concrete/HungarianNotationInspection.cs | 1 + .../MoveFieldCloserToUsageInspection.cs | 2 +- .../Concrete/ParameterCanBeByValInspection.cs | 2 +- .../Concrete/ProcedureNotUsedInspection.cs | 6 ++- .../Concrete/ShadowedDeclarationInspection.cs | 44 ++++++++++++------- ...coreInPublicClassModuleMemberInspection.cs | 2 +- ...sMissingOnInappropriateArgumentQuickFix.cs | 1 + .../Commands/OpenDesignerCommand.cs | 6 +-- .../RefactorExtractInterfaceCommand.cs | 3 +- .../Binding/Bindings/IndexDefaultBinding.cs | 8 +--- .../Bindings/MemberAccessDefaultBinding.cs | 4 +- .../Bindings/MemberAccessTypeBinding.cs | 2 +- .../Binding/Bindings/SimpleNameTypeBinding.cs | 2 +- .../Symbols/ClassModuleDeclaration.cs | 7 +-- Rubberduck.Parsing/Symbols/Declaration.cs | 3 +- .../Symbols/DocumentModuleDeclaration.cs | 32 ++++++++++++++ .../Symbols/IdentifierReferenceResolver.cs | 2 +- .../DeclarationCaching/DeclarationFinder.cs | 27 +++++++----- .../DeclarationResolveRunnerBase.cs | 10 ++++- .../DeclarationSymbolsListener.cs | 5 ++- .../CompilationPasses/TypeAnnotationPass.cs | 2 +- .../CompilationPasses/TypeHierarchyPass.cs | 6 +-- .../ReferenceResolveRunnerBase.cs | 9 ++-- .../VBA/RubberduckParserState.cs | 4 +- .../Common/DeclarationExtensions.cs | 2 +- .../ImplementInterfaceRefactoring.cs | 2 +- .../IntroduceFieldRefactoring.cs | 2 +- .../IntroduceParameterRefactoring.cs | 2 +- .../CodeExplorer/CodeExplorerComparerTests.cs | 2 - 29 files changed, 127 insertions(+), 73 deletions(-) create mode 100644 Rubberduck.Parsing/Symbols/DocumentModuleDeclaration.cs diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/HungarianNotationInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/HungarianNotationInspection.cs index e8d030637a..937c2972a2 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/HungarianNotationInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/HungarianNotationInspection.cs @@ -85,6 +85,7 @@ public sealed class HungarianNotationInspection : InspectionBase DeclarationType.Constant, DeclarationType.Control, DeclarationType.ClassModule, + DeclarationType.Document, DeclarationType.Member, DeclarationType.Module, DeclarationType.ProceduralModule, diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/MoveFieldCloserToUsageInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/MoveFieldCloserToUsageInspection.cs index ad7954720b..78dabe97ba 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/MoveFieldCloserToUsageInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/MoveFieldCloserToUsageInspection.cs @@ -20,7 +20,7 @@ protected override IEnumerable DoGetInspectionResults() .Where(declaration => { if (declaration.IsWithEvents - || !new[] {DeclarationType.ClassModule, DeclarationType.ProceduralModule}.Contains(declaration.ParentDeclaration.DeclarationType) + || !new[] {DeclarationType.ClassModule, DeclarationType.Document, DeclarationType.ProceduralModule}.Contains(declaration.ParentDeclaration.DeclarationType) || IsIgnoringInspectionResultFor(declaration, AnnotationName)) { return false; diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ParameterCanBeByValInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ParameterCanBeByValInspection.cs index 4fd0247b5e..93f803aca9 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ParameterCanBeByValInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ParameterCanBeByValInspection.cs @@ -70,7 +70,7 @@ private bool CanBeChangedToBePassedByValIndividually(ParameterDeclaration parame && (parameter.IsByRef || parameter.IsImplicitByRef) && !IsParameterOfDeclaredLibraryFunction(parameter) && (parameter.AsTypeDeclaration == null - || (parameter.AsTypeDeclaration.DeclarationType != DeclarationType.ClassModule + || (!parameter.AsTypeDeclaration.DeclarationType.HasFlag(DeclarationType.ClassModule) && parameter.AsTypeDeclaration.DeclarationType != DeclarationType.UserDefinedType && parameter.AsTypeDeclaration.DeclarationType != DeclarationType.Enumeration)) && !parameter.References.Any(reference => reference.IsAssignment) diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs index 2bc9832b3a..3b4f32fcd7 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ProcedureNotUsedInspection.cs @@ -29,8 +29,10 @@ protected override IEnumerable DoGetInspectionResults() { var declarations = UserDeclarations.ToList(); - var classes = State.DeclarationFinder.UserDeclarations(DeclarationType.ClassModule).ToList(); // declarations.Where(item => item.DeclarationType == DeclarationType.ClassModule).ToList(); - var modules = State.DeclarationFinder.UserDeclarations(DeclarationType.ProceduralModule).ToList(); // declarations.Where(item => item.DeclarationType == DeclarationType.ProceduralModule).ToList(); + var classes = State.DeclarationFinder.UserDeclarations(DeclarationType.ClassModule) + .Concat(State.DeclarationFinder.UserDeclarations(DeclarationType.Document)) + .ToList(); + var modules = State.DeclarationFinder.UserDeclarations(DeclarationType.ProceduralModule).ToList(); var handlers = State.DeclarationFinder.UserDeclarations(DeclarationType.Control) .SelectMany(control => declarations.FindEventHandlers(control)).ToList(); diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/ShadowedDeclarationInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/ShadowedDeclarationInspection.cs index 869f3912b8..517045e911 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/ShadowedDeclarationInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/ShadowedDeclarationInspection.cs @@ -119,8 +119,8 @@ private static bool DeclarationInReferencedProjectCanBeShadowed(Declaration orig return false; } - var originalDeclarationComponentType = originalDeclaration.QualifiedName.QualifiedModuleName.ComponentType; - var userDeclarationComponentType = userDeclaration.QualifiedName.QualifiedModuleName.ComponentType; + var originalDeclarationEnclosingType = originalDeclaration.QualifiedName.QualifiedModuleName.ComponentType; + var userDeclarationEnclosingType = userDeclaration.QualifiedName.QualifiedModuleName.ComponentType; // It is not possible to directly access a Parameter, UDT Member or Label declared in another project if (originalDeclaration.DeclarationType == DeclarationType.Parameter || originalDeclaration.DeclarationType == DeclarationType.UserDefinedTypeMember || @@ -136,20 +136,20 @@ private static bool DeclarationInReferencedProjectCanBeShadowed(Declaration orig } // It is not possible to directly access a UserForm or Document declared in another project, nor any declarations placed inside them - if (originalDeclarationComponentType == ComponentType.UserForm || originalDeclarationComponentType == ComponentType.Document) + if (originalDeclarationEnclosingType == ComponentType.UserForm || originalDeclarationEnclosingType == ComponentType.Document) { return false; } // It is not possible to directly access any declarations placed inside a Class Module - if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && originalDeclarationComponentType == ComponentType.ClassModule) + if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && originalDeclarationEnclosingType == ComponentType.ClassModule) { return false; } - if (userDeclaration.DeclarationType == DeclarationType.ClassModule) + if (userDeclaration.DeclarationType == DeclarationType.ClassModule || userDeclaration.DeclarationType == DeclarationType.Document) { - switch (userDeclarationComponentType) + switch (userDeclarationEnclosingType) { case ComponentType.UserForm when !ReferencedProjectTypeShadowingRelations[originalDeclaration.DeclarationType].Contains(DeclarationType.UserForm): return false; @@ -158,8 +158,8 @@ private static bool DeclarationInReferencedProjectCanBeShadowed(Declaration orig } } - if (userDeclaration.DeclarationType != DeclarationType.ClassModule || - (userDeclarationComponentType != ComponentType.UserForm && userDeclarationComponentType != ComponentType.Document)) + if ((userDeclaration.DeclarationType != DeclarationType.ClassModule && userDeclaration.DeclarationType != DeclarationType.Document) || + (userDeclarationEnclosingType != ComponentType.UserForm && userDeclarationEnclosingType != ComponentType.Document)) { if (!ReferencedProjectTypeShadowingRelations[originalDeclaration.DeclarationType].Contains(userDeclaration.DeclarationType)) { @@ -188,7 +188,7 @@ private static bool DeclarationInAnotherComponentCanBeShadowed(Declaration origi return false; } - var originalDeclarationComponentType = originalDeclaration.QualifiedName.QualifiedModuleName.ComponentType; + var originalDeclarationEnclosingType = originalDeclaration.QualifiedName.QualifiedModuleName.ComponentType; // It is not possible to directly access a Parameter, UDT Member or Label declared in another component. if (originalDeclaration.DeclarationType == DeclarationType.Parameter || originalDeclaration.DeclarationType == DeclarationType.UserDefinedTypeMember || @@ -198,27 +198,33 @@ private static bool DeclarationInAnotherComponentCanBeShadowed(Declaration origi } // It is not possible to directly access any declarations placed inside a Class Module. - if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && originalDeclarationComponentType == ComponentType.ClassModule) + if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && + originalDeclaration.DeclarationType != DeclarationType.Document && + originalDeclarationEnclosingType == ComponentType.ClassModule) { return false; } // It is not possible to directly access any declarations placed inside a Document Module. (Document Modules have DeclarationType ClassMoodule.) - if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && originalDeclarationComponentType == ComponentType.Document) + if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && + originalDeclaration.DeclarationType != DeclarationType.Document && + originalDeclarationEnclosingType == ComponentType.Document) { return false; } // It is not possible to directly access any declarations placed inside a User Form. (User Forms have DeclarationType ClassMoodule.) - if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && originalDeclarationComponentType == ComponentType.UserForm) + if (originalDeclaration.DeclarationType != DeclarationType.ClassModule && + originalDeclaration.DeclarationType != DeclarationType.Document && + originalDeclarationEnclosingType == ComponentType.UserForm) { return false; } - if (originalDeclaration.DeclarationType == DeclarationType.ClassModule) + if (originalDeclaration.DeclarationType == DeclarationType.ClassModule || originalDeclaration.DeclarationType == DeclarationType.Document) { // Syntax of instantiating a new class makes it impossible to be shadowed - switch (originalDeclarationComponentType) + switch (originalDeclarationEnclosingType) { case ComponentType.ClassModule: return false; @@ -250,8 +256,12 @@ private static bool DeclarationInAnotherComponentCanBeShadowed(Declaration origi private static bool DeclarationInTheSameComponentCanBeShadowed(Declaration originalDeclaration, Declaration userDeclaration) { // Shadowing the component containing the declaration is not a problem, because it is possible to directly access declarations inside that component - if (originalDeclaration.DeclarationType == DeclarationType.ProceduralModule || originalDeclaration.DeclarationType == DeclarationType.ClassModule || - userDeclaration.DeclarationType == DeclarationType.ProceduralModule || userDeclaration.DeclarationType == DeclarationType.ClassModule) + if (originalDeclaration.DeclarationType == DeclarationType.ProceduralModule || + originalDeclaration.DeclarationType == DeclarationType.ClassModule || + originalDeclaration.DeclarationType == DeclarationType.Document || + userDeclaration.DeclarationType == DeclarationType.ProceduralModule || + userDeclaration.DeclarationType == DeclarationType.ClassModule || + userDeclaration.DeclarationType == DeclarationType.Document) { return false; } @@ -360,7 +370,7 @@ private static bool DeclarationIsLocal(Declaration declaration) }.ToHashSet(), [DeclarationType.ClassModule] = new[] { - DeclarationType.Project, DeclarationType.ProceduralModule, DeclarationType.ClassModule, DeclarationType.UserForm + DeclarationType.Project, DeclarationType.ProceduralModule, DeclarationType.ClassModule, DeclarationType.UserForm, DeclarationType.Document }.ToHashSet(), [DeclarationType.Procedure] = new[] { diff --git a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs index d28ec90c9b..052f3c3efb 100644 --- a/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs +++ b/Rubberduck.CodeAnalysis/Inspections/Concrete/UnderscoreInPublicClassModuleMemberInspection.cs @@ -19,7 +19,7 @@ protected override IEnumerable DoGetInspectionResults() var eventHandlers = State.DeclarationFinder.FindEventHandlers().ToList(); var names = State.DeclarationFinder.UserDeclarations(Parsing.Symbols.DeclarationType.Member) - .Where(w => w.ParentDeclaration.DeclarationType == Parsing.Symbols.DeclarationType.ClassModule) + .Where(w => w.ParentDeclaration.DeclarationType.HasFlag(Parsing.Symbols.DeclarationType.ClassModule)) .Where(w => !interfaceMembers.Contains(w) && !eventHandlers.Contains(w)) .Where(w => w.Accessibility == Parsing.Symbols.Accessibility.Public || w.Accessibility == Parsing.Symbols.Accessibility.Implicit) .Where(w => w.IdentifierName.Contains('_')) diff --git a/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs b/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs index 8a69d25d85..25c0fc0faa 100644 --- a/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs +++ b/Rubberduck.CodeAnalysis/QuickFixes/IsMissingOnInappropriateArgumentQuickFix.cs @@ -107,6 +107,7 @@ private string UninitializedComparisonForParameter(ParameterDeclaration paramete switch (parameter.AsTypeDeclaration.DeclarationType) { case DeclarationType.ClassModule: + case DeclarationType.Document: return $"{parameter.IdentifierName} Is {Tokens.Nothing}"; case DeclarationType.Enumeration: var members = _declarationFinderProvider.DeclarationFinder.AllDeclarations.OfType() diff --git a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs index 8c49a4190d..537270c878 100644 --- a/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs +++ b/Rubberduck.Core/UI/CodeExplorer/Commands/OpenDesignerCommand.cs @@ -48,9 +48,9 @@ protected override bool EvaluateCanExecute(object parameter) // ReSharper disable once SwitchStatementMissingSomeCases switch (declaration.DeclarationType) { - case DeclarationType.ClassModule when qualifiedModuleName.ComponentType != ComponentType.Document: - return _projectsProvider.Component(qualifiedModuleName).HasDesigner; case DeclarationType.ClassModule: + return _projectsProvider.Component(qualifiedModuleName).HasDesigner; + case DeclarationType.Document: using (var app = _vbe.HostApplication()) { return app?.CanOpenDocumentDesigner(qualifiedModuleName) ?? false; @@ -71,7 +71,7 @@ protected override void OnExecute(object parameter) if (!base.EvaluateCanExecute(parameter) || !(parameter is CodeExplorerItemViewModel node) || node.Declaration == null || - node.Declaration.DeclarationType != DeclarationType.ClassModule) + !node.Declaration.DeclarationType.HasFlag(DeclarationType.ClassModule)) { return; } diff --git a/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs b/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs index d466383c00..b4d111e78d 100644 --- a/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs +++ b/Rubberduck.Core/UI/Command/Refactorings/RefactorExtractInterfaceCommand.cs @@ -32,8 +32,9 @@ public RefactorExtractInterfaceCommand(RubberduckParserState state, IMessageBox private static readonly IReadOnlyList ModuleTypes = new[] { DeclarationType.ClassModule, + DeclarationType.Document, DeclarationType.UserForm, - DeclarationType.ProceduralModule, + DeclarationType.ProceduralModule }; protected override bool EvaluateCanExecute(object parameter) diff --git a/Rubberduck.Parsing/Binding/Bindings/IndexDefaultBinding.cs b/Rubberduck.Parsing/Binding/Bindings/IndexDefaultBinding.cs index c8f2397713..23dfddee24 100644 --- a/Rubberduck.Parsing/Binding/Bindings/IndexDefaultBinding.cs +++ b/Rubberduck.Parsing/Binding/Bindings/IndexDefaultBinding.cs @@ -201,13 +201,9 @@ private IBoundExpression ResolveDefaultMember(IBoundExpression lExpression, stri The declared type of is a specific class, which has a public default Property Get, Property Let, function or subroutine, and one of the following is true: */ - bool hasDefaultMember = asTypeDeclaration != null - && asTypeDeclaration.DeclarationType == DeclarationType.ClassModule - && ((ClassModuleDeclaration)asTypeDeclaration).DefaultMember != null; - if (hasDefaultMember) + if (asTypeDeclaration is ClassModuleDeclaration classModule + && classModule.DefaultMember is Declaration defaultMember) { - ClassModuleDeclaration classModule = (ClassModuleDeclaration)asTypeDeclaration; - Declaration defaultMember = classModule.DefaultMember; bool isPropertyGetLetFunctionProcedure = defaultMember.DeclarationType == DeclarationType.PropertyGet || defaultMember.DeclarationType == DeclarationType.PropertyLet diff --git a/Rubberduck.Parsing/Binding/Bindings/MemberAccessDefaultBinding.cs b/Rubberduck.Parsing/Binding/Bindings/MemberAccessDefaultBinding.cs index 4e30e30f47..6e98f129b1 100644 --- a/Rubberduck.Parsing/Binding/Bindings/MemberAccessDefaultBinding.cs +++ b/Rubberduck.Parsing/Binding/Bindings/MemberAccessDefaultBinding.cs @@ -144,7 +144,7 @@ private IBoundExpression ResolveLExpressionIsVariablePropertyOrFunction() { return null; } - if (referencedType.DeclarationType != DeclarationType.UserDefinedType && referencedType.DeclarationType != DeclarationType.ClassModule) + if (referencedType.DeclarationType != DeclarationType.UserDefinedType && !referencedType.DeclarationType.HasFlag(DeclarationType.ClassModule)) { return null; } @@ -378,7 +378,7 @@ the member. - The member is a value. In this case, the member access expression is classified as a value with the same declared type as the member. */ - bool isDefaultInstanceVariableClass = _lExpression.Classification == ExpressionClassification.Type && _lExpression.ReferencedDeclaration.DeclarationType == DeclarationType.ClassModule && ((ClassModuleDeclaration)_lExpression.ReferencedDeclaration).HasDefaultInstanceVariable; + bool isDefaultInstanceVariableClass = _lExpression.Classification == ExpressionClassification.Type && _lExpression.ReferencedDeclaration is ClassModuleDeclaration classModule && classModule.HasDefaultInstanceVariable; if (_lExpression.Classification != ExpressionClassification.ProceduralModule && !isDefaultInstanceVariableClass) { return null; diff --git a/Rubberduck.Parsing/Binding/Bindings/MemberAccessTypeBinding.cs b/Rubberduck.Parsing/Binding/Bindings/MemberAccessTypeBinding.cs index 7b9934840e..eb99efe795 100644 --- a/Rubberduck.Parsing/Binding/Bindings/MemberAccessTypeBinding.cs +++ b/Rubberduck.Parsing/Binding/Bindings/MemberAccessTypeBinding.cs @@ -160,7 +160,7 @@ private IBoundExpression ResolveClassModule(bool lExpressionIsEnclosingProject, */ if (lExpressionIsEnclosingProject) { - if (_module.DeclarationType == DeclarationType.ClassModule && _declarationFinder.IsMatch(_module.IdentifierName, name)) + if (_module.DeclarationType.HasFlag(DeclarationType.ClassModule) && _declarationFinder.IsMatch(_module.IdentifierName, name)) { return new MemberAccessExpression(_module, ExpressionClassification.Type, _expression, _unrestrictedNameContext, lExpression); } diff --git a/Rubberduck.Parsing/Binding/Bindings/SimpleNameTypeBinding.cs b/Rubberduck.Parsing/Binding/Bindings/SimpleNameTypeBinding.cs index fb54f1b092..5c081ce686 100644 --- a/Rubberduck.Parsing/Binding/Bindings/SimpleNameTypeBinding.cs +++ b/Rubberduck.Parsing/Binding/Bindings/SimpleNameTypeBinding.cs @@ -154,7 +154,7 @@ private IBoundExpression ResolveEnclosingProject(string name) { return new SimpleNameExpression(proceduralModuleEnclosingProject, ExpressionClassification.ProceduralModule, _expression); } - if (_module.DeclarationType == DeclarationType.ClassModule && _declarationFinder.IsMatch(_module.IdentifierName, name)) + if (_module is ClassModuleDeclaration && _declarationFinder.IsMatch(_module.IdentifierName, name)) { return new SimpleNameExpression(_module, ExpressionClassification.Type, _expression); } diff --git a/Rubberduck.Parsing/Symbols/ClassModuleDeclaration.cs b/Rubberduck.Parsing/Symbols/ClassModuleDeclaration.cs index 2be748a221..be90db1326 100644 --- a/Rubberduck.Parsing/Symbols/ClassModuleDeclaration.cs +++ b/Rubberduck.Parsing/Symbols/ClassModuleDeclaration.cs @@ -9,7 +9,7 @@ namespace Rubberduck.Parsing.Symbols { - public sealed class ClassModuleDeclaration : ModuleDeclaration + public class ClassModuleDeclaration : ModuleDeclaration { private readonly List _supertypeNames; private readonly HashSet _supertypes; @@ -28,12 +28,13 @@ public sealed class ClassModuleDeclaration : ModuleDeclaration Attributes attributes, bool isWithEvents = false, bool hasDefaultInstanceVariable = false, - bool isControl = false) + bool isControl = false, + bool isDocument = false) : base( qualifiedName, projectDeclaration, name, - DeclarationType.ClassModule, + isDocument ? DeclarationType.Document : DeclarationType.ClassModule, isUserDefined, annotations, attributes, diff --git a/Rubberduck.Parsing/Symbols/Declaration.cs b/Rubberduck.Parsing/Symbols/Declaration.cs index 26b2465799..55d359e347 100644 --- a/Rubberduck.Parsing/Symbols/Declaration.cs +++ b/Rubberduck.Parsing/Symbols/Declaration.cs @@ -235,7 +235,7 @@ public static Declaration GetModuleParent(Declaration declaration) { return null; } - if (declaration.DeclarationType == DeclarationType.ClassModule || declaration.DeclarationType == DeclarationType.ProceduralModule) + if (declaration.DeclarationType.HasFlag(DeclarationType.ClassModule) || declaration.DeclarationType == DeclarationType.ProceduralModule) { return declaration; } @@ -546,6 +546,7 @@ public string Scope case DeclarationType.Project: return "VBE"; case DeclarationType.ClassModule: + case DeclarationType.Document: case DeclarationType.ProceduralModule: return QualifiedModuleName.ToString(); case DeclarationType.Procedure: diff --git a/Rubberduck.Parsing/Symbols/DocumentModuleDeclaration.cs b/Rubberduck.Parsing/Symbols/DocumentModuleDeclaration.cs new file mode 100644 index 0000000000..026974f8e7 --- /dev/null +++ b/Rubberduck.Parsing/Symbols/DocumentModuleDeclaration.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Rubberduck.Parsing.Annotations; +using Rubberduck.VBEditor; + +namespace Rubberduck.Parsing.Symbols +{ + public class DocumentModuleDeclaration : ClassModuleDeclaration + { + public DocumentModuleDeclaration( + QualifiedMemberName qualifiedName, + Declaration projectDeclaration, + string name, + IEnumerable annotations, + Attributes attributes) + : base(qualifiedName, + projectDeclaration, + name, + true, + annotations, + attributes, + true, + true, + false, + true) + { } + } +} diff --git a/Rubberduck.Parsing/Symbols/IdentifierReferenceResolver.cs b/Rubberduck.Parsing/Symbols/IdentifierReferenceResolver.cs index fc04244112..90384c429d 100644 --- a/Rubberduck.Parsing/Symbols/IdentifierReferenceResolver.cs +++ b/Rubberduck.Parsing/Symbols/IdentifierReferenceResolver.cs @@ -32,7 +32,7 @@ public IdentifierReferenceResolver(QualifiedModuleName qualifiedModuleName, Decl _withBlockExpressions = new Stack(); _moduleDeclaration = finder.MatchName(_qualifiedModuleName.ComponentName) .SingleOrDefault(item => - (item.DeclarationType == DeclarationType.ClassModule || + (item.DeclarationType.HasFlag(DeclarationType.ClassModule) || item.DeclarationType == DeclarationType.ProceduralModule) && item.QualifiedName.QualifiedModuleName.Equals(_qualifiedModuleName)); SetCurrentScope(); diff --git a/Rubberduck.Parsing/VBA/DeclarationCaching/DeclarationFinder.cs b/Rubberduck.Parsing/VBA/DeclarationCaching/DeclarationFinder.cs index e7b3f5afa3..4a94c7b942 100644 --- a/Rubberduck.Parsing/VBA/DeclarationCaching/DeclarationFinder.cs +++ b/Rubberduck.Parsing/VBA/DeclarationCaching/DeclarationFinder.cs @@ -184,6 +184,7 @@ private void InitializeLazyCollections() private IDictionary<(VBAParser.ImplementsStmtContext Context, Declaration Implementor), List> FindAllImplementingMembers() { var implementsInstructions = UserDeclarations(DeclarationType.ClassModule) + .Concat(UserDeclarations(DeclarationType.Document)) .SelectMany(cls => cls.References .Where(reference => reference.Context is VBAParser.ImplementsStmtContext || (reference.Context).IsDescendentOf()) @@ -214,6 +215,7 @@ private IDictionary<(VBAParser.ImplementsStmtContext Context, Declaration Implem private Dictionary> FindAllImplementionsByInterface() { return UserDeclarations(DeclarationType.ClassModule) + .Concat(UserDeclarations(DeclarationType.Document)) .Cast() .Where(module => module.IsInterface).ToDictionary(intrface => intrface, intrface => intrface.Subtypes.Cast() @@ -237,6 +239,7 @@ private IDictionary<(VBAParser.ImplementsStmtContext Context, Declaration Implem private IDictionary> FindAllIinterfaceMembersByModule() { return UserDeclarations(DeclarationType.ClassModule) + .Concat(UserDeclarations(DeclarationType.Document)) .Cast() .Where(module => module.IsInterface) .ToDictionary( @@ -819,7 +822,8 @@ public Declaration FindDefaultInstanceVariableClassEnclosingProject(Declaration { var nameMatches = MatchName(defaultInstanceVariableClassName); var moduleMatches = nameMatches.Where(m => - m.DeclarationType == DeclarationType.ClassModule && ((ClassModuleDeclaration)m).HasDefaultInstanceVariable + m is ClassModuleDeclaration classModule + && classModule.HasDefaultInstanceVariable && Declaration.GetProjectParent(m).Equals(callingProject)).ToList(); var accessibleModules = moduleMatches.Where(calledModule => AccessibilityCheck.IsModuleAccessible(callingProject, callingModule, calledModule)); var match = accessibleModules.FirstOrDefault(); @@ -848,8 +852,8 @@ public Declaration FindModuleReferencedProject(Declaration callingProject, Decla public Declaration FindDefaultInstanceVariableClassReferencedProject(Declaration callingProject, Declaration callingModule, string calleeModuleName) { var moduleMatches = FindAllInReferencedProjectByPriority(callingProject, calleeModuleName, - p => p.DeclarationType == DeclarationType.ClassModule && - ((ClassModuleDeclaration) p).HasDefaultInstanceVariable); + p => p is ClassModuleDeclaration classModule && + classModule.HasDefaultInstanceVariable); var accessibleModules = moduleMatches.Where(calledModule => AccessibilityCheck.IsModuleAccessible(callingProject, callingModule, calledModule)); var match = accessibleModules.FirstOrDefault(); return match; @@ -860,8 +864,8 @@ public Declaration FindDefaultInstanceVariableClassReferencedProject(Declaration { var moduleMatches = FindAllInReferencedProjectByPriority(callingProject, calleeModuleName, p => referencedProject.Equals(Declaration.GetProjectParent(p)) - && p.DeclarationType == DeclarationType.ClassModule - && ((ClassModuleDeclaration)p).HasDefaultInstanceVariable); + && p is ClassModuleDeclaration classModule + && classModule.HasDefaultInstanceVariable); var accessibleModules = moduleMatches.Where(calledModule => AccessibilityCheck.IsModuleAccessible(callingProject, callingModule, calledModule)); var match = accessibleModules.FirstOrDefault(); return match; @@ -1082,7 +1086,7 @@ public Declaration FindMemberReferencedProject(Declaration callingProject, Decla var isInstanceSensitive = IsInstanceSensitive(memberType); var memberMatches = FindAllInReferencedProjectByPriority(callingProject, memberName, p => (!isInstanceSensitive || Declaration.GetModuleParent(p) == null || - Declaration.GetModuleParent(p).DeclarationType != DeclarationType.ClassModule) && + !Declaration.GetModuleParent(p).DeclarationType.HasFlag(DeclarationType.ClassModule)) && p.DeclarationType.HasFlag(memberType)); var accessibleMembers = memberMatches.Where(m => AccessibilityCheck.IsMemberAccessible(callingProject, callingModule, callingParent, m)); var match = accessibleMembers.FirstOrDefault(); @@ -1109,7 +1113,7 @@ public Declaration FindMemberReferencedProject(Declaration callingProject, Decla memberName, p => p.DeclarationType.HasFlag(memberType) && (Declaration.GetModuleParent(p) == null - || Declaration.GetModuleParent(p).DeclarationType == DeclarationType.ClassModule) + || Declaration.GetModuleParent(p).DeclarationType.HasFlag(DeclarationType.ClassModule)) && ((ClassModuleDeclaration)Declaration.GetModuleParent(p)).IsGlobalClassModule); var accessibleMembers = memberMatches.Where(m => AccessibilityCheck.IsMemberAccessible(callingProject, callingModule, callingParent, m)); var match = accessibleMembers.FirstOrDefault(); @@ -1240,7 +1244,7 @@ public IEnumerable FindNewDeclarationNameConflicts(string newName, return Enumerable.Empty(); } - var identifierMatches = MatchName(newName); + var identifierMatches = MatchName(newName).ToList(); if (!identifierMatches.Any()) { return Enumerable.Empty(); @@ -1252,11 +1256,11 @@ public IEnumerable FindNewDeclarationNameConflicts(string newName, IsEnumOrUDTMemberDeclaration(idm) && idm.ParentDeclaration == renameTarget.ParentDeclaration); } - identifierMatches = identifierMatches.Where(nc => !IsEnumOrUDTMemberDeclaration(nc)); + identifierMatches = identifierMatches.Where(nc => !IsEnumOrUDTMemberDeclaration(nc)).ToList(); var referenceConflicts = identifierMatches.Where(idm => renameTarget.References .Any(renameTargetRef => renameTargetRef.ParentScoping == idm.ParentDeclaration - || renameTarget.ParentDeclaration.DeclarationType != DeclarationType.ClassModule + || !renameTarget.ParentDeclaration.DeclarationType.HasFlag(DeclarationType.ClassModule) && idm == renameTargetRef.ParentScoping && !UsesScopeResolution(renameTargetRef.Context.Parent) || idm.References @@ -1264,7 +1268,8 @@ public IEnumerable FindNewDeclarationNameConflicts(string newName, && !UsesScopeResolution(renameTargetRef.Context.Parent))) || idm.DeclarationType.HasFlag(DeclarationType.Variable) && idm.ParentDeclaration.DeclarationType.HasFlag(DeclarationType.Module) - && renameTarget.References.Any(renameTargetRef => renameTargetRef.QualifiedModuleName == idm.ParentDeclaration.QualifiedModuleName)); + && renameTarget.References.Any(renameTargetRef => renameTargetRef.QualifiedModuleName == idm.ParentDeclaration.QualifiedModuleName)) + .ToList(); if (referenceConflicts.Any()) { diff --git a/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationResolveRunnerBase.cs b/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationResolveRunnerBase.cs index 206c84ad5b..63a73ca84f 100644 --- a/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationResolveRunnerBase.cs +++ b/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationResolveRunnerBase.cs @@ -176,8 +176,7 @@ protected void ResolveDeclarations(QualifiedModuleName module, IParseTree tree, QualifiedModuleName qualifiedModuleName, IParseTree tree, IDictionary> annotationsOnWhiteSpaceLines, - IDictionary<(string scopeIdentifier, DeclarationType scopeType), - Attributes> attributes, + IDictionary<(string scopeIdentifier, DeclarationType scopeType),Attributes> attributes, Declaration projectDeclaration) { var moduleAttributes = ModuleAttributes(qualifiedModuleName, attributes); @@ -201,6 +200,13 @@ protected void ResolveDeclarations(QualifiedModuleName module, IParseTree tree, true, moduleAnnotations, moduleAttributes); + case ComponentType.Document: + return new DocumentModuleDeclaration( + qualifiedModuleName.QualifyMemberName(qualifiedModuleName.ComponentName), + projectDeclaration, + qualifiedModuleName.ComponentName, + moduleAnnotations, + moduleAttributes); default: return new ClassModuleDeclaration( qualifiedModuleName.QualifyMemberName(qualifiedModuleName.ComponentName), diff --git a/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationSymbolsListener.cs b/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationSymbolsListener.cs index 2520b0fbcd..f13ccbe09f 100644 --- a/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationSymbolsListener.cs +++ b/Rubberduck.Parsing/VBA/DeclarationResolving/DeclarationSymbolsListener.cs @@ -279,9 +279,10 @@ private IEnumerable FindGeneralAnnotations(int firstLine) attributes); break; } - if (_parentDeclaration.DeclarationType == DeclarationType.ClassModule && result is ICanBeDefaultMember && ((ICanBeDefaultMember)result).IsDefaultMember) + if (_parentDeclaration is ClassModuleDeclaration classParent && + ((result as ICanBeDefaultMember)?.IsDefaultMember ?? false)) { - ((ClassModuleDeclaration)_parentDeclaration).DefaultMember = result; + classParent.DefaultMember = result; } } return result; diff --git a/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeAnnotationPass.cs b/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeAnnotationPass.cs index e5ea7a7662..ff8dadcced 100644 --- a/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeAnnotationPass.cs +++ b/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeAnnotationPass.cs @@ -43,7 +43,7 @@ public void Execute(IReadOnlyCollection modules) private void AnnotateType(Declaration declaration) { - if (declaration.DeclarationType == DeclarationType.ClassModule || + if (declaration.DeclarationType.HasFlag(DeclarationType.ClassModule) || declaration.DeclarationType == DeclarationType.UserDefinedType || declaration.DeclarationType == DeclarationType.ComAlias) { diff --git a/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeHierarchyPass.cs b/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeHierarchyPass.cs index 79eb55ab1d..295ff5886f 100644 --- a/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeHierarchyPass.cs +++ b/Rubberduck.Parsing/VBA/ReferenceManagement/CompilationPasses/TypeHierarchyPass.cs @@ -31,8 +31,8 @@ public TypeHierarchyPass(DeclarationFinder declarationFinder, VBAExpressionParse public void Execute(IReadOnlyCollection modules) { - var toRelsolveSupertypesFor = _declarationFinder - .UserDeclarations(DeclarationType.ClassModule) + var toRelsolveSupertypesFor = _declarationFinder.UserDeclarations(DeclarationType.ClassModule) + .Concat(_declarationFinder.UserDeclarations(DeclarationType.Document)) .Where(decl => modules.Contains(decl.QualifiedName.QualifiedModuleName)) .Concat(_declarationFinder.BuiltInDeclarations(DeclarationType.ClassModule)); foreach (var declaration in toRelsolveSupertypesFor) @@ -43,7 +43,7 @@ public void Execute(IReadOnlyCollection modules) private void AddImplementedInterface(Declaration potentialClassModule) { - if (potentialClassModule.DeclarationType != DeclarationType.ClassModule) + if (!potentialClassModule.DeclarationType.HasFlag(DeclarationType.ClassModule)) { return; } diff --git a/Rubberduck.Parsing/VBA/ReferenceManagement/ReferenceResolveRunnerBase.cs b/Rubberduck.Parsing/VBA/ReferenceManagement/ReferenceResolveRunnerBase.cs index c2d2035b5d..7c74eb2c59 100644 --- a/Rubberduck.Parsing/VBA/ReferenceManagement/ReferenceResolveRunnerBase.cs +++ b/Rubberduck.Parsing/VBA/ReferenceManagement/ReferenceResolveRunnerBase.cs @@ -148,17 +148,16 @@ private void ExecuteCompilationPasses(IReadOnlyCollection m private void AddSupertypesForDocumentModules(IReadOnlyCollection modules, RubberduckParserState state) { - var allClassModuleDeclarations = state.DeclarationFinder.UserDeclarations(DeclarationType.ClassModule); - var documentModuleDeclarations = allClassModuleDeclarations.Where(declaration => - declaration.QualifiedName.QualifiedModuleName.ComponentType == ComponentType.Document - && modules.Contains(declaration.QualifiedName.QualifiedModuleName)); + var documentModuleDeclarations = state.DeclarationFinder.UserDeclarations(DeclarationType.Document) + .OfType() + .Where(declaration => modules.Contains(declaration.QualifiedName.QualifiedModuleName)); foreach (var documentDeclaration in documentModuleDeclarations) { var documentSupertype = SupertypeForDocument(documentDeclaration.QualifiedName.QualifiedModuleName, state); if (documentSupertype != null) { - ((ClassModuleDeclaration)documentDeclaration).AddSupertype(documentSupertype); + documentDeclaration.AddSupertype(documentSupertype); } } } diff --git a/Rubberduck.Parsing/VBA/RubberduckParserState.cs b/Rubberduck.Parsing/VBA/RubberduckParserState.cs index eeb4cf39c8..d1ee4586e7 100644 --- a/Rubberduck.Parsing/VBA/RubberduckParserState.cs +++ b/Rubberduck.Parsing/VBA/RubberduckParserState.cs @@ -313,10 +313,10 @@ private bool ComponentIsWorksheet(ComponentRenamedEventArgs e) foreach (var declaration in AllUserDeclarations) { if (declaration.ProjectId == e.ProjectId && - declaration.DeclarationType == DeclarationType.ClassModule && + declaration is ClassModuleDeclaration classModule && declaration.IdentifierName == e.OldName) { - foreach (var superType in ((ClassModuleDeclaration)declaration).Supertypes) + foreach (var superType in classModule.Supertypes) { if (superType.IdentifierName == "Worksheet") { diff --git a/Rubberduck.Refactorings/Common/DeclarationExtensions.cs b/Rubberduck.Refactorings/Common/DeclarationExtensions.cs index edaa6a3c92..f743661f70 100644 --- a/Rubberduck.Refactorings/Common/DeclarationExtensions.cs +++ b/Rubberduck.Refactorings/Common/DeclarationExtensions.cs @@ -324,7 +324,7 @@ public static IEnumerable FindFormEventHandlers(this RubberduckPars .Select(item => new { WithEventDeclaration = item, - EventProvider = items.SingleOrDefault(type => type.DeclarationType == DeclarationType.ClassModule && type.QualifiedName.QualifiedModuleName == item.QualifiedName.QualifiedModuleName) + EventProvider = items.SingleOrDefault(type => type.DeclarationType.HasFlag(DeclarationType.ClassModule) && type.QualifiedName.QualifiedModuleName == item.QualifiedName.QualifiedModuleName) }) .Select(item => new { diff --git a/Rubberduck.Refactorings/ImplementInterface/ImplementInterfaceRefactoring.cs b/Rubberduck.Refactorings/ImplementInterface/ImplementInterfaceRefactoring.cs index a5e3e5c533..e6056c9dc6 100644 --- a/Rubberduck.Refactorings/ImplementInterface/ImplementInterfaceRefactoring.cs +++ b/Rubberduck.Refactorings/ImplementInterface/ImplementInterfaceRefactoring.cs @@ -50,7 +50,7 @@ public void Refactor() { DeclarationType.ClassModule, DeclarationType.UserForm, - DeclarationType.Document, + DeclarationType.Document }; public void Refactor(QualifiedSelection selection) diff --git a/Rubberduck.Refactorings/IntroduceField/IntroduceFieldRefactoring.cs b/Rubberduck.Refactorings/IntroduceField/IntroduceFieldRefactoring.cs index 203c97dc0f..b901470ebe 100644 --- a/Rubberduck.Refactorings/IntroduceField/IntroduceFieldRefactoring.cs +++ b/Rubberduck.Refactorings/IntroduceField/IntroduceFieldRefactoring.cs @@ -73,7 +73,7 @@ public void Refactor(Declaration target) private void PromoteVariable(Declaration target) { - if (new[] { DeclarationType.ClassModule, DeclarationType.ProceduralModule }.Contains(target.ParentDeclaration.DeclarationType)) + if (new[] { DeclarationType.ClassModule, DeclarationType.Document, DeclarationType.ProceduralModule }.Contains(target.ParentDeclaration.DeclarationType)) { _messageBox.NotifyWarn(RubberduckUI.PromoteVariable_InvalidSelection, RubberduckUI.IntroduceParameter_Caption); return; diff --git a/Rubberduck.Refactorings/IntroduceParameter/IntroduceParameterRefactoring.cs b/Rubberduck.Refactorings/IntroduceParameter/IntroduceParameterRefactoring.cs index e8e20dd3af..3e4a753518 100644 --- a/Rubberduck.Refactorings/IntroduceParameter/IntroduceParameterRefactoring.cs +++ b/Rubberduck.Refactorings/IntroduceParameter/IntroduceParameterRefactoring.cs @@ -83,7 +83,7 @@ private void PromoteVariable(Declaration target) return; } - if (new[] { DeclarationType.ClassModule, DeclarationType.ProceduralModule }.Contains(target.ParentDeclaration.DeclarationType)) + if (new[] { DeclarationType.ClassModule, DeclarationType.Document, DeclarationType.ProceduralModule }.Contains(target.ParentDeclaration.DeclarationType)) { _messageBox.NotifyWarn(RubberduckUI.PromoteVariable_InvalidSelection, RubberduckUI.IntroduceParameter_Caption); return; diff --git a/RubberduckTests/CodeExplorer/CodeExplorerComparerTests.cs b/RubberduckTests/CodeExplorer/CodeExplorerComparerTests.cs index 4a9e6e35cd..ff6ee23ec7 100644 --- a/RubberduckTests/CodeExplorer/CodeExplorerComparerTests.cs +++ b/RubberduckTests/CodeExplorer/CodeExplorerComparerTests.cs @@ -287,8 +287,6 @@ public void CompareByType_ReturnsClassModuleBelowDocument() var docNode = folder.Children.Single(s => s.Name == "Document1"); // this tests the logic I wrote to place docs above cls modules even though the parser calls them both cls modules - Assert.AreEqual(clsNode.Declaration.DeclarationType, docNode.Declaration.DeclarationType); - Assert.AreEqual(-1, new CompareByDeclarationType().Compare(docNode, clsNode)); } }