예제 #1
0
 public BoundQueryClause Update(
     BoundExpression value,
     RangeVariableSymbol definedSymbol,
     BoundExpression queryInvocation,
     BoundExpression castInvocation,
     Binder binder,
     BoundExpression unoptimizedForm,
     TypeSymbol type)
 {
     if (value != this.Value || definedSymbol != this.DefinedSymbol || queryInvocation != this.Operation || castInvocation != this.Cast || binder != this.Binder || unoptimizedForm != this.UnoptimizedForm || type != this.Type)
     {
         var result = new BoundQueryClause(this.Syntax, value, definedSymbol, queryInvocation, castInvocation, binder, unoptimizedForm, type, this.HasErrors);
         result.WasCompilerGenerated = this.WasCompilerGenerated;
         return(result);
     }
     return(this);
 }
예제 #2
0
 public BoundQueryClause Update(
     BoundExpression value,
     RangeVariableSymbol definedSymbol,
     BoundExpression queryInvocation,
     BoundExpression castInvocation,
     Binder binder,
     BoundExpression unoptimizedForm,
     TypeSymbol type)
 {
     if (value != this.Value || definedSymbol != this.DefinedSymbol || queryInvocation != this.Operation || castInvocation != this.Cast || binder != this.Binder || unoptimizedForm != this.UnoptimizedForm || type != this.Type)
     {
         var result = new BoundQueryClause(this.Syntax, value, definedSymbol, queryInvocation, castInvocation, binder, unoptimizedForm, type, this.HasErrors);
         result.WasCompilerGenerated = this.WasCompilerGenerated;
         return result;
     }
     return this;
 }
예제 #3
0
        protected void VisitUnoptimizedForm(BoundQueryClause queryClause)
        {
            BoundExpression unoptimizedForm = queryClause.UnoptimizedForm;

            // The unoptimized form of a query has an additional argument in the call,
            // which is typically the "trivial" expression x where x is the query
            // variable.  So that we can make sense of x in this
            // context, we store the unoptimized form and visit this extra argument.
            var qc = unoptimizedForm as BoundQueryClause;

            if (qc != null)
            {
                unoptimizedForm = qc.Value;
            }
            var call = unoptimizedForm as BoundCall;

            if (call != null && (object)call.Method != null)
            {
                var arguments = call.Arguments;
#if XSHARP
                if (XSharpString.Equals(call.Method.Name, "Select"))
#else
                if (call.Method.Name == "Select")
#endif
                {
                    this.Visit(arguments[arguments.Length - 1]);
                }
#if XSHARP
                else if (XSharpString.Equals(call.Method.Name, "GroupBy"))
#else
                else if (call.Method.Name == "GroupBy")
#endif
                {
                    this.Visit(arguments[arguments.Length - 2]);
                }
            }
        }
예제 #4
0
 private CSharpTypeInfo GetTypeInfoForQuery(BoundQueryClause bound)
 {
     return bound == null ?
         CSharpTypeInfo.None :
         GetTypeInfoForNode(bound, bound, bound);
 }
예제 #5
0
        private SymbolInfo GetSymbolInfoForQuery(BoundQueryClause bound)
        {
            var call = bound?.Operation as BoundCall;
            if (call == null)
            {
                return default(SymbolInfo);
            }

            var operation = call.IsDelegateCall ? call.ReceiverOpt : call;
            return GetSymbolInfoForNode(SymbolInfoOptions.DefaultOptions, operation, operation, boundNodeForSyntacticParent: null, binderOpt: null);
        }
예제 #6
0
 private QueryClauseInfo GetQueryClauseInfo(BoundQueryClause bound)
 {
     if (bound == null) return default(QueryClauseInfo);
     var castInfo = (bound.Cast == null) ? default(SymbolInfo) : GetSymbolInfoForNode(SymbolInfoOptions.DefaultOptions, bound.Cast, bound.Cast, boundNodeForSyntacticParent: null, binderOpt: null);
     var operationInfo = GetSymbolInfoForQuery(bound);
     return new QueryClauseInfo(castInfo: castInfo, operationInfo: operationInfo);
 }
예제 #7
0
        /// <remarks>
        /// Returned binder doesn't need to have <see cref="BinderFlags.SemanticModel"/> set - the caller will add it.
        /// </remarks>
        private static Binder GetQueryEnclosingBinder(int position, CSharpSyntaxNode startingNode, BoundQueryClause queryClause)
        {
            for (BoundNode n = queryClause.Value; n != null;)
            {
                switch (n.Kind)
                {
                    case BoundKind.QueryClause:
                        queryClause = (BoundQueryClause)n;
                        n = queryClause.Value;
                        continue;
                    case BoundKind.Call:
                        var call = (BoundCall)n;
                        foreach (var arg in call.Arguments)
                        {
                            if (arg.Syntax.FullSpan.Contains(position) ||
                                (arg as BoundQueryClause)?.Value.Syntax.FullSpan.Contains(position) == true)
                            {
                                n = arg;
                                break;
                            }
                        }

                        if (n != call)
                        {
                            continue;
                        }

                        BoundExpression receiver = call.ReceiverOpt;

                        // In some error scenarios, we end-up with a method group as the receiver,
                        // let's get to real receiver.
                        while (receiver?.Kind == BoundKind.MethodGroup)
                        {
                            receiver = ((BoundMethodGroup)receiver).ReceiverOpt;
                        }

                        if (receiver?.Syntax.FullSpan.Contains(position) == true ||
                            (receiver as BoundQueryClause)?.Value.Syntax.FullSpan.Contains(position) == true)
                        {
                            n = receiver;
                            continue;
                        }

                        // TODO: should we look for the "nearest" argument as a fallback?
                        n = call.Arguments.LastOrDefault();
                        continue;
                    case BoundKind.Conversion:
                        n = ((BoundConversion)n).Operand;
                        continue;
                    case BoundKind.UnboundLambda:
                        var unbound = (UnboundLambda)n;
                        return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, unbound.Syntax),
                                                  position, unbound.BindForErrorRecovery().Binder, unbound.Syntax);
                    case BoundKind.Lambda:
                        var lambda = (BoundLambda)n;
                        return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, lambda.Body.Syntax), 
                                                  position, lambda.Binder, lambda.Body.Syntax);
                    default:
                        goto done;
                }
            }

done:
            return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, queryClause.Syntax),
                                      position, queryClause.Binder, queryClause.Syntax);
        }
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     this.Visit(node.Value);
     VisitUnoptimizedForm(node);
     return(null);
 }
예제 #9
0
        /// <remarks>
        /// Returned binder doesn't need to have <see cref="BinderFlags.SemanticModel"/> set - the caller will add it.
        /// </remarks>
        private static Binder GetQueryEnclosingBinder(int position, CSharpSyntaxNode startingNode, BoundQueryClause queryClause)
        {
            BoundExpression node = queryClause;

            do
            {
                switch (node.Kind)
                {
                    case BoundKind.QueryClause:
                        queryClause = (BoundQueryClause)node;
                        node = GetQueryClauseValue(queryClause);
                        continue;
                    case BoundKind.Call:
                        var call = (BoundCall)node;
                        node = GetContainingArgument(call.Arguments, position);
                        if (node != null)
                        {
                            continue;
                        }

                        BoundExpression receiver = call.ReceiverOpt;

                        // In some error scenarios, we end-up with a method group as the receiver,
                        // let's get to real receiver.
                        while (receiver?.Kind == BoundKind.MethodGroup)
                        {
                            receiver = ((BoundMethodGroup)receiver).ReceiverOpt;
                        }

                        if (receiver != null)
                        {
                            node = GetContainingExprOrQueryClause(receiver, position);
                            if (node != null)
                            {
                                continue;
                            }
                        }

                        // TODO: should we look for the "nearest" argument as a fallback?
                        node = call.Arguments.LastOrDefault();
                        continue;
                    case BoundKind.Conversion:
                        node = ((BoundConversion)node).Operand;
                        continue;
                    case BoundKind.UnboundLambda:
                        var unbound = (UnboundLambda)node;
                        return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, unbound.Syntax),
                                                  position, unbound.BindForErrorRecovery().Binder, unbound.Syntax);
                    case BoundKind.Lambda:
                        var lambda = (BoundLambda)node;
                        return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, lambda.Body.Syntax),
                                                  position, lambda.Binder, lambda.Body.Syntax);
                    default:
                        goto done;
                }
            }
            while (node != null);

done:
            return GetEnclosingBinder(AdjustStartingNodeAccordingToNewRoot(startingNode, queryClause.Syntax),
                                      position, queryClause.Binder, queryClause.Syntax);
        }
예제 #10
0
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     return base.VisitQueryClause(node);
 }
예제 #11
0
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     Assign(node, value: null);
     return base.VisitQueryClause(node);
 }
예제 #12
0
        public override BoundNode VisitQueryClause(BoundQueryClause node)
        {
            if (IsInside)
            {
                if ((object)node.DefinedSymbol != null)
                {
                    _variablesDeclared.Add(node.DefinedSymbol);
                }
            }

            return base.VisitQueryClause(node);
        }
예제 #13
0
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     return VisitExpression(node.Value);
 }
예제 #14
0
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     return(VisitExpression(node.Value));
 }
예제 #15
0
 private static BoundExpression GetQueryClauseValue(BoundQueryClause queryClause)
 {
     return queryClause.UnoptimizedForm ?? queryClause.Value;
 }
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     this.Visit(node.Value);
     VisitUnoptimizedForm(node);
     return null;
 }
예제 #17
0
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     Assign(node, value: null);
     return(base.VisitQueryClause(node));
 }
        /// <remarks>
        /// Returned binder doesn't need to have <see cref="BinderFlags.SemanticModel"/> set - the caller will add it.
        /// </remarks>
        private static Binder GetQueryEnclosingBinder(int position, BoundQueryClause queryClause)
        {
            for (BoundNode n = queryClause.Value; n != null;)
            {
                switch (n.Kind)
                {
                    case BoundKind.QueryClause:
                        queryClause = (BoundQueryClause)n;
                        n = queryClause.Value;
                        continue;
                    case BoundKind.Call:
                        var call = (BoundCall)n;
                        if (call == null || call.Arguments.Length == 0) return queryClause.Binder;
                        // TODO: should we look for the "nearest" argument as a fallback?
                        n = call.Arguments[call.Arguments.Length - 1];
                        foreach (var arg in call.Arguments)
                        {
                            if (arg.Syntax.FullSpan.Contains(position)) n = arg;
                        }
                        continue;
                    case BoundKind.Conversion:
                        n = ((BoundConversion)n).Operand;
                        continue;
                    case BoundKind.UnboundLambda:
                        // NOTE: Calling GetLambdaEnclosingBinder would just return this binder.
                        return ((UnboundLambda)n).BindForErrorRecovery().Binder;
                    case BoundKind.Lambda:
                        // NOTE: Calling GetLambdaEnclosingBinder would just return this binder.
                        return ((BoundLambda)n).Binder;
                    default:
                        return queryClause.Binder;
                }
            }

            return queryClause.Binder;
        }
예제 #19
0
 public override BoundNode VisitQueryClause(BoundQueryClause node)
 {
     return(base.VisitQueryClause(node));
 }
 private SymbolInfo GetSymbolInfoForQuery(BoundQueryClause bound)
 {
     return (bound == null || bound.Operation == null) ?
         default(SymbolInfo) :
         GetSymbolInfoForNode(SymbolInfoOptions.DefaultOptions, bound.Operation, bound.Operation, boundNodeForSyntacticParent: null, binderOpt: null);
 }