ICSharpCode.NRefactory.MonoCSharp.Method.Define C# (CSharp) Method

Define() public method

public Define ( ) : bool
return bool
		public override bool Define ()
		{
			if (!base.Define ())
				return false;

			if (member_type.Kind == MemberKind.Void && parameters.IsEmpty && MemberName.Arity == 0 && MemberName.Name == Destructor.MetadataName) {
				Report.Warning (465, 1, Location,
					"Introducing `Finalize' method can interfere with destructor invocation. Did you intend to declare a destructor?");
			}

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

			if (CurrentTypeParameters == null) {
				if (base_method != null && !IsExplicitImpl) {
					if (parameters.Count == 1 && ParameterTypes[0].BuiltinType == BuiltinTypeSpec.Type.Object && MemberName.Name == "Equals")
						Parent.PartialContainer.Mark_HasEquals ();
					else if (parameters.IsEmpty && MemberName.Name == "GetHashCode")
						Parent.PartialContainer.Mark_HasGetHashCode ();
				}
					
			} else {
				DefineTypeParameters ();
			}

			if (block != null) {
				if (block.IsIterator) {
					//
					// Current method is turned into automatically generated
					// wrapper which creates an instance of iterator
					//
					Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
					ModFlags |= Modifiers.DEBUGGER_HIDDEN;
				}

				if ((ModFlags & Modifiers.ASYNC) != 0) {
					if (ReturnType.Kind != MemberKind.Void &&
						ReturnType != Module.PredefinedTypes.Task.TypeSpec &&
						!ReturnType.IsGenericTask) {
						Report.Error (1983, Location, "The return type of an async method must be void, Task, or Task<T>");
					}

					block = (ToplevelBlock) block.ConvertToAsyncTask (this, Parent.PartialContainer, parameters, ReturnType, null, Location);
					ModFlags |= Modifiers.DEBUGGER_STEP_THROUGH;
				}

				if (Compiler.Settings.WriteMetadataOnly)
					block = null;
			}

			if ((ModFlags & Modifiers.STATIC) == 0)
				return true;

			if (parameters.HasExtensionMethodType) {
				if (Parent.PartialContainer.IsStatic && !Parent.IsGenericOrParentIsGeneric) {
					if (!Parent.IsTopLevel)
						Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class",
							GetSignatureForError ());

					PredefinedAttribute pa = Module.PredefinedAttributes.Extension;
					if (!pa.IsDefined) {
						Report.Error (1110, Location,
							"`{0}': Extension methods require `System.Runtime.CompilerServices.ExtensionAttribute' type to be available. Are you missing an assembly reference?",
							GetSignatureForError ());
					}

					ModFlags |= Modifiers.METHOD_EXTENSION;
					Parent.PartialContainer.ModFlags |= Modifiers.METHOD_EXTENSION;
					Spec.DeclaringType.SetExtensionMethodContainer ();
					Parent.Module.HasExtensionMethod = true;
				} else {
					Report.Error (1106, Location, "`{0}': Extension methods must be defined in a non-generic static class",
						GetSignatureForError ());
				}
			}

			//
			// This is used to track the Entry Point,
			//
			var settings = Compiler.Settings;
			if (settings.NeedsEntryPoint && MemberName.Name == "Main" && !IsPartialDefinition && (settings.MainClass == null || settings.MainClass == Parent.TypeBuilder.FullName)) {
				if (IsEntryPoint ()) {
					if (Parent.DeclaringAssembly.EntryPoint == null) {
						if (Parent.IsGenericOrParentIsGeneric || MemberName.IsGeneric) {
							Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type",
								GetSignatureForError ());
						} else if ((ModFlags & Modifiers.ASYNC) != 0) {
							Report.Error (4009, Location, "`{0}': an entry point cannot be async method",
								GetSignatureForError ());
						} else {
							SetIsUsed ();
							Parent.DeclaringAssembly.EntryPoint = this;
						}
					} else {
						Error_DuplicateEntryPoint (Parent.DeclaringAssembly.EntryPoint);
						Error_DuplicateEntryPoint (this);
					}
				} else {
					Report.Warning (28, 4, Location, "`{0}' has the wrong signature to be an entry point",
						GetSignatureForError ());
				}
			}

			return true;
		}

Usage Example

示例#1
0
文件: class.cs 项目: 0xd4d/NRefactory
		//
		// Creates a proxy base method call inside this container for hoisted base member calls
		//
		public MethodSpec CreateHoistedBaseCallProxy (ResolveContext rc, MethodSpec method)
		{
			Method proxy_method;

			//
			// One proxy per base method is enough
			//
			if (hoisted_base_call_proxies == null) {
				hoisted_base_call_proxies = new Dictionary<MethodSpec, Method> ();
				proxy_method = null;
			} else {
				hoisted_base_call_proxies.TryGetValue (method, out proxy_method);
			}

			if (proxy_method == null) {
				string name = CompilerGeneratedContainer.MakeName (method.Name, null, "BaseCallProxy", hoisted_base_call_proxies.Count);

				MemberName member_name;
				TypeArguments targs = null;
				TypeSpec return_type = method.ReturnType;
				var local_param_types = method.Parameters.Types;

				if (method.IsGeneric) {
					//
					// Copy all base generic method type parameters info
					//
					var hoisted_tparams = method.GenericDefinition.TypeParameters;
					var tparams = new TypeParameters ();

					targs = new TypeArguments ();
					targs.Arguments = new TypeSpec[hoisted_tparams.Length];
					for (int i = 0; i < hoisted_tparams.Length; ++i) {
						var tp = hoisted_tparams[i];
						var local_tp = new TypeParameter (tp, null, new MemberName (tp.Name, Location), null);
						tparams.Add (local_tp);

						targs.Add (new SimpleName (tp.Name, Location));
						targs.Arguments[i] = local_tp.Type;
					}

					member_name = new MemberName (name, tparams, Location);

					//
					// Mutate any method type parameters from original
					// to newly created hoisted version
					//
					var mutator = new TypeParameterMutator (hoisted_tparams, tparams);
					return_type = mutator.Mutate (return_type);
					local_param_types = mutator.Mutate (local_param_types);
				} else {
					member_name = new MemberName (name);
				}

				var base_parameters = new Parameter[method.Parameters.Count];
				for (int i = 0; i < base_parameters.Length; ++i) {
					var base_param = method.Parameters.FixedParameters[i];
					base_parameters[i] = new Parameter (new TypeExpression (local_param_types [i], Location),
						base_param.Name, base_param.ModFlags, null, Location);
					base_parameters[i].Resolve (this, i);
				}

				var cloned_params = ParametersCompiled.CreateFullyResolved (base_parameters, method.Parameters.Types);
				if (method.Parameters.HasArglist) {
					cloned_params.FixedParameters[0] = new Parameter (null, "__arglist", Parameter.Modifier.NONE, null, Location);
					cloned_params.Types[0] = Module.PredefinedTypes.RuntimeArgumentHandle.Resolve ();
				}

				// Compiler generated proxy
				proxy_method = new Method (this, new TypeExpression (return_type, Location),
					Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED | Modifiers.DEBUGGER_HIDDEN,
					member_name, cloned_params, null);

				var block = new ToplevelBlock (Compiler, proxy_method.ParameterInfo, Location) {
					IsCompilerGenerated = true
				};

				var mg = MethodGroupExpr.CreatePredefined (method, method.DeclaringType, Location);
				mg.InstanceExpression = new BaseThis (method.DeclaringType, Location);
				if (targs != null)
					mg.SetTypeArguments (rc, targs);

				// Get all the method parameters and pass them as arguments
				var real_base_call = new Invocation (mg, block.GetAllParametersArguments ());
				Statement statement;
				if (method.ReturnType.Kind == MemberKind.Void)
					statement = new StatementExpression (real_base_call);
				else
					statement = new Return (real_base_call, Location);

				block.AddStatement (statement);
				proxy_method.Block = block;

				members.Add (proxy_method);
				proxy_method.Define ();
				proxy_method.PrepareEmit ();

				hoisted_base_call_proxies.Add (method, proxy_method);
			}

			return proxy_method.Spec;
		}
All Usage Examples Of ICSharpCode.NRefactory.MonoCSharp.Method::Define