Inheritance: Mono.CSharp.ImportedMethodDefinition, IGenericMethodDefinition
コード例 #1
0
ファイル: import.cs プロジェクト: Gobiner/ILSpy
		public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
		{
			Modifiers mod = ReadMethodModifiers (mb, declaringType);
			TypeParameterSpec[] tparams;

			var parameters = CreateParameters (declaringType, mb.GetParameters (), mb);

			if (mb.IsGenericMethod) {
				if (!mb.IsGenericMethodDefinition)
					throw new NotSupportedException ("assert");

				tparams = CreateGenericParameters (0, mb.GetGenericArguments ());
			} else {
				tparams = null;
			}

			MemberKind kind;
			TypeSpec returnType;
			if (mb.MemberType == MemberTypes.Constructor) {
				kind = MemberKind.Constructor;
				returnType = module.Compiler.BuiltinTypes.Void;
			} else {
				//
				// Detect operators and destructors
				//
				string name = mb.Name;
				kind = MemberKind.Method;
				if (tparams == null && !mb.DeclaringType.IsInterface && name.Length > 6) {
					if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) {
						if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
							var op_type = Operator.GetType (name);
							if (op_type.HasValue && parameters.Count > 0 && parameters.Count < 3) {
								kind = MemberKind.Operator;
							}
						}
					} else if (parameters.IsEmpty && name == Destructor.MetadataName) {
						kind = MemberKind.Destructor;
						if (declaringType.BuiltinType == BuiltinTypeSpec.Type.Object) {
							mod &= ~Modifiers.OVERRIDE;
							mod |= Modifiers.VIRTUAL;
						}
					}
				}

				var mi = (MethodInfo) mb;
				returnType = ImportType (mi.ReturnType, new DynamicTypeReader (mi.ReturnParameter));

				// Cannot set to OVERRIDE without full hierarchy checks
				// this flag indicates that the method could be override
				// but further validation is needed
				if ((mod & Modifiers.OVERRIDE) != 0) {
					bool is_real_override = false;
					if (kind == MemberKind.Method && declaringType.BaseType != null) {
						var btype = declaringType.BaseType;
						if (IsOverrideMethodBaseTypeAccessible (btype)) {
							var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
							var candidate = MemberCache.FindMember (btype, filter, BindingRestriction.None);

							//
							// For imported class method do additional validation to be sure that metadata
							// override flag was correct
							// 
							// Difference between protected internal and protected is ok
							//
							const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
							if (candidate != null && (candidate.Modifiers & conflict_mask) == (mod & conflict_mask) && !candidate.IsStatic) {
								is_real_override = true;
							}
						}
					}

					if (!is_real_override) {
						mod &= ~Modifiers.OVERRIDE;
						if ((mod & Modifiers.SEALED) != 0)
							mod &= ~Modifiers.SEALED;
						else
							mod |= Modifiers.VIRTUAL;
					}
				}
			}

			IMemberDefinition definition;
			if (tparams != null) {
				var gmd = new ImportedGenericMethodDefinition ((MethodInfo) mb, returnType, parameters, tparams, this);
				foreach (var tp in gmd.TypeParameters) {
					ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ());
				}

				definition = gmd;
			} else {
				definition = new ImportedParameterMemberDefinition (mb, returnType, parameters, this);
			}

			MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
			if (tparams != null)
				ms.IsGeneric = true;

			return ms;
		}
コード例 #2
0
ファイル: import.cs プロジェクト: davidwaters/mono
		public MethodSpec CreateMethod (MethodBase mb, TypeSpec declaringType)
		{
			Modifiers mod = ReadMethodModifiers (mb, declaringType);
			TypeParameterSpec[] tparams;
			ImportedMethodDefinition definition;

			var parameters = CreateParameters (declaringType, mb.GetParameters (), mb);

			if (mb.IsGenericMethod) {
				if (!mb.IsGenericMethodDefinition)
					throw new NotSupportedException ("assert");

				tparams = CreateGenericParameters (0, mb.GetGenericArguments ());
				definition = new ImportedGenericMethodDefinition ((MethodInfo) mb, parameters, tparams);
			} else {
				definition = new ImportedMethodDefinition (mb, parameters);
				tparams = null;
			}

			MemberKind kind;
			TypeSpec returnType;
			if (mb.MemberType == MemberTypes.Constructor) {
				kind = MemberKind.Constructor;
				returnType = TypeManager.void_type;
			} else {
				//
				// Detect operators and destructors
				//
				string name = mb.Name;
				kind = MemberKind.Method;
				if (tparams == null && !mb.DeclaringType.IsInterface && name.Length > 6) {
					if ((mod & (Modifiers.STATIC | Modifiers.PUBLIC)) == (Modifiers.STATIC | Modifiers.PUBLIC)) {
						if (name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
							var op_type = Operator.GetType (name);
							if (op_type.HasValue && parameters.Count > 0 && parameters.Count < 3) {
								kind = MemberKind.Operator;
							}
						}
					} else if (parameters.IsEmpty && name == Destructor.MetadataName) {
						kind = MemberKind.Destructor;
						if (declaringType == TypeManager.object_type) {
							mod &= ~Modifiers.OVERRIDE;
							mod |= Modifiers.VIRTUAL;
						}
					}
				}

				var mi = (MethodInfo) mb;
				returnType = ImportType (mi.ReturnType, mi.ReturnTypeCustomAttributes, 0);

				// Cannot set to OVERRIDE without full hierarchy checks
				// this flag indicates that the method could be override
				// but further validation is needed
				if ((mod & Modifiers.OVERRIDE) != 0 && kind == MemberKind.Method && declaringType.BaseType != null) {
					var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null);
					var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None);

					//
					// For imported class method do additional validation to be sure that metadata
					// override flag was correct
					// 
					// Difference between protected internal and protected is ok
					//
					const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL;
					if (candidate == null || (candidate.Modifiers & conflict_mask) != (mod & conflict_mask) || candidate.IsStatic) {
						mod &= ~Modifiers.OVERRIDE;
					}
				}
			}

			MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
			if (tparams != null)
				ms.IsGeneric = true;

			return ms;
		}