X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fmethod.cs;h=7c7e12e10858008c4526f82f1abd9d05550b1ffe;hb=3e476138366f3dd57de9c1c65961adb3e1321e31;hp=f7f9f350790409426f50a1d506da6319445a2f62;hpb=d6513f517afde9ca1d13ca2c6dd539b539a9f0cf;p=mono.git diff --git a/mcs/mcs/method.cs b/mcs/mcs/method.cs index f7f9f350790..7c7e12e1085 100644 --- a/mcs/mcs/method.cs +++ b/mcs/mcs/method.cs @@ -35,6 +35,7 @@ namespace Mono.CSharp { { public readonly ParametersCompiled Parameters; protected ToplevelBlock block; + protected MethodSpec spec; public MethodCore (DeclSpace parent, GenericMethod generic, FullNamedExpression type, Modifiers mod, Modifiers allowed_mod, @@ -130,6 +131,10 @@ namespace Mono.CSharp { return base.EnableOverloadChecks (overload); } + public MethodSpec Spec { + get { return spec; } + } + protected override bool VerifyClsCompliance () { if (!base.VerifyClsCompliance ()) @@ -149,13 +154,88 @@ namespace Mono.CSharp { } } + interface IGenericMethodDefinition : IMemberDefinition + { + MethodInfo MakeGenericMethod (Type[] targs); + } + public class MethodSpec : MemberSpec { - public MethodInfo MetaInfo; + MethodBase metaInfo; + readonly AParametersCollection parameters; - protected MethodSpec (IMemberDetails details, string name, Modifiers modifiers) - : base (details, name, modifiers) + public MethodSpec (MemberKind kind, IMemberDefinition details, MethodBase info, AParametersCollection parameters, Modifiers modifiers) + : base (kind, details, info.Name, modifiers) { + this.MetaInfo = info; + this.parameters = parameters; + } + + public override Type DeclaringType { + get { + return MetaInfo.DeclaringType; + } + } + + public Type[] GetGenericArguments () + { + return MetaInfo.GetGenericArguments (); + } + + public MethodSpec Inflate (Type[] targs) + { + // TODO: Only create MethodSpec and inflate parameters, defer the call for later + var mb = ((IGenericMethodDefinition) definition).MakeGenericMethod (targs); + + // TODO: Does not work on .NET + var par = TypeManager.GetParameterData (mb); + + return new MethodSpec (Kind, definition, mb, par, Modifiers); + } + + public bool IsAbstract { + get { + return (Modifiers & Modifiers.ABSTRACT) != 0; + } + } + + public bool IsConstructor { + get { + return MetaInfo.IsConstructor; + } + } + + public bool IsGenericMethod { + get { + return MetaInfo.IsGenericMethod; + } + } + + // When is virtual or abstract + public bool IsVirtual { + get { + return (Modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) != 0; + } + } + + public MethodBase MetaInfo { + get { + return metaInfo; + } + set { + metaInfo = value; + } + } + + public AParametersCollection Parameters { + get { return parameters; } + } + + public Type ReturnType { + get { + return IsConstructor ? + TypeManager.void_type : ((MethodInfo) MetaInfo).ReturnType; + } } } @@ -258,6 +338,14 @@ namespace Mono.CSharp { ModFlags |= Modifiers.DEBUGGER_HIDDEN; } + MemberKind kind; + if (this is Operator) + kind = MemberKind.Operator; + else if (this is Destructor) + kind = MemberKind.Destructor; + else + kind = MemberKind.Method; + if (IsPartialDefinition) { caching_flags &= ~Flags.Excluded_Undetected; caching_flags |= Flags.Excluded; @@ -265,7 +353,9 @@ namespace Mono.CSharp { // Add to member cache only when a partial method implementation has not been found yet if ((caching_flags & Flags.PartialDefinitionExists) == 0) { MethodBase mb = new PartialMethodDefinitionInfo (this); - Parent.MemberCache.AddMember (mb, this); + + spec = new MethodSpec (kind, this, mb, Parameters, ModFlags); + Parent.MemberCache.AddMember (mb, spec); TypeManager.AddMethod (mb, this); } @@ -280,10 +370,12 @@ namespace Mono.CSharp { MethodBuilder = MethodData.MethodBuilder; + spec = new MethodSpec (kind, this, MethodBuilder, Parameters, ModFlags); + if (TypeManager.IsGenericMethod (MethodBuilder)) Parent.MemberCache.AddGenericMember (MethodBuilder, this); - Parent.MemberCache.AddMember (MethodBuilder, this); + Parent.MemberCache.AddMember (MethodBuilder, spec); return true; } @@ -515,8 +607,8 @@ namespace Mono.CSharp { } } - public class Method : MethodOrOperator { - + public class Method : MethodOrOperator, IGenericMethodDefinition + { /// /// Modifiers allowed in a class declaration /// @@ -543,7 +635,7 @@ namespace Mono.CSharp { FullNamedExpression return_type, Modifiers mod, MemberName name, ParametersCompiled parameters, Attributes attrs) : base (parent, generic, return_type, mod, - parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers, + parent.PartialContainer.Kind == MemberKind.Interface ? AllowedInterfaceModifiers : AllowedModifiers, name, attrs, parameters) { } @@ -756,7 +848,7 @@ namespace Mono.CSharp { Report.Warning (402, 4, Location, "`{0}': an entry point cannot be generic or in a generic type", GetSignatureForError ()); } else { - SetMemberIsUsed (); + SetIsUsed (); RootContext.EntryPoint = this; } } else { @@ -835,6 +927,11 @@ namespace Mono.CSharp { return mi; } + public MethodInfo MakeGenericMethod (Type[] targs) + { + return MethodBuilder.MakeGenericMethod (targs); + } + public void SetPartialDefinition (Method methodDefinition) { caching_flags |= Flags.PartialDefinitionExists; @@ -957,9 +1054,9 @@ namespace Mono.CSharp { if (!ec.IsStatic) base_constructor_group.InstanceExpression = ec.GetThis (loc); - ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group; + var base_ctor = base_constructor_group.BestCandidate; - if (base_ctor == caller_builder){ + if (base_ctor.MetaInfo == caller_builder){ ec.Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder)); } @@ -1095,7 +1192,7 @@ namespace Mono.CSharp { Parent.MemberCache.CheckExistingMembersOverloads (this, ConstructorInfo.ConstructorName, Parameters, Report); - if (Parent.PartialContainer.Kind == Kind.Struct) { + if (Parent.PartialContainer.Kind == MemberKind.Struct) { if (Parameters.Count == 0) { Report.Error (568, Location, "Structs cannot contain explicit parameterless constructors"); @@ -1148,6 +1245,8 @@ namespace Mono.CSharp { ca, CallingConventions, Parameters.GetEmitTypes ()); + spec = new MethodSpec (MemberKind.Constructor, this, ConstructorBuilder, Parameters, ModFlags); + if (Parent.PartialContainer.IsComImport) { if (!IsDefault ()) { Report.Error (669, Location, "`{0}': A class with the ComImport attribute cannot have a user-defined constructor", @@ -1156,7 +1255,7 @@ namespace Mono.CSharp { ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall); } - Parent.MemberCache.AddMember (ConstructorBuilder, this); + Parent.MemberCache.AddMember (ConstructorBuilder, spec); TypeManager.AddMethod (ConstructorBuilder, this); // It's here only to report an error @@ -1197,12 +1296,12 @@ namespace Mono.CSharp { if (block != null) { // If this is a non-static `struct' constructor and doesn't have any // initializer, it must initialize all of the struct's fields. - if ((Parent.PartialContainer.Kind == Kind.Struct) && + if ((Parent.PartialContainer.Kind == MemberKind.Struct) && ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null)) block.AddThisVariable (Parent, Location); if (block != null && (ModFlags & Modifiers.STATIC) == 0){ - if (Parent.PartialContainer.Kind == Kind.Class && Initializer == null) + if (Parent.PartialContainer.Kind == MemberKind.Class && Initializer == null) Initializer = new GeneratedBaseInitializer (Location); if (Initializer != null) { @@ -1337,7 +1436,7 @@ namespace Mono.CSharp { string GetSignatureForError (); bool IsExcluded (); bool IsClsComplianceRequired (); - void SetMemberIsUsed (); + void SetIsUsed (); void EmitExtraSymbolInfo (SourceMethod source); } @@ -1643,7 +1742,7 @@ namespace Mono.CSharp { new MemberName (MetadataName, l), attrs, parameters) { ModFlags &= ~Modifiers.PRIVATE; - ModFlags |= Modifiers.PROTECTED; + ModFlags |= Modifiers.PROTECTED | Modifiers.OVERRIDE; } public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa) @@ -1658,8 +1757,6 @@ namespace Mono.CSharp { protected override bool CheckBase () { - flags |= MethodAttributes.Virtual; - if (!base.CheckBase ()) return false; @@ -1923,8 +2020,7 @@ namespace Mono.CSharp { return true; } - public override bool IsUsed - { + public override bool IsUsed { get { if (IsDummy) return false; @@ -1933,6 +2029,8 @@ namespace Mono.CSharp { } } + public MethodSpec Spec { get; protected set; } + // // Represents header string for documentation comment. // @@ -2226,6 +2324,16 @@ namespace Mono.CSharp { return null; } + public static OpType? GetType (string metadata_name) + { + for (int i = 0; i < names.Length; ++i) { + if (names[i][1] == metadata_name) + return (OpType) i; + } + + return null; + } + public OpType GetMatchingOperator () { switch (OperatorType) {