CreateFullyResolved() public static method

public static CreateFullyResolved ( System.TypeSpec types ) : AParametersCollection
types System.TypeSpec
return AParametersCollection
		public PredefinedMembers (ModuleContainer module)
		{
			var types = module.PredefinedTypes;
			var atypes = module.PredefinedAttributes;
			var btypes = module.Compiler.BuiltinTypes;

			var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);

			ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
				MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));

			AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));

			AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));

			AsyncTaskMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				"SetStateMachine", MemberKind.Method, () => new[] {
						types.IAsyncStateMachine.TypeSpec
				}, btypes.Void);

			AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Method ("SetException", 0,
				ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));

			AsyncTaskMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Method ("AwaitOnCompleted", 2,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.REF)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
							}, false),
					btypes.Void));

			AsyncTaskMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.REF)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
							}, false),
					btypes.Void));

			AsyncTaskMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Method ("Start", 1,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
							}, false),
					btypes.Void));

			AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
				MemberFilter.Property ("Task", null));

			AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));

			AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				"SetResult", MemberKind.Method, () => new TypeSpec[] {
						types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
				}, btypes.Void);

			AsyncTaskMethodBuilderGenericSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				"SetStateMachine", MemberKind.Method, () => new[] {
						types.IAsyncStateMachine.TypeSpec
				}, btypes.Void);

			AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				MemberFilter.Method ("SetException", 0,
				ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));

			AsyncTaskMethodBuilderGenericOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				MemberFilter.Method ("AwaitOnCompleted", 2,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.REF)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
							}, false),
					btypes.Void));

			AsyncTaskMethodBuilderGenericOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.REF)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
							}, false),
					btypes.Void));

			AsyncTaskMethodBuilderGenericStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
				MemberFilter.Method ("Start", 1,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
							}, false),
					btypes.Void));

			AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
				MemberFilter.Property ("Task", null));

			AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));

			AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				MemberFilter.Method ("SetException", 0, null, btypes.Void));

			AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));

			AsyncVoidMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				"SetStateMachine", MemberKind.Method, () => new[] {
						types.IAsyncStateMachine.TypeSpec
				}, btypes.Void);

			AsyncVoidMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				MemberFilter.Method ("AwaitOnCompleted", 2,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.REF)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
							}, false),
					btypes.Void));

			AsyncVoidMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.REF)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
							}, false),
					btypes.Void));

			AsyncVoidMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
				MemberFilter.Method ("Start", 1,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
							}, false),
					btypes.Void));

			AsyncStateMachineAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.AsyncStateMachine,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
					btypes.Type)));

			DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
				MemberFilter.Constructor (null));

			DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
					btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));

			DecimalCtorInt = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Int)));

			DecimalCtorLong = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Long)));

			DecimalConstantAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DecimalConstant,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
					btypes.Byte, btypes.Byte, btypes.UInt, btypes.UInt, btypes.UInt)));

			DefaultMemberAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DefaultMember,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.String)));

			DelegateCombine = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Combine", btypes.Delegate, btypes.Delegate);
			DelegateRemove = new PredefinedMember<MethodSpec> (module, btypes.Delegate, "Remove", btypes.Delegate, btypes.Delegate);

			DelegateEqual = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
				new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));

			DelegateInequal = new PredefinedMember<MethodSpec> (module, btypes.Delegate,
				new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));

			DynamicAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.Dynamic,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
					ArrayContainer.MakeType (module, btypes.Bool))));

			FieldInfoGetFieldFromHandle = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
				"GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle);

			FieldInfoGetFieldFromHandle2 = new PredefinedMember<MethodSpec> (module, types.FieldInfo,
				"GetFieldFromHandle", MemberKind.Method, types.RuntimeFieldHandle, new PredefinedType (btypes.RuntimeTypeHandle));

			FixedBufferAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.FixedBuffer,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Type, btypes.Int)));

			IDisposableDispose = new PredefinedMember<MethodSpec> (module, btypes.IDisposable, "Dispose", TypeSpec.EmptyTypes);

			IEnumerableGetEnumerator = new PredefinedMember<MethodSpec> (module, btypes.IEnumerable,
				"GetEnumerator", TypeSpec.EmptyTypes);

			InterlockedCompareExchange = new PredefinedMember<MethodSpec> (module, types.Interlocked,
				MemberFilter.Method ("CompareExchange", 0,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.NONE),
								new ParameterData (null, Parameter.Modifier.NONE)
							},
						new[] {
								btypes.Int, btypes.Int, btypes.Int
							},
						false),
				btypes.Int));

			InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
				MemberFilter.Method ("CompareExchange", 1,
					new ParametersImported (
						new[] {
								new ParameterData (null, Parameter.Modifier.REF),
								new ParameterData (null, Parameter.Modifier.NONE),
								new ParameterData (null, Parameter.Modifier.NONE)
							},
						new[] {
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
								new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
							}, false),
					null));

			MethodInfoGetMethodFromHandle = new PredefinedMember<MethodSpec> (module, types.MethodBase,
				"GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle);

			MethodInfoGetMethodFromHandle2 = new PredefinedMember<MethodSpec> (module, types.MethodBase,
				"GetMethodFromHandle", MemberKind.Method, types.RuntimeMethodHandle, new PredefinedType (btypes.RuntimeTypeHandle));

			MonitorEnter = new PredefinedMember<MethodSpec> (module, types.Monitor, "Enter", btypes.Object);

			MonitorEnter_v4 = new PredefinedMember<MethodSpec> (module, types.Monitor,
				MemberFilter.Method ("Enter", 0,
					new ParametersImported (new[] {
							new ParameterData (null, Parameter.Modifier.NONE),
							new ParameterData (null, Parameter.Modifier.REF)
						},
					new[] {
							btypes.Object, btypes.Bool
						}, false), null));

			MonitorExit = new PredefinedMember<MethodSpec> (module, types.Monitor, "Exit", btypes.Object);

			RuntimeCompatibilityWrapNonExceptionThrows = new PredefinedMember<PropertySpec> (module, atypes.RuntimeCompatibility,
				MemberFilter.Property ("WrapNonExceptionThrows", btypes.Bool));

			RuntimeHelpersInitializeArray = new PredefinedMember<MethodSpec> (module, types.RuntimeHelpers,
				"InitializeArray", btypes.Array, btypes.RuntimeFieldHandle);

			RuntimeHelpersOffsetToStringData = new PredefinedMember<PropertySpec> (module, types.RuntimeHelpers,
				MemberFilter.Property ("OffsetToStringData", btypes.Int));

			SecurityActionRequestMinimum = new PredefinedMember<ConstSpec> (module, types.SecurityAction, "RequestMinimum",
				MemberKind.Field, types.SecurityAction);

			StringEmpty = new PredefinedMember<FieldSpec> (module, btypes.String, MemberFilter.Field ("Empty", btypes.String));

			StringEqual = new PredefinedMember<MethodSpec> (module, btypes.String,
				new MemberFilter (Operator.GetMetadataName (Operator.OpType.Equality), 0, MemberKind.Operator, null, btypes.Bool));

			StringInequal = new PredefinedMember<MethodSpec> (module, btypes.String,
				new MemberFilter (Operator.GetMetadataName (Operator.OpType.Inequality), 0, MemberKind.Operator, null, btypes.Bool));

			StructLayoutAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.StructLayout,
				MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (btypes.Short)));

			StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
				MemberKind.Field, types.CharSet);

			StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
				MemberFilter.Field ("Size", btypes.Int));

			TypeGetTypeFromHandle = new PredefinedMember<MethodSpec> (module, btypes.Type, "GetTypeFromHandle", btypes.RuntimeTypeHandle);
		}
Example #2
0
        protected override bool DoDefineMembers()
        {
            PredefinedType builder_type;
            PredefinedMember <MethodSpec> bf;
            PredefinedMember <MethodSpec> bs;
            PredefinedMember <MethodSpec> sr;
            PredefinedMember <MethodSpec> se;
            PredefinedMember <MethodSpec> sm;
            bool has_task_return_type = false;
            var  pred_members         = Module.PredefinedMembers;

            if (return_type.Kind == MemberKind.Void)
            {
                builder_type = Module.PredefinedTypes.AsyncVoidMethodBuilder;
                bf           = pred_members.AsyncVoidMethodBuilderCreate;
                bs           = pred_members.AsyncVoidMethodBuilderStart;
                sr           = pred_members.AsyncVoidMethodBuilderSetResult;
                se           = pred_members.AsyncVoidMethodBuilderSetException;
                sm           = pred_members.AsyncVoidMethodBuilderSetStateMachine;
            }
            else if (return_type == Module.PredefinedTypes.Task.TypeSpec)
            {
                builder_type = Module.PredefinedTypes.AsyncTaskMethodBuilder;
                bf           = pred_members.AsyncTaskMethodBuilderCreate;
                bs           = pred_members.AsyncTaskMethodBuilderStart;
                sr           = pred_members.AsyncTaskMethodBuilderSetResult;
                se           = pred_members.AsyncTaskMethodBuilderSetException;
                sm           = pred_members.AsyncTaskMethodBuilderSetStateMachine;
                task         = pred_members.AsyncTaskMethodBuilderTask.Get();
            }
            else
            {
                builder_type         = Module.PredefinedTypes.AsyncTaskMethodBuilderGeneric;
                bf                   = pred_members.AsyncTaskMethodBuilderGenericCreate;
                bs                   = pred_members.AsyncTaskMethodBuilderGenericStart;
                sr                   = pred_members.AsyncTaskMethodBuilderGenericSetResult;
                se                   = pred_members.AsyncTaskMethodBuilderGenericSetException;
                sm                   = pred_members.AsyncTaskMethodBuilderGenericSetStateMachine;
                task                 = pred_members.AsyncTaskMethodBuilderGenericTask.Get();
                has_task_return_type = true;
            }

            set_result      = sr.Get();
            set_exception   = se.Get();
            builder_factory = bf.Get();
            builder_start   = bs.Get();

            var istate_machine   = Module.PredefinedTypes.IAsyncStateMachine;
            var set_statemachine = sm.Get();

            if (!builder_type.Define() || !istate_machine.Define() || set_result == null || builder_factory == null ||
                set_exception == null || set_statemachine == null || builder_start == null ||
                !Module.PredefinedTypes.INotifyCompletion.Define())
            {
                Report.Error(1993, Location,
                             "Cannot find compiler required types for asynchronous functions support. Are you targeting the wrong framework version?");
                return(base.DoDefineMembers());
            }

            var bt = builder_type.TypeSpec;

            //
            // Inflate generic Task types
            //
            if (has_task_return_type)
            {
                var task_return_type = return_type.TypeArguments;
                if (mutator != null)
                {
                    task_return_type = mutator.Mutate(task_return_type);
                }

                bt               = bt.MakeGenericType(Module, task_return_type);
                set_result       = MemberCache.GetMember(bt, set_result);
                set_exception    = MemberCache.GetMember(bt, set_exception);
                set_statemachine = MemberCache.GetMember(bt, set_statemachine);

                if (task != null)
                {
                    task = MemberCache.GetMember(bt, task);
                }
            }

            builder = AddCompilerGeneratedField("$builder", new TypeExpression(bt, Location));

            var set_state_machine = new Method(this, new TypeExpression(Compiler.BuiltinTypes.Void, Location),
                                               Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN | Modifiers.PUBLIC,
                                               new MemberName("SetStateMachine"),
                                               ParametersCompiled.CreateFullyResolved(
                                                   new Parameter(new TypeExpression(istate_machine.TypeSpec, Location), "stateMachine", Parameter.Modifier.NONE, null, Location),
                                                   istate_machine.TypeSpec),
                                               null);

            ToplevelBlock block = new ToplevelBlock(Compiler, set_state_machine.ParameterInfo, Location);

            block.IsCompilerGenerated = true;
            set_state_machine.Block   = block;

            Members.Add(set_state_machine);

            if (!base.DoDefineMembers())
            {
                return(false);
            }

            //
            // Fabricates SetStateMachine method
            //
            // public void SetStateMachine (IAsyncStateMachine stateMachine)
            // {
            //    $builder.SetStateMachine (stateMachine);
            // }
            //
            var mg = MethodGroupExpr.CreatePredefined(set_statemachine, bt, Location);

            mg.InstanceExpression = new FieldExpr(builder, Location);

            var param_reference = block.GetParameterReference(0, Location);

            param_reference.Type   = istate_machine.TypeSpec;
            param_reference.eclass = ExprClass.Variable;

            var args = new Arguments(1);

            args.Add(new Argument(param_reference));
            set_state_machine.Block.AddStatement(new StatementExpression(new Invocation(mg, args)));

            if (has_task_return_type)
            {
                hoisted_return = LocalVariable.CreateCompilerGenerated(bt.TypeArguments[0], StateMachineMethod.Block, Location);
            }

            return(true);
        }
Example #3
0
        protected override bool DoDefineMembers()
        {
            var builtin_types = Compiler.BuiltinTypes;

            var ctor_parameters = ParametersCompiled.CreateFullyResolved(
                new [] {
                new Parameter(new TypeExpression(builtin_types.Object, Location), "object", Parameter.Modifier.NONE, null, Location),
                new Parameter(new TypeExpression(builtin_types.IntPtr, Location), "method", Parameter.Modifier.NONE, null, Location)
            },
                new [] {
                builtin_types.Object,
                builtin_types.IntPtr
            }
                );

            Constructor = new Constructor(this, Constructor.ConstructorName,
                                          Modifiers.PUBLIC, null, ctor_parameters, null, Location);
            Constructor.Define();

            //
            // Here the various methods like Invoke, BeginInvoke etc are defined
            //
            // First, call the `out of band' special method for
            // defining recursively any types we need:
            //
            var p = parameters;

            if (!p.Resolve(this))
            {
                return(false);
            }

            //
            // Invoke method
            //

            // Check accessibility
            foreach (var partype in p.Types)
            {
                if (!IsAccessibleAs(partype))
                {
                    Report.SymbolRelatedToPreviousError(partype);
                    Report.Error(59, Location,
                                 "Inconsistent accessibility: parameter type `{0}' is less accessible than delegate `{1}'",
                                 TypeManager.CSharpName(partype), GetSignatureForError());
                }
            }

            var ret_type = ReturnType.ResolveAsType(this);

            if (ret_type == null)
            {
                return(false);
            }

            //
            // We don't have to check any others because they are all
            // guaranteed to be accessible - they are standard types.
            //
            if (!IsAccessibleAs(ret_type))
            {
                Report.SymbolRelatedToPreviousError(ret_type);
                Report.Error(58, Location,
                             "Inconsistent accessibility: return type `" +
                             TypeManager.CSharpName(ret_type) + "' is less " +
                             "accessible than delegate `" + GetSignatureForError() + "'");
                return(false);
            }

            CheckProtectedModifier();

            if (Compiler.Settings.StdLib && ret_type.IsSpecialRuntimeType)
            {
                Method.Error1599(Location, ret_type, Report);
                return(false);
            }

            TypeManager.CheckTypeVariance(ret_type, Variance.Covariant, this);

            var resolved_rt = new TypeExpression(ret_type, Location);

            InvokeBuilder = new Method(this, null, resolved_rt, MethodModifiers, new MemberName(InvokeMethodName), p, null);
            InvokeBuilder.Define();

            //
            // Don't emit async method for compiler generated delegates (e.g. dynamic site containers)
            //
            if (!IsCompilerGenerated)
            {
                DefineAsyncMethods(Parameters.CallingConvention, resolved_rt);
            }

            return(true);
        }
Example #4
0
        public override bool Resolve(BlockContext bc)
        {
            if (!base.Resolve(bc))
            {
                return(false);
            }

            type = expr.Type;

            //
            // The task result is of dynamic type
            //
            if (expr.Type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
            {
                throw new NotImplementedException("dynamic await");
            }

            //
            // Check whether the expression is awaitable
            //
            Expression ama = new AwaitableMemberAccess(expr).Resolve(bc);

            if (ama == null)
            {
                return(false);
            }

            Arguments args = new Arguments(0);

            var errors_printer = new SessionReportPrinter();
            var old            = bc.Report.SetPrinter(errors_printer);

            ama = new Invocation(ama, args).Resolve(bc);

            if (errors_printer.ErrorsCount > 0 || !MemberAccess.IsValidDotExpression(ama.Type))
            {
                bc.Report.SetPrinter(old);
                Error_WrongGetAwaiter(bc, loc, expr.Type);
                return(false);
            }

            var awaiter_type = ama.Type;

            awaiter = ((AsyncTaskStorey)machine_initializer.Storey).AddAwaiter(awaiter_type, loc);
            expr    = ama;

            //
            // Predefined: bool IsCompleted { get; }
            //
            var is_completed_ma = new MemberAccess(expr, "IsCompleted").Resolve(bc);

            if (is_completed_ma != null)
            {
                is_completed = is_completed_ma as PropertyExpr;
                if (is_completed != null && is_completed.Type.BuiltinType == BuiltinTypeSpec.Type.Bool && is_completed.IsInstance && is_completed.Getter != null)
                {
                    // valid
                }
                else
                {
                    bc.Report.SetPrinter(old);
                    Error_WrongAwaiterPattern(bc, awaiter_type);
                    return(false);
                }
            }

            bc.Report.SetPrinter(old);

            if (errors_printer.ErrorsCount > 0)
            {
                Error_WrongAwaiterPattern(bc, awaiter_type);
                return(false);
            }

            //
            // Predefined: OnCompleted (Action)
            //
            if (bc.Module.PredefinedTypes.Action.Define())
            {
                on_completed = MemberCache.FindMember(awaiter_type, MemberFilter.Method("OnCompleted", 0,
                                                                                        ParametersCompiled.CreateFullyResolved(bc.Module.PredefinedTypes.Action.TypeSpec), bc.Module.Compiler.BuiltinTypes.Void),
                                                      BindingRestriction.InstanceOnly) as MethodSpec;

                if (on_completed == null)
                {
                    Error_WrongAwaiterPattern(bc, awaiter_type);
                    return(false);
                }
            }

            //
            // Predefined: GetResult ()
            //
            // The method return type is also result type of await expression
            //
            get_result = MemberCache.FindMember(awaiter_type, MemberFilter.Method("GetResult", 0,
                                                                                  ParametersCompiled.EmptyReadOnlyParameters, null),
                                                BindingRestriction.InstanceOnly) as MethodSpec;

            if (get_result == null)
            {
                Error_WrongAwaiterPattern(bc, awaiter_type);
                return(false);
            }

            return(true);
        }
Example #5
0
        //
        // Fabricates stack forwarder based on stack types which copies all
        // parameters to type fields
        //
        public MethodSpec GetStackForwarder(TypeSpec[] types, out FieldSpec[] fields)
        {
            if (stack_forwarders == null)
            {
                stack_forwarders = new Dictionary <TypeSpec[], Tuple <MethodSpec, FieldSpec[]> > (TypeSpecComparer.Default);
            }
            else
            {
                //
                // Does same forwarder method with same types already exist
                //
                Tuple <MethodSpec, FieldSpec[]> method;
                if (stack_forwarders.TryGetValue(types, out method))
                {
                    fields = method.Item2;
                    return(method.Item1);
                }
            }

            Parameter[] p      = new Parameter[types.Length + 1];
            TypeSpec[]  ptypes = new TypeSpec[p.Length];
            fields = new FieldSpec[types.Length];

            for (int i = 0; i < types.Length; ++i)
            {
                var t = types[i];

                TypeSpec parameter_type = t;
                if (parameter_type == InternalType.CurrentTypeOnStack)
                {
                    parameter_type = CurrentType;
                }

                p[i]      = new Parameter(new TypeExpression(parameter_type, Location), null, 0, null, Location);
                ptypes[i] = parameter_type;

                if (t == InternalType.CurrentTypeOnStack)
                {
                    // Null means the type is `this' we can optimize by ignoring
                    continue;
                }

                var reference = t as ReferenceContainer;
                if (reference != null)
                {
                    t = reference.Element;
                }

                fields[i] = CreateStackValueField(t);
            }

            var this_parameter = new Parameter(new TypeExpression(CurrentType, Location), null, 0, null, Location);

            p[types.Length]      = this_parameter;
            ptypes[types.Length] = CurrentType;

            var parameters = ParametersCompiled.CreateFullyResolved(p, ptypes);

            var m = new Method(this, null, new TypeExpression(Compiler.BuiltinTypes.Void, Location),
                               Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
                               new MemberName("<>s__" + stack_forwarders.Count.ToString("X")), parameters, null);

            m.Block = new ToplevelBlock(Compiler, parameters, Location);
            m.Block.AddScopeStatement(new ParametersLoadStatement(fields, ptypes));

            m.Define();
            Methods.Add(m);

            stack_forwarders.Add(types, Tuple.Create(m.Spec, fields));

            return(m.Spec);
        }
Example #6
0
        public override bool Resolve(BlockContext bc)
        {
            if (!base.Resolve(bc))
            {
                return(false);
            }

            Arguments args = new Arguments(0);

            type = expr.Type;

            //
            // The await expression is of dynamic type
            //
            if (type.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
            {
                result_type = type;

                awaiter = ((AsyncTaskStorey)machine_initializer.Storey).AddAwaiter(type, loc);

                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 = ((AsyncTaskStorey)machine_initializer.Storey).AddAwaiter(awaiter_type, loc);

            expr = ama;

            //
            // Predefined: bool IsCompleted { get; }
            //
            is_completed = MemberCache.FindMember(awaiter_type, MemberFilter.Property("IsCompleted", bc.Module.Compiler.BuiltinTypes.Bool),
                                                  BindingRestriction.InstanceOnly) as PropertySpec;

            if (is_completed == null || !is_completed.HasGet)
            {
                Error_WrongAwaiterPattern(bc, awaiter_type);
                return(false);
            }

            //
            // Predefined: OnCompleted (Action)
            //
            if (bc.Module.PredefinedTypes.Action.Define())
            {
                on_completed = MemberCache.FindMember(awaiter_type, MemberFilter.Method("OnCompleted", 0,
                                                                                        ParametersCompiled.CreateFullyResolved(bc.Module.PredefinedTypes.Action.TypeSpec), bc.Module.Compiler.BuiltinTypes.Void),
                                                      BindingRestriction.InstanceOnly) as MethodSpec;

                if (on_completed == null)
                {
                    Error_WrongAwaiterPattern(bc, awaiter_type);
                    return(false);
                }
            }

            //
            // Predefined: GetResult ()
            //
            // The method return type is also result type of await expression
            //
            get_result = MemberCache.FindMember(awaiter_type, MemberFilter.Method("GetResult", 0,
                                                                                  ParametersCompiled.EmptyReadOnlyParameters, null),
                                                BindingRestriction.InstanceOnly) as MethodSpec;

            if (get_result == null)
            {
                Error_WrongAwaiterPattern(bc, awaiter_type);
                return(false);
            }

            result_type = get_result.ReturnType;

            return(true);
        }
Example #7
0
            Method GenerateNumberMatcher()
            {
                var loc        = Location;
                var parameters = ParametersCompiled.CreateFullyResolved(
                    new [] {
                    new Parameter(new TypeExpression(Compiler.BuiltinTypes.Object, loc), "obj", 0, null, loc),
                    new Parameter(new TypeExpression(Compiler.BuiltinTypes.Object, loc), "value", 0, null, loc),
                    new Parameter(new TypeExpression(Compiler.BuiltinTypes.Bool, loc), "enumType", 0, null, loc),
                },
                    new [] {
                    Compiler.BuiltinTypes.Object,
                    Compiler.BuiltinTypes.Object,
                    Compiler.BuiltinTypes.Bool
                });

                var m = new Method(this, new TypeExpression(Compiler.BuiltinTypes.Bool, loc),
                                   Modifiers.PUBLIC | Modifiers.STATIC | Modifiers.DEBUGGER_HIDDEN, new MemberName("NumberMatcher", loc),
                                   parameters, null);

                parameters [0].Resolve(m, 0);
                parameters [1].Resolve(m, 1);
                parameters [2].Resolve(m, 2);

                ToplevelBlock top_block = new ToplevelBlock(Compiler, parameters, loc);

                m.Block = top_block;

                //
                // if (enumType)
                //		return Equals (obj, value);
                //
                var equals_args = new Arguments(2);

                equals_args.Add(new Argument(top_block.GetParameterReference(0, loc)));
                equals_args.Add(new Argument(top_block.GetParameterReference(1, loc)));

                var if_type = new If(
                    top_block.GetParameterReference(2, loc),
                    new Return(new Invocation(new SimpleName("Equals", loc), equals_args), loc),
                    loc);

                top_block.AddStatement(if_type);

                //
                // if (obj is Enum || obj == null)
                //		return false;
                //

                var if_enum = new If(
                    new Binary(Binary.Operator.LogicalOr,
                               new Is(top_block.GetParameterReference(0, loc), new TypeExpression(Compiler.BuiltinTypes.Enum, loc), loc),
                               new Binary(Binary.Operator.Equality, top_block.GetParameterReference(0, loc), new NullLiteral(loc))),
                    new Return(new BoolLiteral(Compiler.BuiltinTypes, false, loc), loc),
                    loc);

                top_block.AddStatement(if_enum);


                var system_convert = new MemberAccess(new QualifiedAliasMember("global", "System", loc), "Convert", loc);
                var expl_block     = new ExplicitBlock(top_block, loc, loc);

                //
                // var converted = System.Convert.ChangeType (obj, System.Convert.GetTypeCode (value));
                //
                var lv_converted = LocalVariable.CreateCompilerGenerated(Compiler.BuiltinTypes.Object, top_block, loc);

                var arguments_gettypecode = new Arguments(1);

                arguments_gettypecode.Add(new Argument(top_block.GetParameterReference(1, loc)));

                var gettypecode = new Invocation(new MemberAccess(system_convert, "GetTypeCode", loc), arguments_gettypecode);

                var arguments_changetype = new Arguments(1);

                arguments_changetype.Add(new Argument(top_block.GetParameterReference(0, loc)));
                arguments_changetype.Add(new Argument(gettypecode));

                var changetype = new Invocation(new MemberAccess(system_convert, "ChangeType", loc), arguments_changetype);

                expl_block.AddStatement(new StatementExpression(new SimpleAssign(new LocalVariableReference(lv_converted, loc), changetype, loc)));


                //
                // return converted.Equals (value)
                //
                var equals_arguments = new Arguments(1);

                equals_arguments.Add(new Argument(top_block.GetParameterReference(1, loc)));
                var equals_invocation = new Invocation(new MemberAccess(new LocalVariableReference(lv_converted, loc), "Equals"), equals_arguments);

                expl_block.AddStatement(new Return(equals_invocation, loc));

                var catch_block = new ExplicitBlock(top_block, loc, loc);

                catch_block.AddStatement(new Return(new BoolLiteral(Compiler.BuiltinTypes, false, loc), loc));
                top_block.AddStatement(new TryCatch(expl_block, new List <Catch> ()
                {
                    new Catch(catch_block, loc)
                }, loc, false));

                m.Define();
                m.PrepareEmit();
                AddMember(m);

                return(m);
            }
Example #8
0
        public T Get()
        {
            if (member != null)
            {
                return(member);
            }

            if (declaring_type == null)
            {
                if (!declaring_type_predefined.Define())
                {
                    return(null);
                }

                declaring_type = declaring_type_predefined.TypeSpec;
            }

            if (parameters_predefined != null)
            {
                TypeSpec[] types = new TypeSpec [parameters_predefined.Length];
                for (int i = 0; i < types.Length; ++i)
                {
                    var p = parameters_predefined [i];
                    if (!p.Define())
                    {
                        return(null);
                    }

                    types[i] = p.TypeSpec;
                }

                if (filter.Kind == MemberKind.Field)
                {
                    filter = new MemberFilter(filter.Name, filter.Arity, filter.Kind, null, types [0]);
                }
                else
                {
                    filter = new MemberFilter(filter.Name, filter.Arity, filter.Kind, ParametersCompiled.CreateFullyResolved(types), filter.MemberType);
                }
            }

            member = MemberCache.FindMember(declaring_type, filter, BindingRestriction.DeclaredOnly) as T;
            if (member == null)
            {
                return(null);
            }

            if (!member.IsAccessible(module))
            {
                return(null);
            }

            return(member);
        }
Example #9
0
 public PredefinedMember(ModuleContainer module, BuiltinTypeSpec type, string name, params TypeSpec[] types)
     : this(module, type, MemberFilter.Method(name, 0, ParametersCompiled.CreateFullyResolved(types), null))
 {
 }
Example #10
0
        //
        // Returns the method specification for a method named `name' defined
        // in type `t' which takes arguments of types `args'
        //
        public static MethodSpec GetPredefinedMethod(TypeSpec t, string name, Location loc, params TypeSpec [] args)
        {
            var pc = ParametersCompiled.CreateFullyResolved(args);

            return(GetPredefinedMethod(t, MemberFilter.Method(name, 0, pc, null), false, loc));
        }
Example #11
0
        //
        // Returns the ConstructorInfo for "args"
        //
        public static MethodSpec GetPredefinedConstructor(TypeSpec t, Location loc, params TypeSpec [] args)
        {
            var pc = ParametersCompiled.CreateFullyResolved(args);

            return(GetPredefinedMember(t, MemberFilter.Constructor(pc), false, loc) as MethodSpec);
        }
Example #12
0
        //
        // Processes "see" or "seealso" elements.
        // Checks cref attribute.
        //
        void HandleXrefCommon(MemberCore mc, DeclSpace ds, XmlElement xref)
        {
            string cref = xref.GetAttribute("cref").Trim(wsChars);

            // when, XmlReader, "if (cref == null)"
            if (!xref.HasAttribute("cref"))
            {
                return;
            }
            if (cref.Length == 0)
            {
                Report.Warning(1001, 1, mc.Location, "Identifier expected");
            }
            // ... and continue until CS1584.

            string signature;        // "x:" are stripped
            string name;             // method invokation "(...)" are removed
            string parameters;       // method parameter list

            // When it found '?:' ('T:' 'M:' 'F:' 'P:' 'E:' etc.),
            // MS ignores not only its member kind, but also
            // the entire syntax correctness. Nor it also does
            // type fullname resolution i.e. "T:List(int)" is kept
            // as T:List(int), not
            // T:System.Collections.Generic.List&lt;System.Int32&gt;
            if (cref.Length > 2 && cref [1] == ':')
            {
                return;
            }
            else
            {
                signature = cref;
            }

            // Also note that without "T:" any generic type
            // indication fails.

            int parens_pos = signature.IndexOf('(');
            int brace_pos  = parens_pos >= 0 ? -1 :
                             signature.IndexOf('[');

            if (parens_pos > 0 && signature [signature.Length - 1] == ')')
            {
                name       = signature.Substring(0, parens_pos).Trim(wsChars);
                parameters = signature.Substring(parens_pos + 1, signature.Length - parens_pos - 2).Trim(wsChars);
            }
            else if (brace_pos > 0 && signature [signature.Length - 1] == ']')
            {
                name       = signature.Substring(0, brace_pos).Trim(wsChars);
                parameters = signature.Substring(brace_pos + 1, signature.Length - brace_pos - 2).Trim(wsChars);
            }
            else
            {
                name       = signature;
                parameters = null;
            }
            Normalize(mc, ref name);

            string identifier = GetBodyIdentifierFromName(name);

            // Check if identifier is valid.
            // This check is not necessary to mark as error, but
            // csc specially reports CS1584 for wrong identifiers.
            string [] name_elems = identifier.Split('.');
            for (int i = 0; i < name_elems.Length; i++)
            {
                string nameElem = GetBodyIdentifierFromName(name_elems [i]);
                if (i > 0)
                {
                    Normalize(mc, ref nameElem);
                }
                if (!Tokenizer.IsValidIdentifier(nameElem) &&
                    nameElem.IndexOf("operator") < 0)
                {
                    Report.Warning(1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
                                   mc.GetSignatureForError(), cref);
                    xref.SetAttribute("cref", "!:" + signature);
                    return;
                }
            }

            // check if parameters are valid
            AParametersCollection parameter_types;

            if (parameters == null)
            {
                parameter_types = null;
            }
            else if (parameters.Length == 0)
            {
                parameter_types = ParametersCompiled.EmptyReadOnlyParameters;
            }
            else
            {
                string [] param_list = parameters.Split(',');
                var       plist      = new List <TypeSpec> ();
                for (int i = 0; i < param_list.Length; i++)
                {
                    string param_type_name = param_list [i].Trim(wsChars);
                    Normalize(mc, ref param_type_name);
                    TypeSpec param_type = FindDocumentedType(mc, param_type_name, ds, cref);
                    if (param_type == null)
                    {
                        Report.Warning(1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
                                       (i + 1).ToString(), cref);
                        return;
                    }
                    plist.Add(param_type);
                }

                parameter_types = ParametersCompiled.CreateFullyResolved(plist.ToArray());
            }

            TypeSpec type = FindDocumentedType(mc, name, ds, cref);

            if (type != null
                // delegate must not be referenced with args
                && (!type.IsDelegate ||
                    parameter_types == null))
            {
                string result = GetSignatureForDoc(type)
                                + (brace_pos < 0 ? String.Empty : signature.Substring(brace_pos));
                xref.SetAttribute("cref", "T:" + result);
                return;                 // a type
            }

            int period = name.LastIndexOf('.');

            if (period > 0)
            {
                string typeName    = name.Substring(0, period);
                string member_name = name.Substring(period + 1);
                string lookup_name = member_name == "this" ? MemberCache.IndexerNameAlias : member_name;
                Normalize(mc, ref lookup_name);
                Normalize(mc, ref member_name);
                type = FindDocumentedType(mc, typeName, ds, cref);
                int warn_result;
                if (type != null)
                {
                    var mi = FindDocumentedMember(mc, type, lookup_name, parameter_types, ds, out warn_result, cref, true, name);
                    if (warn_result > 0)
                    {
                        return;
                    }
                    if (mi != null)
                    {
                        // we cannot use 'type' directly
                        // to get its name, since mi
                        // could be from DeclaringType
                        // for nested types.
                        xref.SetAttribute("cref", GetMemberDocHead(mi) + GetSignatureForDoc(mi.DeclaringType) + "." + member_name + GetParametersFormatted(mi));
                        return;                         // a member of a type
                    }
                }
            }
            else
            {
                int warn_result;
                var mi = FindDocumentedMember(mc, ds.PartialContainer.Definition, name, parameter_types, ds, out warn_result, cref, true, name);

                if (warn_result > 0)
                {
                    return;
                }
                if (mi != null)
                {
                    // we cannot use 'type' directly
                    // to get its name, since mi
                    // could be from DeclaringType
                    // for nested types.
                    xref.SetAttribute("cref", GetMemberDocHead(mi) + GetSignatureForDoc(mi.DeclaringType) + "." + name + GetParametersFormatted(mi));
                    return;                     // local member name
                }
            }

            // It still might be part of namespace name.
            Namespace ns = ds.NamespaceEntry.NS.GetNamespace(name, false);

            if (ns != null)
            {
                xref.SetAttribute("cref", "N:" + ns.GetSignatureForError());
                return;                 // a namespace
            }
            if (mc.Module.GlobalRootNamespace.IsNamespace(name))
            {
                xref.SetAttribute("cref", "N:" + name);
                return;                 // a namespace
            }

            Report.Warning(1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved",
                           mc.GetSignatureForError(), cref);

            xref.SetAttribute("cref", "!:" + name);
        }