private Declaration ResolveInternal(VBAParser.ICS_S_MembersCallContext context, ContextAccessorType accessorType, Declaration localScope = null, bool hasExplicitLetStatement = false, bool isAssignmentTarget = false)
        {
            if (context == null)
            {
                return(null);
            }

            Declaration parent;

            if (_withBlockQualifiers.Any())
            {
                parent = _withBlockQualifiers.Peek();
            }
            else
            {
                if (localScope == null)
                {
                    localScope = _currentScope;
                }
                parent = ResolveInternal(context.iCS_S_ProcedureOrArrayCall(), localScope, accessorType, hasExplicitLetStatement, isAssignmentTarget)
                         ?? ResolveInternal(context.iCS_S_VariableOrProcedureCall(), localScope, accessorType, hasExplicitLetStatement, isAssignmentTarget);

                parent = ResolveType(parent);
            }

            var chainedCalls = context.iCS_S_MemberCall();
            var lastCall     = chainedCalls.Last();

            foreach (var memberCall in chainedCalls)
            {
                // if we're on the left side of an assignment, only the last memberCall is the assignment target.
                var isLast   = memberCall.Equals(lastCall);
                var accessor = isLast
                    ? accessorType
                    : ContextAccessorType.GetValueOrReference;
                var isTarget = isLast && isAssignmentTarget;

                var member = ResolveInternal(memberCall.iCS_S_ProcedureOrArrayCall(), parent, accessor, hasExplicitLetStatement, isTarget)
                             ?? ResolveInternal(memberCall.iCS_S_VariableOrProcedureCall(), parent, accessor, hasExplicitLetStatement, isTarget);

                if (member == null)
                {
                    return(null);
                }

                parent = ResolveType(member);
            }

            var fieldCall = context.dictionaryCallStmt();

            if (fieldCall == null)
            {
                return(parent);
            }

            return(ResolveInternal(fieldCall, parent, hasExplicitLetStatement, isAssignmentTarget));
        }
Пример #2
0
 public override void EnterICS_S_MembersCall(VBAParser.ICS_S_MembersCallContext context)
 {
     // Implement statements are handled separately and directly through new binding expressions.
     // Prevent duplicate references.
     if (BindingMigrationHelper.HasParent <VBAParser.ImplementsStmtContext>(context))
     {
         return;
     }
     _resolver.Resolve(context);
 }
        private Declaration Resolve(VBAParser.ICS_S_MembersCallContext context, out VBAParser.AmbiguousIdentifierContext identifierContext, DeclarationType accessorType)
        {
            if (context == null)
            {
                identifierContext = null;
                return(null);
            }

            var members = context.iCS_S_MemberCall();

            for (var index = 0; index < members.Count; index++)
            {
                var member = members[index];
                if (index < members.Count - 1)
                {
                    var parent = Resolve(member.iCS_S_ProcedureOrArrayCall())
                                 ?? Resolve(member.iCS_S_VariableOrProcedureCall());

                    if (parent == null)
                    {
                        // return early if we can't resolve the whole member chain
                        identifierContext = null;
                        return(null);
                    }
                }
                else
                {
                    var result = Resolve(member.iCS_S_ProcedureOrArrayCall())
                                 ?? Resolve(member.iCS_S_VariableOrProcedureCall());

                    identifierContext = result == null
                        ? null
                        : result.Context == null
                            ? null
                            : ((dynamic)result.Context).ambiguousIdentifier();
                    return(result);
                }
            }

            identifierContext = null;
            return(null);
        }
 private Declaration Resolve(VBAParser.ICS_S_MembersCallContext context)
 {
     VBAParser.AmbiguousIdentifierContext discarded;
     return(Resolve(context, out discarded, DeclarationType.PropertyGet));
 }
        public void Resolve(VBAParser.ICS_S_MembersCallContext context)
        {
            if (context == null || _alreadyResolved.Contains(context))
            {
                return;
            }

            Declaration parent;

            if (_withBlockQualifiers.Any())
            {
                parent = _withBlockQualifiers.Peek();
            }
            else
            {
                parent = ResolveInternal(context.iCS_S_ProcedureOrArrayCall(), _currentScope)
                         ?? ResolveInternal(context.iCS_S_VariableOrProcedureCall(), _currentScope);
                parent = ResolveType(parent);
            }

            if (parent != null && parent.Context != null)
            {
                var identifierContext = ((dynamic)parent.Context).ambiguousIdentifier() as VBAParser.AmbiguousIdentifierContext;

                var parentReference = CreateReference(identifierContext, parent);
                parent.AddReference(parentReference);
                _alreadyResolved.Add(parentReference.Context);
            }

            var chainedCalls = context.iCS_S_MemberCall();

            foreach (var memberCall in chainedCalls)
            {
                var notationToken = memberCall.children[0];
                if (notationToken.GetText() == "!")
                {
                    // the memberCall is a shorthand reference to the type's default member.
                    // since the reference isn't explicit, we don't need to care for it.
                    // (and we couldn't handle it if we wanted to, since we aren't parsing member attributes)
                    return;
                }

                var member = ResolveInternal(memberCall.iCS_S_ProcedureOrArrayCall(), parent)
                             ?? ResolveInternal(memberCall.iCS_S_VariableOrProcedureCall(), parent);

                if (member == null)
                {
                    return;
                }

                parent = ResolveType(member);
            }

            var fieldCall = context.dictionaryCallStmt();

            if (fieldCall == null)
            {
                return;
            }

            ResolveInternal(fieldCall, parent);
            _alreadyResolved.Add(context);
        }
 public override void EnterICS_S_MembersCall(VBAParser.ICS_S_MembersCallContext context)
 {
     _resolver.Resolve(context);
 }