public void Visit(InnerJoinStatement statement, CommonTree tree) { Parent(tree).Children.Add(statement); SetLine(statement, tree); VisitChildren(tree); }
public void Visit(InnerJoinStatement statement) { CodeMemberMethod method = new CodeMemberMethod(); method.Name = "Join_" + Guid.NewGuid().ToString("N"); method.Attributes = MemberAttributes.Private; method.Parameters.Add(new CodeParameterDeclarationExpression(new CodeTypeReference("IEnumerable", _codeStack.Peek().Scope.CodeDomReference), "outer")); GenerateCallStatement(method.Statements, statement.Line.Line); _mainType.Type.Members.Add(method); CodeTypeReference fetchAnonType; var fetchMethod = CreateFetch(statement, out fetchAnonType); method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerable", fetchAnonType), "table", new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, fetchMethod.Name)))); //create combined anon type var anon = "anon_" + Guid.NewGuid().ToString("N"); var bufferTable = new CodeTypeDeclaration(anon) { TypeAttributes = TypeAttributes.NestedPrivate }; bufferTable.BaseTypes.Add(new CodeTypeReference("IRow")); _mainType.Type.Members.Add(bufferTable); bufferTable.Members.AddRange(_joinMembers.ToArray()); //Do Join var anonType = new CodeTypeReference(anon); method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IList", anonType), "join", new CodeObjectCreateExpression(new CodeTypeReference("List", anonType)))); method.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", _codeStack.Peek().Scope.CodeDomReference), "o", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("outer"), "GetEnumerator"))); var outerLoop = new CodeIterationStatement(); outerLoop.InitStatement = new CodeSnippetStatement(); outerLoop.IncrementStatement = new CodeSnippetStatement(); outerLoop.TestExpression = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("o"), "MoveNext"); outerLoop.Statements.Add(new CodeVariableDeclarationStatement(_codeStack.Peek().Scope.CodeDomReference, "oc", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("o"), "Current"))); outerLoop.Statements.Add(new CodeVariableDeclarationStatement(new CodeTypeReference("IEnumerator", fetchAnonType), "i", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("table"), "GetEnumerator"))); var innerLoop = new CodeIterationStatement(); outerLoop.Statements.Add(innerLoop); innerLoop.InitStatement = new CodeSnippetStatement(); innerLoop.IncrementStatement = new CodeSnippetStatement(); innerLoop.TestExpression = new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("i"), "MoveNext"); innerLoop.Statements.Add(new CodeVariableDeclarationStatement(fetchAnonType, "ic", new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("i"), "Current"))); var booleanArgs = VisitChild(statement.Expression); string booleanString = ReplaceBooleanStatement(statement, GenerateCodeFromExpression(booleanArgs.CodeExpression)); var joinIf = new CodeConditionStatement(new CodeSnippetExpression(booleanString)); innerLoop.Statements.Add(joinIf); joinIf.TrueStatements.Add(new CodeVariableDeclarationStatement(anonType, "t", new CodeObjectCreateExpression(anonType))); for(int x = 0; x <_joinMembers.Count - 1; x++) { joinIf.TrueStatements.Add(new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("t"), _joinMembers[x].Name), new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("oc"), _joinMembers[x].Name))); } joinIf.TrueStatements.Add(new CodeAssignStatement( new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("t"), _joinMembers[_joinMembers.Count-1].Name), new CodePropertyReferenceExpression( new CodeVariableReferenceExpression("ic"), _joinMembers[_joinMembers.Count - 1].Name))); joinIf.TrueStatements.Add(new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("join"), "Add", new CodeVariableReferenceExpression("t"))); method.Statements.Add(outerLoop); if(statement.Join != null) { var args = VisitChild(statement.Join, new CodeDomArg() { Scope = new ScopeData<Type> { Type = typeof(int), CodeDomReference = anonType } }); method.Statements.Add(new CodeMethodReturnStatement(args.CodeExpression)); method.ReturnType = args.Scope.CodeDomReference; _codeStack.Peek().Scope = args.Scope; } else { var tableType = new CodeTypeReference("CodeTable", anonType); method.ReturnType = tableType; _codeStack.Peek().Scope = new ScopeData<Type> { Type = typeof(int), CodeDomReference = tableType }; method.Statements.Add(new CodeVariableDeclarationStatement(tableType, "newTable", new CodeObjectCreateExpression(tableType))); method.Statements.Add(new CodeMethodInvokeExpression( new CodeVariableReferenceExpression("newTable"), "SetRows", new CodeMethodInvokeExpression(new CodeVariableReferenceExpression("join"), "ToList"))); method.Statements.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("newTable"))); } _codeStack.Peek().CodeExpression = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(null, method.Name), new CodeVariableReferenceExpression("join")); }