Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
            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;
                }
            }
Beispiel #5
0
        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);
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
                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);
                }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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));
        }
Beispiel #11
0
		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);
		}
Beispiel #12
0
        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));
        }
Beispiel #13
0
		//
		// 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);
				}
			}
		}
Beispiel #14
0
		//
		// 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;
		}
Beispiel #15
0
		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;
		}
Beispiel #16
0
		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);
		}
Beispiel #17
0
			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;
			}
Beispiel #18
0
 public override bool Resolve(BlockContext ec)
 {
     return(true);
 }
Beispiel #19
0
		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));
		}
Beispiel #20
0
 protected override bool DoResolve(BlockContext bc)
 {
     iterator = bc.CurrentIterator;
     return(Yield.CheckContext(bc, loc));
 }
Beispiel #21
0
		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;
		}
Beispiel #22
0
		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);
			}
		}
Beispiel #23
0
		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;
		}
Beispiel #24
0
		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;
		}
Beispiel #25
0
        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);
                }
            }
        }
Beispiel #26
0
        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);
        }
Beispiel #27
0
		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);
		}
Beispiel #28
0
		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;
			}
		}
Beispiel #29
0
		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);
		}