-
- //
- // Base type container declaration. It exists to handle partial types
- // which share same definition (PartialContainer) but have different
- // resolve scopes
- //
- public abstract class DeclSpace : MemberCore {
- /// <summary>
- /// This points to the actual definition that is being
- /// created with System.Reflection.Emit
- /// </summary>
- public TypeBuilder TypeBuilder;
-
- //
- // This is the namespace in which this typecontainer
- // was declared. We use this to resolve names.
- //
- public NamespaceEntry NamespaceEntry;
-
- public readonly string Basename;
-
- protected Dictionary<string, MemberCore> defined_names;
-
- public TypeContainer PartialContainer;
-
- protected readonly bool is_generic;
- readonly int count_type_params;
- protected TypeParameter[] type_params;
- TypeParameter[] type_param_list;
-
- //
- // Whether we are Generic
- //
- public bool IsGeneric {
- get {
- if (is_generic)
- return true;
- else if (Parent != null)
- return Parent.IsGeneric;
- else
- return false;
- }
- }
-
- static readonly string[] attribute_targets = new string [] { "type" };
-
- public DeclSpace (NamespaceEntry ns, DeclSpace parent, MemberName name,
- Attributes attrs)
- : base (parent, name, attrs)
- {
- NamespaceEntry = ns;
- Basename = name.Basename;
- defined_names = new Dictionary<string, MemberCore> ();
- PartialContainer = null;
- if (name.TypeArguments != null) {
- is_generic = true;
- count_type_params = name.TypeArguments.Count;
- }
- if (parent != null)
- count_type_params += parent.count_type_params;
- }
-
- /// <summary>
- /// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
- /// </summary>
- protected virtual bool AddToContainer (MemberCore symbol, string name)
- {
- MemberCore mc;
- if (!defined_names.TryGetValue (name, out mc)) {
- defined_names.Add (name, symbol);
- return true;
- }
-
- if (((mc.ModFlags | symbol.ModFlags) & Modifiers.COMPILER_GENERATED) != 0)
- return true;
-
- if (symbol.EnableOverloadChecks (mc))
- return true;
-
- InterfaceMemberBase im = mc as InterfaceMemberBase;
- if (im != null && im.IsExplicitImpl)
- return true;
-
- Report.SymbolRelatedToPreviousError (mc);
- if ((mc.ModFlags & Modifiers.PARTIAL) != 0 && (symbol is ClassOrStruct || symbol is Interface)) {
- Error_MissingPartialModifier (symbol);
- return false;
- }
-
- if (this is ModuleContainer) {
- Report.Error (101, symbol.Location,
- "The namespace `{0}' already contains a definition for `{1}'",
- ((DeclSpace)symbol).NamespaceEntry.GetSignatureForError (), symbol.MemberName.Name);
- } else if (symbol is TypeParameter) {
- Report.Error (692, symbol.Location,
- "Duplicate type parameter `{0}'", symbol.GetSignatureForError ());
- } else {
- Report.Error (102, symbol.Location,
- "The type `{0}' already contains a definition for `{1}'",
- GetSignatureForError (), symbol.MemberName.Name);
- }
-
- return false;
- }
-
- protected void RemoveFromContainer (string name)
- {
- defined_names.Remove (name);
- }
-
- /// <summary>
- /// Returns the MemberCore associated with a given name in the declaration
- /// space. It doesn't return method based symbols !!
- /// </summary>
- ///
- public MemberCore GetDefinition (string name)
- {
- MemberCore mc = null;
- defined_names.TryGetValue (name, out mc);
- return mc;
- }
-
- //
- // root_types contains all the types. All TopLevel types
- // hence have a parent that points to `root_types', that is
- // why there is a non-obvious test down here.
- //
- public bool IsTopLevel {
- get { return (Parent != null && Parent.Parent == null); }
- }
-
- public virtual bool IsUnmanagedType ()
- {
- return false;
- }
-
- protected abstract TypeAttributes TypeAttr { get; }
-
- /// <remarks>
- /// Should be overriten by the appropriate declaration space
- /// </remarks>
- public abstract void DefineType ();
-
- 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 GetDocCommentName ()
- {
- return DocCommentHeader + Name;
- }
-
- public override string GetSignatureForError ()
- {
- return MemberName.GetSignatureForError ();
- }
-
- TypeParameter[] initialize_type_params ()
- {
- if (type_param_list != null)
- return type_param_list;
-
- DeclSpace the_parent = Parent;
- if (this is GenericMethod)
- the_parent = null;
-
- var list = new List<TypeParameter> ();
- if (the_parent != null && the_parent.IsGeneric) {
- // FIXME: move generics info out of DeclSpace
- TypeParameter[] parent_params = the_parent.TypeParameters;
- list.AddRange (parent_params);
- }
-
- int count = type_params != null ? type_params.Length : 0;
- for (int i = 0; i < count; i++) {
- TypeParameter param = type_params [i];
- list.Add (param);
- if (Parent.CurrentTypeParameters != null) {
- foreach (TypeParameter tp in Parent.CurrentTypeParameters) {
- if (tp.Name != param.Name)
- continue;
-
- Report.SymbolRelatedToPreviousError (tp.Location, null);
- Report.Warning (693, 3, param.Location,
- "Type parameter `{0}' has the same name as the type parameter from outer type `{1}'",
- param.Name, Parent.GetSignatureForError ());
- }
- }
- }
-
- type_param_list = new TypeParameter [list.Count];
- list.CopyTo (type_param_list, 0);
- return type_param_list;
- }
-
- public virtual void SetParameterInfo (List<Constraints> constraints_list)
- {
- if (!is_generic) {
- if (constraints_list != null) {
- Report.Error (
- 80, Location, "Constraints are not allowed " +
- "on non-generic declarations");
- }
-
- return;
- }
-
- TypeParameterName[] names = MemberName.TypeArguments.GetDeclarations ();
- type_params = new TypeParameter [names.Length];
-
- //
- // Register all the names
- //
- for (int i = 0; i < type_params.Length; i++) {
- TypeParameterName name = names [i];
-
- Constraints constraints = null;
- if (constraints_list != null) {
- int total = constraints_list.Count;
- for (int ii = 0; ii < total; ++ii) {
- Constraints constraints_at = (Constraints)constraints_list[ii];
- // TODO: it is used by iterators only
- if (constraints_at == null) {
- constraints_list.RemoveAt (ii);
- --total;
- continue;
- }
- if (constraints_at.TypeParameter.Value == name.Name) {
- constraints = constraints_at;
- constraints_list.RemoveAt(ii);
- break;
- }
- }
- }
-
- Variance variance = name.Variance;
- if (name.Variance != Variance.None && !(this is Delegate || this is Interface)) {
- Report.Error (1960, name.Location, "Variant type parameters can only be used with interfaces and delegates");
- variance = Variance.None;
- }
-
- type_params [i] = new TypeParameter (
- Parent, i, new MemberName (name.Name, Location), constraints, name.OptAttributes, variance);
-
- AddToContainer (type_params [i], name.Name);
- }
-
- if (constraints_list != null && constraints_list.Count > 0) {
- foreach (Constraints constraint in constraints_list) {
- Report.Error(699, constraint.Location, "`{0}': A constraint references nonexistent type parameter `{1}'",
- GetSignatureForError (), constraint.TypeParameter.Value);
- }
- }
- }
-
- protected TypeParameter[] TypeParameters {
- get {
- if (!IsGeneric)
- throw new InvalidOperationException ();
- if ((PartialContainer != null) && (PartialContainer != this))
- return PartialContainer.TypeParameters;
- if (type_param_list == null)
- initialize_type_params ();
-
- return type_param_list;
- }
- }
-
- public int CountTypeParameters {
- get {
- return count_type_params;
- }
- }
-
- public override string[] ValidAttributeTargets {
- get { return attribute_targets; }
- }
-
- protected override bool VerifyClsCompliance ()
- {
- if (!base.VerifyClsCompliance ()) {
- return false;
- }
-
- if (type_params != null) {
- foreach (TypeParameter tp in type_params) {
- tp.VerifyClsCompliance ();
- }
- }
-
- return true;
- }
- }