public DynamicMetaObject Bind (DynamicContext ctx, Type callingType) { Expression res; try { var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, callingType), ResolveOptions); // Static typemanager and internal caches are not thread-safe lock (resolver) { expr = expr.Resolve (rc, Compiler.ResolveFlags.VariableOrValue); } if (expr == null) throw new RuntimeBinderInternalCompilerException ("Expression resolved to null"); res = expr.MakeExpression (new Compiler.BuilderContext ()); } catch (RuntimeBinderException e) { if (errorSuggestion != null) return errorSuggestion; res = CreateBinderException (e.Message); } catch (Exception) { if (errorSuggestion != null) return errorSuggestion; throw; } return new DynamicMetaObject (res, restrictions); }
public override Expression DoResolve (ResolveContext ec) { // // We are born fully resolved // return this; }
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); } }
public virtual Expression CreateExpressionTree (ResolveContext ec) { if (ArgType == AType.Default) ec.Report.Error (854, Expr.Location, "An expression tree cannot contain an invocation which uses optional parameter"); return Expr.CreateExpressionTree (ec); }
/// <summary> /// Performs an explicit conversion of the expression `expr' whose /// type is expr.Type to `target_type'. /// </summary> public static Expression ExplicitConversion(ResolveContext ec, Expression expr, TypeSpec target_type, Location loc) { Expression e = ExplicitConversionCore (ec, expr, target_type, loc); if (e != null) { // // Don't eliminate explicit precission casts // if (e == expr) { if (target_type.BuiltinType == BuiltinTypeSpec.Type.Float) return new OpcodeCast (expr, target_type, OpCodes.Conv_R4); if (target_type.BuiltinType == BuiltinTypeSpec.Type.Double) return new OpcodeCast (expr, target_type, OpCodes.Conv_R8); } return e; } TypeSpec expr_type = expr.Type; if (target_type.IsNullableType) { TypeSpec target; if (expr_type.IsNullableType) { target = Nullable.NullableInfo.GetUnderlyingType (target_type); Expression unwrap = Nullable.Unwrap.Create (expr); e = ExplicitConversion (ec, unwrap, target, expr.Location); if (e == null) return null; return new Nullable.LiftedConversion (e, unwrap, target_type).Resolve (ec); } if (expr_type.BuiltinType == BuiltinTypeSpec.Type.Object) { return new UnboxCast (expr, target_type); } target = TypeManager.GetTypeArguments (target_type) [0]; e = ExplicitConversionCore (ec, expr, target, loc); if (e != null) return TypeSpec.IsReferenceType (expr.Type) ? new UnboxCast (expr, target_type) : Nullable.Wrap.Create (e, target_type); } else if (expr_type.IsNullableType) { e = ImplicitBoxingConversion (expr, Nullable.NullableInfo.GetUnderlyingType (expr_type), target_type); if (e != null) return e; e = Nullable.Unwrap.Create (expr, false); e = ExplicitConversionCore (ec, e, target_type, loc); if (e != null) return EmptyCast.Create (e, target_type); } e = ExplicitUserConversion (ec, expr, target_type, loc); if (e != null) return e; expr.Error_ValueCannotBeConverted (ec, target_type, true); return null; }
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 Expression CreateExpressionTree (ResolveContext ec) { // HACK: avoid referencing mcs internal type if (type == typeof (NullLiteral)) type = TypeManager.object_type; return base.CreateExpressionTree (ec); }
public Constant ImplicitConversionRequired (ResolveContext ec, TypeSpec type, Location loc) { Constant c = ConvertImplicitly (type); if (c == null) Error_ValueCannotBeConverted (ec, type, false); return c; }
/// <summary> /// Performs an explicit conversion of the expression `expr' whose /// type is expr.Type to `target_type'. /// </summary> public static Expression ExplicitConversion(ResolveContext ec, Expression expr, TypeSpec target_type, Location loc) { Expression e = ExplicitConversionCore (ec, expr, target_type, loc); if (e != null) { // // Don't eliminate explicit precission casts // if (e == expr) { if (target_type == TypeManager.float_type) return new OpcodeCast (expr, target_type, OpCodes.Conv_R4); if (target_type == TypeManager.double_type) return new OpcodeCast (expr, target_type, OpCodes.Conv_R8); } return e; } TypeSpec expr_type = expr.Type; if (TypeManager.IsNullableType (target_type)) { if (TypeManager.IsNullableType (expr_type)) { TypeSpec target = Nullable.NullableInfo.GetUnderlyingType (target_type); Expression unwrap = Nullable.Unwrap.Create (expr); e = ExplicitConversion (ec, unwrap, target, expr.Location); if (e == null) return null; return new Nullable.Lifted (e, unwrap, target_type).Resolve (ec); } else if (expr_type == TypeManager.object_type) { return new UnboxCast (expr, target_type); } else { TypeSpec target = TypeManager.GetTypeArguments (target_type) [0]; e = ExplicitConversionCore (ec, expr, target, loc); if (e != null) return Nullable.Wrap.Create (e, target_type); } } else if (TypeManager.IsNullableType (expr_type)) { bool use_class_cast; if (ImplicitBoxingConversionExists (Nullable.NullableInfo.GetUnderlyingType (expr_type), target_type, out use_class_cast)) return new BoxedCast (expr, target_type); e = Nullable.Unwrap.Create (expr, false); e = ExplicitConversionCore (ec, e, target_type, loc); if (e != null) return EmptyCast.Create (e, target_type); } e = ExplicitUserConversion (ec, expr, target_type, loc); if (e != null) return e; expr.Error_ValueCannotBeConverted (ec, loc, target_type, true); return null; }
protected override Expression DoResolve(ResolveContext ec){ var e = base.DoResolve(ec); if (e == null || e != this) return e; var fld = target as FieldExpr; if (fld == null){ var access = target as MemberAccess; if (access != null) fld = access.LeftExpression as FieldExpr; if (fld == null){ Expression simple = target as SimpleName; simple = simple != null ? simple.Resolve(ec) : null; fld = simple as FieldExpr; } if (fld == null) return e; } if (!fld.IsRole) return e; //assigning to a role. Check that the contract is fullfilled var contractName = CSharpParser.GetCurrentRoleContractName(fld.DeclaringType.Name, fld.Name); if (CSharpParser.RoleContracts.ContainsKey(contractName)){ if (source.Type == null) source = source.Resolve(ec); var contract = CSharpParser.RoleContracts[contractName]; if (!source.Type.FullfillsContract(contract)){ var index = -1; var current_class = contract.Parent; if (current_class.IsGeneric) { var typeParameters = current_class.TypeParameters; for (int i = 0; index < 0 && i < typeParameters.Length; i++) { var param = typeParameters[i]; if (target.Type.Name == param.Name) { index = i; } } } if (index < 0) { ec.Report.Error(10009, loc, "Assignment to role '{0}' does not full fill contract", fld.Name); } else { current_class.Spec.AddTypesAndContracts(index, contract); } } } return this; }
public override Expression DoResolve (ResolveContext ec) { ArrayList results = new ArrayList (); AppendResults (results, Prefix, Evaluator.GetVarNames ()); AppendResults (results, Prefix, ec.CurrentTypeDefinition.NamespaceEntry.CompletionGetTypesStartingWith (Prefix)); AppendResults (results, Prefix, Evaluator.GetUsingList ()); throw new CompletionResult (Prefix, (string []) results.ToArray (typeof (string))); }
protected override Expression DoResolve (ResolveContext ec) { var results = new List<string> (); AppendResults (results, Prefix, ec.Module.Evaluator.GetVarNames ()); AppendResults (results, Prefix, ec.CurrentMemberDefinition.Parent.NamespaceEntry.CompletionGetTypesStartingWith (Prefix)); AppendResults (results, Prefix, ec.Module.Evaluator.GetUsingList ()); throw new CompletionResult (Prefix, results.ToArray ()); }
public static DynamicMetaObject Bind(DynamicMetaObject target, Compiler.Expression expr, BindingRestrictions restrictions, DynamicMetaObject errorSuggestion) { var report = new Compiler.Report(ErrorPrinter.Instance) { WarningLevel = 0 }; var ctx = new Compiler.CompilerContext(report); Compiler.RootContext.ToplevelTypes = new Compiler.ModuleContainer(ctx, true); InitializeCompiler(ctx); Expression res; try { // TODO: ResolveOptions Compiler.ResolveContext rc = new Compiler.ResolveContext(new RuntimeBinderContext(ctx)); // Static typemanager and internal caches are not thread-safe lock (resolver) { expr = expr.Resolve(rc); } if (expr == null) { throw new RuntimeBinderInternalCompilerException("Expression resolved to null"); } res = expr.MakeExpression(new Compiler.BuilderContext()); } catch (RuntimeBinderException e) { if (errorSuggestion != null) { return(errorSuggestion); } if (binder_exception_ctor == null) { binder_exception_ctor = typeof(RuntimeBinderException).GetConstructor(new[] { typeof(string) }); } // // Uses target type to keep expressions composition working // res = Expression.Throw(Expression.New(binder_exception_ctor, Expression.Constant(e.Message)), target.LimitType); } catch (Exception) { if (errorSuggestion != null) { return(errorSuggestion); } throw; } return(new DynamicMetaObject(res, restrictions)); }
public override Expression CreateExpressionTree (ResolveContext ec) { if (expr_tree != null) return expr_tree (ec, mg); Arguments args = Arguments.CreateForExpressionTree (ec, arguments, new NullLiteral (loc), mg.CreateExpressionTree (ec)); return CreateExpressionFactoryCall (ec, "Call", args); }
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 override void Error_ValueCannotBeConverted (ResolveContext ec, Location loc, TypeSpec target, bool expl) { if (!expl && IsLiteral && (TypeManager.IsPrimitiveType (target) || type == TypeManager.decimal_type) && (TypeManager.IsPrimitiveType (type) || type == TypeManager.decimal_type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", AsString (), TypeManager.CSharpName (target)); } else { base.Error_ValueCannotBeConverted (ec, loc, target, expl); } }
public static bool CheckContext (ResolveContext ec, Location loc) { if (!ec.CurrentAnonymousMethod.IsIterator) { ec.Report.Error (1621, loc, "The yield statement cannot be used inside " + "anonymous method blocks"); return false; } return true; }
public override void Error_ValueCannotBeConverted (ResolveContext ec, TypeSpec target, bool expl) { if (!expl && IsLiteral && type.BuiltinType != BuiltinTypeSpec.Type.Double && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (target) && BuiltinTypeSpec.IsPrimitiveTypeOrDecimal (type)) { ec.Report.Error (31, loc, "Constant value `{0}' cannot be converted to a `{1}'", GetValueAsLiteral (), target.GetSignatureForError ()); } else { base.Error_ValueCannotBeConverted (ec, target, expl); } }
public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args) { var ctx = CSharpBinder.CreateDefaultCompilerContext (); CSharpBinder.InitializeCompiler (ctx); var context_type = TypeImporter.Import (callingContext); var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, context_type), 0); var expr = Compiler.Expression.MemberLookup (rc, context_type, context_type, name, 0, false, Compiler.Location.Null); var binder = new CSharpBinder ( this, new Compiler.BoolConstant (expr is Compiler.EventExpr, Compiler.Location.Null), null); binder.AddRestrictions (target); return binder.Bind (callingContext, target); }
public static bool CheckContext (ResolveContext ec, Location loc) { // // We can't use `ec.InUnsafe' here because it's allowed to have an iterator // inside an unsafe class. See test-martin-29.cs for an example. // if (!ec.CurrentAnonymousMethod.IsIterator) { ec.Report.Error (1621, loc, "The yield statement cannot be used inside " + "anonymous method blocks"); return false; } return true; }
public override DynamicMetaObject Bind (DynamicMetaObject target, DynamicMetaObject[] args) { var ctx = DynamicContext.Create (); var context_type = ctx.ImportType (callingContext); var queried_type = ctx.ImportType (target.LimitType); var rc = new Compiler.ResolveContext (new RuntimeBinderContext (ctx, context_type), 0); var expr = Compiler.Expression.MemberLookup (rc, context_type, queried_type, name, 0, false, Compiler.Location.Null); var binder = new CSharpBinder ( this, new Compiler.BoolConstant (expr is Compiler.EventExpr, Compiler.Location.Null), null); binder.AddRestrictions (target); return binder.Bind (ctx, callingContext); }
public AnonymousExpression Compatible(ResolveContext ec, AnonymousExpression ae) { // TODO: Implement clone BlockContext aec = new BlockContext (ec.MemberContext, Block, ReturnType); aec.CurrentAnonymousMethod = ae; IDisposable aec_dispose = null; ResolveContext.Options flags = 0; if (ec.HasSet (ResolveContext.Options.InferReturnType)) { flags |= ResolveContext.Options.InferReturnType; aec.ReturnTypeInference = new TypeInferenceContext (); } if (ec.IsInProbingMode) flags |= ResolveContext.Options.ProbingMode; if (ec.HasSet (ResolveContext.Options.FieldInitializerScope)) flags |= ResolveContext.Options.FieldInitializerScope; if (ec.IsUnsafe) flags |= ResolveContext.Options.UnsafeScope; if (ec.HasSet (ResolveContext.Options.CheckedScope)) flags |= ResolveContext.Options.CheckedScope; if (ec.HasSet (ResolveContext.Options.ExpressionTreeConversion)) flags |= ResolveContext.Options.ExpressionTreeConversion; // HACK: Flag with 0 cannot be set if (flags != 0) aec_dispose = aec.Set (flags); bool res = Block.Resolve (ec.CurrentBranching, aec, Block.Parameters, null); if (aec.HasReturnLabel) return_label = aec.ReturnLabel; if (ec.HasSet (ResolveContext.Options.InferReturnType)) { aec.ReturnTypeInference.FixAllTypes (ec); ReturnType = aec.ReturnTypeInference.InferredTypeArguments [0]; } if (aec_dispose != null) { aec_dispose.Dispose (); } return res ? this : null; }
protected override ParametersCompiled ResolveParameters (ResolveContext ec, TypeInferenceContext tic, Type delegateType) { if (!TypeManager.IsDelegateType (delegateType)) return null; AParametersCollection d_params = TypeManager.GetDelegateParameters (ec, 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; Type [] ptypes = new Type [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.ISBYREF) != 0) return null; Type d_param = d_params.Types [i]; #if MS_COMPATIBLE // Blablabla, because reflection does not work with dynamic types if (d_param.IsGenericParameter) d_param = delegateType.GetGenericArguments () [d_param.GenericParameterPosition]; #endif // // When type inference context exists try to apply inferred type arguments // if (tic != null) { d_param = tic.InflateGenericArgument (d_param); } ptypes [i] = d_param; ((ImplicitLambdaParameter) Parameters.FixedParameters [i]).Type = d_param; } Parameters.Types = ptypes; return Parameters; }
public override bool GetAttributableValue (ResolveContext ec, Type value_type, out object value) { if (value_type == TypeManager.object_type) { value = GetTypedValue (); return true; } Constant c = ImplicitConversionRequired (ec, value_type, loc); if (c == null) { value = null; return false; } value = c.GetTypedValue (); return true; }
public override DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args) { var ctx = DynamicContext.Create(); var context_type = ctx.ImportType(callingContext); var queried_type = ctx.ImportType(target.LimitType); var rc = new Compiler.ResolveContext(new RuntimeBinderContext(ctx, context_type), 0); var expr = Compiler.Expression.MemberLookup(rc, context_type, queried_type, name, 0, Compiler.Expression.MemberLookupRestrictions.ExactArity, Compiler.Location.Null); var binder = new CSharpBinder( this, new Compiler.BoolConstant(expr is Compiler.EventExpr, Compiler.Location.Null), null); binder.AddRestrictions(target); return(binder.Bind(ctx, callingContext)); }
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", t.GetSignatureForError ()); return; } base.Error_ValueCannotBeConverted (ec, t, expl); }
public static TypeSpec CreateDelegateType (ResolveContext rc, AParametersCollection parameters, TypeSpec returnType, Location loc) { Namespace type_ns; string paramsSuffix = ""; TypeSpec[] paramTypes = parameters.Types; type_ns = rc.Module.GlobalRootNamespace.GetNamespace ("System", true); // Do we have a PARAMS argument as the final argument? (Only supported in PlayScript) if (rc.FileType == SourceFileType.PlayScript && parameters.FixedParameters.Length > 0 && (parameters.FixedParameters [parameters.FixedParameters.Length - 1].ModFlags & Parameter.Modifier.PARAMS) != 0) { paramsSuffix = "P"; TypeSpec[] newTypes = new TypeSpec[paramTypes.Length - 1]; Array.Copy (paramTypes, 0, newTypes, 0, newTypes.Length); paramTypes = newTypes; type_ns = rc.Module.GlobalRootNamespace.GetNamespace ("PlayScript", true); } if (type_ns == null) { return null; } if (returnType == rc.BuiltinTypes.Void) { var actArgs = paramTypes; var actionType = type_ns.LookupType (rc.Module, "Action" + paramsSuffix, actArgs.Length, LookupMode.Normal, loc); if (actionType == null) { return rc.BuiltinTypes.Delegate; } var actionSpec = actionType.ResolveAsType(rc); if (actionSpec == null) { return null; } if (actArgs.Length == 0) return actionSpec; else return actionSpec.MakeGenericType(rc, actArgs); } else { TypeSpec[] funcArgs = new TypeSpec[paramTypes.Length + 1]; paramTypes.CopyTo(funcArgs, 0); funcArgs[paramTypes.Length] = returnType; var funcSpec = type_ns.LookupType (rc.Module, "Func" + paramsSuffix, funcArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc); if (funcSpec == null) { return rc.BuiltinTypes.Delegate; } return funcSpec.MakeGenericType(rc, funcArgs); } }
// // 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; }
static bool ConvertPromotion (ResolveContext rc, ref Constant prim, ref Constant second, TypeSpec type) { Constant c = prim.ConvertImplicitly (rc, type); if (c != null) { prim = c; return true; } if (type == TypeManager.uint32_type) { type = TypeManager.int64_type; prim = prim.ConvertImplicitly (rc, type); second = second.ConvertImplicitly (rc, 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, tic, 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, tic, 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; }
protected override Expression CreateExpressionTree (ResolveContext ec, Type delegate_type) { if (ec.IsInProbingMode) return this; BlockContext bc = new BlockContext (ec.MemberContext, ec.CurrentBlock.Explicit, TypeManager.void_type); 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); }
public DynamicMetaObject Bind(DynamicContext ctx, Type callingType) { Expression res; try { var rc = new Compiler.ResolveContext(new RuntimeBinderContext(ctx, callingType), ResolveOptions); // Static typemanager and internal caches are not thread-safe lock (resolver) { expr = expr.Resolve(rc, Compiler.ResolveFlags.VariableOrValue); } if (expr == null) { throw new RuntimeBinderInternalCompilerException("Expression resolved to null"); } res = expr.MakeExpression(new Compiler.BuilderContext()); } catch (RuntimeBinderException e) { if (errorSuggestion != null) { return(errorSuggestion); } res = CreateBinderException(e.Message); } catch (Exception) { if (errorSuggestion != null) { return(errorSuggestion); } throw; } return(new DynamicMetaObject(res, restrictions)); }
// Resolve any dynamic params to the type of the target parameters list (for PlayScript only). public bool AsTryResolveDynamicArgs(ResolveContext ec, IList <MemberSpec> candidates) { if (candidates.Count == 0) { return(false); } if (candidates.Count == 1) { // if there's a single candidate, then use it return(AsTryResolveDynamicArgs(ec, candidates[0])); } AParametersCollection parameters = null; foreach (MemberSpec memberSpec in candidates) { AParametersCollection possibleParams = null; int fixedArgsLen = 0; if (memberSpec is MethodSpec) { MethodSpec methodSpec = memberSpec as MethodSpec; possibleParams = methodSpec.Parameters; fixedArgsLen = possibleParams.FixedParameters.Length; if (methodSpec.IsExtensionMethod) { fixedArgsLen--; } } else if (memberSpec is IndexerSpec) { IndexerSpec indexerSpec = memberSpec as IndexerSpec; possibleParams = indexerSpec.Parameters; fixedArgsLen = possibleParams.FixedParameters.Length; } if (fixedArgsLen == args.Count) { if (parameters != null) { parameters = null; // Can't be more than one - or we give up and do a dynamic call.. break; } parameters = possibleParams; } } if (parameters != null) { for (var i = 0; i < args.Count; i++) { var arg = args [i]; var paramType = parameters.Types [i]; if (arg.Expr.Type.IsDynamic) { var parCastType = paramType.BuiltinType == BuiltinTypeSpec.Type.Dynamic ? ec.BuiltinTypes.Object : paramType; var new_arg = new Argument(new Cast( new TypeExpression(parCastType, arg.Expr.Location), arg.Expr, arg.Expr.Location), arg.ArgType); new_arg.Resolve(ec); args [i] = new_arg; } } return(true); } return(false); }
public override Expression CreateExpressionTree(ResolveContext ec) { throw new NotSupportedException("ET"); }
public void EmitPrologue(EmitContext ec) { awaiter = ((AsyncTaskStorey)machine_initializer.Storey).AddAwaiter(expr.Type, loc); var fe_awaiter = new FieldExpr(awaiter, loc); fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); Label skip_continuation = ec.DefineLabel(); using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) { // // awaiter = expr.GetAwaiter (); // fe_awaiter.EmitAssign(ec, expr, false, false); Expression completed_expr; if (IsDynamic) { var rc = new ResolveContext(ec.MemberContext); Arguments dargs = new Arguments(1); dargs.Add(new Argument(fe_awaiter)); completed_expr = new DynamicMemberBinder("IsCompleted", dargs, loc).Resolve(rc); dargs = new Arguments(1); dargs.Add(new Argument(completed_expr)); completed_expr = new DynamicConversion(ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve(rc); } else { var pe = PropertyExpr.CreatePredefined(awaiter_definition.IsCompleted, loc); pe.InstanceExpression = fe_awaiter; completed_expr = pe; } completed_expr.EmitBranchable(ec, skip_continuation, true); } base.DoEmit(ec); // // The stack has to be empty before calling await continuation. We handle this // by lifting values which would be left on stack into class fields. The process // is quite complicated and quite hard to test because any expression can possibly // leave a value on the stack. // // Following assert fails when some of expression called before is missing EmitToField // or parent expression fails to find await in children expressions // ec.AssertEmptyStack(); var storey = (AsyncTaskStorey)machine_initializer.Storey; if (IsDynamic) { storey.EmitAwaitOnCompletedDynamic(ec, fe_awaiter); } else { storey.EmitAwaitOnCompleted(ec, fe_awaiter); } // Return ok machine_initializer.EmitLeave(ec, unwind_protect); ec.MarkLabel(resume_point); ec.MarkLabel(skip_continuation); }
public override Expression CreateExpressionTree(ResolveContext ec) { return(base.CreateExpressionTree(ec)); }
public override Expression CreateExpressionTree(ResolveContext ec) { ec.Report.Error(853, loc, "An expression tree cannot contain named argument"); return(base.CreateExpressionTree(ec)); }
bool OverloadResolver.IErrorHandler.TypeInferenceFailed(ResolveContext rc, MemberSpec best) { return(false); }
protected override Compiler.Expression DoResolve(Compiler.ResolveContext rc) { type = expr.Type; eclass = Compiler.ExprClass.Value; return(this); }
public override Expression CreateExpressionTree(ResolveContext ec) { ec.Report.Error(832, loc, "An expression tree cannot contain an assignment operator"); return(null); }
protected override Compiler.Expression DoResolveDynamic(Compiler.ResolveContext ec, Compiler.Expression memberExpr) { return(new RuntimeDynamicInvocation(this, memberExpr).Resolve(ec)); }
protected override Expression ResolveConversions(ResolveContext ec) { source = EmptyCast.Create(source, target.Type); return(this); }
public FieldInitializerContext(IMemberContext mc, ResolveContext constructorContext) : base(mc, Options.FieldInitializerScope | Options.ConstructorScope) { this.ctor_block = constructorContext.CurrentBlock.Explicit; }
public ArrayInitializer CreateDynamicBinderArguments(ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer(args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace(rc, loc); foreach (Argument a in args) { Arguments dargs = new Arguments(2); // CSharpArgumentInfoFlags.None = 0 const string info_flags_enum = "CSharpArgumentInfoFlags"; Expression info_flags = new IntLiteral(rc.BuiltinTypes, 0, loc); if (a.Expr is Constant) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "Constant", loc)); } else if (a.ArgType == Argument.AType.Ref) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsRef", loc)); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.Out) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsOut", loc)); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.DynamicTypeName) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "IsStaticType", loc)); } TypeSpec arg_type; if (rc.FileType == SourceFileType.PlayScript && a.Expr is ArrayInitializer || a.Expr is AsObjectInitializer) { if (a.Expr is ArrayInitializer) { arg_type = rc.Module.PredefinedTypes.AsArray.Resolve(); } else { arg_type = rc.Module.PredefinedTypes.AsExpandoObject.Resolve(); } } else { arg_type = a.Expr.Type; } if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; bool wasConverted = false; // In PlayScript, we try to implicity convert to dynamic, which handles conversions of method groups to delegates, and // anon methods to delegates. if (rc.FileType == SourceFileType.PlayScript && (mg != null || arg_type == InternalType.AnonymousMethod)) { var expr = Convert.ImplicitConversion(rc, a.Expr, rc.BuiltinTypes.Dynamic, loc); if (expr != null) { a.Expr = expr; arg_type = rc.BuiltinTypes.Dynamic; wasConverted = true; } } // Failed.. check the C# error if (!wasConverted) { if (mg != null) { rc.Report.Error(1976, a.Expr.Location, "The method group `{0}' cannot be used as an argument of dynamic operation. Consider using parentheses to invoke the method", mg.Name); } else if (arg_type == InternalType.AnonymousMethod) { rc.Report.Error(1977, a.Expr.Location, "An anonymous method or lambda expression cannot be used as an argument of dynamic operation. Consider using a cast"); } else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) { rc.Report.Error(1978, a.Expr.Location, "An expression of type `{0}' cannot be used as an argument of dynamic operation", arg_type.GetSignatureForError()); } } info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } string named_value; NamedArgument na = a as NamedArgument; if (na != null) { info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "NamedArgument", loc)); named_value = na.Name; } else { named_value = null; } dargs.Add(new Argument(info_flags)); dargs.Add(new Argument(new StringLiteral(rc.BuiltinTypes, named_value, loc))); all.Add(new Invocation(new MemberAccess(new MemberAccess(binder, "CSharpArgumentInfo", loc), "Create", loc), dargs)); } return(all); }
public override Expression DoResolveLValue(ResolveContext ec, Expression right_side) { return(this); }
protected override Expression DoResolve(ResolveContext ec) { right = right.Resolve(ec); if (right == null) { return(null); } MemberAccess ma = target as MemberAccess; using (ec.Set(ResolveContext.Options.CompoundAssignmentScope)) { target = target.Resolve(ec); } if (target == null) { return(null); } if (target is MethodGroupExpr) { ec.Report.Error(1656, loc, "Cannot assign to `{0}' because it is a `{1}'", ((MethodGroupExpr)target).Name, target.ExprClassName); return(null); } var event_expr = target as EventExpr; if (event_expr != null) { source = Convert.ImplicitConversionRequired(ec, right, target.Type, loc); if (source == null) { return(null); } Expression rside; if (op == Binary.Operator.Addition) { rside = EmptyExpression.EventAddition; } else if (op == Binary.Operator.Subtraction) { rside = EmptyExpression.EventSubtraction; } else { rside = null; } target = target.ResolveLValue(ec, rside); if (target == null) { return(null); } eclass = ExprClass.Value; type = event_expr.Operator.ReturnType; return(this); } // // Only now we can decouple the original source/target // into a tree, to guarantee that we do not have side // effects. // if (left == null) { left = new TargetExpression(target); } source = new Binary(op, left, right, true); if (target is DynamicMemberAssignable) { Arguments targs = ((DynamicMemberAssignable)target).Arguments; source = source.Resolve(ec); Arguments args = new Arguments(targs.Count + 1); args.AddRange(targs); args.Add(new Argument(source)); var binder_flags = CSharpBinderFlags.ValueFromCompoundAssignment; // // Compound assignment does target conversion using additional method // call, set checked context as the binary operation can overflow // if (ec.HasSet(ResolveContext.Options.CheckedScope)) { binder_flags |= CSharpBinderFlags.CheckedContext; } if (target is DynamicMemberBinder) { source = new DynamicMemberBinder(ma.Name, binder_flags, args, loc).Resolve(ec); // Handles possible event addition/subtraction if (op == Binary.Operator.Addition || op == Binary.Operator.Subtraction) { args = new Arguments(targs.Count + 1); args.AddRange(targs); args.Add(new Argument(right)); string method_prefix = op == Binary.Operator.Addition ? Event.AEventAccessor.AddPrefix : Event.AEventAccessor.RemovePrefix; var invoke = DynamicInvocation.CreateSpecialNameInvoke( new MemberAccess(right, method_prefix + ma.Name, loc), args, loc).Resolve(ec); args = new Arguments(targs.Count); args.AddRange(targs); source = new DynamicEventCompoundAssign(ma.Name, args, (ExpressionStatement)source, (ExpressionStatement)invoke, loc).Resolve(ec); } } else { source = new DynamicIndexBinder(binder_flags, args, loc).Resolve(ec); } return(source); } return(base.DoResolve(ec)); }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments(member != null ? 5 : 3); bool is_member_access = member is MemberAccess; CSharpBinderFlags call_flags; if (!is_member_access && member is SimpleName) { call_flags = CSharpBinderFlags.InvokeSimpleName; is_member_access = true; } else { call_flags = 0; } binder_args.Add(new Argument(new BinderFlags(call_flags, this))); if (is_member_access) { binder_args.Add(new Argument(new StringLiteral(ec.BuiltinTypes, member.Name, member.Location))); } if (member != null && member.HasTypeArguments) { TypeArguments ta = member.TypeArguments; if (ta.Resolve(ec)) { var targs = new ArrayInitializer(ta.Count, loc); foreach (TypeSpec t in ta.Arguments) { targs.Add(new TypeOf(t, loc)); } binder_args.Add(new Argument(new ImplicitlyTypedArrayCreation(targs, loc))); } } else if (is_member_access) { binder_args.Add(new Argument(new NullLiteral(loc))); } binder_args.Add(new Argument(new TypeOf(ec.CurrentType, loc))); Expression real_args; if (args == null) { // Cannot be null because .NET trips over real_args = new ArrayCreation( new MemberAccess(GetBinderNamespace(ec, loc), "CSharpArgumentInfo", loc), new ArrayInitializer(0, loc), loc); } else { real_args = new ImplicitlyTypedArrayCreation(args.CreateDynamicBinderArguments(ec), loc); } binder_args.Add(new Argument(real_args)); return(new Invocation(GetBinder(is_member_access ? "InvokeMember" : "Invoke", loc), binder_args)); }
protected override Expression ResolveConversions(ResolveContext ec) { // // LAMESPEC: Under dynamic context no target conversion is happening // This allows more natual dynamic behaviour but breaks compatibility // with static binding // if (target is RuntimeValueExpression) { return(this); } TypeSpec target_type = target.Type; // // 1. the return type is implicitly convertible to the type of target // if (Convert.ImplicitConversionExists(ec, source, target_type)) { source = Convert.ImplicitConversion(ec, source, target_type, loc); return(this); } // // Otherwise, if the selected operator is a predefined operator // Binary b = source as Binary; if (b == null) { if (source is ReducedExpression) { b = ((ReducedExpression)source).OriginalExpression as Binary; } else if (source is Nullable.LiftedBinaryOperator) { var po = ((Nullable.LiftedBinaryOperator)source); if (po.UserOperator == null) { b = po.Binary; } } else if (source is TypeCast) { b = ((TypeCast)source).Child as Binary; } } if (b != null) { // // 2a. the operator is a shift operator // // 2b. the return type is explicitly convertible to the type of x, and // y is implicitly convertible to the type of x // if ((b.Oper & Binary.Operator.ShiftMask) != 0 || Convert.ImplicitConversionExists(ec, right, target_type)) { source = Convert.ExplicitConversion(ec, source, target_type, loc); return(this); } } if (source.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { Arguments arg = new Arguments(1); arg.Add(new Argument(source)); return(new SimpleAssign(target, new DynamicConversion(target_type, CSharpBinderFlags.ConvertExplicit, arg, loc), loc).Resolve(ec)); } right.Error_ValueCannotBeConverted(ec, target_type, false); return(null); }
bool OverloadResolver.IErrorHandler.AmbiguousCandidates(ResolveContext ec, MemberSpec best, MemberSpec ambiguous) { return(false); }
bool OverloadResolver.IErrorHandler.NoArgumentMatch(ResolveContext rc, MemberSpec best) { Error_ConversionFailed(rc, best as MethodSpec, null); return(true); }
public override Expression CreateExpressionTree(ResolveContext ec) { return(null); }
bool OverloadResolver.IErrorHandler.ArgumentMismatch(ResolveContext rc, MemberSpec best, Argument arg, int index) { Error_ConversionFailed(rc, best as MethodSpec, null); return(true); }
protected override Expression DoResolve(ResolveContext rc) { throw new CompletionResult("", new string [0]); }
void Error_WrongAwaiterPattern(ResolveContext rc, TypeSpec awaiter) { rc.Report.Error(4011, loc, "The awaiter type `{0}' must have suitable IsCompleted and GetResult members", awaiter.GetSignatureForError()); }
protected override Expression DoResolve(ResolveContext rc) { var sn = expr as SimpleName; const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type; if (sn != null) { var errors_printer = new SessionReportPrinter(); var old = rc.Report.SetPrinter(errors_printer); try { expr = sn.LookupNameExpression(rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity); } finally { rc.Report.SetPrinter(old); } if (errors_printer.ErrorsCount != 0) { return(null); } // // Resolve expression which does have type set as we need expression type // with disable flow analysis as we don't know whether left side expression // is used as variable or type // if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) { expr = expr.Resolve(rc); } else if (expr is TypeParameterExpr) { expr.Error_UnexpectedKind(rc, flags, sn.Location); expr = null; } } else { expr = expr.Resolve(rc, flags); } if (expr == null) { return(null); } TypeSpec expr_type = expr.Type; if (expr_type.IsPointer || expr_type.Kind == MemberKind.Void || expr_type == InternalType.NullLiteral || expr_type == InternalType.AnonymousMethod) { expr.Error_OperatorCannotBeApplied(rc, loc, ".", expr_type); return(null); } if (targs != null) { if (!targs.Resolve(rc, true)) { return(null); } } var results = new List <string> (); var nexpr = expr as NamespaceExpression; if (nexpr != null) { string namespaced_partial; if (partial_name == null) { namespaced_partial = nexpr.Namespace.Name; } else { namespaced_partial = nexpr.Namespace.Name + "." + partial_name; } rc.CurrentMemberDefinition.GetCompletionStartingWith(namespaced_partial, results); if (partial_name != null) { results = results.Select(l => l.Substring(partial_name.Length)).ToList(); } } else { var r = MemberCache.GetCompletitionMembers(rc, expr_type, partial_name).Select(l => l.Name); AppendResults(results, partial_name, r); } throw new CompletionResult(partial_name == null ? "" : partial_name, results.Distinct().ToArray()); }
protected override void Error_TypeDoesNotContainDefinition(ResolveContext rc, TypeSpec type, string name) { Error_OperatorCannotBeApplied(rc, type); }
protected override Expression DoResolve(ResolveContext ec) { type = child.Type; eclass = ExprClass.Value; return(this); }
protected override Expression DoResolve(ResolveContext ec) { return(this); }
protected override Expression DoResolve(ResolveContext ec) { constructor_method = Delegate.GetConstructor(type); var invoke_method = Delegate.GetInvokeMethod(type); Arguments arguments = CreateDelegateMethodArguments(invoke_method.Parameters, invoke_method.Parameters.Types, loc); method_group = method_group.OverloadResolve(ec, ref arguments, this, OverloadResolver.Restrictions.CovariantDelegate); if (method_group == null) { return(null); } var delegate_method = method_group.BestCandidate; if (delegate_method.DeclaringType.IsNullableType) { ec.Report.Error(1728, loc, "Cannot create delegate from method `{0}' because it is a member of System.Nullable<T> type", delegate_method.GetSignatureForError()); return(null); } Invocation.IsSpecialMethodInvocation(ec, delegate_method, loc); ExtensionMethodGroupExpr emg = method_group as ExtensionMethodGroupExpr; if (emg != null) { method_group.InstanceExpression = emg.ExtensionExpression; TypeSpec e_type = emg.ExtensionExpression.Type; if (TypeManager.IsValueType(e_type)) { ec.Report.Error(1113, loc, "Extension method `{0}' of value type `{1}' cannot be used to create delegates", delegate_method.GetSignatureForError(), TypeManager.CSharpName(e_type)); } } TypeSpec rt = delegate_method.ReturnType; if (!Delegate.IsTypeCovariant(ec, rt, invoke_method.ReturnType)) { Expression ret_expr = new TypeExpression(rt, loc); Error_ConversionFailed(ec, delegate_method, ret_expr); } if (delegate_method.IsConditionallyExcluded(ec.Module.Compiler, loc)) { ec.Report.SymbolRelatedToPreviousError(delegate_method); MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator; if (m != null && m.IsPartialDefinition) { ec.Report.Error(762, loc, "Cannot create delegate from partial method declaration `{0}'", delegate_method.GetSignatureForError()); } else { ec.Report.Error(1618, loc, "Cannot create delegate with `{0}' because it has a Conditional attribute", TypeManager.CSharpSignature(delegate_method)); } } var expr = method_group.InstanceExpression; if (expr != null && (expr.Type.IsGenericParameter || !TypeManager.IsReferenceType(expr.Type))) { method_group.InstanceExpression = new BoxedCast(expr, ec.BuiltinTypes.Object); } eclass = ExprClass.Value; return(this); }