//
// Copyright 2001 Ximian, Inc (http://www.ximian.com)
// Copyright 2004-2008 Novell, Inc
+// Copyright 2011 Xamarin Inc
//
//
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
#if NET_2_1
using XmlElement = System.Object;
//
// Better name would be DottenName
//
- public class MemberName {
+ [DebuggerDisplay ("{GetSignatureForError()}")]
+ public class MemberName
+ {
+ public static readonly MemberName Null = new MemberName ("");
+
public readonly string Name;
- public TypeArguments TypeArguments;
+ public TypeParameters TypeParameters;
+ public readonly FullNamedExpression ExplicitInterface;
+ public readonly Location Location;
public readonly MemberName Left;
- public readonly Location Location;
- public static readonly MemberName Null = new MemberName ("");
+ public MemberName (string name)
+ : this (name, Location.Null)
+ { }
- bool is_double_colon;
+ public MemberName (string name, Location loc)
+ : this (null, name, loc)
+ { }
- private MemberName (MemberName left, string name, bool is_double_colon,
- Location loc)
+ public MemberName (string name, TypeParameters tparams, Location loc)
{
this.Name = name;
this.Location = loc;
- this.is_double_colon = is_double_colon;
- this.Left = left;
+
+ this.TypeParameters = tparams;
}
- private MemberName (MemberName left, string name, bool is_double_colon,
- TypeArguments args, Location loc)
- : this (left, name, is_double_colon, loc)
+ public MemberName (string name, TypeParameters tparams, FullNamedExpression explicitInterface, Location loc)
+ : this (name, tparams, loc)
{
- if (args != null && args.Count > 0)
- this.TypeArguments = args;
+ this.ExplicitInterface = explicitInterface;
}
- public MemberName (string name)
- : this (name, Location.Null)
- { }
-
- public MemberName (string name, Location loc)
- : this (null, name, false, loc)
- { }
-
- public MemberName (string name, TypeArguments args, Location loc)
- : this (null, name, false, args, loc)
- { }
-
- public MemberName (MemberName left, string name)
- : this (left, name, left != null ? left.Location : Location.Null)
- { }
-
public MemberName (MemberName left, string name, Location loc)
- : this (left, name, false, loc)
- { }
-
- public MemberName (MemberName left, string name, TypeArguments args, Location loc)
- : this (left, name, false, args, loc)
- { }
-
- public MemberName (string alias, string name, TypeArguments args, Location loc)
- : this (new MemberName (alias, loc), name, true, args, loc)
- { }
-
- public MemberName (MemberName left, MemberName right)
- : this (left, right, right.Location)
- { }
+ {
+ this.Name = name;
+ this.Location = loc;
+ this.Left = left;
+ }
- public MemberName (MemberName left, MemberName right, Location loc)
- : this (null, right.Name, false, right.TypeArguments, loc)
+ public MemberName (MemberName left, string name, FullNamedExpression explicitInterface, Location loc)
+ : this (left, name, loc)
{
- if (right.is_double_colon)
- throw new InternalErrorException ("Cannot append double_colon member name");
- this.Left = (right.Left == null) ? left : new MemberName (left, right.Left);
+ this.ExplicitInterface = explicitInterface;
}
- // TODO: Remove
- public string GetName ()
+ public MemberName (MemberName left, MemberName right)
{
- return GetName (false);
+ this.Name = right.Name;
+ this.Location = right.Location;
+ this.TypeParameters = right.TypeParameters;
+ this.Left = left;
}
public int Arity {
get {
- return TypeArguments == null ? 0 : TypeArguments.Count;
+ return TypeParameters == null ? 0 : TypeParameters.Count;
}
}
public bool IsGeneric {
get {
- if (TypeArguments != null)
- return true;
- else if (Left != null)
- return Left.IsGeneric;
- else
- return false;
+ return TypeParameters != null;
}
}
- public string GetName (bool is_generic)
- {
- string name = is_generic ? Basename : Name;
- if (Left != null)
- return Left.GetName (is_generic) + (is_double_colon ? "::" : ".") + name;
-
- return name;
+ public string Basename {
+ get {
+ if (TypeParameters != null)
+ return MakeName (Name, TypeParameters);
+ return Name;
+ }
}
- public ATypeNameExpression GetTypeExpression ()
+ public void CreateMetadataName (StringBuilder sb)
{
- if (Left == null) {
- if (TypeArguments != null)
- return new SimpleName (Name, TypeArguments, Location);
-
- return new SimpleName (Name, Location);
- }
+ if (Left != null)
+ Left.CreateMetadataName (sb);
- if (is_double_colon) {
- if (Left.Left != null)
- throw new InternalErrorException ("The left side of a :: should be an identifier");
- return new QualifiedAliasMember (Left.Name, Name, TypeArguments, Location);
+ if (sb.Length != 0) {
+ sb.Append (".");
}
- Expression lexpr = Left.GetTypeExpression ();
- return new MemberAccess (lexpr, Name, TypeArguments, Location);
+ sb.Append (Basename);
}
- public MemberName Clone ()
+ public string GetSignatureForDocumentation ()
{
- MemberName left_clone = Left == null ? null : Left.Clone ();
- return new MemberName (left_clone, Name, is_double_colon, TypeArguments, Location);
- }
+ var s = Basename;
- public string Basename {
- get {
- if (TypeArguments != null)
- return MakeName (Name, TypeArguments);
- return Name;
- }
+ if (ExplicitInterface != null)
+ s = ExplicitInterface.GetSignatureForError () + "." + s;
+
+ if (Left == null)
+ return s;
+
+ return Left.GetSignatureForDocumentation () + "." + s;
}
public string GetSignatureForError ()
{
- string append = TypeArguments == null ? "" : "<" + TypeArguments.GetSignatureForError () + ">";
+ string s = TypeParameters == null ? null : "<" + TypeParameters.GetSignatureForError () + ">";
+ s = Name + s;
+
+ if (ExplicitInterface != null)
+ s = ExplicitInterface.GetSignatureForError () + "." + s;
+
if (Left == null)
- return Name + append;
- string connect = is_double_colon ? "::" : ".";
- return Left.GetSignatureForError () + connect + Name + append;
+ return s;
+
+ return Left.GetSignatureForError () + "." + s;
}
public override bool Equals (object other)
return true;
if (other == null || Name != other.Name)
return false;
- if (is_double_colon != other.is_double_colon)
- return false;
- if ((TypeArguments != null) &&
- (other.TypeArguments == null || TypeArguments.Count != other.TypeArguments.Count))
+ if ((TypeParameters != null) &&
+ (other.TypeParameters == null || TypeParameters.Count != other.TypeParameters.Count))
return false;
- if ((TypeArguments == null) && (other.TypeArguments != null))
+ if ((TypeParameters == null) && (other.TypeParameters != null))
return false;
if (Left == null)
int hash = Name.GetHashCode ();
for (MemberName n = Left; n != null; n = n.Left)
hash ^= n.Name.GetHashCode ();
- if (is_double_colon)
- hash ^= 0xbadc01d;
- if (TypeArguments != null)
- hash ^= TypeArguments.Count << 5;
+ if (TypeParameters != null)
+ hash ^= TypeParameters.Count << 5;
return hash & 0x7FFFFFFF;
}
- public int CountTypeArguments {
- get {
- if (TypeArguments != null)
- return TypeArguments.Count;
- else if (Left != null)
- return Left.CountTypeArguments;
- else
- return 0;
- }
- }
-
- public static string MakeName (string name, TypeArguments args)
+ public static string MakeName (string name, TypeParameters args)
{
if (args == null)
return name;
[System.Diagnostics.DebuggerDisplay ("{GetSignatureForError()}")]
public abstract class MemberCore : Attributable, IMemberContext, IMemberDefinition
{
- /// <summary>
- /// Public name
- /// </summary>
-
- protected string cached_name;
- // TODO: Remove in favor of MemberName
- public string Name {
- get {
- if (cached_name == null)
- cached_name = MemberName.GetName (!(this is GenericMethod) && !(this is Method));
- return cached_name;
- }
- }
-
string IMemberDefinition.Name {
get {
return member_name.Name;
IsAssigned = 1 << 12, // Field is assigned
HasExplicitLayout = 1 << 13,
PartialDefinitionExists = 1 << 14, // Set when corresponding partial method definition exists
- HasStructLayout = 1 << 15 // Has StructLayoutAttribute
+ HasStructLayout = 1 << 15, // Has StructLayoutAttribute
+ HasInstanceConstructor = 1 << 16,
+ HasUserOperators = 1 << 17
}
/// <summary>
/// </summary>
internal Flags caching_flags;
- public MemberCore (DeclSpace parent, MemberName name, Attributes attrs)
+ public MemberCore (TypeContainer parent, MemberName name, Attributes attrs)
{
- this.Parent = parent as TypeContainer;
+ this.Parent = parent;
member_name = name;
caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
AddAttributes (attrs, this);
protected virtual void SetMemberName (MemberName new_name)
{
member_name = new_name;
- cached_name = null;
+ }
+
+ public virtual void Accept (StructuralVisitor visitor)
+ {
+ visitor.Visit (this);
}
protected bool CheckAbstractAndExtern (bool has_block)
//
public virtual string GetSignatureForError ()
{
- if (Parent == null || Parent.Parent == null)
+ var parent = Parent.GetSignatureForError ();
+ if (parent == null)
return member_name.GetSignatureForError ();
- return Parent.GetSignatureForError () + "." + member_name.GetSignatureForError ();
+ return parent + "." + member_name.GetSignatureForError ();
}
/// <summary>
caching_flags |= Flags.IsAssigned;
}
+ public void SetConstraints (List<Constraints> constraints_list)
+ {
+ var tparams = member_name.TypeParameters;
+ if (tparams == null) {
+ Report.Error (80, Location, "Constraints are not allowed on non-generic declarations");
+ return;
+ }
+
+ foreach (var c in constraints_list) {
+ var tp = tparams.Find (c.TypeParameter.Value);
+ if (tp == null) {
+ Report.Error (699, c.Location, "`{0}': A constraint references nonexistent type parameter `{1}'",
+ GetSignatureForError (), c.TypeParameter.Value);
+ continue;
+ }
+
+ tp.Constraints = c;
+ }
+ }
+
/// <summary>
/// Returns instance of ObsoleteAttribute for this MemberCore
/// </summary>
case Modifiers.PROTECTED:
if (al == Modifiers.PROTECTED) {
- same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent);
+ same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition (p_parent);
break;
}
// When type is private and any of its parents derives from
// protected type then the type is accessible
//
- while (mc.Parent != null) {
- if (mc.Parent.IsBaseTypeDefinition (p_parent))
+ while (mc.Parent != null && mc.Parent.PartialContainer != null) {
+ if (mc.Parent.PartialContainer.IsBaseTypeDefinition (p_parent))
same_access_restrictions = true;
mc = mc.Parent;
}
if (al == Modifiers.INTERNAL)
same_access_restrictions = p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly);
else if (al == (Modifiers.PROTECTED | Modifiers.INTERNAL))
- same_access_restrictions = mc.Parent.IsBaseTypeDefinition (p_parent) && p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly);
+ same_access_restrictions = mc.Parent.PartialContainer.IsBaseTypeDefinition (p_parent) && p.MemberDefinition.IsInternalAsPublic (mc.Module.DeclaringAssembly);
else
goto case Modifiers.PROTECTED;
var decl = mc.Parent;
do {
same_access_restrictions = decl.CurrentType == p_parent;
- } while (!same_access_restrictions && !decl.IsTopLevel && (decl = decl.Parent) != null);
+ } while (!same_access_restrictions && !decl.PartialContainer.IsTopLevel && (decl = decl.Parent) != null);
}
break;
return true;
}
- if (Parent.PartialContainer.IsClsComplianceRequired ()) {
+ if (Parent.IsClsComplianceRequired ()) {
caching_flags |= Flags.ClsCompliant;
return true;
}
public bool IsExposedFromAssembly ()
{
if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
- return false;
+ return this is NamespaceContainer;
- DeclSpace parentContainer = Parent.PartialContainer;
- while (parentContainer != null && parentContainer.ModFlags != 0) {
+ var parentContainer = Parent.PartialContainer;
+ while (parentContainer != null) {
if ((parentContainer.ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
return false;
- parentContainer = parentContainer.Parent;
+
+ parentContainer = parentContainer.Parent.PartialContainer;
}
+
return true;
}
- public virtual IList<MethodSpec> LookupExtensionMethod (TypeSpec extensionType, string name, int arity, ref NamespaceEntry scope)
+ //
+ // Does extension methods look up to find a method which matches name and extensionType.
+ // Search starts from this namespace and continues hierarchically up to top level.
+ //
+ public ExtensionMethodCandidates LookupExtensionMethod (TypeSpec extensionType, string name, int arity)
{
- return Parent.LookupExtensionMethod (extensionType, name, arity, ref scope);
+ var m = Parent;
+ do {
+ var ns = m as NamespaceContainer;
+ if (ns != null)
+ return ns.LookupExtensionMethod (this, extensionType, name, arity, ns, 0);
+
+ m = m.Parent;
+ } while (m != null);
+
+ return null;
}
public virtual FullNamedExpression LookupNamespaceAlias (string name)
{
- return Parent.NamespaceEntry.LookupNamespaceAlias (name);
+ return Parent.LookupNamespaceAlias (name);
}
- public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, Location loc, bool ignore_cs0104)
+ public virtual FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
{
- return Parent.LookupNamespaceOrType (name, arity, loc, ignore_cs0104);
+ return Parent.LookupNamespaceOrType (name, arity, mode, loc);
}
/// <summary>
}
if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0) {
- if (Parent.Kind == MemberKind.Interface && Parent.IsClsComplianceRequired ()) {
+ if (Parent is Interface && Parent.IsClsComplianceRequired ()) {
Report.Warning (3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
} else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired ()) {
Report.Warning (3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
return false;
}
- if (Parent.Parent != null && !Parent.IsClsComplianceRequired ()) {
+ if (Parent.Kind != MemberKind.Namespace && Parent.Kind != 0 && !Parent.IsClsComplianceRequired ()) {
Attribute a = OptAttributes.Search (Module.PredefinedAttributes.CLSCompliant);
Report.Warning (3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
GetSignatureForError (), Parent.GetSignatureForError ());
if (!IsExposedFromAssembly ())
return false;
- if (!Parent.PartialContainer.IsClsComplianceRequired ())
+ if (!Parent.IsClsComplianceRequired ())
return false;
}
if (member_name.Name [0] == '_') {
- Report.Warning (3008, 1, Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError () );
+ Warning_IdentifierNotCompliant ();
}
+ if (member_name.TypeParameters != null)
+ member_name.TypeParameters.VerifyClsCompliance ();
+
return true;
}
- //
- // Raised (and passed an XmlElement that contains the comment)
- // when GenerateDocComment is writing documentation expectedly.
- //
- internal virtual void OnGenerateDocComment (XmlElement intermediateNode)
+ protected void Warning_IdentifierNotCompliant ()
{
+ Report.Warning (3008, 1, MemberName.Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError ());
}
//
// Returns a string that represents the signature for this
// member which should be used in XML documentation.
//
- public virtual string GetDocCommentName ()
+ public abstract string GetSignatureForDocumentation ();
+
+ public virtual void GetCompletionStartingWith (string prefix, List<string> results)
{
- return DocCommentHeader + Parent.Name + "." + Name;
+ Parent.GetCompletionStartingWith (prefix, results);
}
//
#region IMemberContext Members
public virtual CompilerContext Compiler {
- get { return Parent.Compiler; }
+ get {
+ return Module.Compiler;
+ }
}
public virtual TypeSpec CurrentType {
get { return this; }
}
- public virtual TypeParameter[] CurrentTypeParameters {
+ public virtual TypeParameters CurrentTypeParameters {
get { return null; }
}
- public virtual bool HasUnresolvedConstraints {
- get { return false; }
- }
-
public bool IsObsolete {
get {
if (GetAttributeObsolete () != null)
MissingDependency_Undetected = 1 << 4,
MissingDependency = 1 << 5,
HasDynamicElement = 1 << 6,
+ ConstraintsChecked = 1 << 7,
IsAccessor = 1 << 9, // Method is an accessor
IsGeneric = 1 << 10, // Member contains type arguments
PendingMemberCacheMembers = 1 << 14,
PendingBaseTypeInflate = 1 << 15,
InterfacesExpanded = 1 << 16,
- IsNotRealProperty = 1 << 17,
+ IsNotCSharpCompatible = 1 << 17,
SpecialRuntimeType = 1 << 18,
InflatedExpressionType = 1 << 19,
InflatedNullableType = 1 << 20,
GenericIterateInterface = 1 << 21,
+ GenericTask = 1 << 22
}
protected Modifiers modifiers;
}
}
+ //
+ // Returns true for imported members which are not compatible with C# language
+ //
+ public bool IsNotCSharpCompatible {
+ get {
+ return (state & StateFlags.IsNotCSharpCompatible) != 0;
+ }
+ set {
+ state = value ? state | StateFlags.IsNotCSharpCompatible : state & ~StateFlags.IsNotCSharpCompatible;
+ }
+ }
+
public bool IsPrivate {
get { return (modifiers & Modifiers.PRIVATE) != 0; }
}
return cls == false;
}
+ public virtual string GetSignatureForDocumentation ()
+ {
+ return DeclaringType.GetSignatureForDocumentation () + "." + Name;
+ }
+
public virtual string GetSignatureForError ()
{
var bf = MemberDefinition as Property.BackingField;
- var name = bf == null ? Name : bf.OriginalName;
+ string name;
+ if (bf == null) {
+ name = Name;
+ } else {
+ name = bf.OriginalProperty.MemberName.Name;
+ }
+
return DeclaringType.GetSignatureForError () + "." + name;
}
return (state & StateFlags.CLSCompliant) != 0;
}
- public bool IsConditionallyExcluded (CompilerContext ctx, Location loc)
+ public bool IsConditionallyExcluded (IMemberContext ctx, Location loc)
{
if ((Kind & (MemberKind.Class | MemberKind.Method)) == 0)
return false;
if (conditions == null)
return false;
- foreach (var condition in conditions) {
- if (loc.CompilationUnit.IsConditionalDefined (ctx, condition))
- return false;
+ var m = ctx.CurrentMemberDefinition;
+ CompilationSourceFile unit = null;
+ while (m != null && unit == null) {
+ unit = m as CompilationSourceFile;
+ m = m.Parent;
+ }
+
+ if (unit != null) {
+ foreach (var condition in conditions) {
+ if (unit.IsConditionalDefined (condition))
+ return false;
+ }
}
return true;
{
TypeSpec MemberType { get; }
}
-
- //
- // 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;
- }
- }
}