Esempio n. 1
0
        public override void VisitJoinClause(JoinClauseSyntax node)
        {
            IncrementNodeCount(2); // direct equivalent of SQL `INNER JOIN`
            AddOperator("join");

            base.VisitJoinClause(node);
        }
Esempio n. 2
0
        public override void VisitJoinClause(JoinClauseSyntax node)
        {
            var paramInfo  = m_LinqParamInfoStack.Peek();
            var paramNames = paramInfo.ParamNames;

            CodeBuilder.AppendFormat("join((function({0}){{ return(", string.Join(", ", paramNames.ToArray()));
            var opd = m_Model.GetOperation(node.InExpression) as IConversionExpression;

            OutputExpressionSyntax(node.InExpression, opd);
            CodeBuilder.Append("); }), ");

            paramInfo.JoinParamName = node.Identifier.Text;
            paramNames.Add(paramInfo.JoinParamName);

            CodeBuilder.AppendFormat("(function({0}){{ return(", string.Join(", ", paramNames.ToArray()));
            var opdl = m_Model.GetOperation(node.LeftExpression) as IConversionExpression;

            OutputExpressionSyntax(node.LeftExpression, opdl);
            CodeBuilder.Append("); }), ");

            CodeBuilder.AppendFormat("(function({0}){{ return(", string.Join(", ", paramNames.ToArray()));
            var opdr = m_Model.GetOperation(node.RightExpression) as IConversionExpression;

            OutputExpressionSyntax(node.RightExpression, opdr);
            CodeBuilder.Append("); }))");

            if (null != node.Into)
            {
                VisitJoinIntoClause(node.Into);
            }
        }
Esempio n. 3
0
        public override Evaluation VisitJoinClause(JoinClauseSyntax node)
        {
            node.InExpression?.Accept <Evaluation>(this);
            node.Into?.Accept <Evaluation>(this);
            node.LeftExpression?.Accept <Evaluation>(this);
            node.RightExpression?.Accept <Evaluation>(this);
            node.Type?.Accept <Evaluation>(this);

            return(base.VisitJoinClause(node));
        }
Esempio n. 4
0
        public override void VisitJoinClause(JoinClauseSyntax node)
        {
            node.InExpression?.Accept(this);
            node.Into?.Accept(this);
            node.LeftExpression?.Accept(this);
            node.RightExpression?.Accept(this);
            node.Type?.Accept(this);

            base.VisitJoinClause(node);
        }
Esempio n. 5
0
        private LuaExpressionSyntax BuildJoinClause(LuaExpressionSyntax collection, JoinClauseSyntax node, ref IQueryRangeVariable rangeVariable, out bool isOver)
        {
            isOver = false;

            var rangeVariable2   = AddRangeIdentifier(node.Identifier);
            var inner            = (LuaExpressionSyntax)node.InExpression.Accept(this);
            var outerKeySelector = new LuaFunctionExpressionSyntax();

            PushFunction(outerKeySelector);
            outerKeySelector.AddParameter(rangeVariable.Name);
            var left = (LuaExpressionSyntax)node.LeftExpression.Accept(this);

            outerKeySelector.AddStatement(new LuaReturnStatementSyntax(left));
            PopFunction();

            var keyTypeSymbol = semanticModel_.GetTypeInfo(node.LeftExpression).Type;
            var keyType       = GetTypeName(keyTypeSymbol);

            var innerKeySelector = new LuaFunctionExpressionSyntax();

            PushFunction(innerKeySelector);
            innerKeySelector.AddParameter(rangeVariable2.Name);
            var right = (LuaExpressionSyntax)node.RightExpression.Accept(this);

            innerKeySelector.AddStatement(new LuaReturnStatementSyntax(right));
            PopFunction();

            LuaFunctionExpressionSyntax resultSelector = new LuaFunctionExpressionSyntax();

            PushFunction(resultSelector);
            LuaExpressionSyntax     resultSelectorExpression;
            LuaExpressionSyntax     resultSelectorType;
            LuaIdentifierNameSyntax methodName;

            var parentNode = (QueryBodySyntax)node.Parent;

            if (node.Into == null)
            {
                methodName = LuaIdentifierNameSyntax.LinqJoin;
                resultSelector.AddParameter(rangeVariable.Name);
                resultSelector.AddParameter(rangeVariable2.Name);
                isOver = BuildQueryJoin(node, out resultSelectorExpression, out resultSelectorType, ref rangeVariable, rangeVariable2);
            }
            else
            {
                methodName = LuaIdentifierNameSyntax.LinqGroupJoin;
                var rangeVariableOfInto = AddRangeIdentifier(node.Into.Identifier);
                resultSelector.AddParameter(rangeVariable.Name);
                resultSelector.AddParameter(rangeVariableOfInto.Name);
                isOver = BuildQueryJoin(node, out resultSelectorExpression, out resultSelectorType, ref rangeVariable, rangeVariableOfInto);
            }
            resultSelector.AddStatement(new LuaReturnStatementSyntax(resultSelectorExpression));
            PopFunction();
            return(new LuaInvocationExpressionSyntax(methodName, collection, inner, outerKeySelector, innerKeySelector, resultSelector, LuaIdentifierLiteralExpressionSyntax.Nil, keyType, resultSelectorType));
        }
Esempio n. 6
0
        public override void VisitJoinClause(JoinClauseSyntax node)
        {
            if (!PreVisit(node))
            {
                return;
            }

            node.InExpression?.Accept(this);
            node.Into?.Accept(this);
            node.LeftExpression?.Accept(this);
            node.RightExpression?.Accept(this);
            node.Type?.Accept(this);

            base.VisitJoinClause(node);

            PostVisit(node);
        }
        public void VisitJoinClause(JoinClauseSyntax node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            node.Validate();

            if (!_writer.Configuration.LineBreaksAndWrapping.Other.PlaceLinqExpressionOnSingleLine)
            {
                _writer.Break(true);
            }

            _writer.WriteKeyword(PrinterKeyword.Join);
            _writer.WriteSpace();

            if (node.Type != null)
            {
                node.Type.Accept(this);
                _writer.WriteSpace();
            }

            _writer.WriteIdentifier(node.Identifier);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.In);
            _writer.WriteSpace();
            node.InExpression.Accept(this);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.On);
            _writer.WriteSpace();
            node.LeftExpression.Accept(this);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.Equals);
            _writer.WriteSpace();
            node.RightExpression.Accept(this);

            if (node.Into != null)
            {
                _writer.WriteSpace();
                node.Into.Accept(this);
            }
        }
Esempio n. 8
0
        public override void VisitJoinClause(JoinClauseSyntax node)
        {
            var membersVisitor = new GetMembersVisitor(this);

            membersVisitor.Visit(node.InExpression);
            _variables.Add(node.Identifier.ValueText, membersVisitor._properties);
            _fromVariables.Add(node.Identifier.ValueText, _linqIndex);
            AddProperties(membersVisitor._properties);
            Visit(node.LeftExpression);
            _proceed = false;
            Visit(node.RightExpression);
            if (node.Into != null)
            {
                _variables.Add(node.Into.Identifier.ValueText, membersVisitor._properties);
                _fromVariables.Add(node.Into.Identifier.ValueText, _linqIndex);
                _fromVariables.Remove(node.Identifier.ValueText);
                _variables.Remove(node.Identifier.ValueText);
            }
            _proceed = true;
        }
        private bool BuildQueryJoin(JoinClauseSyntax node, out LuaExpressionSyntax resultSelectorExpression, out LuaExpressionSyntax resultSelectorType, ref IQueryRangeVariable rangeVariable, QueryIdentifier queryIdentifier)
        {
            var parentNode = (QueryBodySyntax)node.Parent;

            if (IsSpecialQueryNode(parentNode))
            {
                var selectClause = (SelectClauseSyntax)parentNode.SelectOrGroup;
                resultSelectorExpression = (LuaExpressionSyntax)selectClause.Expression.Accept(this);
                var typeSymbol = semanticModel_.GetTypeInfo(selectClause.Expression).Type;
                resultSelectorType = GetTypeName(typeSymbol);
                return(true);
            }
            else
            {
                resultSelectorExpression = CreateQueryAnonymousType(rangeVariable.Name, rangeVariable.Name, queryIdentifier.Name, queryIdentifier.Name);
                resultSelectorType       = LuaIdentifierNameSyntax.AnonymousType;
                rangeVariable            = new QueryPackVariable(rangeVariable, queryIdentifier);
                return(false);
            }
        }
        public void VisitJoinClause(JoinClauseSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            if (!_writer.Configuration.LineBreaksAndWrapping.Other.PlaceLinqExpressionOnSingleLine)
                _writer.Break(true);

            _writer.WriteKeyword(PrinterKeyword.Join);
            _writer.WriteSpace();

            if (node.Type != null)
            {
                node.Type.Accept(this);
                _writer.WriteSpace();
            }

            _writer.WriteIdentifier(node.Identifier);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.In);
            _writer.WriteSpace();
            node.InExpression.Accept(this);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.On);
            _writer.WriteSpace();
            node.LeftExpression.Accept(this);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.Equals);
            _writer.WriteSpace();
            node.RightExpression.Accept(this);

            if (node.Into != null)
            {
                _writer.WriteSpace();
                node.Into.Accept(this);
            }
        }
Esempio n. 11
0
 private Doc PrintJoinClauseSyntax(JoinClauseSyntax node)
 {
     return(Concat(
                this.PrintSyntaxToken(node.JoinKeyword, " "),
                this.PrintSyntaxToken(node.Identifier, " "),
                this.PrintSyntaxToken(node.InKeyword, " "),
                this.Print(node.InExpression),
                SpaceIfNoPreviousComment,
                this.PrintSyntaxToken(node.OnKeyword, " "),
                this.Print(node.LeftExpression),
                SpaceIfNoPreviousComment,
                this.PrintSyntaxToken(node.EqualsKeyword, " "),
                this.Print(node.RightExpression),
                node.Into != null
             ? Concat(
                    SpaceIfNoPreviousComment,
                    this.PrintSyntaxToken(node.Into.IntoKeyword, " "),
                    this.PrintSyntaxToken(node.Into.Identifier)
                    )
             : Doc.Null
                ));
 }
        public override SyntaxNode VisitJoinClause(JoinClauseSyntax node)
        {
            if (!_visitQuerySyntax)
            {
                return(base.VisitJoinClause(node));
            }

            var joinClause = (JoinClauseSyntax)SetFlagAndVisit(node);

            if (joinClause.Into == null)
            {
                SyntaxToken[] rangeVariables = { GetLambdaParameterToken(joinClause.LeftExpression), joinClause.Identifier };
                var           join           = BuildFluentInvocation(
                    "Join",
                    Argument(joinClause.InExpression),
                    Argument(BuildSimpleLambdaExpression(joinClause.LeftExpression)),
                    Argument(BuildSimpleLambdaExpression(joinClause.RightExpression, Parameter(joinClause.Identifier))),
                    Argument(BuildLambdaExpression(rangeVariables, BuildAnonymousObject(rangeVariables))));

                SetAnonymousState(rangeVariables);
                return(join);
            }
            else
            {
                SyntaxToken[] rangeVariables = { GetLambdaParameterToken(joinClause.LeftExpression), Identifier(joinClause.Into.Identifier.ValueText) };
                var           groupJoin      =
                    BuildFluentInvocation(
                        "GroupJoin",
                        Argument(joinClause.InExpression),
                        Argument(BuildSimpleLambdaExpression(joinClause.LeftExpression)),
                        Argument(BuildSimpleLambdaExpression(joinClause.RightExpression, Parameter(joinClause.Identifier))),
                        Argument(BuildLambdaExpression(rangeVariables, BuildAnonymousObject(rangeVariables))));

                SetAnonymousState(joinClause.Into.Identifier);
                return(groupJoin);
            }
        }
Esempio n. 13
0
 public static Doc Print(JoinClauseSyntax node)
 {
     return(Doc.Group(
                Token.PrintWithSuffix(node.JoinKeyword, " "),
                Token.PrintWithSuffix(node.Identifier, " "),
                Token.PrintWithSuffix(node.InKeyword, " "),
                Node.Print(node.InExpression),
                Doc.Indent(
                    Doc.Line,
                    Token.PrintWithSuffix(node.OnKeyword, " "),
                    Node.Print(node.LeftExpression),
                    " ",
                    Token.PrintWithSuffix(node.EqualsKeyword, " "),
                    Node.Print(node.RightExpression),
                    node.Into != null
                 ? Doc.Concat(
                        Doc.Line,
                        Token.PrintWithSuffix(node.Into.IntoKeyword, " "),
                        Token.Print(node.Into.Identifier)
                        )
                 : Doc.Null
                    )
                ));
 }
Esempio n. 14
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     Visit(node.InExpression);
 }
            public override void VisitJoinClause(JoinClauseSyntax node)
            {
                Visit(node.InExpression);

                var saveCurrentScope = currentScope;

                currentScope = new DeclarationScope(saveCurrentScope);
                Visit(node.LeftExpression);

                currentScope = new DeclarationScope(saveCurrentScope);
                Visit(node.RightExpression);

                Debug.Assert(currentScope.Parent == saveCurrentScope);
                currentScope = saveCurrentScope;
            }
Esempio n. 16
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     Log(node, "Unsupported Syntax !");
 }
 public override LuaSyntaxNode VisitJoinClause(JoinClauseSyntax node)
 {
     throw new InvalidOperationException();
 }
Esempio n. 18
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     throw new NotImplementedException();
 }
Esempio n. 19
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     this.Found |= node.Identifier.ValueText == this.name;
     base.VisitJoinClause(node);
 }
Esempio n. 20
0
        private void ReduceJoin(JoinClauseSyntax join, QueryTranslationState state, DiagnosticBag diagnostics)
        {
            var inExpression = BindValue(join.InExpression, diagnostics, BindValueKind.RValue);

            // If the from expression is of the type dynamic we can't infer the types for any lambdas that occur in the query.
            // Only if there are none we could bind the query but we report an error regardless since such queries are not useful.
            if (inExpression.HasDynamicType())
            {
                diagnostics.Add(ErrorCode.ERR_BadDynamicQuery, join.InExpression.Location);
                inExpression = BadExpression(join.InExpression, inExpression);
            }

            BoundExpression castInvocation = null;
            if (join.Type != null)
            {
                // A join clause that explicitly specifies a range variable type
                //     join T x in e on k1 equals k2
                // is translated into
                //     join x in ( e ) . Cast < T > ( ) on k1 equals k2
                var castType = BindTypeArgument(join.Type, diagnostics);
                castInvocation = MakeQueryInvocation(join, inExpression, "Cast", join.Type, castType, diagnostics);
                inExpression = castInvocation;
            }

            var outerKeySelectorLambda = MakeQueryUnboundLambda(state.RangeVariableMap(), state.rangeVariable, join.LeftExpression);

            var x1 = state.rangeVariable;
            var x2 = state.AddRangeVariable(this, join.Identifier, diagnostics);
            var innerKeySelectorLambda = MakeQueryUnboundLambda(QueryTranslationState.RangeVariableMap(x2), x2, join.RightExpression);

            if (state.clauses.IsEmpty() && state.selectOrGroup.Kind() == SyntaxKind.SelectClause)
            {
                var select = state.selectOrGroup as SelectClauseSyntax;
                BoundCall invocation;
                if (join.Into == null)
                {
                    // A query expression with a join clause without an into followed by a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2
                    //     select v
                    // is translated into
                    //     ( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )
                    var resultSelectorLambda = MakeQueryUnboundLambda(state.RangeVariableMap(), ImmutableArray.Create(x1, x2), select.Expression);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "Join",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);
                }
                else
                {
                    // A query expression with a join clause with an into followed by a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2 into g
                    //     select v
                    // is translated into
                    //     ( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )
                    state.allRangeVariables[x2].Free();
                    state.allRangeVariables.Remove(x2);
                    var g = state.AddRangeVariable(this, join.Into.Identifier, diagnostics);

                    var resultSelectorLambda = MakeQueryUnboundLambda(state.RangeVariableMap(), ImmutableArray.Create(x1, g), select.Expression);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "GroupJoin",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);

                    // record the into clause in the bound tree
                    var arguments = invocation.Arguments;
                    arguments = arguments.SetItem(arguments.Length - 1, MakeQueryClause(join.Into, arguments[arguments.Length - 1], g));

                    invocation = invocation.Update(invocation.ReceiverOpt, invocation.Method, arguments);
                }

                state.Clear(); // this completes the whole query
                state.fromExpression = MakeQueryClause(join, invocation, x2, invocation, castInvocation);
                state.fromExpression = MakeQueryClause(select, state.fromExpression);
            }
            else
            {
                BoundCall invocation;
                if (join.Into == null)
                {
                    // A query expression with a join clause without an into followed by something other than a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2 
                    //     ...
                    // is translated into
                    //     from * in ( e1 ) . Join(
                    //           e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 })
                    //     ...
                    var resultSelectorLambda = MakePairLambda(join, state, x1, x2);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "Join",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);
                }
                else
                {
                    // A query expression with a join clause with an into followed by something other than a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2 into g
                    //     ...
                    // is translated into
                    //     from * in ( e1 ) . GroupJoin(
                    //                 e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g })
                    //     ...
                    state.allRangeVariables[x2].Free();
                    state.allRangeVariables.Remove(x2);

                    var g = state.AddRangeVariable(this, join.Into.Identifier, diagnostics);
                    var resultSelectorLambda = MakePairLambda(join, state, x1, g);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "GroupJoin",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);

                    var arguments = invocation.Arguments;
                    arguments = arguments.SetItem(arguments.Length - 1, MakeQueryClause(join.Into, arguments[arguments.Length - 1], g));

                    invocation = invocation.Update(invocation.ReceiverOpt, invocation.Method, arguments);
                }

                state.fromExpression = MakeQueryClause(join, invocation, x2, invocation, castInvocation);
            }
        }
Esempio n. 21
0
 /// <inheritdoc />
 public override Expression VisitJoinClause(JoinClauseSyntax node)
 {
     throw Unexpected(node, nameof(VisitQueryExpression));
 }
Esempio n. 22
0
 public override SyntaxNode VisitJoinClause(JoinClauseSyntax node)
 {
     //不支持的语法
     return(ReportAndAttachError(base.VisitJoinClause(node), "[Cs2LuaRewriter] Unsupported linq Syntax !"));
 }
Esempio n. 23
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
 }
Esempio n. 24
0
 public override SyntaxNode VisitJoinClause(JoinClauseSyntax node)
 {
     node = (JoinClauseSyntax)base.VisitJoinClause(node);
     Classes.Add(node);
     return(node);
 }
Esempio n. 25
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     this.Found |= node.Identifier.ValueText == this.name;
     base.VisitJoinClause(node);
 }
Esempio n. 26
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitJoinClause(JoinClauseSyntax node)
 {
     this.OnNodeVisited(node);
     if (!this.traverseRootOnly) base.VisitJoinClause(node);
 }
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     base.VisitJoinClause(node);
     Add(node.Identifier);
 }
Esempio n. 28
0
        //public override void VisitInvocationExpression(InvocationExpressionSyntax node)
        //{
        //    base.VisitInvocationExpression(node);
        //}

        //public override void VisitIsPatternExpression(IsPatternExpressionSyntax node)
        //{
        //    base.VisitIsPatternExpression(node);
        //}

        public override void VisitJoinClause(JoinClauseSyntax node)
        {
            VisitType(node.Type);
            //base.VisitJoinClause(node);
        }
Esempio n. 29
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     map.Add(node.Identifier.ValueText, node.Identifier);
     base.VisitJoinClause(node);
 }
Esempio n. 30
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     var membersVisitor = new GetMembersVisitor(this);
     membersVisitor.Visit(node.InExpression);
     _variables.Add(node.Identifier.ValueText, membersVisitor._properties);
     _fromVariables.Add(node.Identifier.ValueText, _linqIndex);
     AddProperties(membersVisitor._properties);
     Visit(node.LeftExpression);
     _proceed = false;
     Visit(node.RightExpression);
     if (node.Into != null)
     {
         _variables.Add(node.Into.Identifier.ValueText, membersVisitor._properties);
         _fromVariables.Add(node.Into.Identifier.ValueText, _linqIndex);
         _fromVariables.Remove(node.Identifier.ValueText);
         _variables.Remove(node.Identifier.ValueText);
     }
     _proceed = true;
 }
 //
 // Summary:
 //     Called when the visitor visits a JoinClauseSyntax node.
 public virtual void VisitJoinClause(JoinClauseSyntax node);
Esempio n. 32
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     FindSpellingMistakesForIdentifier(node.Identifier);
     base.VisitJoinClause(node);
 }
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     base.VisitJoinClause(node);
     Add(node.Identifier);
 }
Esempio n. 34
0
 public override void VisitJoinClause(JoinClauseSyntax node) => base.VisitJoinClause(node);
Esempio n. 35
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     map.Add(node.Identifier.ValueText, node.Identifier);
     base.VisitJoinClause(node);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitJoinClause(JoinClauseSyntax node)
 {
     this.OnNodeVisited(node, this.type.IsInstanceOfType(node));
     base.VisitJoinClause(node);
 }
Esempio n. 37
0
        private void ReduceJoin(JoinClauseSyntax join, QueryTranslationState state, DiagnosticBag diagnostics)
        {
            var inExpression = BindValue(join.InExpression, diagnostics, BindValueKind.RValue);

            // If the from expression is of the type dynamic we can't infer the types for any lambdas that occur in the query.
            // Only if there are none we could bind the query but we report an error regardless since such queries are not useful.
            if (inExpression.HasDynamicType())
            {
                diagnostics.Add(ErrorCode.ERR_BadDynamicQuery, join.InExpression.Location);
                inExpression = BadExpression(join.InExpression, inExpression);
            }

            BoundExpression castInvocation = null;

            if (join.Type != null)
            {
                // A join clause that explicitly specifies a range variable type
                //     join T x in e on k1 equals k2
                // is translated into
                //     join x in ( e ) . Cast < T > ( ) on k1 equals k2
                var castType = BindTypeArgument(join.Type, diagnostics);
                castInvocation = MakeQueryInvocation(join, inExpression, "Cast", join.Type, castType, diagnostics);
                inExpression   = castInvocation;
            }

            var outerKeySelectorLambda = MakeQueryUnboundLambda(state.RangeVariableMap(), state.rangeVariable, join.LeftExpression);

            var x1 = state.rangeVariable;
            var x2 = state.AddRangeVariable(this, join.Identifier, diagnostics);
            var innerKeySelectorLambda = MakeQueryUnboundLambda(QueryTranslationState.RangeVariableMap(x2), x2, join.RightExpression);

            if (state.clauses.IsEmpty() && state.selectOrGroup.Kind() == SyntaxKind.SelectClause)
            {
                var       select = state.selectOrGroup as SelectClauseSyntax;
                BoundCall invocation;
                if (join.Into == null)
                {
                    // A query expression with a join clause without an into followed by a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2
                    //     select v
                    // is translated into
                    //     ( e1 ) . Join( e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => v )
                    var resultSelectorLambda = MakeQueryUnboundLambda(state.RangeVariableMap(), ImmutableArray.Create(x1, x2), select.Expression);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "Join",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);
                }
                else
                {
                    // A query expression with a join clause with an into followed by a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2 into g
                    //     select v
                    // is translated into
                    //     ( e1 ) . GroupJoin( e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => v )
                    state.allRangeVariables[x2].Free();
                    state.allRangeVariables.Remove(x2);
                    var g = state.AddRangeVariable(this, join.Into.Identifier, diagnostics);

                    var resultSelectorLambda = MakeQueryUnboundLambda(state.RangeVariableMap(), ImmutableArray.Create(x1, g), select.Expression);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "GroupJoin",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);

                    // record the into clause in the bound tree
                    var arguments = invocation.Arguments;
                    arguments = arguments.SetItem(arguments.Length - 1, MakeQueryClause(join.Into, arguments[arguments.Length - 1], g));

                    invocation = invocation.Update(invocation.ReceiverOpt, invocation.Method, arguments);
                }

                state.Clear(); // this completes the whole query
                state.fromExpression = MakeQueryClause(join, invocation, x2, invocation, castInvocation);
                state.fromExpression = MakeQueryClause(select, state.fromExpression);
            }
            else
            {
                BoundCall invocation;
                if (join.Into == null)
                {
                    // A query expression with a join clause without an into followed by something other than a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2
                    //     ...
                    // is translated into
                    //     from * in ( e1 ) . Join(
                    //           e2 , x1 => k1 , x2 => k2 , ( x1 , x2 ) => new { x1 , x2 })
                    //     ...
                    var resultSelectorLambda = MakePairLambda(join, state, x1, x2);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "Join",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);
                }
                else
                {
                    // A query expression with a join clause with an into followed by something other than a select clause
                    //     from x1 in e1
                    //     join x2 in e2 on k1 equals k2 into g
                    //     ...
                    // is translated into
                    //     from * in ( e1 ) . GroupJoin(
                    //                 e2 , x1 => k1 , x2 => k2 , ( x1 , g ) => new { x1 , g })
                    //     ...
                    state.allRangeVariables[x2].Free();
                    state.allRangeVariables.Remove(x2);

                    var g = state.AddRangeVariable(this, join.Into.Identifier, diagnostics);
                    var resultSelectorLambda = MakePairLambda(join, state, x1, g);

                    invocation = MakeQueryInvocation(
                        join,
                        state.fromExpression,
                        "GroupJoin",
                        ImmutableArray.Create(inExpression, outerKeySelectorLambda, innerKeySelectorLambda, resultSelectorLambda),
                        diagnostics);

                    var arguments = invocation.Arguments;
                    arguments = arguments.SetItem(arguments.Length - 1, MakeQueryClause(join.Into, arguments[arguments.Length - 1], g));

                    invocation = invocation.Update(invocation.ReceiverOpt, invocation.Method, arguments);
                }

                state.fromExpression = MakeQueryClause(join, invocation, x2, invocation, castInvocation);
            }
        }
Esempio n. 38
0
 public override void VisitJoinClause(JoinClauseSyntax node)
 {
     throw new NotSupportedException();
 }