public ExprRelationalOpAllAnyNodeForgeEval( ExprRelationalOpAllAnyNodeForge forge, ExprEvaluator[] evaluators) { this.forge = forge; this.evaluators = evaluators; }
public static CodegenExpression Codegen( ExprRelationalOpAllAnyNodeForge forge, CodegenMethodScope codegenMethodScope, ExprForgeCodegenSymbol exprSymbol, CodegenClassScope codegenClassScope) { var forges = ExprNodeUtilityQuery.GetForges(forge.ForgeRenderable.ChildNodes); var valueLeftType = forges[0].EvaluationType; var isAll = forge.ForgeRenderable.IsAll; if (forges.Length == 1) { return Constant(isAll); } var methodNode = codegenMethodScope.MakeChild( typeof(bool?), typeof(ExprRelationalOpAllAnyNodeForgeEval), codegenClassScope); var block = methodNode.Block .DeclareVar<bool>("hasNonNullRow", ConstantFalse()) .DeclareVar( valueLeftType, "valueLeft", forges[0].EvaluateCodegen(valueLeftType, methodNode, exprSymbol, codegenClassScope)); for (var i = 1; i < forges.Length; i++) { var refforge = forges[i]; var refname = "r" + i; var reftype = refforge.EvaluationType; block.DeclareVar( reftype, refname, refforge.EvaluateCodegen(reftype, methodNode, exprSymbol, codegenClassScope)); if (reftype.IsArray) { var blockIfNotNull = block.IfCondition(NotEqualsNull(Ref(refname))); { var forLoopArray = blockIfNotNull.ForLoopIntSimple("index", ArrayLength(Ref(refname))); { forLoopArray.DeclareVar( Boxing.GetBoxedType(reftype.GetElementType()), "item", ArrayAtIndex(Ref(refname), Ref("index"))); var ifItemNull = forLoopArray.IfCondition(EqualsNull(Ref("item"))); { if (isAll) { ifItemNull.IfReturn(ConstantNull()); } } var ifItemNotNull = ifItemNull.IfElse(); { ifItemNotNull.AssignRef("hasNonNullRow", ConstantTrue()); var ifLeftNotNull = ifItemNotNull.IfCondition(NotEqualsNull(Ref("valueLeft"))); { ifLeftNotNull.IfCondition( NotOptional( isAll, forge.Computer.Codegen( Ref("valueLeft"), valueLeftType, Ref("item"), typeof(object)))) .BlockReturn(isAll ? ConstantFalse() : ConstantTrue()); } } } } } else if (reftype.IsGenericDictionary()) { var blockIfNotNull = block.IfCondition(NotEqualsNull(Ref(refname))); { var forEach = blockIfNotNull.ForEach( typeof(object), "item", ExprDotName(Ref(refname), "Keys")); { var ifNotNumber = forEach.IfCondition(Not(InstanceOf(Ref("item"), typeof(object)))); { if (isAll) { ifNotNumber.IfRefNullReturnNull("item"); } } var ifNotNumberElse = ifNotNumber.IfElse(); { ifNotNumberElse.AssignRef("hasNonNullRow", ConstantTrue()); var ifLeftNotNull = ifNotNumberElse.IfCondition(NotEqualsNull(Ref("valueLeft"))); { ifLeftNotNull.IfCondition( NotOptional( isAll, forge.Computer.Codegen( Ref("valueLeft"), valueLeftType, Cast(typeof(object), Ref("item")), typeof(object)))) .BlockReturn(isAll ? ConstantFalse() : ConstantTrue()); } } } } } else if (reftype.IsGenericCollection()) { var blockIfNotNull = block.IfCondition(NotEqualsNull(Ref(refname))); { var forEach = blockIfNotNull.ForEach(typeof(object), "item", Ref(refname)); { var ifNotNumber = forEach.IfCondition(Not(InstanceOf(Ref("item"), typeof(object)))); { if (isAll) { ifNotNumber.IfRefNullReturnNull("item"); } } var ifNotNumberElse = ifNotNumber.IfElse(); { ifNotNumberElse.AssignRef("hasNonNullRow", ConstantTrue()); var ifLeftNotNull = ifNotNumberElse.IfCondition(NotEqualsNull(Ref("valueLeft"))); { ifLeftNotNull.IfCondition( NotOptional( isAll, forge.Computer.Codegen( Ref("valueLeft"), valueLeftType, Cast(typeof(object), Ref("item")), typeof(object)))) .BlockReturn(isAll ? ConstantFalse() : ConstantTrue()); } } } } } else if (!TypeHelper.IsSubclassOrImplementsInterface( Boxing.GetBoxedType(reftype), typeof(object))) { if (reftype.CanBeNull()) { block.IfRefNullReturnNull(refname); } block.AssignRef("hasNonNullRow", ConstantTrue()); if (isAll) { block.BlockReturn(ConstantNull()); } } else { if (reftype.CanNotBeNull()) { block.AssignRef("hasNonNullRow", ConstantTrue()); block.IfCondition( NotOptional( isAll, forge.Computer.Codegen(Ref("valueLeft"), valueLeftType, Ref(refname), reftype))) .BlockReturn(isAll ? ConstantFalse() : ConstantTrue()); } else { if (isAll) { block.IfRefNullReturnNull(refname); } var ifRefNotNull = block.IfRefNotNull(refname); { ifRefNotNull.AssignRef("hasNonNullRow", ConstantTrue()); var ifLeftNotNull = ifRefNotNull.IfCondition(NotEqualsNull(Ref("valueLeft"))); ifLeftNotNull.IfCondition( NotOptional( isAll, forge.Computer.Codegen( Ref("valueLeft"), valueLeftType, Ref(refname), typeof(object)))) .BlockReturn(isAll ? ConstantFalse() : ConstantTrue()); } } } } block.IfCondition(Not(Ref("hasNonNullRow"))) .BlockReturn(ConstantNull()); if (valueLeftType.CanBeNull()) { block.IfRefNullReturnNull("valueLeft"); } block.MethodReturn(Constant(isAll)); return LocalMethod(methodNode); }