diff --git a/ICSharpCode.NRefactory/Accessibility.cs b/ICSharpCode.NRefactory/Accessibility.cs new file mode 100644 index 0000000000..ff6c02056c --- /dev/null +++ b/ICSharpCode.NRefactory/Accessibility.cs @@ -0,0 +1,42 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory +{ + /// + /// Enum that describes the accessibility of an entity. + /// + public enum Accessibility + { + /// + /// The entity is completely inaccessible. This is used for C# explicit interface implementations. + /// + None, + /// + /// The entity is only accessible within the same class. + /// + Private, + /// + /// The entity is accessible everywhere. + /// + Public, + /// + /// The entity is only accessible within the same class and in derived classes. + /// + Protected, + /// + /// The entity is accessible within the same project content. + /// + Internal, + /// + /// The entity is accessible both everywhere in the project content, and in all derived classes. + /// + ProtectedOrInternal, + /// + /// The entity is accessible in derived classes within the same project content. + /// + ProtectedAndInternal + } +} diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 95a494b56a..970627bf93 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -40,8 +40,47 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ICSharpCode.NRefactory/MyClass.cs b/ICSharpCode.NRefactory/TypeSystem/ClassType.cs similarity index 66% rename from ICSharpCode.NRefactory/MyClass.cs rename to ICSharpCode.NRefactory/TypeSystem/ClassType.cs index baa4612406..539a55305a 100644 --- a/ICSharpCode.NRefactory/MyClass.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ClassType.cs @@ -4,13 +4,15 @@ using System; using System.Collections.Generic; -namespace ICSharpCode.NRefactory +namespace ICSharpCode.NRefactory.TypeSystem { - /// - /// Description of MyClass. - /// - public class MyClass + public enum ClassType { - + Class, + Enum, + Interface, + Struct, + Delegate, + Module, } -} \ No newline at end of file +} diff --git a/ICSharpCode.NRefactory/TypeSystem/DomRegion.cs b/ICSharpCode.NRefactory/TypeSystem/DomRegion.cs new file mode 100644 index 0000000000..f59f4cc34d --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/DomRegion.cs @@ -0,0 +1,135 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Globalization; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [Serializable] + public struct DomRegion : IEquatable + { + readonly string fileName; + readonly int beginLine; + readonly int endLine; + readonly int beginColumn; + readonly int endColumn; + + public readonly static DomRegion Empty = new DomRegion(null, -1, -1); + + public bool IsEmpty { + get { + return BeginLine <= 0; + } + } + + public string FileName { + get { return fileName; } + } + + public int BeginLine { + get { + return beginLine; + } + } + + /// + /// if the end line is == -1 the end column is -1 too + /// this stands for an unknwon end + /// + public int EndLine { + get { + return endLine; + } + } + + public int BeginColumn { + get { + return beginColumn; + } + } + + /// + /// if the end column is == -1 the end line is -1 too + /// this stands for an unknown end + /// + public int EndColumn { + get { + return endColumn; + } + } + + public DomRegion(string fileName, int beginLine, int beginColumn, int endLine, int endColumn) + { + if (fileName == null) + throw new ArgumentNullException("fileName"); + this.fileName = fileName; + this.beginLine = beginLine; + this.beginColumn = beginColumn; + this.endLine = endLine; + this.endColumn = endColumn; + } + + public DomRegion(string fileName, int beginLine, int beginColumn) + { + if (fileName == null) + throw new ArgumentNullException("fileName"); + this.fileName = fileName; + this.beginLine = beginLine; + this.beginColumn = beginColumn; + this.endLine = -1; + this.endColumn = -1; + } + + /// + /// Returns true, if the given coordinates (row, column) are in the region. + /// This method assumes that for an unknown end the end line is == -1 + /// + public bool IsInside(int row, int column) + { + if (IsEmpty) + return false; + return row >= BeginLine && + (row <= EndLine || EndLine == -1) && + (row != BeginLine || column >= BeginColumn) && + (row != EndLine || column <= EndColumn); + } + + public override string ToString() + { + return string.Format( + CultureInfo.InvariantCulture, + "[DomRegion FileName={0}, BeginLine={1}, EndLine={2}, BeginColumn={3}, EndColumn={4}]", + fileName, beginLine, endLine, beginColumn, endColumn); + } + + public override bool Equals(object obj) + { + return obj is DomRegion && Equals((DomRegion)obj); + } + + public override int GetHashCode() + { + unchecked { + return BeginColumn + 1100009 * BeginLine + 1200007 * BeginColumn + 1300021 * EndColumn; + } + } + + public bool Equals(DomRegion other) + { + return BeginLine == other.BeginLine && BeginColumn == other.BeginColumn + && EndLine == other.EndLine && EndColumn == other.EndColumn + && fileName == other.fileName; + } + + public static bool operator ==(DomRegion left, DomRegion right) + { + return left.Equals(right); + } + + public static bool operator !=(DomRegion left, DomRegion right) + { + return !left.Equals(right); + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/EntityType.cs b/ICSharpCode.NRefactory/TypeSystem/EntityType.cs new file mode 100644 index 0000000000..98e79850ff --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/EntityType.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + public enum EntityType + { + Class, + Field, + Property, + Indexer, + Event, + Method, + Operator, + Constructor, + Destructor + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs new file mode 100644 index 0000000000..62d748290f --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs @@ -0,0 +1,66 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents an attribute. + /// + [ContractClass(typeof(IAttributeContract))] + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")] + public interface IAttribute : IFreezable + { + /// + /// Gets the code region of this attribute. + /// + DomRegion Region { get; } + + /// + /// Gets the type of the attribute. + /// + ITypeReference AttributeType { get; } + + /// + /// Gets the positional arguments passed to the attribute. + /// + IList PositionalArguments { get; } + + /// + /// Gets the named arguments passed to the attribute. + /// + IList> NamedArguments { get; } + } + + [ContractClassFor(typeof(IAttribute))] + abstract class IAttributeContract : IFreezableContract, IAttribute + { + DomRegion IAttribute.Region { + get { return DomRegion.Empty; } + } + + ITypeReference IAttribute.AttributeType { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + IList IAttribute.PositionalArguments { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList> IAttribute.NamedArguments { + get { + Contract.Ensures(Contract.Result>>() != null); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs b/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs new file mode 100644 index 0000000000..14e421ea41 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IConstantValue.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(IConstantValueContract))] + public interface IConstantValue : IFreezable + { + /// + /// Gets the type of the constant value. + /// + IType GetValueType(ITypeResolveContext context); + + /// + /// Gets the .NET value of the constant value. + /// Possible return values are: + /// - primitive integers + /// - float/double + /// - bool + /// - string + /// - IType (for typeof-expressions) + /// and arrays of these values. Enum values are returned using the underlying primitive integer. + /// + object GetValue(ITypeResolveContext context); + } + + [ContractClassFor(typeof(IConstantValue))] + abstract class IConstantValueContract : IFreezableContract, IConstantValue + { + IType IConstantValue.GetValueType(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result() != null); + return null; + } + + object IConstantValue.GetValue(ITypeResolveContext context) + { + Contract.Requires(context != null); + return null; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IEntity.cs b/ICSharpCode.NRefactory/TypeSystem/IEntity.cs new file mode 100644 index 0000000000..d6566599d2 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IEntity.cs @@ -0,0 +1,137 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(IEntityContract))] + public interface IEntity : INamedElement, IFreezable + { + EntityType EntityType { get; } + + DomRegion Region { get; } + DomRegion BodyRegion { get; } + + /// + /// Gets the declaring class. + /// For members, this is the class that contains the member. + /// For nested classes, this is the outer class. For top-level classes, this property returns null. + /// + ITypeDefinition DeclaringTypeDefinition { get; } + + IList Attributes { get; } + + string Documentation { get; } + + /// + /// Gets whether this entity is static. + /// Returns true if either the 'static' or the 'const' modifier is set. + /// + bool IsStatic { + get; + } + + Accessibility Accessibility { get; } + + bool IsAbstract { get; } + + bool IsSealed { get; } + + /// + /// Gets whether this member is declared to be shadowing another member with the same name. + /// + bool IsShadowing { + get; + } + + /// + /// Gets whether this member is generated by a macro/compiler feature. + /// + bool IsSynthetic { + get; + } + + /// + /// The project content in which this entity is defined. + /// This property never returns null. + /// + IProjectContent ProjectContent { + get; + } + + //bool IsAccessible(IClass callingClass, bool isAccessThoughReferenceOfCurrentClass); + } + + [ContractClassFor(typeof(IEntity))] + abstract class IEntityContract : INamedElementContract, IEntity + { + EntityType IEntity.EntityType { + get { return default(EntityType); } + } + + DomRegion IEntity.Region { + get { return DomRegion.Empty; } + } + + DomRegion IEntity.BodyRegion { + get { return DomRegion.Empty; } + } + + ITypeDefinition IEntity.DeclaringTypeDefinition { + get { return null; } + } + + IList IEntity.Attributes { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + string IEntity.Documentation { + get { return null; } + } + + bool IEntity.IsStatic { + get { return false; } + } + + Accessibility IEntity.Accessibility { + get { return default(Accessibility); } + } + + bool IEntity.IsAbstract { + get { return false; } + } + + bool IEntity.IsSealed { + get { return false; } + } + + bool IEntity.IsShadowing { + get { return false; } + } + + bool IEntity.IsSynthetic { + get { return false; } + } + + IProjectContent IEntity.ProjectContent { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + bool IFreezable.IsFrozen { + get { return false; } + } + + void IFreezable.Freeze() + { + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IEvent.cs b/ICSharpCode.NRefactory/TypeSystem/IEvent.cs new file mode 100644 index 0000000000..8789461832 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IEvent.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(IEventContract))] + public interface IEvent : IMember + { + /// + /// Gets the add method. + /// + IMethod AddMethod { get; } + + /// + /// Gets the remove method. + /// + IMethod RemoveMethod { get; } + + /// + /// Gets the raise method. + /// + IMethod RaiseMethod { get; } + } + + [ContractClassFor(typeof(IEvent))] + abstract class IEventContract : IMemberContract, IEvent + { + IMethod IEvent.AddMethod { + get { return null; } + } + + IMethod IEvent.RemoveMethod { + get { return null; } + } + + IMethod IEvent.RaiseMethod { + get { return null; } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IExplicitInterfaceImplementation.cs b/ICSharpCode.NRefactory/TypeSystem/IExplicitInterfaceImplementation.cs new file mode 100644 index 0000000000..91259ff0e1 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IExplicitInterfaceImplementation.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents an explicit interface implementation. + /// + [ContractClass(typeof(IExplicitInterfaceImplementationContract))] + public interface IExplicitInterfaceImplementation : IFreezable + { + /// + /// Gets the type of the interface. + /// + ITypeReference InterfaceType { get; } + + /// + /// Gets the member name. + /// + string MemberName { get; } + } + + [ContractClassFor(typeof(IExplicitInterfaceImplementation))] + abstract class IExplicitInterfaceImplementationContract : IFreezableContract, IExplicitInterfaceImplementation + { + ITypeReference IExplicitInterfaceImplementation.InterfaceType { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + string IExplicitInterfaceImplementation.MemberName { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IField.cs b/ICSharpCode.NRefactory/TypeSystem/IField.cs new file mode 100644 index 0000000000..db72702027 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IField.cs @@ -0,0 +1,70 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents a field or constant. + /// + [ContractClass(typeof(IFieldContract))] + public interface IField : IMember, IVariable + { + /// + /// Gets the name of the field. + /// + new string Name { get; } // solve ambiguity between INamedElement.Name and IVariable.Name + + /// + /// Gets whether this field is a constant (C#-like const). + /// + bool IsConst { get; } + + /// + /// Gets whether this field is readonly. + /// + bool IsReadOnly { get; } + + /// + /// If this field is a constant, retrieves the value. + /// + IConstantValue ConstantValue { get; } + } + + [ContractClassFor(typeof(IField))] + abstract class IFieldContract : IMemberContract, IField + { + string IField.Name { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + bool IField.IsConst { + get { + IField @this = this; + Contract.Ensures(Contract.Result() == (@this.ConstantValue != null)); + return false; + } + } + + bool IField.IsReadOnly { + get { return false; } + } + + IConstantValue IField.ConstantValue { + get { return null; } + } + + string IVariable.Name { + get { throw new NotImplementedException(); } + } + + ITypeReference IVariable.Type { + get { throw new NotImplementedException(); } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs b/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs new file mode 100644 index 0000000000..1705b4d752 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs @@ -0,0 +1,36 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(IFreezableContract))] + public interface IFreezable + { + /// + /// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe. + /// + bool IsFrozen { get; } + + /// + /// Freezes this instance. + /// + void Freeze(); + } + + [ContractClassFor(typeof(IFreezable))] + abstract class IFreezableContract : IFreezable + { + bool IFreezable.IsFrozen { + get { return default(bool); } + } + + void IFreezable.Freeze() + { + IFreezable self = this; + Contract.Ensures(self.IsFrozen); + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs new file mode 100644 index 0000000000..50d246b073 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs @@ -0,0 +1,49 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(IInterningProviderContract))] + public interface IInterningProvider + { + /// + /// Intern the specified string. + /// + string InternString(string s); + + /// + /// Interns the specified object. + /// The object must implement , otherwise it will be returned without being interned. + /// + T InternObject(T obj); + + IList InternObjectList(IList list); + } + + [ContractClassFor(typeof(IInterningProvider))] + abstract class IInterningProviderContract : IInterningProvider + { + string IInterningProvider.InternString(string s) + { + Contract.Ensures((Contract.Result() == null) == (s == null)); + Contract.Ensures(string.IsNullOrEmpty(Contract.Result()) == string.IsNullOrEmpty(s)); + return s; + } + + T IInterningProvider.InternObject(T obj) + { + Contract.Ensures((Contract.Result() == null) == (obj == null)); + return obj; + } + + IList IInterningProvider.InternObjectList(IList list) + { + Contract.Ensures((Contract.Result>() == null) == (list == null)); + return list; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IMember.cs b/ICSharpCode.NRefactory/TypeSystem/IMember.cs new file mode 100644 index 0000000000..3aa3672730 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IMember.cs @@ -0,0 +1,115 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Method/field/entity. + /// + [ContractClass(typeof(IMemberContract))] + public interface IMember : IEntity + { + /// + /// Gets the type definition that contains the member. This property never returns null. + /// + new ITypeDefinition DeclaringTypeDefinition { get; } + + /// + /// Gets/Sets the declaring type (incl. type arguments, if any). + /// This property never returns null. + /// If this is not a specialized member, the value returned is equal to . + /// + IType DeclaringType { get; } + + /// + /// Gets the generic member this member is based on. + /// Returns null if this is not a specialized member. + /// Specialized members are the result of overload resolution with type substitution. + /// + IMember GenericMember { get; } + + /// + /// Gets the return type of this member. + /// This property never returns null. + /// + ITypeReference ReturnType { get; } + + /// + /// Gets the list of interfaces this member is implementing explicitly. + /// + IList InterfaceImplementations { get; } + + /// + /// Gets if the member is virtual. Is true only if the "virtual" modifier was used, but non-virtual + /// members can be overridden, too; if they are already overriding a method. + /// + bool IsVirtual { + get; + } + + bool IsOverride { + get; + } + + /// + /// Gets if the member can be overridden. Returns true when the member is "virtual" or "override" but not "sealed". + /// + bool IsOverridable { + get; + } + } + + [ContractClassFor(typeof(IMember))] + abstract class IMemberContract : IEntityContract, IMember + { + ITypeDefinition IMember.DeclaringTypeDefinition { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + IType IMember.DeclaringType { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + IMember IMember.GenericMember { + get { + return null; + } + } + + ITypeReference IMember.ReturnType { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + IList IMember.InterfaceImplementations { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + bool IMember.IsVirtual { + get { return false; } + } + + bool IMember.IsOverride { + get { return false; } + } + + bool IMember.IsOverridable { + get { return false; } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IMethod.cs b/ICSharpCode.NRefactory/TypeSystem/IMethod.cs new file mode 100644 index 0000000000..56ded253d2 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IMethod.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents a method, constructor, destructor or operator. + /// + [ContractClass(typeof(IMethodContract))] + public interface IMethod : IParameterizedMember + { + /// + /// Gets the attributes associated with the return type. + /// + IList ReturnTypeAttributes { get; } + + IList TypeParameters { get; } + + // handles is VB-specific and not part of the public API, so + // we don't really need it + //IList HandlesClauses { get; } + + bool IsExtensionMethod { get; } + bool IsConstructor { get; } + bool IsDestructor { get; } + bool IsOperator { get; } + } + + [ContractClassFor(typeof(IMethod))] + abstract class IMethodContract : IParameterizedMemberContract, IMethod + { + IList IMethod.ReturnTypeAttributes { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList IMethod.TypeParameters { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + +// IList IMethod.HandlesClauses { +// get { +// Contract.Ensures(Contract.Result>() != null); +// return null; +// } +// } + + bool IMethod.IsExtensionMethod { + get { return false; } + } + + bool IMethod.IsConstructor { + get { return false; } + } + + bool IMethod.IsDestructor { + get { return false; } + } + + bool IMethod.IsOperator { + get { return false; } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs b/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs new file mode 100644 index 0000000000..093f3f55e0 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/INamedElement.cs @@ -0,0 +1,89 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(INamedElementContract))] + public interface INamedElement + { + /// + /// Gets the fully qualified name of the class the return type is pointing to. + /// + /// + /// "System.Int32" for int[]
+ /// "System.Collections.Generic.List" for List<string> + ///
+ string FullName { + get; + } + + /// + /// Gets the short name of the class the return type is pointing to. + /// + /// + /// "Int32" or "int" (depending how the return type was created) for int[]
+ /// "List" for List<string> + ///
+ string Name { + get; + } + + /// + /// Gets the namespace of the class the return type is pointing to. + /// + /// + /// "System" for int[]
+ /// "System.Collections.Generic" for List<string> + ///
+ string Namespace { + get; + } + + /// + /// Gets the full dotnet name of the return type. The DotnetName is used for the + /// documentation tags. + /// + /// + /// "System.Int[]" for int[]
+ /// "System.Collections.Generic.List{System.String}" for List<string> + ///
+ string DotNetName { + get; + } + } + + [ContractClassFor(typeof(INamedElement))] + abstract class INamedElementContract : INamedElement + { + string INamedElement.FullName { + get { + Contract.Ensures(!string.IsNullOrEmpty(Contract.Result())); + return null; + } + } + + string INamedElement.Name { + get { + Contract.Ensures(!string.IsNullOrEmpty(Contract.Result())); + return null; + } + } + + string INamedElement.Namespace { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + string INamedElement.DotNetName { + get { + Contract.Ensures(!string.IsNullOrEmpty(Contract.Result())); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IParameter.cs b/ICSharpCode.NRefactory/TypeSystem/IParameter.cs new file mode 100644 index 0000000000..854901546c --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IParameter.cs @@ -0,0 +1,98 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(IParameterContract))] + public interface IParameter : IVariable, IFreezable + { + /// + /// Gets the list of attributes. + /// + IList Attributes { get; } + + /// + /// Gets the default value of optional parameters. + /// + IConstantValue DefaultValue { get; } + + /// + /// Gets the code region where the parameter is defined. + /// + DomRegion Region { get; } + + /// + /// Gets whether this parameter is a C# 'ref' parameter. + /// + bool IsRef { get; } + + /// + /// Gets whether this parameter is a C# 'out' parameter. + /// + bool IsOut { get; } + + /// + /// Gets whether this parameter is a C# 'params' parameter. + /// + bool IsParams { get; } + + /// + /// Gets whether this parameter is optional. + /// + bool IsOptional { get; } + } + + [ContractClassFor(typeof(IParameter))] + abstract class IParameterContract : IVariableContract, IParameter + { + IList IParameter.Attributes { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IConstantValue IParameter.DefaultValue { + get { return null; } + } + + DomRegion IParameter.Region { + get { return DomRegion.Empty; } + } + + bool IParameter.IsRef { + get { return false; } + } + + bool IParameter.IsOut { + get { return false; } + } + + bool IParameter.IsParams { + get { return false; } + } + + bool IParameter.IsOptional { + get { + IParameter @this = this; + Contract.Ensures(Contract.Result() == (@this.DefaultValue != null)); + return false; + } + } + + bool IFreezable.IsFrozen { + get { + throw new NotImplementedException(); + } + } + + void IFreezable.Freeze() + { + throw new NotImplementedException(); + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IParameterizedMember.cs b/ICSharpCode.NRefactory/TypeSystem/IParameterizedMember.cs new file mode 100644 index 0000000000..e719ca59a8 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IParameterizedMember.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents a method or property. + /// + [ContractClass(typeof(IParameterizedMemberContract))] + public interface IParameterizedMember : IMember + { + IList Parameters { get; } + } + + [ContractClassFor(typeof(IParameterizedMember))] + abstract class IParameterizedMemberContract : IMemberContract, IParameterizedMember + { + IList IParameterizedMember.Parameters { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs new file mode 100644 index 0000000000..b4d7664c1b --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Mutable container of all classes in an assembly. + /// + [ContractClass(typeof(IProjectContentContract))] + public interface IProjectContent : ITypeResolveContext + { + LanguageProperties Language { get; } + } + + [ContractClassFor(typeof(IProjectContent))] + abstract class IProjectContentContract : ITypeResolveContextContract, IProjectContent + { + LanguageProperties IProjectContent.Language { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IProperty.cs b/ICSharpCode.NRefactory/TypeSystem/IProperty.cs new file mode 100644 index 0000000000..43caf6c8b5 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IProperty.cs @@ -0,0 +1,18 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents a property or indexer. + /// + public interface IProperty : IParameterizedMember + { + IMethod GetMethod { get; } + IMethod SetMethod { get; } + + bool IsIndexer { get; } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs new file mode 100644 index 0000000000..ae4226d372 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Interface for DOM objects that support interning. + /// + [ContractClass(typeof(ISupportsInterningContract))] + public interface ISupportsInterning : IFreezable + { + /// + /// Interns child objects and strings. + /// + void PrepareForInterning(IInterningProvider provider); + + /// + /// Gets a hash code for interning. + /// + int GetHashCodeForInterning(); + + /// + /// Equality test for interning. + /// + bool EqualsForInterning(ISupportsInterning other); + } + + [ContractClassFor(typeof(ISupportsInterning))] + abstract class ISupportsInterningContract : IFreezableContract, ISupportsInterning + { + void ISupportsInterning.PrepareForInterning(IInterningProvider provider) + { + Contract.Requires(provider != null); + } + + int ISupportsInterning.GetHashCodeForInterning() + { + return 0; + } + + bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) + { + return false; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IType.cs b/ICSharpCode.NRefactory/TypeSystem/IType.cs new file mode 100644 index 0000000000..0a77c83650 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IType.cs @@ -0,0 +1,126 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(ITypeContract))] + public interface IType : ITypeReference, INamedElement, IEquatable + { + /// + /// Gets whether the type is a reference type or value type. + /// + /// + /// true, if the type is a reference type. + /// false, if the type is a value type. + /// null, if the type is not known (e.g. unconstrained generic type parameter or type not found) + /// + bool? IsReferenceType { get; } + + /// + /// Gets the element type of array or pointer types. + /// + IType GetElementType(); + + /// + /// Gets the underlying type definition. + /// Can return null for types which do not have a type definition (for example type parameters) + /// + ITypeDefinition GetDefinition(); + + /// + /// Gets the parent type, if this is a nested type. + /// Returns null for top-level types. + /// + IType DeclaringType { get; } + + /// + /// Gets whether this type is an array type. + /// + bool IsArrayType { get; } + + /// + /// Gets whether this type is a pointer type. + /// + bool IsPointerType { get; } + + /// + /// Gets the number of type parameters. + /// + int TypeParameterCount { get; } + } + + [ContractClassFor(typeof(IType))] + abstract class ITypeContract : ITypeReferenceContract, IType + { + Nullable IType.IsReferenceType { + get { return null; } + } + + bool IType.IsArrayType { + get { return false; } + } + + bool IType.IsPointerType { + get { return false; } + } + + int IType.TypeParameterCount { + get { + Contract.Ensures(Contract.Result() >= 0); + return 0; + } + } + + IType IType.DeclaringType { + get { return null; } + } + + string INamedElement.FullName { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + string INamedElement.Name { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + string INamedElement.Namespace { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + string INamedElement.DotNetName { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + IType IType.GetElementType() + { + Contract.Ensures(Contract.Result() != null); + return null; + } + + ITypeDefinition IType.GetDefinition() + { + return null; + } + + bool IEquatable.Equals(IType other) + { + return false; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs new file mode 100644 index 0000000000..743b69ea2d --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs @@ -0,0 +1,198 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents a class, enum, interface, struct, delegate or VB module. + /// + [ContractClass(typeof(ITypeDefinitionContract))] + public interface ITypeDefinition : IType, IEntity + { + ClassType ClassType { get; } + + IList BaseTypes { get; } + IList TypeParameters { get; } + + /// + /// If this is a partial class, gets the compound class containing information from all parts. + /// If this is not a partial class, a reference to this class is returned. + /// + /// This method will always retrieve the latest version of the class, which might not contain this class as a part. + /// + ITypeDefinition GetCompoundClass(); + + /// + /// If this is a compound class (combination of class parts), this method retrieves all individual class parts. + /// Otherwise, a list containing this is returned. + /// + IList GetParts(); + + IList InnerClasses { get; } + IList Fields { get; } + IList Properties { get; } + IList Methods { get; } + IList Events { get; } + IEnumerable Members { get; } + } + + [ContractClassFor(typeof(ITypeDefinition))] + abstract class ITypeDefinitionContract : ITypeContract, ITypeDefinition + { + ClassType ITypeDefinition.ClassType { + get { return default(ClassType); } + } + + IList ITypeDefinition.BaseTypes { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList ITypeDefinition.TypeParameters { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList ITypeDefinition.InnerClasses { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList ITypeDefinition.Fields { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList ITypeDefinition.Properties { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList ITypeDefinition.Methods { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IList ITypeDefinition.Events { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IEnumerable ITypeDefinition.Members { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + ITypeDefinition ITypeDefinition.GetCompoundClass() + { + Contract.Ensures(Contract.Result() != null); + return null; + } + + IList ITypeDefinition.GetParts() + { + Contract.Ensures(Contract.Result>() != null); + return null; + } + + #region IEntity + EntityType IEntity.EntityType { + get { + throw new NotImplementedException(); + } + } + + DomRegion IEntity.Region { + get { + throw new NotImplementedException(); + } + } + + DomRegion IEntity.BodyRegion { + get { + throw new NotImplementedException(); + } + } + + ITypeDefinition IEntity.DeclaringTypeDefinition { + get { + throw new NotImplementedException(); + } + } + + IList IEntity.Attributes { + get { + throw new NotImplementedException(); + } + } + + string IEntity.Documentation { + get { + throw new NotImplementedException(); + } + } + + bool IEntity.IsStatic { + get { + throw new NotImplementedException(); + } + } + + Accessibility IEntity.Accessibility { + get { + throw new NotImplementedException(); + } + } + + bool IEntity.IsAbstract { + get { + throw new NotImplementedException(); + } + } + + bool IEntity.IsSealed { + get { + throw new NotImplementedException(); + } + } + + bool IEntity.IsShadowing { + get { + throw new NotImplementedException(); + } + } + + bool IEntity.IsSynthetic { + get { + throw new NotImplementedException(); + } + } + + IProjectContent IEntity.ProjectContent { + get { + throw new NotImplementedException(); + } + } + #endregion + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs new file mode 100644 index 0000000000..6136095bfa --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeParameter.cs @@ -0,0 +1,146 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Type parameter of a generic class/method. + /// + [ContractClass(typeof(ITypeParameterContract))] + public interface ITypeParameter : IFreezable + { + /// + /// The name of the type parameter (for example "T") + /// + string Name { get; } + + /// + /// Gets the index of the type parameter in the type parameter list of the owning method/class. + /// + int Index { get; } + + /// + /// Gets the list of attributes declared on this type parameter. + /// + IList Attributes { get; } + + /// + /// The method this type parameter is defined for. + /// This property is null when the type parameter is for a class. + /// + IMethod ParentMethod { get; } + + /// + /// The class this type parameter is defined for. + /// When the type parameter is defined for a method, this is the class containing + /// that method. + /// + ITypeDefinition ParentClass { get; } + + /// + /// Gets the contraints of this type parameter. + /// + IList Constraints { get; } + + /// + /// Gets if the type parameter has the 'new()' constraint. + /// + bool HasConstructableConstraint { get; } + + /// + /// Gets if the type parameter has the 'class' constraint. + /// + bool HasReferenceTypeConstraint { get; } + + /// + /// Gets if the type parameter has the 'struct' constraint. + /// + bool HasValueTypeConstraint { get; } + + /// + /// Gets the type that was used to bind this type parameter. + /// This property returns null for generic methods/classes, it + /// is non-null only for constructed versions of generic methods. + /// + IType BoundTo { get; } + + /// + /// If this type parameter was bound, returns the unbound version of it. + /// + ITypeParameter UnboundTypeParameter { get; } + } + + + [ContractClassFor(typeof(ITypeParameter))] + abstract class ITypeParameterContract : IFreezableContract, ITypeParameter + { + string ITypeParameter.Name { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + int ITypeParameter.Index { + get { + Contract.Ensures(Contract.Result() >= 0); + return 0; + } + } + + IList ITypeParameter.Attributes { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + IMethod ITypeParameter.ParentMethod { + get { + return null; + } + } + + ITypeDefinition ITypeParameter.ParentClass { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + IList ITypeParameter.Constraints { + get { + Contract.Ensures(Contract.Result>() != null); + return null; + } + } + + bool ITypeParameter.HasConstructableConstraint { + get { return false; } + } + + bool ITypeParameter.HasReferenceTypeConstraint { + get { return false; } + } + + bool ITypeParameter.HasValueTypeConstraint { + get { return false; } + } + + IType ITypeParameter.BoundTo { + get { return null; } + } + + ITypeParameter ITypeParameter.UnboundTypeParameter { + get { + ITypeParameter @this = this; + Contract.Ensures((Contract.Result() != null) == (@this.BoundTo != null)); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs new file mode 100644 index 0000000000..e297e29275 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs @@ -0,0 +1,100 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + [ContractClass(typeof(ITypeReferenceContract))] + public interface ITypeReference : IFreezable + { + /// + /// Resolves this type reference. + /// + IType Resolve(ITypeResolveContext context); + + /// + /// Gets the base type. May return null. + /// + IType GetBaseType(ITypeResolveContext context); + + /// + /// Gets inner classes (including inherited inner classes). + /// + IList GetNestedTypes(ITypeResolveContext context); + + /// + /// Gets all methods that can be called on this return type. + /// + IList GetMethods(ITypeResolveContext context); + + /// + /// Gets all properties that can be called on this return type. + /// + IList GetProperties(ITypeResolveContext context); + + /// + /// Gets all fields that can be called on this return type. + /// + IList GetFields(ITypeResolveContext context); + + /// + /// Gets all events that can be called on this return type. + /// + IList GetEvents(ITypeResolveContext context); + } + + [ContractClassFor(typeof(ITypeReference))] + abstract class ITypeReferenceContract : IFreezableContract, ITypeReference + { + IType ITypeReference.Resolve(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result() != null); + return null; + } + + IType ITypeReference.GetBaseType(ITypeResolveContext context) + { + Contract.Requires(context != null); + return null; + } + + IList ITypeReference.GetNestedTypes(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList ITypeReference.GetMethods(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList ITypeReference.GetProperties(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList ITypeReference.GetFields(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + + IList ITypeReference.GetEvents(ITypeResolveContext context) + { + Contract.Requires(context != null); + Contract.Ensures(Contract.Result>() != null); + return null; + } + } +} \ No newline at end of file diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs new file mode 100644 index 0000000000..1c9a808a62 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Context representing the set of assemblies in which a type is being searched. + /// + [ContractClass(typeof(ITypeResolveContextContract))] + public interface ITypeResolveContext + { + ITypeDefinition GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer); + } + + [ContractClassFor(typeof(ITypeResolveContext))] + abstract class ITypeResolveContextContract : ITypeResolveContext + { + ITypeDefinition ITypeResolveContext.GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer) + { + Contract.Requires(fullTypeName != null); + Contract.Requires(typeParameterCount >= 0); + Contract.Requires(nameComparer != null); + return null; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IVariable.cs b/ICSharpCode.NRefactory/TypeSystem/IVariable.cs new file mode 100644 index 0000000000..79dc53708c --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/IVariable.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Represents a variable (name/return type pair). + /// + [ContractClass(typeof(IVariableContract))] + public interface IVariable + { + /// + /// Gets the name of the variable. + /// + string Name { get; } + + /// + /// Gets the type of the variable. + /// + ITypeReference Type { get; } + } + + [ContractClassFor(typeof(IVariable))] + abstract class IVariableContract : IVariable + { + string IVariable.Name { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + + ITypeReference IVariable.Type { + get { + Contract.Ensures(Contract.Result() != null); + return null; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs new file mode 100644 index 0000000000..51839cf90c --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractFreezable.cs @@ -0,0 +1,86 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Base class for immutable objects. Provides implementation for IFreezable that reports the + /// object as always-frozen. + /// + public abstract class Immutable : IFreezable + { + bool IFreezable.IsFrozen { + get { return true; } + } + + void IFreezable.Freeze() + { + } + } + + public abstract class AbstractFreezable : IFreezable + { + bool isFrozen; + + /// + /// Gets if this instance is frozen. Frozen instances are immutable and thus thread-safe. + /// + public bool IsFrozen { + get { return isFrozen; } + } + + /// + /// Freezes this instance. + /// + public void Freeze() + { + if (!isFrozen) { + FreezeInternal(); + isFrozen = true; + } + } + + protected virtual void FreezeInternal() + { + } + + protected void CheckBeforeMutation() + { + if (isFrozen) + throw new InvalidOperationException("Cannot mutate frozen " + GetType().Name); + } + + protected static IList FreezeList(IList list) where T : IFreezable + { + if (list == null || list.Count == 0) + return EmptyList.Instance; + list = new ReadOnlyCollection(list.ToArray()); + foreach (T item in list) { + item.Freeze(); + } + return list; + } + + protected static IList FreezeList(IList list) + { + if (list == null || list.Count == 0) + return EmptyList.Instance; + else + return new ReadOnlyCollection(list.ToArray()); + } + } + + static class EmptyList + { + public static readonly ReadOnlyCollection Instance = new ReadOnlyCollection(new T[0]); + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs new file mode 100644 index 0000000000..948c865767 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractType.cs @@ -0,0 +1,114 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Default implementation for IType interface. + /// + public abstract class AbstractType : AbstractFreezable, IType + { + public virtual string FullName { + get { + string ns = this.Namespace; + string name = this.Name; + if (string.IsNullOrEmpty(ns)) { + return name; + } else { + string combinedName = ns + "." + name; + Contract.Assume(!string.IsNullOrEmpty(combinedName)); + return combinedName; + } + } + } + + public abstract string Name { get; } + + public virtual string Namespace { + get { return string.Empty; } + } + + public virtual string DotNetName { + get { return this.FullName; } + } + + public abstract bool? IsReferenceType { get; } + + public virtual bool IsArrayType { + get { return false; } + } + + public virtual bool IsPointerType { + get { return false; } + } + + public virtual int TypeParameterCount { + get { return 0; } + } + + public virtual IType DeclaringType { + get { return null; } + } + + public virtual IType GetElementType() + { + throw new InvalidOperationException(); + } + + public virtual ITypeDefinition GetDefinition() + { + return null; + } + + public IType Resolve(ITypeResolveContext context) + { + return this; + } + + public IType GetBaseType(ITypeResolveContext context) + { + return null; + } + + public virtual IList GetNestedTypes(ITypeResolveContext context) + { + return EmptyList.Instance; + } + + public virtual IList GetMethods(ITypeResolveContext context) + { + return EmptyList.Instance; + } + + public virtual IList GetProperties(ITypeResolveContext context) + { + return EmptyList.Instance; + } + + public virtual IList GetFields(ITypeResolveContext context) + { + return EmptyList.Instance; + } + + public virtual IList GetEvents(ITypeResolveContext context) + { + return EmptyList.Instance; + } + + public override bool Equals(object obj) + { + return Equals(obj as IType); + } + + public abstract override int GetHashCode(); + public abstract bool Equals(IType other); + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs new file mode 100644 index 0000000000..a3f71865a8 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/AbstractTypeReference.cs @@ -0,0 +1,47 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + public abstract class AbstractTypeReference : Immutable, ITypeReference + { + public abstract IType Resolve(ITypeResolveContext context); + + public virtual IType GetBaseType(ITypeResolveContext context) + { + return Resolve(context).GetBaseType(context); + } + + public virtual IList GetNestedTypes(ITypeResolveContext context) + { + return Resolve(context).GetNestedTypes(context); + } + + public virtual IList GetMethods(ITypeResolveContext context) + { + return Resolve(context).GetMethods(context); + } + + public virtual IList GetProperties(ITypeResolveContext context) + { + return Resolve(context).GetProperties(context); + } + + public virtual IList GetFields(ITypeResolveContext context) + { + return Resolve(context).GetFields(context); + } + + public virtual IList GetEvents(ITypeResolveContext context) + { + return Resolve(context).GetEvents(context); + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultExplicitInterfaceImplementation.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultExplicitInterfaceImplementation.cs new file mode 100644 index 0000000000..51d4299990 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultExplicitInterfaceImplementation.cs @@ -0,0 +1,38 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Default implementation for IExplicitInterfaceImplementation. + /// + public sealed class DefaultExplicitInterfaceImplementation : IExplicitInterfaceImplementation + { + public ITypeReference InterfaceType { get; private set; } + public string MemberName { get; private set; } + + public DefaultExplicitInterfaceImplementation(ITypeReference interfaceType, string memberName) + { + if (interfaceType == null) + throw new ArgumentNullException("interfaceType"); + if (memberName == null) + throw new ArgumentNullException("memberName"); + this.InterfaceType = interfaceType; + this.MemberName = memberName; + } + + bool IFreezable.IsFrozen { + get { return true; } + } + + void IFreezable.Freeze() + { + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs new file mode 100644 index 0000000000..dfd498c1b7 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultParameter.cs @@ -0,0 +1,141 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Default implementation for IParameter. + /// + public sealed class DefaultParameter : AbstractFreezable, IParameter, ISupportsInterning + { + string name = string.Empty; + ITypeReference type = SharedTypes.UnknownType; + IList attributes; + IConstantValue defaultValue; + DomRegion region; + byte flags; + + protected override void FreezeInternal() + { + type.Freeze(); + attributes = FreezeList(attributes); + if (defaultValue != null) + defaultValue.Freeze(); + base.FreezeInternal(); + } + + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(type != null); + Contract.Invariant(name != null); + } + + public string Name { + get { return name; } + set { + if (value == null) + throw new ArgumentNullException(); + Contract.EndContractBlock(); + CheckBeforeMutation(); + name = value; + } + } + + public ITypeReference Type { + get { return type; } + set { + if (value == null) + throw new ArgumentNullException(); + Contract.EndContractBlock(); + CheckBeforeMutation(); + type = value; + } + } + + public IList Attributes { + get { + if (attributes == null) + attributes = new List(); + return attributes; + } + } + + public IConstantValue DefaultValue { + get { return defaultValue; } + set { + CheckBeforeMutation(); + defaultValue = value; + } + } + + public DomRegion Region { + get { return region; } + set { + CheckBeforeMutation(); + region = value; + } + } + + bool HasFlag(byte flag) + { + return (this.flags & flag) != 0; + } + void SetFlag(byte flag, bool value) + { + CheckBeforeMutation(); + if (value) + this.flags |= flag; + else + this.flags &= unchecked((byte)~flag); + } + + public bool IsRef { + get { return HasFlag(1); } + set { SetFlag(1, value); } + } + + public bool IsOut { + get { return HasFlag(2); } + set { SetFlag(2, value); } + } + + public bool IsParams { + get { return HasFlag(4); } + set { SetFlag(4, value); } + } + + public bool IsOptional { + get { return this.DefaultValue != null; } + } + + void ISupportsInterning.PrepareForInterning(IInterningProvider provider) + { + CheckBeforeMutation(); + name = provider.InternString(name); + type = provider.InternObject(type); + attributes = provider.InternObjectList(attributes); + defaultValue = provider.InternObject(defaultValue); + } + + int ISupportsInterning.GetHashCodeForInterning() + { + return type.GetHashCode() ^ (attributes != null ? attributes.GetHashCode() : 0) ^ (defaultValue != null ? defaultValue.GetHashCode() : 0); + } + + bool ISupportsInterning.EqualsForInterning(ISupportsInterning other) + { + DefaultParameter p = other as DefaultParameter; + return p != null && type == p.type && attributes == p.attributes + && defaultValue == p.defaultValue && region == p.region && flags == p.flags; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs new file mode 100644 index 0000000000..b02ae85998 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs @@ -0,0 +1,409 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + public class DefaultTypeDefinition : AbstractFreezable, ITypeDefinition + { + readonly IProjectContent projectContent; + readonly ITypeDefinition declaringTypeDefinition; + + readonly string ns; + readonly string name; + + ClassType classType; + IList baseTypes; + IList typeParameters; + IList innerClasses; + IList fields; + IList methods; + IList properties; + IList events; + IList attributes; + + DomRegion region; + DomRegion bodyRegion; + Accessibility accessibility; + + protected override void FreezeInternal() + { + baseTypes = FreezeList(baseTypes); + typeParameters = FreezeList(typeParameters); + innerClasses = FreezeList(innerClasses); + fields = FreezeList(fields); + methods = FreezeList(methods); + properties = FreezeList(properties); + events = FreezeList(events); + attributes = FreezeList(attributes); + base.FreezeInternal(); + } + + public DefaultTypeDefinition(ITypeDefinition declaringTypeDefinition, string name) + { + if (declaringTypeDefinition == null) + throw new ArgumentNullException("declaringTypeDefinition"); + if (string.IsNullOrEmpty(name)) + throw new ArgumentException("name"); + Contract.EndContractBlock(); + this.projectContent = declaringTypeDefinition.ProjectContent; + this.declaringTypeDefinition = declaringTypeDefinition; + this.name = name; + this.ns = declaringTypeDefinition.Namespace; + } + + public DefaultTypeDefinition(IProjectContent projectContent, string ns, string name) + { + if (projectContent == null) + throw new ArgumentNullException("projectContent"); + if (string.IsNullOrEmpty(name)) + throw new ArgumentException("name"); + Contract.EndContractBlock(); + this.projectContent = projectContent; + this.ns = ns ?? string.Empty; + this.name = name; + } + + [ContractInvariantMethod] + void ObjectInvariant() + { + Contract.Invariant(projectContent != null); + Contract.Invariant(!string.IsNullOrEmpty(name)); + Contract.Invariant(ns != null); + } + + public ClassType ClassType { + get { return classType; } + set { + CheckBeforeMutation(); + classType = value; + } + } + + public IList BaseTypes { + get { + if (baseTypes == null) + baseTypes = new List(); + return baseTypes; + } + } + + public IList TypeParameters { + get { + if (typeParameters == null) + typeParameters = new List(); + return typeParameters; + } + } + + public IList InnerClasses { + get { + if (innerClasses == null) + innerClasses = new List(); + return innerClasses; + } + } + + public IList Fields { + get { + if (fields == null) + fields = new List(); + return fields; + } + } + + public IList Properties { + get { + if (properties == null) + properties = new List(); + return properties; + } + } + + public IList Methods { + get { + if (methods == null) + methods = new List(); + return methods; + } + } + + public IList Events { + get { + if (events == null) + events = new List(); + return events; + } + } + + public IEnumerable Members { + get { + return this.Fields.Concat(this.Properties).Concat(this.Methods).Concat(this.Events); + } + } + + public bool? IsReferenceType { + get { + return this.ClassType == ClassType.Enum || this.ClassType == ClassType.Struct; + } + } + + bool IType.IsArrayType { + get { return false; } + } + + bool IType.IsPointerType { + get { return false; } + } + + public string FullName { + get { + if (declaringTypeDefinition != null) { + string combinedName = declaringTypeDefinition.FullName + "." + this.name; + Contract.Assume(!string.IsNullOrEmpty(combinedName)); + return combinedName; + } else if (string.IsNullOrEmpty(ns)) { + return this.name; + } else { + string combinedName = this.ns + "." + this.name; + Contract.Assume(!string.IsNullOrEmpty(combinedName)); + return combinedName; + } + } + } + + public string Name { + get { return this.name; } + } + + public string Namespace { + get { return this.ns; } + } + + public string DotNetName { + get { + if (declaringTypeDefinition != null) { + int tpCount = this.TypeParameterCount - declaringTypeDefinition.TypeParameterCount; + string combinedName; + if (tpCount > 0) + combinedName = declaringTypeDefinition.DotNetName + "+" + this.Name + "`" + tpCount.ToString(CultureInfo.InvariantCulture); + else + combinedName = declaringTypeDefinition.DotNetName + "+" + this.Name; + Contract.Assume(!string.IsNullOrEmpty(combinedName)); // help out the static checker + return combinedName; + } else { + if (string.IsNullOrEmpty(ns)) { + return this.Name; + } else { + string combinedName = this.Namespace + "." + this.Name; + Contract.Assume(!string.IsNullOrEmpty(combinedName)); // help out the static checker + return combinedName; + } + } + } + } + + public int TypeParameterCount { + get { return typeParameters != null ? typeParameters.Count : 0; } + } + + public EntityType EntityType { + get { return EntityType.Class; } + } + + public DomRegion Region { + get { return region; } + set { + CheckBeforeMutation(); + region = value; + } + } + + public DomRegion BodyRegion { + get { return bodyRegion; } + set { + CheckBeforeMutation(); + bodyRegion = value; + } + } + + public ITypeDefinition DeclaringTypeDefinition { + get { return declaringTypeDefinition; } + } + + public IType DeclaringType { + get { return declaringTypeDefinition; } + } + + public IList Attributes { + get { + if (attributes == null) + attributes = new List(); + return attributes; + } + } + + public virtual string Documentation { + get { return null; } + } + + public bool IsStatic { + get { + throw new NotImplementedException(); + } + } + + public Accessibility Accessibility { + get { return accessibility; } + set { + CheckBeforeMutation(); + accessibility = value; + } + } + + public bool IsAbstract { + get { + throw new NotImplementedException(); + } + } + + public bool IsSealed { + get { + throw new NotImplementedException(); + } + } + + public bool IsVirtual { + get { + throw new NotImplementedException(); + } + } + + public bool IsOverride { + get { + throw new NotImplementedException(); + } + } + + public bool IsOverridable { + get { + throw new NotImplementedException(); + } + } + + public bool IsShadowing { + get { + throw new NotImplementedException(); + } + } + + public bool IsSynthetic { + get { + throw new NotImplementedException(); + } + } + + public IProjectContent ProjectContent { + get { return projectContent; } + } + + public IType GetBaseType(ITypeResolveContext context) + { + throw new NotImplementedException(); + } + + public ITypeDefinition GetCompoundClass() + { + if (declaringTypeDefinition != null) { + return declaringTypeDefinition.GetCompoundClass().InnerClasses.FirstOrDefault(c => projectContent.Language.NameComparer.Equals(c.Name, this.Name)) ?? this; + } else { + return projectContent.GetClass(this.FullName, this.TypeParameterCount, projectContent.Language.NameComparer) ?? this; + } + } + + public virtual IList GetParts() + { + return new ITypeDefinition[] { this }; + } + + public IType GetElementType() + { + throw new InvalidOperationException(); + } + + public ITypeDefinition GetDefinition() + { + return this; + } + + public IType Resolve(ITypeResolveContext context) + { + return this; + } + + public IList GetNestedTypes(ITypeResolveContext context) + { + throw new NotImplementedException(); + } + + public IList GetMethods(ITypeResolveContext context) + { + throw new NotImplementedException(); + } + + public IList GetProperties(ITypeResolveContext context) + { + throw new NotImplementedException(); + } + + public IList GetFields(ITypeResolveContext context) + { + throw new NotImplementedException(); + } + + public IList GetEvents(ITypeResolveContext context) + { + throw new NotImplementedException(); + } + + public override bool Equals(object obj) + { + return Equals(obj as ITypeDefinition); + } + + public bool Equals(IType other) + { + return Equals(other as ITypeDefinition); + } + + public bool Equals(ITypeDefinition other) + { + if (other == null) + return false; + if (declaringTypeDefinition != null) { + return declaringTypeDefinition.Equals(other.DeclaringTypeDefinition) && this.Name == other.Name && this.TypeParameterCount == other.TypeParameterCount; + } else { + return other.DeclaringTypeDefinition == null && this.ProjectContent == other.ProjectContent + && this.Namespace == other.Namespace && this.Name == other.Name && this.TypeParameterCount == other.TypeParameterCount; + } + } + + public override int GetHashCode() + { + if (declaringTypeDefinition != null) { + return declaringTypeDefinition.GetHashCode() ^ name.GetHashCode(); + } else { + return ns.GetHashCode() ^ name.GetHashCode() ^ projectContent.GetHashCode(); + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/NullType.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/NullType.cs new file mode 100644 index 0000000000..3811304387 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/NullType.cs @@ -0,0 +1,35 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Type of the 'null' literal. + /// + sealed class NullType : AbstractType + { + public override string Name { + get { return "null"; } + } + + public override bool? IsReferenceType { + get { return true; } + } + + public override bool Equals(IType other) + { + return other is NullType; + } + + public override int GetHashCode() + { + return 362709548; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/UnknownType.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/UnknownType.cs new file mode 100644 index 0000000000..ce899c98ee --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/UnknownType.cs @@ -0,0 +1,35 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Type representing resolve errors. + /// + sealed class UnknownType : AbstractType + { + public override string Name { + get { return "?"; } + } + + public override bool? IsReferenceType { + get { return null; } + } + + public override bool Equals(IType other) + { + return other is UnknownType; + } + + public override int GetHashCode() + { + return 950772036; + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs b/ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs new file mode 100644 index 0000000000..ffcb07e931 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Describes the properties of a language. + /// + public class LanguageProperties + { + // TODO: is this class actually useful? consider removing it + + public virtual StringComparer NameComparer { + get { + Contract.Ensures(Contract.Result() != null); + Contract.Assume(StringComparer.Ordinal != null); + return StringComparer.Ordinal; + } + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs b/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs new file mode 100644 index 0000000000..fa277d2572 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2010 AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under MIT X11 license (for details please see \doc\license.txt) + +using System; +using ICSharpCode.NRefactory.TypeSystem.Implementation; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Contains static implementations of well-known types. + /// + public static class SharedTypes + { + /// + /// Gets the type representing resolve errors. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable")] + public readonly static IType UnknownType = new UnknownType(); + + /// + /// The null type is used as type of the null literal. It is a reference type without any members that is a subtype of all reference types. + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification = "It's immutable")] + public readonly static IType Null = new NullType(); + } +}