public static TypeSpec CreateDelegateType (ResolveContext rc, AParametersCollection parameters, TypeSpec returnType, Location loc) { Namespace type_ns = rc.Module.GlobalRootNamespace.GetNamespace ("System", true); if (type_ns == null) { return null; } if (returnType == rc.BuiltinTypes.Void) { var actArgs = parameters.Types; var actionSpec = type_ns.LookupType (rc.Module, "Action", actArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc); if (actionSpec == null) { return null; } if (actArgs.Length == 0) return actionSpec; else return actionSpec.MakeGenericType(rc, actArgs); } else { TypeSpec[] funcArgs = new TypeSpec[parameters.Types.Length + 1]; parameters.Types.CopyTo(funcArgs, 0); funcArgs[parameters.Types.Length] = returnType; var funcSpec = type_ns.LookupType (rc.Module, "Func", funcArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc); if (funcSpec == null) return null; return funcSpec.MakeGenericType(rc, funcArgs); } }
protected override Expression DoResolve(ResolveContext ec) { // // It's null when lifting non-nullable type // if (unwrap == null) { // S -> T? is wrap only if (TypeManager.IsNullableType (type)) return Wrap.Create (expr, type); // S -> T can be simplified return expr; } // Wrap target for T? if (TypeManager.IsNullableType (type)) { expr = Wrap.Create (expr, type); if (expr == null) return null; null_value = LiftedNull.Create (type, loc); } else { null_value = new NullConstant (type, loc); } eclass = ExprClass.Value; return this; }
object ResolveField(FieldInfo fieldInfo, ResolveContext context, ZenUtil.InjectInfo injectInfo) { var desiredType = fieldInfo.FieldType; var valueObj = _container.TryResolve(desiredType, context); if (valueObj == null) { // If it's a list it might map to a collection if (ReflectionUtil.IsGenericList(desiredType)) { var subTypes = desiredType.GetGenericArguments(); if (subTypes.Length == 1) { var subType = subTypes[0]; // Dependencies that are lists are only optional if declared as such using the inject attribute bool optional = (injectInfo == null ? false : injectInfo.Optional); valueObj = _container.ResolveMany(subType, context, optional); } } } return valueObj; }
protected override Expression Error_MemberLookupFailed (ResolveContext ec, Type container_type, Type qualifier_type, Type queried_type, string name, string class_name, MemberTypes mt, BindingFlags bf) { ec.Report.Error (1935, loc, "An implementation of `{0}' query expression pattern could not be found. " + "Are you missing `System.Linq' using directive or `System.Core.dll' assembly reference?", name); return null; }
public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc) { Constant c = ConvertImplicitly (type); if (c == null) Error_ValueCannotBeConverted (ec, type, false); return c; }
protected override Expression DoResolve (ResolveContext ec) { var results = new List<string> (); ec.CurrentMemberDefinition.GetCompletionStartingWith (Prefix, results); throw new CompletionResult (Prefix, results.Distinct ().Select (l => l.Substring (Prefix.Length)).ToArray ()); }
public override object Resolve(ResolveContext context, DependencyRegistration registration) { if (registration.RegistrationKind == RegistrationKind.FactoryFunction) { return registration.FactoryFunction(context.Resolver); } return context.Builder.CreateObject(registration); }
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { if (!expl && IsLiteral && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", GetValueAsLiteral (), TypeManager.CSharpName (target)); } else { base.Error_ValueCannotBeConverted (ec, target, expl); } }
public object Resolve(ResolveContext context) { if (_instance == null) { lock (this) { if (_instance == null) { _instance = _innerResolver.Resolve(context); } } } return _instance; }
public override Expression DoResolve (ResolveContext ec) { int counter = QueryBlock.TransparentParameter.Counter; Expression e = BuildQueryClause (ec, null); e = e.Resolve (ec); // // Reset counter in probing mode to ensure that all transparent // identifier anonymous types are created only once // if (ec.IsInProbingMode) QueryBlock.TransparentParameter.Counter = counter; return e; }
public void Inject(object injectable) { Assert.That(injectable != null); var fields = ZenUtil.GetFieldDependencies(injectable.GetType()); var parentDependencies = new List<Type>(_container.LookupsInProgress); foreach (var fieldInfo in fields) { var injectInfo = ZenUtil.GetInjectInfo(fieldInfo); Assert.That(injectInfo != null); bool foundAdditional = false; foreach (object obj in _additional) { if (fieldInfo.FieldType.IsAssignableFrom(obj.GetType())) { fieldInfo.SetValue(injectable, obj); _additional.Remove(obj); foundAdditional = true; break; } } if (foundAdditional) { continue; } var context = new ResolveContext() { Target = injectable.GetType(), FieldName = fieldInfo.Name, Name = injectInfo.Name, Parents = parentDependencies, TargetInstance = injectable, }; var valueObj = ResolveField(fieldInfo, context, injectInfo); Assert.That(valueObj != null || injectInfo.Optional, () => "Unable to find field with type '" + fieldInfo.FieldType + "' when injecting dependencies into '" + injectable + "'. \nObject graph:\n" + _container.GetCurrentObjectGraph()); fieldInfo.SetValue(injectable, valueObj); } }
public virtual Expression BuildQueryClause(ResolveContext ec, Expression lSide) { Arguments args; CreateArguments (ec, out args); lSide = CreateQueryExpression (lSide, args); if (next != null) { Select s = next as Select; if (s == null || s.IsRequired) return next.BuildQueryClause (ec, lSide); // Skip transparent select clause if any clause follows if (next.next != null) return next.next.BuildQueryClause (ec, lSide); } return lSide; }
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec t, bool expl) { if (t.IsGenericParameter) { ec.Report.Error(403, loc, "Cannot convert null to the type parameter `{0}' because it could be a value " + "type. Consider using `default ({0})' instead", t.Name); return; } if (TypeSpec.IsValueType (t)) { ec.Report.Error(37, loc, "Cannot convert null to `{0}' because it is a value type", TypeManager.CSharpName(t)); return; } base.Error_ValueCannotBeConverted (ec, t, expl); }
// // Performs the numeric promotions on the left and right expresions // and deposits the results on `lc' and `rc'. // // On success, the types of `lc' and `rc' on output will always match, // and the pair will be one of: // // TODO: BinaryFold should be called as an optimization step only, // error checking here is weak // static bool DoBinaryNumericPromotions (ResolveContext rc, ref Constant left, ref Constant right) { TypeSpec ltype = left.Type; TypeSpec rtype = right.Type; foreach (TypeSpec t in rc.BuiltinTypes.BinaryPromotionsTypes) { if (t == ltype) return t == rtype || ConvertPromotion (rc, ref right, ref left, t); if (t == rtype) return t == ltype || ConvertPromotion (rc, ref left, ref right, t); } left = left.ConvertImplicitly (rc.BuiltinTypes.Int); right = right.ConvertImplicitly (rc.BuiltinTypes.Int); return left != null && right != null; }
static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, TypeSpec type) { Constant c = prim.ConvertImplicitly (type); if (c != null) { prim = c; return true; } if (type.BuiltinType == BuiltinTypeSpec.Type.UInt) { type = rc.BuiltinTypes.Long; prim = prim.ConvertImplicitly (type); second = second.ConvertImplicitly (type); return prim != null && second != null; } return false; }
protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, TypeSpec delegateType) { if (!delegateType.IsDelegate) return null; AParametersCollection d_params = Delegate.GetParameters (delegateType); if (HasExplicitParameters) { if (!VerifyExplicitParameters (ec, delegateType, d_params)) return null; return Parameters; } // // If L has an implicitly typed parameter list we make implicit parameters explicit // Set each parameter of L is given the type of the corresponding parameter in D // if (!VerifyParameterCompatibility (ec, delegateType, d_params, ec.IsInProbingMode)) return null; TypeSpec [] ptypes = new TypeSpec [Parameters.Count]; for (int i = 0; i < d_params.Count; i++) { // D has no ref or out parameters if ((d_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != 0) return null; TypeSpec d_param = d_params.Types [i]; // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument (ec, d_param); } ptypes [i] = d_param; ImplicitLambdaParameter ilp = (ImplicitLambdaParameter) Parameters.FixedParameters [i]; ilp.SetParameterType (d_param); ilp.Resolve (null, i); } Parameters.Types = ptypes; return Parameters; }
public override Constant ConvertInitializer (ResolveContext rc, Constant expr) { if (expr is EnumConstant) expr = ((EnumConstant) expr).Child; var underlying = ((Enum) Parent).UnderlyingType; if (expr != null) { expr = expr.ImplicitConversionRequired (rc, underlying, Location); if (expr != null && !IsValidEnumType (expr.Type)) { Enum.Error_1008 (Location, Report); expr = null; } } if (expr == null) expr = New.Constantify (underlying, Location); return new EnumConstant (expr, MemberType); }
public virtual Expression BuildQueryClause(ResolveContext ec, Expression lSide, Parameter parameter) { Arguments args = null; CreateArguments (ec, parameter, ref args); lSide = CreateQueryExpression (lSide, args); if (next != null) { parameter = CreateChildrenParameters (parameter); Select s = next as Select; if (s == null || s.IsRequired (parameter)) return next.BuildQueryClause (ec, lSide, parameter); // Skip transparent select clause if any clause follows if (next.next != null) return next.next.BuildQueryClause (ec, lSide, parameter); } return lSide; }
protected override Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type) { if (ec.IsInProbingMode) return this; BlockContext bc = new BlockContext (ec.MemberContext, ec.ConstructorBlock, ec.BuiltinTypes.Void) { CurrentAnonymousMethod = ec.CurrentAnonymousMethod }; Expression args = Parameters.CreateExpressionTree (bc, loc); Expression expr = Block.CreateExpressionTree (ec); if (expr == null) return null; Arguments arguments = new Arguments (2); arguments.Add (new Argument (expr)); arguments.Add (new Argument (args)); return CreateExpressionFactoryCall (ec, "Lambda", new TypeArguments (new TypeExpression (delegate_type, loc)), arguments); }
internal bool DefaultValidateOnRun(ResolveContext ctx) { // warrior can only deal damage while it is on battlefield var causeWarrior = Cause as Behaviors.Warrior; if (causeWarrior != null) { var causeBhvHost = causeWarrior.Host; if (causeBhvHost == null || causeBhvHost.IsDestroyed || !causeBhvHost.IsOnBattlefield && !causeBhvHost.IsActivatedAssist) { return false; } } if (this is IInitiativeCommand) { if (!ctx.CheckCompulsoryTargets()) { return false; } } return true; }
public override Expression CreateExpressionTree(ResolveContext ec) { return(expr.CreateExpressionTree(ec)); }
public override Expression DoResolveLValue(ResolveContext ec, Expression right_side) { expr = expr.DoResolveLValue(ec, right_side); return(this); }
protected override Expression DoResolve(ResolveContext ec) { return(this); }
public IValueBuilder Resolve(ResolveContext context) => _resolve(context);
public virtual IStatBuilder Resolve(ResolveContext context) => With(CoreStatBuilder.Resolve(context));
public ICoreStatBuilder Resolve(ResolveContext context) => new ModifiersApplyToOtherStatCoreStatBuilder( _source.Resolve(context), _target.Resolve(context), _form, _statFactory);
protected override MethodGroupExpr DoResolveOverload(ResolveContext ec) { MethodGroupExpr rmg = mg.OverloadResolve(ec, ref arguments, this, OverloadResolver.Restrictions.None); return(rmg); }
public override Expression DoResolveLeftValue(ResolveContext ec, Expression right_side) { return(this); }
public IKeywordBuilder Resolve(ResolveContext context) => With(_coreDamageType.Resolve(context));
public ICoreBuilder <TResult> Resolve(ResolveContext context) => new ProxyCoreBuilder <TProxied, TResult>(_proxiedBuilder.Resolve(context), _build);
public ICoreBuilder <TResult> Resolve(ResolveContext context) => new BinaryOperatorCoreBuilder <TResult>(_left.Resolve(context), _right.Resolve(context), _operator);
public override IEffectBuilder Resolve(ResolveContext context) => new BuffBuilder(StatFactory, Identity.Resolve(context));
public IConditionBuilder Resolve(ResolveContext context) => new OrCompositeConditionBuilder(Conditions.Select(c => c.Resolve(context)).ToList());
protected override void CreateArguments(ResolveContext ec, Parameter parameter, ref Arguments args) { expr = CreateRangeVariableType(ec, parameter, identifier, expr); base.CreateArguments(ec, parameter, ref args); }
public override Expression CreateExpressionTree(ResolveContext ec) { return(new SimpleAssign(this, this).CreateExpressionTree(ec)); }
protected override Expression DoResolve(ResolveContext ec) { pi = ec.CurrentBlock.ParametersBlock.GetParameterInfo(parameter); return(base.DoResolve(ec)); }
public IValueBuilder Resolve(ResolveContext context) => this;
public override Expression DoResolve(ResolveContext ec) { return(this); }
protected override Expression DoResolve (ResolveContext ec) { unwrap = Unwrap.Create (Expr, false); if (unwrap == null) return null; Expression res = base.ResolveOperator (ec, unwrap); if (res != this) { if (user_operator == null) return res; } else { res = Expr = LiftExpression (ec, Expr); } if (res == null) return null; eclass = ExprClass.Value; type = res.Type; return this; }
public TService Resolve <TService>(ResolveContext <TService> context) { return(context.Factory()); }
protected override Expression ResolveEnumOperator (ResolveContext ec, Expression expr, TypeSpec[] predefined) { expr = base.ResolveEnumOperator (ec, expr, predefined); if (expr == null) return null; Expr = LiftExpression (ec, Expr); return LiftExpression (ec, expr); }
public override Expression CreateExpressionTree (ResolveContext ec) { if (user_operator != null) return user_operator.CreateExpressionTree (ec); return base.CreateExpressionTree (ec); }
protected override void Error_TypeDoesNotContainDefinition(ResolveContext ec, TypeSpec type, string name) { ec.Report.Error(1935, loc, "An implementation of `{0}' query expression pattern could not be found. " + "Are you missing `System.Linq' using directive or `System.Core.dll' assembly reference?", name); }
protected override Expression DoResolve (ResolveContext ec) { if ((Oper & Operator.LogicalMask) != 0) { Error_OperatorCannotBeApplied (ec, left, right); return null; } bool use_default_call = (Oper & (Operator.BitwiseMask | Operator.EqualityMask)) != 0; left_orig = left; if (left.Type.IsNullableType) { left = left_unwrap = Unwrap.Create (left, use_default_call); if (left == null) return null; } right_orig = right; if (right.Type.IsNullableType) { right = right_unwrap = Unwrap.Create (right, use_default_call); if (right == null) return null; } // // Some details are in 6.4.2, 7.2.7 // Arguments can be lifted for equal operators when the return type is bool and both // arguments are of same type // if (left_orig is NullLiteral) { left = right; state |= State.LeftNullLifted; type = ec.BuiltinTypes.Bool; } if (right_orig.IsNull) { if ((Oper & Operator.ShiftMask) != 0) right = new EmptyExpression (ec.BuiltinTypes.Int); else right = left; state |= State.RightNullLifted; type = ec.BuiltinTypes.Bool; } eclass = ExprClass.Value; return DoResolveCore (ec, left_orig, right_orig); }
protected override Expression DoResolve(ResolveContext ec) { Expression e = BuildQueryClause(ec, null, null); return(e.Resolve(ec)); }
protected override Expression ResolveOperatorPredefined (ResolveContext ec, Binary.PredefinedOperator [] operators, bool primitives_only, TypeSpec enum_type) { Expression e = base.ResolveOperatorPredefined (ec, operators, primitives_only, enum_type); if (e == this || enum_type != null) return LiftResult (ec, e); // // 7.9.9 Equality operators and null // // The == and != operators permit one operand to be a value of a nullable type and // the other to be the null literal, even if no predefined or user-defined operator // (in unlifted or lifted form) exists for the operation. // if (e == null && (Oper & Operator.EqualityMask) != 0) { if ((IsLeftNullLifted && right_unwrap != null) || (IsRightNullLifted && left_unwrap != null)) return LiftResult (ec, this); } return e; }
protected override void Error_InvalidInitializer(ResolveContext ec, string initializer) { ec.Report.Error(1932, loc, "A range variable `{0}' cannot be initialized with `{1}'", Name, initializer); }
public override Expression CreateExpressionTree(ResolveContext ec) { throw new NotSupportedException("ET"); }
public ICoreBuilder <TResult> Resolve(ResolveContext context) => new ParametrisedCoreBuilder <TParameter, TResult>(_parameter.Resolve(context), _build);
Expression LiftResult(ResolveContext ec, Expression res_expr) { TypeSpec lifted_type; // // Avoid double conversion // if (left_unwrap == null || IsLeftNullLifted || left_unwrap.Type != left.Type || (left_unwrap != null && IsRightNullLifted)) { lifted_type = new NullableType(left.Type, loc).ResolveAsType(ec); if (lifted_type == null) { return(null); } if (left is UserCast || left is EmptyCast || left is OpcodeCast) { left.Type = lifted_type; } else { left = EmptyCast.Create(left, lifted_type); } } if (left != right && (right_unwrap == null || IsRightNullLifted || right_unwrap.Type != right.Type || (right_unwrap != null && IsLeftNullLifted))) { lifted_type = new NullableType(right.Type, loc).ResolveAsType(ec); if (lifted_type == null) { return(null); } var r = right; if (r is ReducedExpression) { r = ((ReducedExpression)r).OriginalExpression; } if (r is UserCast || r is EmptyCast || r is OpcodeCast) { r.Type = lifted_type; } else { right = EmptyCast.Create(right, lifted_type); } } if ((Oper & Operator.ComparisonMask) == 0) { lifted_type = new NullableType(res_expr.Type, loc).ResolveAsType(ec); if (lifted_type == null) { return(null); } wrap_ctor = NullableInfo.GetConstructor(lifted_type); type = res_expr.Type = lifted_type; } if (IsLeftNullLifted) { left = LiftedNull.Create(right.Type, left.Location); // // Special case for bool?, the result depends on both null right side and left side value // if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType(type).BuiltinType == BuiltinTypeSpec.Type.Bool) { return(res_expr); } if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) { return(LiftedNull.CreateFromExpression(ec, res_expr)); } // // Value types and null comparison // if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0) { return(CreateNullConstant(ec, right_orig)); } } if (IsRightNullLifted) { right = LiftedNull.Create(left.Type, right.Location); // // Special case for bool?, the result depends on both null right side and left side value // if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType(type).BuiltinType == BuiltinTypeSpec.Type.Bool) { return(res_expr); } if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) { return(LiftedNull.CreateFromExpression(ec, res_expr)); } // // Value types and null comparison // if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0) { return(CreateNullConstant(ec, left_orig)); } } return(res_expr); }
Expression LiftExpression (ResolveContext ec, Expression expr) { TypeExpr lifted_type = new NullableType (expr.Type, expr.Location); lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false); if (lifted_type == null) return null; expr.Type = lifted_type.Type; return expr; }
public ICoreBuilder <TOut> Resolve(ResolveContext context) => new UnaryOperatorCoreBuilder <TIn, TOut>(_operand.Resolve(context), _operator);
protected override Expression ResolveUserOperator (ResolveContext ec, Expression expr) { expr = base.ResolveUserOperator (ec, expr); if (expr == null) return null; // // When a user operator is of non-nullable type // if (Expr is Unwrap) { user_operator = LiftExpression (ec, expr); return user_operator; } return expr; }
public override Task <DirectoryInfo> ResolveTo(ResolveContext context, string path) => Package.ResolveTo(context, path);
// // CSC 2 has this behavior, it allows structs to be compared // with the null literal *outside* of a generics context and // inlines that as true or false. // Constant CreateNullConstant (ResolveContext ec, Expression expr) { // FIXME: Handle side effect constants Constant c = new BoolConstant (ec.BuiltinTypes, Oper == Operator.Inequality, loc); if ((Oper & Operator.EqualityMask) != 0) { ec.Report.Warning (472, 2, loc, "The result of comparing value type `{0}' with null is `{1}'", TypeManager.CSharpName (expr.Type), c.GetValueAsLiteral ()); } else { ec.Report.Warning (464, 2, loc, "The result of comparing type `{0}' with null is always `{1}'", TypeManager.CSharpName (expr.Type), c.GetValueAsLiteral ()); } return ReducedExpression.Create (c, this); }
public IEquipmentBuilder Resolve(ResolveContext context) => this;
Expression LiftResult (ResolveContext ec, Expression res_expr) { TypeExpr lifted_type; // // Avoid double conversion // if (left_unwrap == null || IsLeftNullLifted || left_unwrap.Type != left.Type || (left_unwrap != null && IsRightNullLifted)) { lifted_type = new NullableType (left.Type, loc); lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false); if (lifted_type == null) return null; if (left is UserCast || left is TypeCast) left.Type = lifted_type.Type; else left = EmptyCast.Create (left, lifted_type.Type); } if (left != right && (right_unwrap == null || IsRightNullLifted || right_unwrap.Type != right.Type || (right_unwrap != null && IsLeftNullLifted))) { lifted_type = new NullableType (right.Type, loc); lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false); if (lifted_type == null) return null; var r = right; if (r is ReducedExpression) r = ((ReducedExpression) r).OriginalExpression; if (r is UserCast || r is TypeCast) r.Type = lifted_type.Type; else right = EmptyCast.Create (right, lifted_type.Type); } if ((Oper & Operator.ComparisonMask) == 0) { lifted_type = new NullableType (res_expr.Type, loc); lifted_type = lifted_type.ResolveAsTypeTerminal (ec, false); if (lifted_type == null) return null; wrap_ctor = NullableInfo.GetConstructor (lifted_type.Type); type = res_expr.Type = lifted_type.Type; } if (IsLeftNullLifted) { left = LiftedNull.Create (right.Type, left.Location); // // Special case for bool?, the result depends on both null right side and left side value // if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType (type).BuiltinType == BuiltinTypeSpec.Type.Bool) { return res_expr; } if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) return LiftedNull.CreateFromExpression (ec, res_expr); // // Value types and null comparison // if (right_unwrap == null || (Oper & Operator.RelationalMask) != 0) return CreateNullConstant (ec, right_orig); } if (IsRightNullLifted) { right = LiftedNull.Create (left.Type, right.Location); // // Special case for bool?, the result depends on both null right side and left side value // if ((Oper == Operator.BitwiseAnd || Oper == Operator.BitwiseOr) && NullableInfo.GetUnderlyingType (type).BuiltinType == BuiltinTypeSpec.Type.Bool) { return res_expr; } if ((Oper & (Operator.ArithmeticMask | Operator.ShiftMask | Operator.BitwiseMask)) != 0) return LiftedNull.CreateFromExpression (ec, res_expr); // // Value types and null comparison // if (left_unwrap == null || (Oper & Operator.RelationalMask) != 0) return CreateNullConstant (ec, left_orig); } return res_expr; }
public ILeechStatBuilder Resolve(ResolveContext context) => _resolver(this, context);
protected override Expression ResolveUserOperator (ResolveContext ec, Expression left, Expression right) { // // Try original types first for exact match without unwrapping // Expression expr = base.ResolveUserOperator (ec, left_orig, right_orig); if (expr != null) return expr; State orig_state = state; // // One side is a nullable type, try to match underlying types // if (left_unwrap != null || right_unwrap != null || (state & (State.RightNullLifted | State.LeftNullLifted)) != 0) { expr = base.ResolveUserOperator (ec, left, right); } if (expr == null) return null; // // Lift the result in the case it can be null and predefined or user operator // result type is of a value type // if (!TypeManager.IsValueType (expr.Type)) return null; if (state != orig_state) return expr; expr = LiftResult (ec, expr); if (expr is Constant) return expr; type = expr.Type; user_operator = expr; return this; }
Expression ConvertExpression(ResolveContext ec) { // TODO: ImplicitConversionExists should take care of this if (left.eclass == ExprClass.MethodGroup) { return(null); } TypeSpec ltype = left.Type; // // If left is a nullable type and an implicit conversion exists from right to underlying type of left, // the result is underlying type of left // if (ltype.IsNullableType) { unwrap = Unwrap.Create(left, false); if (unwrap == null) { return(null); } // // Reduce (left ?? null) to left // if (right.IsNull) { return(ReducedExpression.Create(left, this)); } if (Convert.ImplicitConversionExists(ec, right, unwrap.Type)) { left = unwrap; ltype = left.Type; // // If right is a dynamic expression, the result type is dynamic // if (right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { type = right.Type; // Need to box underlying value type left = Convert.ImplicitBoxingConversion(left, ltype, type); return(this); } right = Convert.ImplicitConversion(ec, right, ltype, loc); type = ltype; return(this); } } else if (TypeSpec.IsReferenceType(ltype)) { if (Convert.ImplicitConversionExists(ec, right, ltype)) { // // If right is a dynamic expression, the result type is dynamic // if (right.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { type = right.Type; return(this); } // // Reduce ("foo" ?? expr) to expression // Constant lc = left as Constant; if (lc != null && !lc.IsDefaultValue) { return(ReducedExpression.Create(lc, this)); } // // Reduce (left ?? null) to left OR (null-constant ?? right) to right // if (right.IsNull || lc != null) { return(ReducedExpression.Create(lc != null ? right : left, this)); } right = Convert.ImplicitConversion(ec, right, ltype, loc); type = ltype; return(this); } // // Special case null ?? null // if (ltype == right.Type) { type = ltype; return(this); } } else { return(null); } TypeSpec rtype = right.Type; if (!Convert.ImplicitConversionExists(ec, unwrap != null ? unwrap : left, rtype) || right.eclass == ExprClass.MethodGroup) { return(null); } // // Reduce (null ?? right) to right // if (left.IsNull) { return(ReducedExpression.Create(right, this).Resolve(ec)); } left = Convert.ImplicitConversion(ec, unwrap != null ? unwrap : left, rtype, loc); type = rtype; return(this); }