X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fclass.cs;h=980b6858a1c92377bcd1e881dbe5201bc19f59ff;hb=a651e64e7518044338d18ea58952d2ed7ca6f5bd;hp=390a16b2b7ba8cecb4468a7e76e7376b24394390;hpb=c4274ee9e8472a5893632c9918098080a623c78f;p=mono.git diff --git a/mcs/mcs/class.cs b/mcs/mcs/class.cs index 390a16b2b7b..980b6858a1c 100644 --- a/mcs/mcs/class.cs +++ b/mcs/mcs/class.cs @@ -154,6 +154,46 @@ namespace Mono.CSharp { } } + // + // Different context is needed when resolving type container base + // types. Type names come from the parent scope but type parameter + // names from the container scope. + // + struct BaseContext : IResolveContext + { + TypeContainer tc; + + public BaseContext (TypeContainer tc) + { + this.tc = tc; + } + + #region IResolveContext Members + + public DeclSpace DeclContainer { + get { return tc.Parent; } + } + + public bool IsInObsoleteScope { + get { return tc.IsInObsoleteScope; } + } + + public bool IsInUnsafeScope { + get { return tc.IsInUnsafeScope; } + } + + public FullNamedExpression LookupNamespaceOrType (string name, Location loc, bool ignore_cs0104) + { + return tc.Parent.LookupNamespaceOrType (name, loc, ignore_cs0104); + } + + public DeclSpace GenericDeclContainer { + get { return tc.GenericDeclContainer; } + } + + #endregion + } + [Flags] enum CachedMethods { @@ -733,33 +773,6 @@ namespace Mono.CSharp { } } - // - // Emits the instance field initializers - // - public bool EmitFieldInitializers (EmitContext ec) - { - if (partial_parts != null) { - foreach (TypeContainer part in partial_parts) - part.EmitFieldInitializers (ec); - } - - ArrayList fields; - - if (ec.IsStatic){ - fields = initialized_static_fields; - } else { - fields = initialized_fields; - } - - if (fields == null) - return true; - - foreach (FieldInitializer f in fields) { - f.EmitStatement (ec); - } - return true; - } - public override string DocComment { get { return comment; @@ -809,6 +822,7 @@ namespace Mono.CSharp { int count = type_bases.Count; TypeExpr [] ifaces = null; + IResolveContext base_context = new BaseContext (this); for (int i = 0, j = 0; i < count; i++){ FullNamedExpression fne = (FullNamedExpression) type_bases [i]; @@ -817,12 +831,16 @@ namespace Mono.CSharp { // it does ObsoleteAttribute and constraint checks which require // base type to be set // - TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (this, false); + TypeExpr fne_resolved = fne.ResolveAsBaseTerminal (base_context, false); if (fne_resolved == null) continue; if (i == 0 && Kind == Kind.Class && !fne_resolved.Type.IsInterface) { - base_class = fne_resolved; + if (fne_resolved is DynamicTypeExpr) + Report.Error (1965, Location, "Class `{0}' cannot derive from the dynamic type", + GetSignatureForError ()); + else + base_class = fne_resolved; continue; } @@ -1289,7 +1307,10 @@ namespace Mono.CSharp { GenericTypeExpr ct = iface as GenericTypeExpr; if (ct != null) { - if (!ct.CheckConstraints (this) || !ct.VerifyVariantTypeParameters ()) + // TODO: passing `this' is wrong, should be base type iface instead + TypeManager.CheckTypeVariance (ct.Type, Variance.Covariant, this); + + if (!ct.CheckConstraints (this)) return false; } } @@ -2905,6 +2926,9 @@ namespace Mono.CSharp { } public sealed class Struct : ClassOrStruct { + + bool is_unmanaged, has_unmanaged_check_done; + // // Modifiers allowed in a struct declaration // @@ -2964,6 +2988,11 @@ namespace Mono.CSharp { if (requires_delayed_unmanagedtype_check) return true; + if (has_unmanaged_check_done) + return is_unmanaged; + + has_unmanaged_check_done = true; + foreach (FieldBase f in fields) { if ((f.ModFlags & Modifiers.STATIC) != 0) continue; @@ -2972,6 +3001,7 @@ namespace Mono.CSharp { // struct S { S* s; } Type mt = f.MemberType; if (mt == null) { + has_unmanaged_check_done = false; requires_delayed_unmanagedtype_check = true; return true; } @@ -2988,6 +3018,7 @@ namespace Mono.CSharp { return false; } + is_unmanaged = true; return true; } @@ -3444,6 +3475,11 @@ namespace Mono.CSharp { if (!IsInterface && (base_method.IsVirtual || base_method.IsAbstract)) { Report.Warning (114, 2, Location, "`{0}' hides inherited member `{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (), TypeManager.CSharpSignature (base_method)); + if (base_method.IsAbstract){ + Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'", + GetSignatureForError (), TypeManager.CSharpSignature (base_method)); + ok = false; + } } else { Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", GetSignatureForError (), TypeManager.CSharpSignature (base_method)); @@ -3548,6 +3584,10 @@ namespace Mono.CSharp { bool error = false; for (int i = 0; i < parameters.Count; ++i) { Parameter p = parameters [i]; + + if (p.HasDefaultValue && (IsExplicitImpl || this is Operator || (this is Indexer && parameters.Count == 1))) + p.Warning_UselessOptionalParameter (); + if (p.CheckAccessibility (this)) continue; @@ -3823,11 +3863,14 @@ namespace Mono.CSharp { if ((ModFlags & Modifiers.PARTIAL) != 0) { for (int i = 0; i < Parameters.Count; ++i) { - if (Parameters.FixedParameters[i].ModFlags == Parameter.Modifier.OUT) { + IParameterData p = Parameters.FixedParameters [i]; + if (p.ModFlags == Parameter.Modifier.OUT) { Report.Error (752, Location, "`{0}': A partial method parameters cannot use `out' modifier", GetSignatureForError ()); - break; } + + if (p.HasDefaultValue && IsPartialImplementation) + ((Parameter) p).Warning_UselessOptionalParameter (); } } } @@ -3850,6 +3893,11 @@ namespace Mono.CSharp { if ((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0) PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (MethodBuilder); + if (TypeManager.IsDynamicType (ReturnType)) { + return_attributes = new ReturnParameter (MethodBuilder, Location); + return_attributes.EmitPredefined (PredefinedAttributes.Get.Dynamic, Location); + } + if (OptAttributes != null) OptAttributes.Emit (); @@ -4046,6 +4094,8 @@ namespace Mono.CSharp { const int AllowedInterfaceModifiers = Modifiers.NEW | Modifiers.UNSAFE; + Method partialMethodImplementation; + public Method (DeclSpace parent, GenericMethod generic, FullNamedExpression return_type, int mod, MemberName name, ParametersCompiled parameters, Attributes attrs) @@ -4188,6 +4238,9 @@ namespace Mono.CSharp { if (!base.Define ()) return false; + if (partialMethodImplementation != null && IsPartialDefinition) + MethodBuilder = partialMethodImplementation.MethodBuilder; + if (RootContext.StdLib && TypeManager.IsSpecialType (ReturnType)) { Error1599 (Location, ReturnType); return false; @@ -4204,7 +4257,7 @@ namespace Mono.CSharp { return true; if (Parameters.HasExtensionMethodType) { - if (Parent.IsStaticClass && !Parent.IsGeneric) { + if (Parent.PartialContainer.IsStaticClass && !Parent.IsGeneric) { if (!Parent.IsTopLevel) Report.Error (1109, Location, "`{0}': Extension methods cannot be defined in a nested class", GetSignatureForError ()); @@ -4264,17 +4317,16 @@ namespace Mono.CSharp { Report.Debug (64, "METHOD EMIT", this, MethodBuilder, Location, Block, MethodData); if (IsPartialDefinition) { // - // Do attribute checks only when partial implementation does not exist + // Use partial method implementation builder for partial method declaration attributes // - if (MethodBuilder == null) - base.Emit (); - - return; - } - - if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) + if (partialMethodImplementation != null) { + MethodBuilder = partialMethodImplementation.MethodBuilder; + return; + } + } else if ((ModFlags & Modifiers.PARTIAL) != 0 && (caching_flags & Flags.PartialDefinitionExists) == 0) { Report.Error (759, Location, "A partial method `{0}' implementation is missing a partial method declaration", GetSignatureForError ()); + } base.Emit (); @@ -4322,7 +4374,12 @@ namespace Mono.CSharp { public void SetPartialDefinition (Method methodDefinition) { caching_flags |= Flags.PartialDefinitionExists; - methodDefinition.MethodBuilder = MethodBuilder; + methodDefinition.partialMethodImplementation = this; + + for (int i = 0; i < methodDefinition.Parameters.Count; ++i ) { + Parameters [i].DefaultValue = methodDefinition.Parameters [i].DefaultValue; + } + if (methodDefinition.attributes == null) return; @@ -4350,16 +4407,16 @@ namespace Mono.CSharp { public abstract class ConstructorInitializer : ExpressionStatement { - ArrayList argument_list; + Arguments argument_list; MethodGroupExpr base_constructor_group; - - public ConstructorInitializer (ArrayList argument_list, Location loc) + + public ConstructorInitializer (Arguments argument_list, Location loc) { this.argument_list = argument_list; this.loc = loc; } - public ArrayList Arguments { + public Arguments Arguments { get { return argument_list; } @@ -4370,24 +4427,26 @@ namespace Mono.CSharp { throw new NotSupportedException ("ET"); } - public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec) + public ExpressionStatement Resolve (ConstructorBuilder caller_builder, EmitContext ec) { - if (argument_list != null){ - foreach (Argument a in argument_list){ - if (!a.Resolve (ec, loc)) - return false; + if (argument_list != null) { + bool dynamic; + argument_list.Resolve (ec, out dynamic); + if (dynamic) { + SimpleName ctor = new SimpleName (ConstructorBuilder.ConstructorName, loc); + return new DynamicInvocation (ctor, argument_list, loc).Resolve (ec) as ExpressionStatement; } } if (this is ConstructorBaseInitializer) { if (ec.ContainerType.BaseType == null) - return true; + return this; type = ec.ContainerType.BaseType; if (TypeManager.IsStruct (ec.ContainerType)) { Report.Error (522, loc, "`{0}': Struct constructors cannot call base constructors", TypeManager.CSharpSignature (caller_builder)); - return false; + return this; } } else { // @@ -4397,7 +4456,7 @@ namespace Mono.CSharp { // struct D { public D (int a) : this () {} // if (TypeManager.IsStruct (ec.ContainerType) && argument_list == null) - return true; + return this; type = ec.ContainerType; } @@ -4408,13 +4467,13 @@ namespace Mono.CSharp { loc) as MethodGroupExpr; if (base_constructor_group == null) - return false; + return this; base_constructor_group = base_constructor_group.OverloadResolve ( ec, ref argument_list, false, loc); if (base_constructor_group == null) - return false; + return this; ConstructorInfo base_ctor = (ConstructorInfo)base_constructor_group; @@ -4422,7 +4481,7 @@ namespace Mono.CSharp { Report.Error (516, loc, "Constructor `{0}' cannot call itself", TypeManager.CSharpSignature (caller_builder)); } - return true; + return this; } public override Expression DoResolve (EmitContext ec) @@ -4450,7 +4509,7 @@ namespace Mono.CSharp { } public class ConstructorBaseInitializer : ConstructorInitializer { - public ConstructorBaseInitializer (ArrayList argument_list, Location l) : + public ConstructorBaseInitializer (Arguments argument_list, Location l) : base (argument_list, l) { } @@ -4464,7 +4523,7 @@ namespace Mono.CSharp { } public class ConstructorThisInitializer : ConstructorInitializer { - public ConstructorThisInitializer (ArrayList argument_list, Location l) : + public ConstructorThisInitializer (Arguments argument_list, Location l) : base (argument_list, l) { } @@ -4678,9 +4737,9 @@ namespace Mono.CSharp { // if (Initializer != null) { ec.IsStatic = true; - Initializer.Resolve (ConstructorBuilder, ec); + ExpressionStatement expr = Initializer.Resolve (ConstructorBuilder, ec); ec.IsStatic = false; - block.AddScopeStatement (new StatementExpression (Initializer)); + block.AddScopeStatement (new StatementExpression (expr)); } } } @@ -5047,7 +5106,8 @@ namespace Mono.CSharp { if (builder == null) { builder = container.TypeBuilder.DefineMethod ( method_name, flags, method.CallingConventions, - method.ReturnType, param.GetEmitTypes ()); + TypeManager.TypeToReflectionType (method.ReturnType), + param.GetEmitTypes ()); return; } @@ -5164,7 +5224,7 @@ namespace Mono.CSharp { // TODO: Should use AddScopeStatement or something else which emits correct // debugger scope // - finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new ArrayList (0)))); + finaly_block.AddStatement (new StatementExpression (new Invocation (method_expr, new Arguments (0)))); new_block.AddStatement (new TryFinally (try_block, finaly_block, Location)); block = new_block; @@ -5276,11 +5336,9 @@ namespace Mono.CSharp { "accessible than field `" + GetSignatureForError () + "'"); } } -#if GMCS_SOURCE - if (MemberType.IsGenericParameter && (MemberType.GenericParameterAttributes & GenericParameterAttributes.Contravariant) != 0) { - Report.Error (-33, Location, "Contravariant type parameters can only be used in input positions"); - } -#endif + + Variance variance = this is Event ? Variance.Contravariant : Variance.Covariant; + TypeManager.CheckTypeVariance (MemberType, variance, this); } protected bool IsTypePermitted () @@ -5406,7 +5464,7 @@ namespace Mono.CSharp { return true; } - if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) { + if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0) { Report.SymbolRelatedToPreviousError (conflict_symbol); Report.Warning (108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended", GetSignatureForError (), TypeManager.GetFullNameSignature (conflict_symbol)); @@ -5439,6 +5497,9 @@ namespace Mono.CSharp { public override void Emit () { + if (TypeManager.IsDynamicType (member_type)) + PredefinedAttributes.Get.Dynamic.EmitAttribute (FieldBuilder); + if ((ModFlags & Modifiers.COMPILER_GENERATED) != 0 && !Parent.IsCompilerGenerated) PredefinedAttributes.Get.CompilerGenerated.EmitAttribute (FieldBuilder); @@ -5748,7 +5809,8 @@ namespace Mono.CSharp { MemberType == TypeManager.sbyte_type || MemberType == TypeManager.byte_type || MemberType == TypeManager.short_type || MemberType == TypeManager.ushort_type || MemberType == TypeManager.int32_type || MemberType == TypeManager.uint32_type || - MemberType == TypeManager.float_type) + MemberType == TypeManager.float_type || + MemberType == TypeManager.intptr_type || MemberType == TypeManager.uintptr_type) return true; if (TypeManager.IsEnumType (MemberType)) @@ -6030,6 +6092,11 @@ namespace Mono.CSharp { if (((ModFlags & Modifiers.DEBUGGER_HIDDEN) != 0)) PredefinedAttributes.Get.DebuggerHidden.EmitAttribute (method_data.MethodBuilder); + if (TypeManager.IsDynamicType (ReturnType)) { + return_attributes = new ReturnParameter (method_data.MethodBuilder, Location); + return_attributes.EmitPredefined (PredefinedAttributes.Get.Dynamic, Location); + } + if (OptAttributes != null) OptAttributes.Emit (); @@ -6196,7 +6263,7 @@ namespace Mono.CSharp { public override MethodBuilder Define (DeclSpace parent) { - parameters.Resolve (ResolveContext); + parameters.Resolve (this); base.Define (parent); @@ -6538,8 +6605,13 @@ namespace Mono.CSharp { // case, we do not actually emit the ".property", so there is nowhere to // put the attribute // - if (PropertyBuilder != null && OptAttributes != null) - OptAttributes.Emit (); + if (PropertyBuilder != null) { + if (OptAttributes != null) + OptAttributes.Emit (); + + if (TypeManager.IsDynamicType (member_type)) + PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder); + } if (!Get.IsDummy) Get.Emit (Parent); @@ -6913,7 +6985,7 @@ namespace Mono.CSharp { sealed class AddDelegateMethod: AEventPropertyAccessor { public AddDelegateMethod (Event method, Accessor accessor): - base (method, accessor, "add_") + base (method, accessor, AddPrefix) { } } @@ -6921,7 +6993,7 @@ namespace Mono.CSharp { sealed class RemoveDelegateMethod: AEventPropertyAccessor { public RemoveDelegateMethod (Event method, Accessor accessor): - base (method, accessor, "remove_") + base (method, accessor, RemovePrefix) { } } @@ -6995,7 +7067,7 @@ namespace Mono.CSharp { sealed class AddDelegateMethod: EventFieldAccessor { public AddDelegateMethod (Event method): - base (method, "add_") + base (method, AddPrefix) { } @@ -7007,7 +7079,7 @@ namespace Mono.CSharp { sealed class RemoveDelegateMethod: EventFieldAccessor { public RemoveDelegateMethod (Event method): - base (method, "remove_") + base (method, RemovePrefix) { } @@ -7058,14 +7130,16 @@ namespace Mono.CSharp { GetSignatureForError ()); } - if (!HasBackingField) + if (!HasBackingField) { + SetMemberIsUsed (); return true; + } // FIXME: We are unable to detect whether generic event is used because // we are using FieldExpr instead of EventExpr for event access in that // case. When this issue will be fixed this hack can be removed. if (TypeManager.IsGenericType (MemberType)) - SetMemberIsUsed(); + SetMemberIsUsed (); if (Add.IsInterfaceImplementation) SetMemberIsUsed (); @@ -7107,6 +7181,9 @@ namespace Mono.CSharp { static readonly string[] attribute_targets = new string [] { "method", "param", "return" }; + public const string AddPrefix = "add_"; + public const string RemovePrefix = "remove_"; + protected AEventAccessor (Event method, string prefix) : base (method, prefix) { @@ -7357,7 +7434,7 @@ namespace Mono.CSharp { public override MethodBuilder Define (DeclSpace parent) { - parameters.Resolve (ResolveContext); + parameters.Resolve (this); return base.Define (parent); } @@ -7690,11 +7767,19 @@ namespace Mono.CSharp { Type first_arg_type_unwrap = first_arg_type; if (TypeManager.IsNullableType (first_arg_type)) - first_arg_type_unwrap = TypeManager.GetTypeArguments (first_arg_type) [0]; + first_arg_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (first_arg_type) [0]); Type return_type_unwrap = return_type; if (TypeManager.IsNullableType (return_type)) - return_type_unwrap = TypeManager.GetTypeArguments (return_type) [0]; + return_type_unwrap = TypeManager.TypeToCoreType (TypeManager.GetTypeArguments (return_type) [0]); + + if (TypeManager.IsDynamicType (return_type) || TypeManager.IsDynamicType (first_arg_type)) { + Report.Error (1964, Location, + "User-defined operator `{0}' cannot convert to or from the dynamic type", + GetSignatureForError ()); + + return false; + } // // Rules for conversion operators