protected virtual IEnumerable <Declaration> RelevantDeclarationsInModule(QualifiedModuleName module, DeclarationFinder finder)
        {
            var potentiallyRelevantDeclarations = RelevantDeclarationTypes.Length == 0
                ? finder.Members(module)
                : RelevantDeclarationTypes
                                                  .SelectMany(declarationType => finder.Members(module, declarationType))
                                                  .Distinct();

            return(potentiallyRelevantDeclarations
                   .Where(declaration => !ExcludeDeclarationTypes.Contains(declaration.DeclarationType)));
        }
        private IEnumerable <IInspectionResult> DeclarationResults(QualifiedModuleName module, DeclarationFinder finder)
        {
            var objectionableDeclarations = finder.Members(module)
                                            .Where(declaration => declaration.HasTypeHint);

            return(objectionableDeclarations.Select(InspectionResult));
        }
Exemple #3
0
        protected override IEnumerable <IInspectionResult> DoGetInspectionResults(QualifiedModuleName module, DeclarationFinder finder)
        {
            var userDeclarations     = finder.Members(module).ToList();
            var identifierReferences = finder.IdentifierReferences(module).ToList();
            var annotations          = finder.FindAnnotations(module);

            var unboundAnnotations = UnboundAnnotations(annotations, userDeclarations, identifierReferences)
                                     .Where(annotation => !annotation.Annotation.Target.HasFlag(AnnotationTarget.General) ||
                                            annotation.AnnotatedLine == null);

            var attributeAnnotationsOnDeclarationsNotAllowingAttributes = AttributeAnnotationsOnDeclarationsNotAllowingAttributes(userDeclarations);

            var illegalAnnotations = unboundAnnotations
                                     .Concat(attributeAnnotationsOnDeclarationsNotAllowingAttributes)
                                     .Distinct();

            if (module.ComponentType == ComponentType.Document)
            {
                var attributeAnnotationsInDocuments = AttributeAnnotationsInDocuments(userDeclarations);
                illegalAnnotations = illegalAnnotations
                                     .Concat(attributeAnnotationsInDocuments)
                                     .Distinct();
            }

            return(illegalAnnotations
                   .Select(InspectionResult)
                   .ToList());
        }
 private static bool ProcedureHasMinusOneLabel(DeclarationFinder finder, QualifiedContext <ParserRuleContext> context)
 {
     return(finder.Members(context.ModuleName, DeclarationType.LineLabel)
            .Any(label => label.IdentifierName.Equals("-1") &&
                 (label.ParentScopeDeclaration
                  .Context?.GetSelection()
                  .Contains(context.Context.GetSelection()) ?? false)));
 }
        protected sealed override IEnumerable <IInspectionResult> DoGetInspectionResults(QualifiedModuleName module, DeclarationFinder finder)
        {
            var annotations          = finder.FindAnnotations(module);
            var userDeclarations     = finder.Members(module).ToList();
            var identifierReferences = finder.IdentifierReferences(module).ToList();

            var invalidAnnotations = GetInvalidAnnotations(annotations, userDeclarations, identifierReferences);

            return(invalidAnnotations.Select(InspectionResult).ToList());
        }
        protected override IEnumerable <IdentifierReference> ReferencesInModule(QualifiedModuleName module, DeclarationFinder finder)
        {
            var localNonArrayVariables = finder.Members(module, DeclarationType.Variable)
                                         .Where(declaration => !declaration.IsArray &&
                                                !declaration.ParentScopeDeclaration.DeclarationType.HasFlag(DeclarationType.Module));

            return(localNonArrayVariables
                   .Where(declaration => !declaration.IsIgnoringInspectionResultFor(AnnotationName))
                   .SelectMany(d => FindUnusedAssignmentReferences(d, _walker)));
        }
Exemple #7
0
        private static bool IsIgnoringInspectionResultFor(this QualifiedModuleName module, int line, DeclarationFinder declarationFinder, string inspectionName)
        {
            var lineScopedAnnotations = declarationFinder.FindAnnotations <IgnoreAnnotation>(module, line);
            var moduleDeclaration     = declarationFinder.Members(module).First(decl => decl.DeclarationType.HasFlag(DeclarationType.Module));

            var isLineIgnored   = lineScopedAnnotations.Any(annotation => annotation.AnnotationArguments.Contains(inspectionName));
            var isModuleIgnored = moduleDeclaration.HasModuleIgnoreFor(inspectionName);

            return(isLineIgnored || isModuleIgnored);
        }
Exemple #8
0
        protected void AddModuleToModuleReferences(DeclarationFinder finder, QualifiedModuleName referencedModule)
        {
            var referencingModules = finder.Members(referencedModule)
                                     .SelectMany(declaration => declaration.References)
                                     .Select(reference => reference.QualifiedModuleName)
                                     .Distinct()
                                     .Where(referencingModule => !referencedModule.Equals(referencingModule));

            foreach (var referencingModule in referencingModules)
            {
                _moduleToModuleReferenceManager.AddModuleToModuleReference(referencingModule, referencedModule);
            }
        }
        protected override bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder)
        {
            if (!IsInterfaceDeclaration(declaration))
            {
                return(false);
            }

            var moduleBodyElements = finder.Members(declaration, DeclarationType.Member)
                                     .OfType <ModuleBodyElementDeclaration>();

            return(moduleBodyElements
                   .Any(member => member.Block.ContainsExecutableStatements(true)));
        }
        /// <summary>
        /// Filters false positive result references due to GoTo and Resume statements.  e.g.,
        /// An ErrorHandler block that branches execution to a location where the asignment may be used.
        /// </summary>
        /// <remarks>
        /// Filters Assignment references that meet the following conditions:
        /// 1. Reference precedes a GoTo or Resume statement that branches execution to a line before the
        ///     assignment reference, AND
        /// 2. A non-assignment reference is present on a line that is:
        ///     a) At or below the start of the execution branch, AND
        ///     b) Above the next ExitStatement line (if one exists) or the end of the procedure
        /// </remarks>
        private static bool IsPotentiallyUsedViaJump(IdentifierReference resultCandidate, DeclarationFinder finder)
        {
            if (!resultCandidate.Declaration.References.Any(rf => !rf.IsAssignment))
            {
                return(false);
            }

            var labelIdLineNumberPairs = finder.Members(resultCandidate.QualifiedModuleName, DeclarationType.LineLabel)
                                         .Where(label => resultCandidate.ParentScoping.Equals(label.ParentDeclaration))
                                         .ToDictionary(key => key.IdentifierName, v => v.Context.Start.Line);

            return(JumpStmtPotentiallyUsesVariable <VBAParser.GoToStmtContext>(resultCandidate, labelIdLineNumberPairs) ||
                   JumpStmtPotentiallyUsesVariable <VBAParser.ResumeStmtContext>(resultCandidate, labelIdLineNumberPairs));
        }
        private static Declaration SelectedDeclarationViaArgument(QualifiedSelection qualifiedSelection, DeclarationFinder finder)
        {
            var members = finder.Members(qualifiedSelection.QualifiedName)
                          .Where(m => (m.DeclarationType.HasFlag(DeclarationType.Procedure) || // includes PropertyLet and PropertySet and LibraryProcedure
                                       m.DeclarationType.HasFlag(DeclarationType.Function)) && // includes PropertyGet and LibraryFunction
                                 !m.DeclarationType.HasFlag(DeclarationType.LibraryFunction) &&
                                 !m.DeclarationType.HasFlag(DeclarationType.LibraryProcedure));
            var enclosingProcedure = members.SingleOrDefault(m => m.Context.GetSelection().Contains(qualifiedSelection.Selection));

            if (enclosingProcedure == null)
            {
                return(null);
            }

            var allArguments = enclosingProcedure.Context.GetDescendents <VBAParser.ArgumentContext>();

            var context = allArguments
                          .Where(arg => arg.missingArgument() == null)
                          .FirstOrDefault(m =>
            {
                var isOnWhitespace = false;
                if (m.TryGetPrecedingContext <VBAParser.WhiteSpaceContext>(out var whitespace))
                {
                    isOnWhitespace = whitespace.GetSelection().ContainsFirstCharacter(qualifiedSelection.Selection);
                }
                return(isOnWhitespace || m.GetSelection().ContainsFirstCharacter(qualifiedSelection.Selection));
            });

            var skippedArg = allArguments
                             .Where(arg => arg.missingArgument() != null)
                             .FirstOrDefault(m =>
            {
                var isOnWhitespace = false;
                if (m.TryGetPrecedingContext <VBAParser.WhiteSpaceContext>(out var whitespace))
                {
                    isOnWhitespace = whitespace.GetSelection().ContainsFirstCharacter(qualifiedSelection.Selection);
                }
                return(isOnWhitespace || m.GetSelection().ContainsFirstCharacter(qualifiedSelection.Selection));
            });

            context = context ?? skippedArg;
            if (context != null)
            {
                return((Declaration)finder.FindParameterOfNonDefaultMemberFromSimpleArgumentNotPassedByValExplicitly(context, enclosingProcedure)
                       ?? finder.FindInvokedMemberFromArgumentContext(context, qualifiedSelection.QualifiedName)); // fallback to the invoked procedure declaration
            }

            return(null);
        }
        private SerializableDeclarationTree SerializableModule(QualifiedModuleName module, ProjectDeclaration project, Dictionary <Declaration, List <Declaration> > projectLevelDeclarationsByParent, DeclarationFinder finder)
        {
            var members         = finder.Members(module).ToList();
            var membersByParent = members.Where(declaration => declaration.ParentDeclaration != null)
                                  .GroupBy(declaration => declaration.ParentDeclaration)
                                  .ToDictionary();

            var moduleDeclaration  = membersByParent[project].Single();
            var serializableModule = SerializableTree(moduleDeclaration, membersByParent);

            if (projectLevelDeclarationsByParent.TryGetValue(moduleDeclaration, out var memberDeclarationsOnProjectLevel))
            {
                serializableModule.AddChildren(memberDeclarationsOnProjectLevel);
            }

            return(serializableModule);
        }
        private static Declaration SelectedDeclarationViaDeclaration(QualifiedSelection qualifiedSelection, DeclarationFinder finder)
        {
            //There cannot be the identifier of a reference at this selection, but the module itself has this selection.
            //Resolving to the module would skip several valid alternatives.
            if (qualifiedSelection.Selection.Equals(Selection.Home))
            {
                return(null);
            }

            var declarationsInModule = finder.Members(qualifiedSelection.QualifiedName);

            return(declarationsInModule
                   .Where(declaration => declaration.IsSelected(qualifiedSelection))
                   .OrderByDescending(declaration => declaration.DeclarationType)
                   // they're sorted by type, so a local comes before the procedure it's in
                   .FirstOrDefault());
        }
Exemple #14
0
        protected ParameterDeclaration ParameterForReference(ArgumentReference reference, DeclarationFinder finder)
        {
            var argumentContext = reference.Context as VBAParser.LExprContext;

            if (!(argumentContext?.lExpression() is VBAParser.SimpleNameExprContext name))
            {
                return(null);
            }

            var procedure = reference.Context.GetAncestor <VBAParser.ModuleBodyElementContext>();
            var module    = reference.QualifiedModuleName;

            return(finder.Members(module, DeclarationType.Member)
                   .OfType <ModuleBodyElementDeclaration>()
                   .FirstOrDefault(decl => decl.Context.Parent == procedure)?.Parameters
                   .FirstOrDefault(param => param.IdentifierName.Equals(name.GetText())));
        }
        private static Declaration SelectedDeclarationViaConstantDeclarationStatement(QualifiedSelection qualifiedSelection, DeclarationFinder finder)
        {
            var constantsInModule = finder.Members(qualifiedSelection.QualifiedName)
                                    .Where(declaration => declaration.DeclarationType == DeclarationType.Constant);

            //This is annoying to do in method syntax LINQ. So this FirstOrDefault is done by hand.
            foreach (var constantDeclaration in constantsInModule)
            {
                var declarationSelection = SingleConstantDeclarationStatementSelection(constantDeclaration.Context as VBAParser.ConstSubStmtContext);
                if (declarationSelection.HasValue && declarationSelection.Value.Contains(qualifiedSelection.Selection))
                {
                    return(constantDeclaration);
                }
            }

            return(null);
        }
        protected override IEnumerable <IInspectionResult> DoGetInspectionResults(QualifiedModuleName module, DeclarationFinder finder, bool excelIsReferenced)
        {
            if (!excelIsReferenced || module.ComponentType != ComponentType.StandardModule)
            {
                return(Enumerable.Empty <IInspectionResult>());
            }

            var proceduralModuleDeclaration = finder.Members(module, DeclarationType.ProceduralModule)
                                              .SingleOrDefault() as ProceduralModuleDeclaration;

            if (proceduralModuleDeclaration == null ||
                proceduralModuleDeclaration.IsPrivateModule)
            {
                return(Enumerable.Empty <IInspectionResult>());
            }

            return(base.DoGetInspectionResults(module, finder, excelIsReferenced));
        }
 private IEnumerable <Declaration> ProjectLevelDeclarations(QualifiedModuleName projectName, DeclarationFinder finder)
 {
     return(finder.Members(projectName));
 }
Exemple #18
0
        //This does not live on the RubberduckParserState to keep concurrency haanlding out of it.
        public void RemoveAllReferencesBy(ICollection <QualifiedModuleName> referencesFromToRemove, ICollection <QualifiedModuleName> modulesNotNeedingReferenceRemoval, DeclarationFinder finder, CancellationToken token)
        {
            var referencedModulesNeedingReferenceRemoval = State.ModulesReferencedBy(referencesFromToRemove).Where(qmn => !modulesNotNeedingReferenceRemoval.Contains(qmn));

            var options = new ParallelOptions();

            options.CancellationToken      = token;
            options.MaxDegreeOfParallelism = _maxDegreeOfReferenceRemovalParallelism;

            Parallel.ForEach(referencedModulesNeedingReferenceRemoval, options, qmn => RemoveReferences(finder.Members(qmn), referencesFromToRemove));
        }
Exemple #19
0
        private static QualifiedMemberName?GetQualifiedMemberName(DeclarationFinder finder, IdentifierReference reference)
        {
            var members = finder.Members(reference.QualifiedModuleName);

            return(members.SingleOrDefault(m => reference.Context.IsDescendentOf(m.Context))?.QualifiedName);
        }