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)); }
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))); }
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); }
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()); }
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)); }
//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)); }
private static QualifiedMemberName?GetQualifiedMemberName(DeclarationFinder finder, IdentifierReference reference) { var members = finder.Members(reference.QualifiedModuleName); return(members.SingleOrDefault(m => reference.Context.IsDescendentOf(m.Context))?.QualifiedName); }