示例#1
0
        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)));
        }
示例#3
0
        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)));
        }
示例#5
0
        private static bool ThereIsADebugModule(DeclarationFinder finder, Declaration vbaProject)
        {
            var debugModule = DebugModuleDeclaration(vbaProject);

            return(finder.MatchName(debugModule.IdentifierName)
                   .Any(declaration => declaration.Equals(debugModule)));
        }
示例#6
0
        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);
                }
            }
        }
示例#7
0
 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))));
            }
        }
示例#10
0
        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);
        }
示例#11
0
        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);
        }
示例#12
0
 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));
 }
示例#16
0
        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."));
        }