private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.CallStmtContext expression, IBoundExpression withBlockVariable, StatementResolutionContext statementContext) { // Call statements always have an argument list. // One of the reasons we're doing this is that an empty argument list could represent a call to a default member, // which requires us to use an IndexDefaultBinding. if (expression.CALL() == null) { dynamic lexpr = expression.expression(); var lexprBinding = Visit(module, parent, lexpr, withBlockVariable, StatementResolutionContext.Undefined); var argList = VisitArgumentList(module, parent, expression.argumentList(), withBlockVariable, StatementResolutionContext.Undefined); SetLeftMatch(lexprBinding, argList.Arguments.Count); return(new IndexDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression.expression(), lexprBinding, argList)); } else { var lexprBinding = Visit(module, parent, (dynamic)expression.expression(), withBlockVariable, StatementResolutionContext.Undefined); if (!(lexprBinding is IndexDefaultBinding)) { return(new IndexDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression.expression(), lexprBinding, new ArgumentList())); } else { return(lexprBinding); } } }
protected override void OnExecute(object parameter) { if (_state.Status != ParserState.Ready) { return; } var declaration = parameter is CodeExplorerItemViewModel explorerItem ? explorerItem.Declaration : GetDeclaration(); if (!(Declaration.GetProjectParent(declaration) is ProjectDeclaration project)) { return; } var dialog = _factory.Create(project); var model = dialog?.Show(); if (model is null) { return; } _reconciler.ReconcileReferences(model); _state.OnParseRequested(this); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.MemberAccessExprContext expression, IBoundExpression withBlockVariable, StatementResolutionContext statementContext) { dynamic lExpression = expression.lExpression(); var lExpressionBinding = Visit(module, parent, lExpression, withBlockVariable, StatementResolutionContext.Undefined); return(new MemberAccessDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, lExpressionBinding, statementContext, expression.unrestrictedIdentifier())); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.MemberAccessExprContext expression) { var lExpression = expression.lExpression(); var lExpressionBinding = Visit(module, parent, lExpression); return(new MemberAccessProcedurePointerBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, expression.unrestrictedIdentifier(), lExpressionBinding)); }
public AddRemoveReferencesPresenter Create() { using (var pane = _vbe.ActiveCodePane) { var selected = (ProjectDeclaration)Declaration.GetProjectParent(_state.DeclarationFinder.FindSelectedDeclaration(pane)); return(selected is null ? null : Create(selected)); } }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.MemberAccessExprContext expression) { dynamic lExpression = expression.lExpression(); var lExpressionBinding = Visit(module, parent, lExpression); SetPreferProjectOverUdt(lExpressionBinding); return(new MemberAccessTypeBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, expression.unrestrictedIdentifier(), lExpressionBinding)); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.WithMemberAccessExprContext expression, IBoundExpression withBlockVariable, StatementResolutionContext statementContext) { if (withBlockVariable == null) { withBlockVariable = new ResolutionFailedExpression(expression); } return(new MemberAccessDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, withBlockVariable, expression.unrestrictedIdentifier().GetText(), statementContext, expression.unrestrictedIdentifier())); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.IndexExprContext expression, IBoundExpression withBlockVariable, StatementResolutionContext statementContext) { dynamic lExpression = expression.lExpression(); var lExpressionBinding = Visit(module, parent, lExpression, withBlockVariable, StatementResolutionContext.Undefined); var argumentListBinding = VisitArgumentList(module, parent, expression.argumentList(), withBlockVariable, StatementResolutionContext.Undefined); SetLeftMatch(lExpressionBinding, argumentListBinding.Arguments.Count); return(new IndexDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, lExpressionBinding, argumentListBinding)); }
private IExpressionBinding VisitDictionaryAccessExpression(Declaration module, Declaration parent, ParserRuleContext expression, ParserRuleContext nameContext, IBoundExpression lExpression, StatementResolutionContext statementContext) { /* * A dictionary access expression is syntactically translated into an index expression with the same * expression for <l-expression> and an argument list with a single positional argument with a * declared type of String and a value equal to the name value of <unrestricted-name>. */ var fakeArgList = new ArgumentList(); fakeArgList.AddArgument(new ArgumentListArgument(new LiteralDefaultBinding(nameContext), ArgumentListArgumentType.Positional)); return(new IndexDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, lExpression, fakeArgList)); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.UnqualifiedObjectPrintStmtContext expression, IBoundExpression withBlockVariable) { var printMethodContext = expression.printMethod(); var simpleNameBinding = new SimpleNameDefaultBinding( _declarationFinder, Declaration.GetProjectParent(parent), module, parent, printMethodContext, printMethodContext.GetText(), StatementResolutionContext.Undefined); var outputListContext = expression.outputList(); var outputListBinding = outputListContext != null ? Visit( module, parent, outputListContext, withBlockVariable) : null; return(new ObjectPrintDefaultBinding(expression, simpleNameBinding, outputListBinding)); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.ObjectPrintExprContext expression, IBoundExpression withBlockVariable) { var lExpression = expression.lExpression(); var lExpressionBinding = Visit(module, parent, lExpression, withBlockVariable, StatementResolutionContext.Undefined); var memberAccessBinding = new MemberAccessDefaultBinding( _declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, lExpressionBinding, StatementResolutionContext.Undefined, expression.printMethod()); var outputListContext = expression.outputList(); var outputListBinding = outputListContext != null ? Visit( module, parent, outputListContext, withBlockVariable) : null; return(new ObjectPrintDefaultBinding(expression, memberAccessBinding, outputListBinding)); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.SimpleNameExprContext expression) { return(new SimpleNameTypeBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression)); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.IdentifierValueContext expression, IBoundExpression withBlockVariable, StatementResolutionContext statementContext) { return(new SimpleNameDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, Identifier.GetName(expression), statementContext)); }
private IExpressionBinding Visit(Declaration module, Declaration parent, VBAParser.SimpleNameExprContext expression, StatementResolutionContext statementContext) { return(new SimpleNameDefaultBinding(_declarationFinder, Declaration.GetProjectParent(parent), module, parent, expression, Identifier.GetName(expression.identifier()), statementContext)); }
/// <summary> /// Determines whether the 'Set' keyword is required (whether it's present or not) for the specified identifier reference. /// </summary> /// <param name="reference">The identifier reference to analyze</param> /// <param name="declarationFinderProvider">The parser state</param> public static bool RequiresSetAssignment(IdentifierReference reference, IDeclarationFinderProvider declarationFinderProvider) { if (!reference.IsAssignment) { // reference isn't assigning its declaration; not interesting return(false); } if (reference.IsSetAssignment) { // don't assume Set keyword is legit... return(reference.Declaration.IsObject); } var declaration = reference.Declaration; if (declaration.IsArray) { // arrays don't need a Set statement... todo figure out if array items are objects return(false); } var isObjectVariable = declaration.IsObject; if (!isObjectVariable && !(declaration.IsUndeclared || Tokens.Variant.Equals(declaration.AsTypeName))) { return(false); } // For Each iterators are implicitly set. var letStmtContext = reference.Context.GetAncestor <VBAParser.LetStmtContext>(); if (reference.Context.GetAncestor <VBAParser.ForEachStmtContext>() != null && letStmtContext == null) { return(false); } if (isObjectVariable) { // get the members of the returning type, a default member could make us lie otherwise var classModule = declaration.AsTypeDeclaration as ClassModuleDeclaration; return(!HasPotentiallyNonObjectParameterlessDefaultMember(classModule)); } // assigned declaration is a variant. we need to know about the RHS of the assignment. if (letStmtContext == null) { // not an assignment return(false); } var expression = letStmtContext.expression(); if (expression == null) { Debug.Assert(false, "RHS expression is empty? What's going on here?"); return(false); } var module = Declaration.GetModuleParent(reference.ParentScoping); if (expression is VBAParser.NewExprContext newExpr) { var newTypeExpression = newExpr.expression(); // todo resolve expression type //Covers the case of a single type on the RHS of the assignment. var simpleTypeName = newTypeExpression.GetDescendent <VBAParser.SimpleNameExprContext>(); if (simpleTypeName != null && simpleTypeName.GetText() == newTypeExpression.GetText()) { var qualifiedIdentifierSelection = new QualifiedSelection(module.QualifiedModuleName, simpleTypeName.identifier().GetSelection()); var identifierText = simpleTypeName.identifier().GetText(); return(declarationFinderProvider.DeclarationFinder.IdentifierReferences(qualifiedIdentifierSelection) .Select(identifierReference => identifierReference.Declaration) .Where(decl => identifierText == decl.IdentifierName) .OfType <ClassModuleDeclaration>() .Any(typeDecl => !HasPotentiallyNonObjectParameterlessDefaultMember(typeDecl))); } //Here, we err on the side of false-positives, but that seems more appropriate than not to treat qualified type expressions incorrectly. //Whether there is a legitimate use here for default members is questionable anyway. return(true); } var literalExpression = expression as VBAParser.LiteralExprContext; if (literalExpression?.literalExpression()?.literalIdentifier()?.objectLiteralIdentifier() != null) { // RHS is a 'Nothing' token - LHS needs a 'Set' keyword: return(true); } if (literalExpression != null) { return(false); // any other literal expression definitely isn't an object. } // todo resolve expression return type //Covers the case of a single variable on the RHS of the assignment. var simpleName = expression.GetDescendent <VBAParser.SimpleNameExprContext>(); if (simpleName != null && simpleName.GetText() == expression.GetText()) { var qualifiedIdentifierSelection = new QualifiedSelection(module.QualifiedModuleName, simpleName.identifier().GetSelection()); return(declarationFinderProvider.DeclarationFinder.IdentifierReferences(qualifiedIdentifierSelection) .Select(identifierReference => identifierReference.Declaration) .Where(decl => decl.IsObject && simpleName.identifier().GetText() == decl.IdentifierName) .Select(typeDeclaration => typeDeclaration.AsTypeDeclaration as ClassModuleDeclaration) .Any(typeDecl => !HasPotentiallyNonObjectParameterlessDefaultMember(typeDecl))); } var project = Declaration.GetProjectParent(reference.ParentScoping); //todo: Use code path analysis to ensure that we are really picking up the last assignment to the RHS. // is the reference referring to something else in scope that's a object? return(declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText()) .Any(decl => (decl.DeclarationType.HasFlag(DeclarationType.ClassModule) || Tokens.Object.Equals(decl.AsTypeName)) && AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, decl))); }
/// <summary> /// Determines whether the 'Set' keyword is required (whether it's present or not) for the specified identifier reference. /// </summary> /// <param name="reference">The identifier reference to analyze</param> /// <param name="declarationFinderProvider">The parser state</param> public static bool RequiresSetAssignment(IdentifierReference reference, IDeclarationFinderProvider declarationFinderProvider) { if (!reference.IsAssignment) { // reference isn't assigning its declaration; not interesting return(false); } if (reference.IsSetAssignment) { // don't assume Set keyword is legit... return(reference.Declaration.IsObject); } var declaration = reference.Declaration; if (declaration.IsArray) { // arrays don't need a Set statement... todo figure out if array items are objects return(false); } var isObjectVariable = declaration.IsObject; if (!isObjectVariable && !(declaration.IsUndeclared || Tokens.Variant.Equals(declaration.AsTypeName))) { return(false); } // For Each iterators are implicitly set. var letStmtContext = reference.Context.GetAncestor <VBAParser.LetStmtContext>(); if (reference.Context.GetAncestor <VBAParser.ForEachStmtContext>() != null && letStmtContext == null) { return(false); } if (isObjectVariable) { // get the members of the returning type, a default member could make us lie otherwise var classModule = declaration.AsTypeDeclaration as ClassModuleDeclaration; if (classModule?.DefaultMember == null) { return(true); } var parameters = (classModule.DefaultMember as IParameterizedDeclaration)?.Parameters; // assign declaration is an object without a default parameterless (or with all parameters optional) member - LHS needs a 'Set' keyword. return(parameters != null && parameters.All(p => p.IsOptional)); } // assigned declaration is a variant. we need to know about the RHS of the assignment. if (letStmtContext == null) { // not an assignment return(false); } var expression = letStmtContext.expression(); if (expression == null) { Debug.Assert(false, "RHS expression is empty? What's going on here?"); return(false); } if (expression is VBAParser.NewExprContext) { // RHS expression is newing up an object reference - LHS needs a 'Set' keyword: return(true); } var literalExpression = expression as VBAParser.LiteralExprContext; if (literalExpression?.literalExpression()?.literalIdentifier()?.objectLiteralIdentifier() != null) { // RHS is a 'Nothing' token - LHS needs a 'Set' keyword: return(true); } if (literalExpression != null) { return(false); // any other literal expression definitely isn't an object. } // todo resolve expression return type var project = Declaration.GetProjectParent(reference.ParentScoping); var module = Declaration.GetModuleParent(reference.ParentScoping); var simpleName = expression.GetDescendent <VBAParser.SimpleNameExprContext>(); if (simpleName != null) { return(declarationFinderProvider.DeclarationFinder.MatchName(simpleName.identifier().GetText()) .Any(d => AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, d) && d.IsObject)); } // is the reference referring to something else in scope that's a object? return(declarationFinderProvider.DeclarationFinder.MatchName(expression.GetText()) .Any(decl => (decl.DeclarationType.HasFlag(DeclarationType.ClassModule) || Tokens.Object.Equals(decl.AsTypeName)) && AccessibilityCheck.IsAccessible(project, module, reference.ParentScoping, decl))); }