public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc) { if (_resolved) { return(this); } ResolveContext oldResolver = rc; try { rc = rc.WithCheckForOverflow(true); Expr = Expr.DoResolve(rc); } finally { rc = oldResolver; } if (Expr == null) { return(null); } //TODO:Anonymous if (Expr is Constant || Expr is MethodGroupExpression || /*Expr is AnonymousMethodExpression ||*/ Expr is DefaultValueExpression) { return(Expr); } eclass = Expr.eclass; ResolvedType = Expr.Type; _resolved = true; return(this); }
public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc) { if (_resolved) { return(this); } if (source == null) { return(EmptyExpressionStatement.Instance); } if (!ResolveElement(rc)) { return(null); } if (source is CollectionOrObjectInitializers) { rc = rc.PushObjectInitializer(target); source = source.DoResolve(rc); rc = rc.PopObjectInitializer(); if (source == null) { return(null); } eclass = source.eclass; ResolvedType = source.Type; _resolved = true; return(this); } return(base.DoResolve(rc)); }
public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc) { UnaryOperatorType op = UnaryOperatorType.PostIncrement; if (mode == Mode.PreIncrement) { op = UnaryOperatorType.PreIncrement; } else if (mode == Mode.PreDecrement) { op = UnaryOperatorType.Decrement; } else if (mode == Mode.PostDecrement) { op = UnaryOperatorType.PostDecrement; } expr = expr.DoResolve(rc); if (expr == null) { return(null); } // ++/-- on pointer variables of all types except void* if (expr.Type is PointerTypeSpec) { if (((PointerTypeSpec)expr.Type).ElementType.Kind == TypeKind.Void) { rc.Report.Error(0, loc, "The operation in question is undefined on void pointers"); return(null); } } if (expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.IndexerAccess || expr.eclass == ExprClass.PropertyAccess) { expr = expr.DoResolveLeftValue(rc, expr); } else { rc.Report.Error(0, loc, "The operand of an increment or decrement operator must be a variable, property or indexer"); } operation = new UnaryExpression(op, expr, loc).DoResolve(rc); if (operation == null) { return(null); } _resolved = true; ResolvedType = operation.Type; eclass = ExprClass.Value; return(this); }
public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc) { if (parameters == null) { anonymous_type = CreateAnonymousType(rc, EmptyParameters); RequestedType = new TypeExpression(anonymous_type, loc); return(base.DoResolve(rc)); } bool error = false; arguments = new Arguments(parameters.Count); for (int i = 0; i < parameters.Count; ++i) { Expression e = parameters[i].DoResolve(rc); if (e == null) { error = true; continue; } arguments.Add(new Argument(e, e.Location)); } if (error) { return(null); } anonymous_type = CreateAnonymousType(rc, parameters); if (anonymous_type == null) { return(null); } return(base.DoResolve(rc)); }
public override VSC.AST.Expression Constantify(VSC.TypeSystem.Resolver.ResolveContext resolver) { return(DoResolve(resolver) as Constant); }
public override VSC.AST.Expression DoResolve(VSC.TypeSystem.Resolver.ResolveContext rc) { expr = expr.DoResolve(rc); true_expr = true_expr.DoResolve(rc); false_expr = false_expr.DoResolve(rc); if (true_expr == null || false_expr == null || expr == null) { return(null); } eclass = ExprClass.Value; // V# 4.0 spec §7.14: Conditional operator bool isValid; IType resultType; if (true_expr.Type.Kind == TypeKind.Dynamic || false_expr.Type.Kind == TypeKind.Dynamic) { resultType = SpecialTypeSpec.Dynamic; isValid = rc.TryConvert(ref true_expr, resultType) & rc.TryConvert(ref false_expr, resultType); } else if (rc.HasType(true_expr) && rc.HasType(false_expr)) { Conversion t2f = rc.conversions.ImplicitConversion(true_expr, false_expr.Type); Conversion f2t = rc.conversions.ImplicitConversion(false_expr, true_expr.Type); // The operator is valid: // a) if there's a conversion in one direction but not the other // b) if there are conversions in both directions, and the types are equivalent if (rc.IsBetterConditionalConversion(t2f, f2t)) { resultType = false_expr.Type; isValid = true; true_expr = rc.Convert(true_expr, resultType, t2f); } else if (rc.IsBetterConditionalConversion(f2t, t2f)) { resultType = true_expr.Type; isValid = true; false_expr = rc.Convert(false_expr, resultType, f2t); } else { resultType = true_expr.Type; isValid = true_expr.Type.Equals(false_expr.Type); if (!isValid) { _resolved = true; ResolvedType = resultType; rc.Report.Error(248, true_expr.Location, "Type of conditional expression cannot be determined as `{0}' and `{1}' convert implicitly to each other", true_expr.Type.ToString(), false_expr.Type.ToString()); return(this); } } } else if (rc.HasType(true_expr)) { resultType = true_expr.Type; isValid = rc.TryConvert(ref false_expr, resultType); } else if (rc.HasType(false_expr)) { resultType = false_expr.Type; isValid = rc.TryConvert(ref true_expr, resultType); } else { return(ErrorResult); } expr = rc.ResolveCondition(expr); if (isValid) { if (expr.IsCompileTimeConstant && true_expr.IsCompileTimeConstant && false_expr.IsCompileTimeConstant) { bool?val = expr.ConstantValue as bool?; if (val == true) { return(true_expr); } else if (val == false) { return(false_expr); } } _resolved = true; this.ResolvedType = resultType; return(this); } else { rc.Report.Error(249, true_expr.Location, "Type of conditional expression cannot be determined because there is no implicit conversion between `{0}' and `{1}'", true_expr.Type.ToString(), false_expr.Type.ToString()); } return(this); }