public override bool Resolve(BlockContext bc) { if (!CheckContext(bc, loc)) { return(false); } if (bc.HasAny(ResolveContext.Options.TryWithCatchScope)) { bc.Report.Error(1626, loc, "Cannot yield a value in the body of a try block with a catch clause"); } if (bc.HasSet(ResolveContext.Options.CatchScope)) { bc.Report.Error(1631, loc, "Cannot yield a value in the body of a catch clause"); } if (!base.Resolve(bc)) { return(false); } var otype = bc.CurrentIterator.OriginalIteratorType; if (expr.Type != otype) { expr = Convert.ImplicitConversionRequired(bc, expr, otype, loc); if (expr == null) { return(false); } } return(true); }
public string [] GetCompletions(string input, out string prefix) { prefix = ""; if (input == null || input.Length == 0) { return(null); } lock (evaluator_lock){ if (!inited) { Init(); } bool partial_input; CSharpParser parser = ParseString(ParseMode.GetCompletions, input, out partial_input); if (parser == null) { return(null); } Class host = parser.InteractiveResult; var base_class_imported = importer.ImportType(base_class); var baseclass_list = new List <FullNamedExpression> (1) { new TypeExpression(base_class_imported, host.Location) }; host.SetBaseTypes(baseclass_list); #if NET_4_0 var access = AssemblyBuilderAccess.RunAndCollect; #else var access = AssemblyBuilderAccess.Run; #endif var a = new AssemblyDefinitionDynamic(module, "completions"); a.Create(AppDomain.CurrentDomain, access); module.SetDeclaringAssembly(a); // Need to setup MemberCache host.CreateContainer(); // Need to setup base type host.DefineContainer(); var method = host.Members[0] as Method; BlockContext bc = new BlockContext(method, method.Block, ctx.BuiltinTypes.Void); try { method.Block.Resolve(bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return(cr.Result); } } return(null); }
public static VariableInfo Create(BlockContext bc, Parameter parameter) { var info = new VariableInfo(parameter.Name, parameter.Type, bc.AssignmentInfoOffset, bc) { IsParameter = true }; bc.AssignmentInfoOffset += info.Length; return(info); }
public FieldInitializerContext(IMemberContext mc, BlockContext constructorContext) : base(mc, null, constructorContext.ReturnType) { flags |= Options.FieldInitializerScope | Options.ConstructorScope; this.ctor_block = constructorContext.CurrentBlock.Explicit; if (ctor_block.IsCompilerGenerated) { CurrentBlock = ctor_block; } }
public override bool Resolve(BlockContext bc) { expr = expr.Resolve(bc); if (expr == null) { return(false); } machine_initializer = bc.CurrentAnonymousMethod as T; inside_try_block = bc.CurrentTryBlock; return(true); }
protected virtual BlockContext CreateBlockContext(BlockContext bc) { var ctx = new BlockContext(bc, block, bc.ReturnType); ctx.CurrentAnonymousMethod = this; ctx.AssignmentInfoOffset = bc.AssignmentInfoOffset; ctx.EnclosingLoop = bc.EnclosingLoop; ctx.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch; ctx.Switch = bc.Switch; return(ctx); }
public override bool Resolve(BlockContext ec) { TypeExpression storey_type_expr = new TypeExpression(host.Definition, loc); List <Expression> init = null; if (host.hoisted_this != null) { init = new List <Expression> (host.hoisted_params == null ? 1 : host.HoistedParameters.Count + 1); HoistedThis ht = host.hoisted_this; FieldExpr from = new FieldExpr(ht.Field, loc); from.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); init.Add(new ElementInitializer(ht.Field.Name, from, loc)); } if (host.hoisted_params != null) { if (init == null) { init = new List <Expression> (host.HoistedParameters.Count); } for (int i = 0; i < host.hoisted_params.Count; ++i) { HoistedParameter hp = host.hoisted_params [i]; HoistedParameter hp_cp = host.hoisted_params_copy [i] ?? hp; FieldExpr from = new FieldExpr(hp_cp.Field, loc); from.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc); init.Add(new ElementInitializer(hp.Field.Name, from, loc)); } } if (init != null) { new_storey = new NewInitialize(storey_type_expr, null, new CollectionOrObjectInitializers(init, loc), loc); } else { new_storey = new New(storey_type_expr, null, loc); } new_storey = new_storey.Resolve(ec); if (new_storey != null) { new_storey = Convert.ImplicitConversionRequired(ec, new_storey, host_method.MemberType, loc); } return(true); }
protected override BlockContext CreateBlockContext(BlockContext bc) { var ctx = base.CreateBlockContext(bc); var am = bc.CurrentAnonymousMethod as AnonymousMethodBody; if (am != null) { return_inference = am.ReturnTypeInference; } ctx.Set(ResolveContext.Options.TryScope); return(ctx); }
public static bool CheckContext(BlockContext bc, Location loc) { if (!bc.CurrentAnonymousMethod.IsIterator) { bc.Report.Error(1621, loc, "The yield statement cannot be used inside anonymous method blocks"); return(false); } if (bc.HasSet(ResolveContext.Options.FinallyScope)) { bc.Report.Error(1625, loc, "Cannot yield in the body of a finally clause"); return(false); } return(true); }
public override Expression CreateExpressionTree(ResolveContext ec) { BlockContext bc = new BlockContext(ec.MemberContext, Block, ReturnType); 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(type, loc)), arguments)); }
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); }
protected override bool DoResolve(BlockContext ec) { // // When delegate returns void, only expression statements can be used // if (ec.ReturnType.Kind == MemberKind.Void) { Expr = Expr.Resolve(ec); if (Expr == null) { return(false); } statement = Expr as ExpressionStatement; if (statement == null) { Expr.Error_InvalidExpressionStatement(ec); } return(true); } return(base.DoResolve(ec)); }
// // Emits the code // public void Emit (TypeDefinition parent) { DefineOverride (parent); method.ParameterInfo.ApplyAttributes (method, MethodBuilder); ToplevelBlock block = method.Block; if (block != null) { BlockContext bc = new BlockContext (method, block, method.ReturnType); if (block.Resolve (bc, method)) { debug_builder = member.Parent.CreateMethodSymbolEntry (); EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator (), debug_builder); block.Emit (ec); } } }
// // Emits the code // public override void Emit () { if (Parent.PartialContainer.IsComImport) { if (!IsDefault ()) { Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor", Parent.GetSignatureForError ()); } // Set as internal implementation and reset block data // to ensure no IL is generated ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall); block = null; } if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) Module.PredefinedAttributes.DebuggerHidden.EmitAttribute (ConstructorBuilder); if (OptAttributes != null) OptAttributes.Emit (); base.Emit (); parameters.ApplyAttributes (this, ConstructorBuilder); BlockContext bc = new BlockContext (this, block, Compiler.BuiltinTypes.Void); bc.Set (ResolveContext.Options.ConstructorScope); if (block != null) { if (!IsStatic && Initializer == null && Parent.PartialContainer.Kind == MemberKind.Struct) { // // If this is a non-static `struct' constructor and doesn't have any // initializer, it must initialize all of the struct's fields. // block.AddThisVariable (bc); } // // If we use a "this (...)" constructor initializer, then // do not emit field initializers, they are initialized in the other constructor // if (!(Initializer is ConstructorThisInitializer)) Parent.PartialContainer.ResolveFieldInitializers (bc); if (!IsStatic) { if (Initializer == null && Parent.PartialContainer.Kind == MemberKind.Class) { Initializer = new GeneratedBaseInitializer (Location, null); } if (Initializer != null) { // // mdb format does not support reqions. Try to workaround this by emitting the // sequence point at initializer. Any breakpoint at constructor header should // be adjusted to this sequence point as it's the next one which follows. // block.AddScopeStatement (new StatementExpression (Initializer)); } } if (block.Resolve (bc, this)) { debug_builder = Parent.CreateMethodSymbolEntry (); EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType, debug_builder); ec.With (EmitContext.Options.ConstructorScope, true); block.Emit (ec); } } if (declarative_security != null) { foreach (var de in declarative_security) { #if STATIC ConstructorBuilder.__AddDeclarativeSecurity (de); #else ConstructorBuilder.AddDeclarativeSecurity (de.Key, de.Value); #endif } } block = null; }
public static VariableInfo Create (BlockContext bc, Parameter parameter) { var info = new VariableInfo (parameter.Name, parameter.Type, bc.AssignmentInfoOffset, bc) { IsParameter = true }; bc.AssignmentInfoOffset += info.Length; return info; }
protected override bool DoResolve (BlockContext ec) { // // When delegate returns void, only expression statements can be used // if (ec.ReturnType.Kind == MemberKind.Void) { Expr = Expr.Resolve (ec); if (Expr == null) return false; statement = Expr as ExpressionStatement; if (statement == null) Expr.Error_InvalidExpressionStatement (ec); return true; } return base.DoResolve (ec); }
public FieldInitializerContext (IMemberContext mc, BlockContext constructorContext) : base (mc, null, constructorContext.ReturnType) { flags |= Options.FieldInitializerScope | Options.ConstructorScope; this.ctor_block = constructorContext.CurrentBlock.Explicit; if (ctor_block.IsCompilerGenerated) CurrentBlock = ctor_block; }
public override bool Resolve(BlockContext ec) { return(true); }
public ExpressionStatement CreateExpressionTreeVariable (BlockContext ec) { if ((modFlags & Modifier.RefOutMask) != 0) ec.Report.Error (1951, Location, "An expression tree parameter cannot use `ref' or `out' modifier"); expr_tree_variable = TemporaryVariableReference.Create (ResolveParameterExpressionType (ec, Location).Type, ec.CurrentBlock.ParametersBlock, Location); expr_tree_variable = (TemporaryVariableReference) expr_tree_variable.Resolve (ec); Arguments arguments = new Arguments (2); arguments.Add (new Argument (new TypeOf (parameter_type, Location))); arguments.Add (new Argument (new StringConstant (ec.BuiltinTypes, Name, Location))); return new SimpleAssign (ExpressionTreeVariableReference (), Expression.CreateExpressionFactoryCall (ec, "Parameter", null, arguments, Location)); }
protected override bool DoResolve(BlockContext bc) { iterator = bc.CurrentIterator; return(Yield.CheckContext(bc, loc)); }
public AnonymousExpression Compatible (ResolveContext ec, AnonymousExpression ae) { if (block.Resolved) return this; // TODO: Implement clone BlockContext aec = new BlockContext (ec, block, ReturnType); aec.CurrentAnonymousMethod = ae; var am = this as AnonymousMethodBody; if (ec.HasSet (ResolveContext.Options.InferReturnType) && am != null) { am.ReturnTypeInference = new TypeInferenceContext (); } var bc = ec as BlockContext; if (bc != null) { aec.AssignmentInfoOffset = bc.AssignmentInfoOffset; aec.EnclosingLoop = bc.EnclosingLoop; aec.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch; aec.Switch = bc.Switch; } var errors = ec.Report.Errors; bool res = Block.Resolve (aec); if (res && errors == ec.Report.Errors) { MarkReachable (new Reachability ()); if (!CheckReachableExit (ec.Report)) { return null; } if (bc != null) bc.AssignmentInfoOffset = aec.AssignmentInfoOffset; } if (am != null && am.ReturnTypeInference != null) { am.ReturnTypeInference.FixAllTypes (ec); ReturnType = am.ReturnTypeInference.InferredTypeArguments [0]; am.ReturnTypeInference = null; // // If e is synchronous the inferred return type is T // If e is asynchronous and the body of F is either an expression classified as nothing // or a statement block where no return statements have expressions, the inferred return type is Task // If e is async and has an inferred result type T, the inferred return type is Task<T> // if (block.IsAsync && ReturnType != null) { ReturnType = ReturnType.Kind == MemberKind.Void ? ec.Module.PredefinedTypes.Task.TypeSpec : ec.Module.PredefinedTypes.TaskGeneric.TypeSpec.MakeGenericType (ec, new [] { ReturnType }); } } if (res && errors != ec.Report.Errors) return null; return res ? this : null; }
protected void EmitCall (EmitContext ec, Expression binder, Arguments arguments, bool isStatement) { // // This method generates all internal infrastructure for a dynamic call. The // reason why it's quite complicated is the mixture of dynamic and anonymous // methods. Dynamic itself requires a temporary class (ContainerX) and anonymous // methods can generate temporary storey as well (AnonStorey). Handling MVAR // type parameters rewrite is non-trivial in such case as there are various // combinations possible therefore the mutator is not straightforward. Secondly // we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit // correct Site field type and its access from EmitContext. // int dyn_args_count = arguments == null ? 0 : arguments.Count; int default_args = isStatement ? 1 : 2; var module = ec.Module; bool has_ref_out_argument = false; var targs = new TypeExpression[dyn_args_count + default_args]; targs[0] = new TypeExpression (module.PredefinedTypes.CallSite.TypeSpec, loc); TypeExpression[] targs_for_instance = null; TypeParameterMutator mutator; var site_container = ec.CreateDynamicSite (); if (context_mvars != null) { TypeParameters tparam; TypeContainer sc = site_container; do { tparam = sc.CurrentTypeParameters; sc = sc.Parent; } while (tparam == null); mutator = new TypeParameterMutator (context_mvars, tparam); if (!ec.IsAnonymousStoreyMutateRequired) { targs_for_instance = new TypeExpression[targs.Length]; targs_for_instance[0] = targs[0]; } } else { mutator = null; } for (int i = 0; i < dyn_args_count; ++i) { Argument a = arguments[i]; if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref) has_ref_out_argument = true; var t = a.Type; // Convert any internal type like dynamic or null to object if (t.Kind == MemberKind.InternalCompilerType) t = ec.BuiltinTypes.Object; if (targs_for_instance != null) targs_for_instance[i + 1] = new TypeExpression (t, loc); if (mutator != null) t = t.Mutate (mutator); targs[i + 1] = new TypeExpression (t, loc); } TypeExpr del_type = null; TypeExpr del_type_instance_access = null; if (!has_ref_out_argument) { string d_name = isStatement ? "Action" : "Func"; TypeSpec te = null; Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true); if (type_ns != null) { te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc); } if (te != null) { if (!isStatement) { var t = type; if (t.Kind == MemberKind.InternalCompilerType) t = ec.BuiltinTypes.Object; if (targs_for_instance != null) targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression (t, loc); if (mutator != null) t = t.Mutate (mutator); targs[targs.Length - 1] = new TypeExpression (t, loc); } del_type = new GenericTypeExpr (te, new TypeArguments (targs), loc); if (targs_for_instance != null) del_type_instance_access = new GenericTypeExpr (te, new TypeArguments (targs_for_instance), loc); else del_type_instance_access = del_type; } } // // Create custom delegate when no appropriate predefined delegate has been found // Delegate d; if (del_type == null) { TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : type; Parameter[] p = new Parameter[dyn_args_count + 1]; p[0] = new Parameter (targs[0], "p0", Parameter.Modifier.NONE, null, loc); var site = ec.CreateDynamicSite (); int index = site.Containers == null ? 0 : site.Containers.Count; if (mutator != null) rt = mutator.Mutate (rt); for (int i = 1; i < dyn_args_count + 1; ++i) { p[i] = new Parameter (targs[i], "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc); } d = new Delegate (site, new TypeExpression (rt, loc), Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED, new MemberName ("Container" + index.ToString ("X")), new ParametersCompiled (p), null); d.CreateContainer (); d.DefineContainer (); d.Define (); d.PrepareEmit (); site.AddTypeContainer (d); // // Add new container to inflated site container when the // member cache already exists // if (site.CurrentType is InflatedTypeSpec && index > 0) site.CurrentType.MemberCache.AddMember (d.CurrentType); del_type = new TypeExpression (d.CurrentType, loc); if (targs_for_instance != null) { del_type_instance_access = null; } else { del_type_instance_access = del_type; } } else { d = null; } var site_type_decl = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc); var field = site_container.CreateCallSiteField (site_type_decl, loc); if (field == null) return; if (del_type_instance_access == null) { var dt = d.CurrentType.DeclaringType.MakeGenericType (module, context_mvars.Types); del_type_instance_access = new TypeExpression (MemberCache.GetMember (dt, d.CurrentType), loc); } var instanceAccessExprType = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type_instance_access), loc); if (instanceAccessExprType.ResolveAsType (ec.MemberContext) == null) return; bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired; TypeSpec gt; if (inflate_using_mvar || context_mvars == null) { gt = site_container.CurrentType; } else { gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types); } // When site container already exists the inflated version has to be // updated manually to contain newly created field if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) { var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes; var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments); gt.MemberCache.AddMember (field.InflateMember (inflator)); } FieldExpr site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc); BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void); Arguments args = new Arguments (1); args.Add (new Argument (binder)); StatementExpression s = new StatementExpression (new SimpleAssign (site_field_expr, new Invocation (new MemberAccess (instanceAccessExprType, "Create"), args))); using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) { if (s.Resolve (bc)) { Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc); init.Emit (ec); } args = new Arguments (1 + dyn_args_count); args.Add (new Argument (site_field_expr)); if (arguments != null) { int arg_pos = 1; foreach (Argument a in arguments) { if (a is NamedArgument) { // Name is not valid in this context args.Add (new Argument (a.Expr, a.ArgType)); } else { args.Add (a); } if (inflate_using_mvar && a.Type != targs[arg_pos].Type) a.Expr.Type = targs[arg_pos].Type; ++arg_pos; } } Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, false, loc).Resolve (bc); if (target != null) target.Emit (ec); } }
public string [] GetCompletions (string input, out string prefix) { prefix = ""; if (input == null || input.Length == 0) return null; lock (evaluator_lock){ if (!inited) Init (); bool partial_input; CSharpParser parser = ParseString (ParseMode.GetCompletions, input, out partial_input); if (parser == null){ return null; } Class host = parser.InteractiveResult; var base_class_imported = importer.ImportType (base_class); var baseclass_list = new List<FullNamedExpression> (1) { new TypeExpression (base_class_imported, host.Location) }; host.SetBaseTypes (baseclass_list); #if NET_4_0 var access = AssemblyBuilderAccess.RunAndCollect; #else var access = AssemblyBuilderAccess.Run; #endif var a = new AssemblyDefinitionDynamic (module, "completions"); a.Create (AppDomain.CurrentDomain, access); module.SetDeclaringAssembly (a); // Need to setup MemberCache host.CreateContainer (); // Need to setup base type host.DefineContainer (); var method = host.Members[0] as Method; BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void); try { method.Block.Resolve (bc, method); } catch (CompletionResult cr) { prefix = cr.BaseText; return cr.Result; } } return null; }
public static VariableInfo Create (BlockContext bc, LocalVariable variable) { var info = new VariableInfo (variable.Name, variable.Type, bc.AssignmentInfoOffset, bc); bc.AssignmentInfoOffset += info.Length; return info; }
protected void EmitCall(EmitContext ec, Expression binder, Arguments arguments, bool isStatement) { // // This method generates all internal infrastructure for a dynamic call. The // reason why it's quite complicated is the mixture of dynamic and anonymous // methods. Dynamic itself requires a temporary class (ContainerX) and anonymous // methods can generate temporary storey as well (AnonStorey). Handling MVAR // type parameters rewrite is non-trivial in such case as there are various // combinations possible therefore the mutator is not straightforward. Secondly // we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit // correct Site field type and its access from EmitContext. // int dyn_args_count = arguments == null ? 0 : arguments.Count; int default_args = isStatement ? 1 : 2; var module = ec.Module; bool has_ref_out_argument = false; var targs = new TypeExpression[dyn_args_count + default_args]; targs[0] = new TypeExpression(module.PredefinedTypes.CallSite.TypeSpec, loc); TypeExpression[] targs_for_instance = null; TypeParameterMutator mutator; var site_container = ec.CreateDynamicSite(); if (context_mvars != null) { TypeParameters tparam; TypeContainer sc = site_container; do { tparam = sc.CurrentTypeParameters; sc = sc.Parent; } while (tparam == null); mutator = new TypeParameterMutator(context_mvars, tparam); if (!ec.IsAnonymousStoreyMutateRequired) { targs_for_instance = new TypeExpression[targs.Length]; targs_for_instance[0] = targs[0]; } } else { mutator = null; } for (int i = 0; i < dyn_args_count; ++i) { Argument a = arguments[i]; if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref) { has_ref_out_argument = true; } var t = a.Type; // Convert any internal type like dynamic or null to object if (t.Kind == MemberKind.InternalCompilerType) { t = ec.BuiltinTypes.Object; } if (targs_for_instance != null) { targs_for_instance[i + 1] = new TypeExpression(t, loc); } if (mutator != null) { t = t.Mutate(mutator); } targs[i + 1] = new TypeExpression(t, loc); } TypeExpr del_type = null; TypeExpr del_type_instance_access = null; if (!has_ref_out_argument) { string d_name = isStatement ? "Action" : "Func"; TypeSpec te = null; Namespace type_ns = module.GlobalRootNamespace.GetNamespace("System", true); if (type_ns != null) { te = type_ns.LookupType(module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc); } if (te != null) { if (!isStatement) { var t = type; if (t.Kind == MemberKind.InternalCompilerType) { t = ec.BuiltinTypes.Object; } if (targs_for_instance != null) { targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression(t, loc); } if (mutator != null) { t = t.Mutate(mutator); } targs[targs.Length - 1] = new TypeExpression(t, loc); } del_type = new GenericTypeExpr(te, new TypeArguments(targs), loc); if (targs_for_instance != null) { del_type_instance_access = new GenericTypeExpr(te, new TypeArguments(targs_for_instance), loc); } else { del_type_instance_access = del_type; } } } // // Create custom delegate when no appropriate predefined delegate has been found // Delegate d; if (del_type == null) { TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : type; Parameter[] p = new Parameter[dyn_args_count + 1]; p[0] = new Parameter(targs[0], "p0", Parameter.Modifier.NONE, null, loc); var site = ec.CreateDynamicSite(); int index = site.Containers == null ? 0 : site.Containers.Count; if (mutator != null) { rt = mutator.Mutate(rt); } for (int i = 1; i < dyn_args_count + 1; ++i) { p[i] = new Parameter(targs[i], "p" + i.ToString("X"), arguments[i - 1].Modifier, null, loc); } d = new Delegate(site, new TypeExpression(rt, loc), Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED, new MemberName("Container" + index.ToString("X")), new ParametersCompiled(p), null); d.CreateContainer(); d.DefineContainer(); d.Define(); d.PrepareEmit(); site.AddTypeContainer(d); // // Add new container to inflated site container when the // member cache already exists // if (site.CurrentType is InflatedTypeSpec && index > 0) { site.CurrentType.MemberCache.AddMember(d.CurrentType); } del_type = new TypeExpression(d.CurrentType, loc); if (targs_for_instance != null) { del_type_instance_access = null; } else { del_type_instance_access = del_type; } } else { d = null; } var site_type_decl = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments(del_type), loc); var field = site_container.CreateCallSiteField(site_type_decl, loc); if (field == null) { return; } if (del_type_instance_access == null) { var dt = d.CurrentType.DeclaringType.MakeGenericType(module, context_mvars.Types); del_type_instance_access = new TypeExpression(MemberCache.GetMember(dt, d.CurrentType), loc); } var instanceAccessExprType = new GenericTypeExpr(module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments(del_type_instance_access), loc); if (instanceAccessExprType.ResolveAsType(ec.MemberContext) == null) { return; } bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired; TypeSpec gt; if (inflate_using_mvar || context_mvars == null) { gt = site_container.CurrentType; } else { gt = site_container.CurrentType.MakeGenericType(module, context_mvars.Types); } // When site container already exists the inflated version has to be // updated manually to contain newly created field if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) { var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes; var inflator = new TypeParameterInflator(module, gt, tparams, gt.TypeArguments); gt.MemberCache.AddMember(field.InflateMember(inflator)); } FieldExpr site_field_expr = new FieldExpr(MemberCache.GetMember(gt, field), loc); BlockContext bc = new BlockContext(ec.MemberContext, null, ec.BuiltinTypes.Void); Arguments args = new Arguments(1); args.Add(new Argument(binder)); StatementExpression s = new StatementExpression(new SimpleAssign(site_field_expr, new Invocation(new MemberAccess(instanceAccessExprType, "Create"), args))); using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) { if (s.Resolve(bc)) { Statement init = new If(new Binary(Binary.Operator.Equality, site_field_expr, new NullLiteral(loc)), s, loc); init.Emit(ec); } args = new Arguments(1 + dyn_args_count); args.Add(new Argument(site_field_expr)); if (arguments != null) { int arg_pos = 1; foreach (Argument a in arguments) { if (a is NamedArgument) { // Name is not valid in this context args.Add(new Argument(a.Expr, a.ArgType)); } else { args.Add(a); } if (inflate_using_mvar && a.Type != targs[arg_pos].Type) { a.Expr.Type = targs[arg_pos].Type; } ++arg_pos; } } Expression target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, false, loc).Resolve(bc); if (target != null) { target.Emit(ec); } } }
public override bool Resolve(BlockContext bc) { if (bc.CurrentBlock is Linq.QueryBlock) { bc.Report.Error(1995, loc, "The `await' operator may only be used in a query expression within the first collection expression of the initial `from' clause or within the collection expression of a `join' clause"); return(false); } if (!base.Resolve(bc)) { return(false); } type = expr.Type; Arguments args = new Arguments(0); // // The await expression is of dynamic type // if (type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { result_type = type; expr = new Invocation(new MemberAccess(expr, "GetAwaiter"), args).Resolve(bc); return(true); } // // Check whether the expression is awaitable // Expression ama = new AwaitableMemberAccess(expr).Resolve(bc); if (ama == null) { return(false); } var errors_printer = new SessionReportPrinter(); var old = bc.Report.SetPrinter(errors_printer); ama = new Invocation(ama, args).Resolve(bc); bc.Report.SetPrinter(old); if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression(ama.Type)) { bc.Report.Error(1986, expr.Location, "The `await' operand type `{0}' must have suitable GetAwaiter method", expr.Type.GetSignatureForError()); return(false); } var awaiter_type = ama.Type; awaiter_definition = bc.Module.GetAwaiter(awaiter_type); if (!awaiter_definition.IsValidPattern) { Error_WrongAwaiterPattern(bc, awaiter_type); return(false); } if (!awaiter_definition.INotifyCompletion) { bc.Report.Error(4027, loc, "The awaiter type `{0}' must implement interface `{1}'", awaiter_type.GetSignatureForError(), bc.Module.PredefinedTypes.INotifyCompletion.GetSignatureForError()); return(false); } expr = ama; result_type = awaiter_definition.GetResult.ReturnType; return(true); }
public override Expression CreateExpressionTree (ResolveContext ec) { BlockContext bc = new BlockContext (ec.MemberContext, Block, ReturnType); 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 (type, loc)), arguments); }
public void ResolveFieldInitializers (BlockContext ec) { Debug.Assert (!IsPartialPart); if (ec.IsStatic) { if (initialized_static_fields == null) return; bool has_complex_initializer = !ec.Module.Compiler.Settings.Optimize; int i; ExpressionStatement [] init = new ExpressionStatement [initialized_static_fields.Count]; for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = initialized_static_fields [i]; ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) { s = EmptyExpressionStatement.Instance; } else if (!fi.IsSideEffectFree) { has_complex_initializer = true; } init [i] = s; } for (i = 0; i < initialized_static_fields.Count; ++i) { FieldInitializer fi = initialized_static_fields [i]; // // Need special check to not optimize code like this // static int a = b = 5; // static int b = 0; // if (!has_complex_initializer && fi.IsDefaultInitializer) continue; ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i])); } return; } if (initialized_fields == null) return; for (int i = 0; i < initialized_fields.Count; ++i) { FieldInitializer fi = initialized_fields [i]; // // Clone before resolving otherwise when field initializer is needed // in more than 1 constructor any resolve after the initial one would // only took the resolved expression which is problem for expressions // that generate extra expressions or code during Resolve phase // var cloned = fi.Clone (new CloneContext ()); ExpressionStatement s = fi.ResolveStatement (ec); if (s == null) { initialized_fields [i] = new FieldInitializer (fi.Field, ErrorExpression.Instance, Location.Null); continue; } // // Field is re-initialized to its default value => removed // if (fi.IsDefaultInitializer && Kind != MemberKind.Struct && ec.Module.Compiler.Settings.Optimize) continue; ec.AssignmentInfoOffset += fi.AssignmentOffset; ec.CurrentBlock.AddScopeStatement (new StatementExpression (s)); initialized_fields [i] = (FieldInitializer) cloned; } }
public Expression CreateExpressionTree (BlockContext ec, Location loc) { var initializers = new ArrayInitializer (Count, loc); foreach (Parameter p in FixedParameters) { // // Each parameter expression is stored to local variable // to save some memory when referenced later. // StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec), Location.Null); if (se.Resolve (ec)) { ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ())); ec.CurrentBlock.AddScopeStatement (se); } initializers.Add (p.ExpressionTreeVariableReference ()); } return new ArrayCreation ( Parameter.ResolveParameterExpressionType (ec, loc), initializers, loc); }