Inheritance: Rubberduck.Parsing.Binding.BoundExpression
Beispiel #1
0
        private IBoundExpression ResolveRecursiveDefaultMember(Declaration defaultMember, ExpressionClassification defaultMemberClassification, ArgumentList argumentList, ParserRuleContext expression, Declaration parent, int defaultMemberResolutionRecursionDepth, RecursiveDefaultMemberAccessExpression containedExpression)
        {
            var defaultMemberRecursionExpression = new RecursiveDefaultMemberAccessExpression(defaultMember, defaultMemberClassification, _lExpression.Context, defaultMemberResolutionRecursionDepth, containedExpression);

            var defaultMemberAsLExpression = new SimpleNameExpression(defaultMember, defaultMemberClassification, expression);

            return(Resolve(defaultMemberAsLExpression, argumentList, expression, parent, defaultMemberResolutionRecursionDepth, defaultMemberRecursionExpression));
        }
        private IBoundExpression ResolveDefaultMember(IBoundExpression lExpression, string asTypeName, Declaration asTypeDeclaration)
        {
            if (lExpression.ReferencedDeclaration.IsArray)
            {
                return(null);
            }

            /*
             *  The declared type of <l-expression> is Object or Variant, and <argument-list> contains no
             *  named arguments. In this case, the index expression is classified as an unbound member with
             *  a declared type of Variant, referencing <l-expression> with no member name.
             */
            if (
                asTypeName != null &&
                (asTypeName.ToUpperInvariant() == "VARIANT" || asTypeName.ToUpperInvariant() == "OBJECT") &&
                !_argumentList.HasNamedArguments)
            {
                return(new IndexExpression(null, ExpressionClassification.Unbound, _expression, lExpression, _argumentList));
            }

            /*
             *  The declared type of <l-expression> is a specific class, which has a public default Property
             *  Get, Property Let, function or subroutine, and one of the following is true:
             */
            bool hasDefaultMember = asTypeDeclaration != null &&
                                    asTypeDeclaration.DeclarationType == DeclarationType.ClassModule &&
                                    ((ClassModuleDeclaration)asTypeDeclaration).DefaultMember != null;

            if (hasDefaultMember)
            {
                ClassModuleDeclaration classModule     = (ClassModuleDeclaration)asTypeDeclaration;
                Declaration            defaultMember   = classModule.DefaultMember;
                bool isPropertyGetLetFunctionProcedure =
                    defaultMember.DeclarationType == DeclarationType.PropertyGet ||
                    defaultMember.DeclarationType == DeclarationType.PropertyLet ||
                    defaultMember.DeclarationType == DeclarationType.Function ||
                    defaultMember.DeclarationType == DeclarationType.Procedure;
                bool isPublic =
                    defaultMember.Accessibility == Accessibility.Global ||
                    defaultMember.Accessibility == Accessibility.Implicit ||
                    defaultMember.Accessibility == Accessibility.Public;
                if (isPropertyGetLetFunctionProcedure && isPublic)
                {
                    /*
                     *  This default member’s parameter list is compatible with <argument-list>. In this case, the
                     *  index expression references this default member and takes on its classification and
                     *  declared type.
                     *
                     *  TODO: Primitive argument compatibility checking for now.
                     */
                    if (((IParameterizedDeclaration)defaultMember).Parameters.Count() == _argumentList.Arguments.Count)
                    {
                        return(new IndexExpression(defaultMember, lExpression.Classification, _expression, lExpression, _argumentList));
                    }

                    /**
                     *  This default member cannot accept any parameters. In this case, the static analysis restarts
                     *  recursively, as if this default member was specified instead for <l-expression> with the
                     *  same <argument-list>.
                     */
                    if (((IParameterizedDeclaration)defaultMember).Parameters.Count() == 0)
                    {
                        // Recursion limit reached, abort.
                        if (DEFAULT_MEMBER_RECURSION_LIMIT == _defaultMemberRecursionLimitCounter)
                        {
                            return(null);
                        }
                        _defaultMemberRecursionLimitCounter++;
                        ExpressionClassification classification;
                        if (defaultMember.DeclarationType.HasFlag(DeclarationType.Property))
                        {
                            classification = ExpressionClassification.Property;
                        }
                        else if (defaultMember.DeclarationType == DeclarationType.Procedure)
                        {
                            classification = ExpressionClassification.Subroutine;
                        }
                        else
                        {
                            classification = ExpressionClassification.Function;
                        }
                        var defaultMemberAsLExpression = new SimpleNameExpression(defaultMember, classification, _expression);
                        return(Resolve(defaultMemberAsLExpression));
                    }
                }
            }
            return(null);
        }