public void SetCurrentScope(string memberName, DeclarationType type) { Logger.Trace("Setting current scope: {0} ({1}) in thread {2}", memberName, type, Thread.CurrentThread.ManagedThreadId); _currentParent = _declarationFinder.MatchName(memberName).SingleOrDefault(item => item.QualifiedName.QualifiedModuleName == _qualifiedModuleName && item.DeclarationType == type); _currentScope = _declarationFinder.MatchName(memberName).SingleOrDefault(item => item.QualifiedName.QualifiedModuleName == _qualifiedModuleName && item.DeclarationType == type) ?? _moduleDeclaration; Logger.Trace("Current scope is now {0} in thread {1}", _currentScope == null ? "null" : _currentScope.IdentifierName, Thread.CurrentThread.ManagedThreadId); }
private static bool ThereIsAnLBoundFunctionDeclaration(DeclarationFinder finder, Declaration InformationModule) { var lBoundFunction = LBoundFunction(InformationModule); return(finder.MatchName(lBoundFunction.IdentifierName) .Any(declaration => declaration.Equals(lBoundFunction))); }
private static bool TheFormsActivateEventIsAlreadyThere(DeclarationFinder finder, Declaration formsClassModule) { var userFormActivateEvent = UserFormActivateEvent(formsClassModule); return(finder.MatchName(userFormActivateEvent.IdentifierName) .Any(declaration => declaration.Equals(userFormActivateEvent))); }
private bool ThereIsAnErrorFunctionDeclaration(DeclarationFinder finder) { var errorFunction = ErrorFunction(); return(finder.MatchName(errorFunction.IdentifierName) .Any(declaration => declaration.Equals(errorFunction))); }
private static bool ThereIsADebugModule(DeclarationFinder finder, Declaration vbaProject) { var debugModule = DebugModuleDeclaration(vbaProject); return(finder.MatchName(debugModule.IdentifierName) .Any(declaration => declaration.Equals(debugModule))); }
private void AddBuiltInDeclarations(IReadOnlyList <VBProject> projects) { var finder = new DeclarationFinder(_state.AllDeclarations, new CommentNode[] { }, new IAnnotation[] { }); foreach (var item in finder.MatchName(Tokens.Err)) { if (item.IsBuiltIn && item.DeclarationType == DeclarationType.Variable && item.Accessibility == Accessibility.Global) { return; } } var vba = finder.FindProject("VBA"); if (vba == null) { // if VBA project is null, we haven't loaded any COM references; // we're in a unit test and mock project didn't setup any references. return; } var informationModule = finder.FindStdModule("Information", vba, true); Debug.Assert(informationModule != null, "We expect the information module to exist in the VBA project."); var customDeclarations = CustomDeclarations.Load(vba, informationModule); lock (_state) { foreach (var customDeclaration in customDeclarations) { _state.AddDeclaration(customDeclaration); } } }
protected override bool IsResultDeclaration(Declaration declaration, DeclarationFinder finder) { return((declaration.Accessibility == Accessibility.Implicit || declaration.Accessibility == Accessibility.Public || declaration.Accessibility == Accessibility.Global) && finder.MatchName(declaration.IdentifierName) .Where(otherDeclaration => otherDeclaration.QualifiedModuleName.Equals(declaration.QualifiedModuleName)) .All(accessor => accessor.DeclarationType != DeclarationType.PropertyGet)); }
protected override IEnumerable <Declaration> ObjectionableDeclarations(DeclarationFinder finder) { return(finder.UserDeclarations(DeclarationType.Variable) .Where(declaration => !declaration.IsArray && !declaration.IsSelfAssigned && finder.MatchName(declaration.AsTypeName) .All(d => d.DeclarationType != DeclarationType.UserDefinedType) && !declaration.References .Any(reference => reference.IsAssignment) && !declaration.References .Any(reference => IsAssignedByRefArgument(reference.ParentScoping, reference, finder)))); }
protected override bool IsResultReference(IdentifierReference reference, DeclarationFinder finder) { var qualifiers = base.GetQualifierCandidates(reference, finder); var isQualified = qualifiers.Any(); var document = Declaration.GetModuleParent(reference.ParentNonScoping) as DocumentModuleDeclaration; var isHostWorkbook = (document?.SupertypeNames.Contains("Workbook") ?? false) && (document?.ProjectId?.Equals(reference.QualifiedModuleName.ProjectId) ?? false); if (!isQualified) { // unqualified calls aren't referring to ActiveWorkbook only inside a Workbook module: return(!isHostWorkbook); } else { if (_applicationCandidates == null) { var applicationClass = finder.FindClassModule("Application", base.Excel, includeBuiltIn: true); // note: underscored declarations would be for unqualified calls var workbookClass = finder.FindClassModule("Workbook", base.Excel, includeBuiltIn: true); var worksheetClass = finder.FindClassModule("Worksheet", base.Excel, includeBuiltIn: true); var hostBook = finder.UserDeclarations(DeclarationType.Document) .Cast <DocumentModuleDeclaration>() .SingleOrDefault(doc => doc.ProjectId.Equals(reference.QualifiedModuleName.ProjectId) && doc.SupertypeNames.Contains("Workbook")); _applicationCandidates = finder.MatchName("Application") .Where(m => m.Equals(applicationClass) || (m.ParentDeclaration.Equals(workbookClass) && m.DeclarationType.HasFlag(DeclarationType.PropertyGet)) || (m.ParentDeclaration.Equals(worksheetClass) && m.DeclarationType.HasFlag(DeclarationType.PropertyGet)) || (m.ParentDeclaration.Equals(hostBook) && m.DeclarationType.HasFlag(DeclarationType.PropertyGet))) .ToList(); } // qualified calls are referring to ActiveWorkbook if qualifier is the Application object: return(_applicationCandidates.Any(candidate => qualifiers.Any(q => q.Equals(candidate)))); } }
public IdentifierReferenceResolver(QualifiedModuleName qualifiedModuleName, DeclarationFinder finder) { _declarationFinder = finder; _qualifiedModuleName = qualifiedModuleName; _withBlockExpressions = new Stack <IBoundExpression>(); _moduleDeclaration = finder.MatchName(_qualifiedModuleName.ComponentName) .SingleOrDefault(item => (item.DeclarationType.HasFlag(DeclarationType.ClassModule) || item.DeclarationType == DeclarationType.ProceduralModule) && item.QualifiedName.QualifiedModuleName.Equals(_qualifiedModuleName)); SetCurrentScope(); var typeBindingContext = new TypeBindingContext(_declarationFinder); var procedurePointerBindingContext = new ProcedurePointerBindingContext(_declarationFinder); _bindingService = new BindingService( _declarationFinder, new DefaultBindingContext(_declarationFinder, typeBindingContext, procedurePointerBindingContext), typeBindingContext, procedurePointerBindingContext); _boundExpressionVisitor = new BoundExpressionVisitor(finder); _failedResolutionVisitor = new FailedResolutionVisitor(finder); }
private void AddBuiltInDeclarations(IReadOnlyList <VBProject> projects) { SyncComReferences(projects); var finder = new DeclarationFinder(_state.AllDeclarations, new CommentNode[] {}, new IAnnotation[] {}); if (finder.MatchName(Tokens.Err).Any(item => item.IsBuiltIn && item.DeclarationType == DeclarationType.Variable && item.Accessibility == Accessibility.Global)) { return; } var vba = finder.FindProject("VBA"); Debug.Assert(vba != null); var errObject = finder.FindClass(vba, "ErrObject", true); Debug.Assert(errObject != null); var qualifiedName = new QualifiedModuleName(vba.IdentifierName, vba.IdentifierName, errObject.IdentifierName); var err = new Declaration(new QualifiedMemberName(qualifiedName, Tokens.Err), vba, "Global", errObject.IdentifierName, true, false, Accessibility.Global, DeclarationType.Variable); _state.AddDeclaration(err); var debugClassName = new QualifiedModuleName(vba.IdentifierName, vba.IdentifierName, "DebugClass"); var debugClass = new Declaration(new QualifiedMemberName(debugClassName, "DebugClass"), vba, "Global", "DebugClass", false, false, Accessibility.Global, DeclarationType.ClassModule); var debugObject = new Declaration(new QualifiedMemberName(debugClassName, "Debug"), vba, "Global", "DebugClass", true, false, Accessibility.Global, DeclarationType.Variable); var debugAssert = new Declaration(new QualifiedMemberName(debugClassName, "Assert"), debugObject, debugObject.Scope, null, false, false, Accessibility.Global, DeclarationType.Procedure); var debugPrint = new Declaration(new QualifiedMemberName(debugClassName, "Print"), debugObject, debugObject.Scope, null, false, false, Accessibility.Global, DeclarationType.Procedure); _state.AddDeclaration(debugClass); _state.AddDeclaration(debugObject); _state.AddDeclaration(debugAssert); _state.AddDeclaration(debugPrint); }
private static bool ThereIsAGlobalBuiltInErrVariableDeclaration(DeclarationFinder finder) { return(finder.MatchName(Grammar.Tokens.Err).Any(declaration => declaration.IsBuiltIn && declaration.DeclarationType == DeclarationType.Variable && declaration.Accessibility == Accessibility.Global)); }
/// <summary> /// Gets the possible <see cref="Declaration"/> that qualifies an identifier reference in a member access expression. /// </summary> protected IEnumerable <Declaration> GetQualifierCandidates(IdentifierReference reference, DeclarationFinder finder) { if (reference.Context.TryGetAncestor <VBAParser.MemberAccessExprContext>(out var memberAccess)) { var parentModule = Declaration.GetModuleParent(reference.ParentScoping); var qualifyingExpression = memberAccess.lExpression(); if (qualifyingExpression is VBAParser.SimpleNameExprContext simpleName) { if (simpleName.GetText().Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase)) { // qualifier is 'Me' return(new[] { parentModule }); } // todo get the actual qualifying declaration? return(finder.MatchName(simpleName.GetText()) .Where(candidate => !candidate.IdentifierName.Equals(reference.Declaration.IdentifierName, System.StringComparison.InvariantCultureIgnoreCase))); } if (qualifyingExpression.ChildCount == 1 && qualifyingExpression.GetText().Equals(Tokens.Me, System.StringComparison.InvariantCultureIgnoreCase)) { // qualifier is 'Me' return(new[] { parentModule }); } } if (reference.Context.TryGetAncestor <VBAParser.WithMemberAccessExprContext>(out var dot)) { // qualifier is a With block var withBlock = dot.GetAncestor <VBAParser.WithStmtContext>(); return(finder.ContainedIdentifierReferences(new QualifiedSelection(reference.QualifiedModuleName, withBlock.GetSelection())) .Select(r => r.Declaration).Distinct() .Where(candidate => !candidate.Equals(reference.Declaration))); } if (reference.Context.TryGetAncestor <VBAParser.CallStmtContext>(out var callStmt)) { if (reference.Context.TryGetAncestor <VBAParser.LExpressionContext>(out var lExpression)) { // reference is in lexpression of a call statement if (lExpression is VBAParser.MemberAccessExprContext member) { if (member.lExpression() is VBAParser.SimpleNameExprContext name) { if (reference.IdentifierName.Equals(name.identifier().GetText(), System.StringComparison.InvariantCultureIgnoreCase)) { // unqualified return(Enumerable.Empty <Declaration>()); } return(finder.MatchName(name.identifier().GetText()) .Where(candidate => !candidate.Equals(reference.Declaration))); } // todo get the actual qualifying declaration? return(finder.MatchName(member.lExpression().children.First().GetText()) .Where(candidate => !candidate.Equals(reference.Declaration))); } } } return(Enumerable.Empty <Declaration>()); }
private static Declaration ShadowedDeclaration(Declaration userDeclaration, ICollection <string> referencedProjectIds, DeclarationFinder finder) { return(finder.MatchName(userDeclaration.IdentifierName) .FirstOrDefault(declaration => !declaration.Equals(userDeclaration) && DeclarationCanBeShadowed(declaration, userDeclaration, referencedProjectIds))); }
private static bool HasUdtType(Declaration declaration, DeclarationFinder finder) { return(finder.MatchName(declaration.AsTypeName) .Any(item => item.DeclarationType == DeclarationType.UserDefinedType)); }
private static ClassModuleDeclaration GetHostApplicationDeclaration(DeclarationFinder finder) { var result = finder.MatchName("Application").OfType <ClassModuleDeclaration>().FirstOrDefault(t => t.ProjectName == "Excel" && !t.IsUserDefined) as ClassModuleDeclaration; return(result ?? throw new System.InvalidOperationException("Failed to find the host Application declaration.")); }