public InconsistentConditionalExpression(JSToCSharpExceptionType type, RelinqScriptExpression root, ConditionalExpression expression, RelinqScriptType inferredTypeOfTest, RelinqScriptType inferredTypeOfIfTrue, RelinqScriptType inferredTypeOfIfFalse) : base(type, root, expression) { InferredTypeOfTest = inferredTypeOfTest; InferredTypeOfIfTrue = inferredTypeOfIfTrue; InferredTypeOfIfFalse = inferredTypeOfIfFalse; }
private void InferConditional(ConditionalExpression ce, TypeInferenceCache cache) { ce.Children.ForEach(child => InferTypes(child, cache)); var typeofTest = cache[ce.Test]; var typeofFalse = cache[ce.IfFalse]; var typeofTrue = cache[ce.IfTrue]; if (typeofTest is Variant || typeofFalse is Variant || typeofTrue is Variant) { cache.Add(ce, new Variant()); } else { if (!(typeofTest is ClrType && typeofTest.HasImplicitCastTo(typeof(bool)))) { throw new InconsistentConditionalExpression( JSToCSharpExceptionType.ConditionalTestInvalidType, Root, ce, typeofTest, typeofTrue, typeofFalse); } var f2t = typeofFalse.HasImplicitCastTo(typeofTrue); var t2f = typeofTrue.HasImplicitCastTo(typeofFalse); if (!f2t && !t2f) { if (typeofFalse is Lambda || typeofTrue is Lambda) { throw new NotImplementedException(String.Format( "Don't know how to infer the '{0} ? {1} : {2}' conditional expression.", typeofTest, typeofTrue, typeofFalse)); } else { throw new InconsistentConditionalExpression( JSToCSharpExceptionType.ConditionalClausesNoCommonTypeWithOnlyOneClauseBeingCast, Root, ce, typeofTest, typeofTrue, typeofFalse); } } else if (f2t && t2f && typeofFalse != typeofTrue) { throw new InconsistentConditionalExpression( JSToCSharpExceptionType.ConditionalClausesAmbiguousCommonType, Root, ce, typeofTest, typeofTrue, typeofFalse); } else { cache.Add(ce, f2t ? typeofTrue : typeofFalse); } } }
private LinqExpression CompileConditional(ConditionalExpression ce, CompilationContext ctx) { // todo. conditional has to have a CLR type inferred. // cba to check this stuff var typeofTest = ctx.Types[ce.Test]; var typeofFalse = ctx.Types[ce.IfFalse]; var typeofTrue = ctx.Types[ce.IfTrue]; var castTest = Cast.Lookup(typeofTest, typeof(bool)); if (typeofTest is ClrType) { if (castTest == null) { throw new CSharpBuilderException( JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx); } } else { throw new CSharpBuilderException( JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx); } var f2tCast = Cast.Lookup(typeofFalse, typeofTrue); var t2fCast = Cast.Lookup(typeofTrue, typeofFalse); if (f2tCast == null && t2fCast == null) { throw new CSharpBuilderException( JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx); } else if (f2tCast != null && t2fCast != null && typeofFalse != typeofTrue) { throw new CSharpBuilderException( JSToCSharpExceptionType.UnexpectedInferredAst, Ast, ce, ctx); } return LinqExpression.Condition( CompileCast(castTest, ce.Test, ctx), f2tCast == null ? Compile(ce.IfFalse, ctx) : CompileCast(f2tCast, ce.IfFalse, ctx), t2fCast == null ? Compile(ce.IfTrue, ctx) : CompileCast(t2fCast, ce.IfTrue, ctx)); }