+ public readonly MemberKind Kind;
+ public readonly string Basename;
+
+ protected List<TypeContainer> containers;
+
+ TypeDefinition main_container;
+
+ protected Dictionary<string, MemberCore> defined_names;
+
+ protected bool is_defined;
+
+ public TypeContainer (TypeContainer parent, MemberName name, Attributes attrs, MemberKind kind)
+ : base (parent, name, attrs)
+ {
+ this.Kind = kind;
+ if (name != null)
+ this.Basename = name.Basename;
+
+ defined_names = new Dictionary<string, MemberCore> ();
+ }
+
+ public override TypeSpec CurrentType {
+ get {
+ return null;
+ }
+ }
+
+ public Dictionary<string, MemberCore> DefinedNames {
+ get {
+ return defined_names;
+ }
+ }
+
+ public TypeDefinition PartialContainer {
+ get {
+ return main_container;
+ }
+ protected set {
+ main_container = value;
+ }
+ }
+
+ public IList<TypeContainer> Containers {
+ get {
+ return containers;
+ }
+ }
+
+ //
+ // Any unattached attributes during parsing get added here. User
+ // by FULL_AST mode
+ //
+ public Attributes UnattachedAttributes {
+ get; set;
+ }
+
+ public virtual void AddCompilerGeneratedClass (CompilerGeneratedContainer c)
+ {
+ containers.Add (c);
+ }
+
+ public virtual void AddPartial (TypeDefinition next_part)
+ {
+ MemberCore mc;
+ (PartialContainer ?? this).defined_names.TryGetValue (next_part.Basename, out mc);
+
+ AddPartial (next_part, mc as TypeDefinition);
+ }
+
+ protected void AddPartial (TypeDefinition next_part, TypeDefinition existing)
+ {
+ next_part.ModFlags |= Modifiers.PARTIAL;
+
+ if (existing == null) {
+ AddTypeContainer (next_part);
+ return;
+ }
+
+ if ((existing.ModFlags & Modifiers.PARTIAL) == 0) {
+ if (existing.Kind != next_part.Kind) {
+ AddTypeContainer (next_part);
+ } else {
+ Report.SymbolRelatedToPreviousError (next_part);
+ Error_MissingPartialModifier (existing);
+ }
+
+ return;
+ }
+
+ if (existing.Kind != next_part.Kind) {
+ Report.SymbolRelatedToPreviousError (existing);
+ Report.Error (261, next_part.Location,
+ "Partial declarations of `{0}' must be all classes, all structs or all interfaces",
+ next_part.GetSignatureForError ());
+ }
+
+ if ((existing.ModFlags & Modifiers.AccessibilityMask) != (next_part.ModFlags & Modifiers.AccessibilityMask) &&
+ ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0 &&
+ (next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) == 0)) {
+ Report.SymbolRelatedToPreviousError (existing);
+ Report.Error (262, next_part.Location,
+ "Partial declarations of `{0}' have conflicting accessibility modifiers",
+ next_part.GetSignatureForError ());
+ }
+
+ var tc_names = existing.CurrentTypeParameters;
+ if (tc_names != null) {
+ for (int i = 0; i < tc_names.Count; ++i) {
+ var tp = next_part.MemberName.TypeParameters[i];
+ if (tc_names[i].MemberName.Name != tp.MemberName.Name) {
+ Report.SymbolRelatedToPreviousError (existing.Location, "");
+ Report.Error (264, next_part.Location, "Partial declarations of `{0}' must have the same type parameter names in the same order",
+ next_part.GetSignatureForError ());
+ break;
+ }
+
+ if (tc_names[i].Variance != tp.Variance) {
+ Report.SymbolRelatedToPreviousError (existing.Location, "");
+ Report.Error (1067, next_part.Location, "Partial declarations of `{0}' must have the same type parameter variance modifiers",
+ next_part.GetSignatureForError ());
+ break;
+ }
+ }
+ }
+
+ if ((next_part.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+ existing.ModFlags |= next_part.ModFlags & ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
+ } else if ((existing.ModFlags & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) {
+ existing.ModFlags &= ~(Modifiers.DEFAULT_ACCESS_MODIFER | Modifiers.AccessibilityMask);
+ existing.ModFlags |= next_part.ModFlags;
+ } else {
+ existing.ModFlags |= next_part.ModFlags;
+ }
+
+ existing.Definition.Modifiers = existing.ModFlags;
+
+ if (next_part.attributes != null) {
+ if (existing.attributes == null)
+ existing.attributes = next_part.attributes;
+ else
+ existing.attributes.AddAttributes (next_part.attributes.Attrs);
+ }
+
+ next_part.PartialContainer = existing;
+
+ if (containers == null)
+ containers = new List<TypeContainer> ();
+
+ containers.Add (next_part);
+ }
+
+ public virtual void AddTypeContainer (TypeContainer tc)
+ {
+ containers.Add (tc);
+
+ var tparams = tc.MemberName.TypeParameters;
+ if (tparams != null && tc.PartialContainer != null) {
+ var td = (TypeDefinition) tc;
+ for (int i = 0; i < tparams.Count; ++i) {
+ var tp = tparams[i];
+ if (tp.MemberName == null)
+ continue;
+
+ td.AddNameToContainer (tp, tp.Name);
+ }
+ }
+ }
+
+ public virtual void CloseContainer ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.CloseContainer ();
+ }
+ }
+ }
+
+ public virtual void CreateMetadataName (StringBuilder sb)
+ {
+ if (Parent != null && Parent.MemberName != null)
+ Parent.CreateMetadataName (sb);
+
+ MemberName.CreateMetadataName (sb);
+ }
+
+ public virtual bool CreateContainer ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.CreateContainer ();
+ }
+ }
+
+ return true;
+ }
+
+ public override bool Define ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.Define ();
+ }
+ }
+
+ // Release cache used by parser only
+ if (Module.Evaluator == null) {
+ defined_names = null;
+ } else {
+ defined_names.Clear ();
+ }
+
+ return true;
+ }
+
+ public virtual void PrepareEmit ()
+ {
+ if (containers != null) {
+ foreach (var t in containers) {
+ try {
+ t.PrepareEmit ();
+ } catch (Exception e) {
+ if (MemberName == MemberName.Null)
+ throw;
+
+ throw new InternalErrorException (t, e);
+ }
+ }
+ }
+ }
+
+ public virtual bool DefineContainer ()
+ {
+ if (is_defined)
+ return true;
+
+ is_defined = true;
+
+ DoDefineContainer ();
+
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ try {
+ tc.DefineContainer ();
+ } catch (Exception e) {
+ if (MemberName == MemberName.Null)
+ throw;
+
+ throw new InternalErrorException (tc, e);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ protected virtual void DefineNamespace ()
+ {
+ if (containers != null) {
+ foreach (var tc in containers) {
+ try {
+ tc.DefineNamespace ();
+ } catch (Exception e) {
+ throw new InternalErrorException (tc, e);
+ }
+ }
+ }
+ }
+
+ protected virtual void DoDefineContainer ()
+ {
+ }
+
+ public virtual void EmitContainer ()
+ {
+ if (containers != null) {
+ for (int i = 0; i < containers.Count; ++i)
+ containers[i].EmitContainer ();
+ }
+ }
+
+ protected void Error_MissingPartialModifier (MemberCore type)
+ {
+ Report.Error (260, type.Location,
+ "Missing partial modifier on declaration of type `{0}'. Another partial declaration of this type exists",
+ type.GetSignatureForError ());
+ }
+
+ public override string GetSignatureForDocumentation ()
+ {
+ if (Parent != null && Parent.MemberName != null)
+ return Parent.GetSignatureForDocumentation () + "." + MemberName.GetSignatureForDocumentation ();
+
+ return MemberName.GetSignatureForDocumentation ();
+ }
+
+ public override string GetSignatureForError ()
+ {
+ if (Parent != null && Parent.MemberName != null)
+ return Parent.GetSignatureForError () + "." + MemberName.GetSignatureForError ();
+
+ return MemberName.GetSignatureForError ();
+ }
+
+ public string GetSignatureForMetadata ()
+ {
+#if STATIC
+ if (Parent is TypeDefinition) {
+ return Parent.GetSignatureForMetadata () + "+" + TypeNameParser.Escape (MemberName.Basename);
+ }
+
+ var sb = new StringBuilder ();
+ CreateMetadataName (sb);
+ return sb.ToString ();
+#else
+ throw new NotImplementedException ();
+#endif
+ }
+
+ public virtual void RemoveContainer (TypeContainer cont)
+ {
+ if (containers != null)
+ containers.Remove (cont);
+
+ var tc = Parent == Module ? Module : this;
+ tc.defined_names.Remove (cont.Basename);
+ }
+
+ public virtual void VerifyMembers ()
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers)
+ tc.VerifyMembers ();
+ }
+ }
+
+ public override void WriteDebugSymbol (MonoSymbolFile file)
+ {
+ if (containers != null) {
+ foreach (TypeContainer tc in containers) {
+ tc.WriteDebugSymbol (file);
+ }
+ }
+ }