From 0035f34051647adf5f1029e39a3cb39303d99f0d Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Wed, 4 Aug 2010 15:09:45 +0200 Subject: [PATCH] Add CecilProjectContent --- .../ICSharpCode.NRefactory.Tests.csproj | 108 ++++++----- ICSharpCode.NRefactory.Tests/MyClassTests.cs | 1 + .../ICSharpCode.NRefactory.csproj | 10 +- .../{ => TypeSystem}/Accessibility.cs | 2 +- .../TypeSystem/CecilProjectContent.cs | 183 ++++++++++++++++++ ICSharpCode.NRefactory/TypeSystem/IEntity.cs | 2 +- .../TypeSystem/IProjectContent.cs | 7 +- .../ISynchronizedTypeResolveContext.cs | 24 +++ .../TypeSystem/ITypeResolveContext.cs | 15 ++ .../Implementation/DefaultTypeDefinition.cs | 12 +- .../Implementation/ProxyTypeResolveContext.cs | 36 ++++ .../TypeSystem/LanguageProperties.cs | 24 --- .../TypeSystem/SharedTypes.cs | 2 +- NRefactory.sln | 53 ++--- README | 7 + 15 files changed, 368 insertions(+), 118 deletions(-) rename ICSharpCode.NRefactory/{ => TypeSystem}/Accessibility.cs (96%) create mode 100644 ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs create mode 100644 ICSharpCode.NRefactory/TypeSystem/ISynchronizedTypeResolveContext.cs create mode 100644 ICSharpCode.NRefactory/TypeSystem/Implementation/ProxyTypeResolveContext.cs delete mode 100644 ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs create mode 100644 README diff --git a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj index 17eba1ae1..1b8fc54e2 100644 --- a/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj +++ b/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj @@ -1,54 +1,56 @@ - - - - {63D3B27A-D966-4902-90B3-30290E1692F1} - Debug - AnyCPU - Library - ICSharpCode.NRefactory.Tests - ICSharpCode.NRefactory.Tests - v4.0 - Properties - - - x86 - - - bin\Debug\ - True - Full - False - True - DEBUG;TRACE - - - bin\Release\ - False - None - True - False - TRACE - - - - - - 3.5 - - - - 3.5 - - - - - - - - - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} - ICSharpCode.NRefactory - - - + + + + {63D3B27A-D966-4902-90B3-30290E1692F1} + Debug + AnyCPU + Library + ICSharpCode.NRefactory.Tests + ICSharpCode.NRefactory.Tests + v4.0 + Properties + + + x86 + + + bin\Debug\ + True + Full + False + True + DEBUG;TRACE + + + bin\Release\ + False + None + True + False + TRACE + + + + ..\lib\nunit.framework.dll + + + + 3.5 + + + + 3.5 + + + + + + + + + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371} + ICSharpCode.NRefactory + + + \ No newline at end of file diff --git a/ICSharpCode.NRefactory.Tests/MyClassTests.cs b/ICSharpCode.NRefactory.Tests/MyClassTests.cs index 8cc53de8c..822937ad8 100644 --- a/ICSharpCode.NRefactory.Tests/MyClassTests.cs +++ b/ICSharpCode.NRefactory.Tests/MyClassTests.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using NUnit.Framework; namespace ICSharpCode.NRefactory.Tests { diff --git a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj index 0c9021460..19756fd08 100644 --- a/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj +++ b/ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj @@ -30,6 +30,9 @@ TRACE + + ..\lib\Mono.Cecil.dll + 3.5 @@ -40,7 +43,6 @@ - @@ -127,6 +129,8 @@ + + @@ -145,6 +149,7 @@ + @@ -154,15 +159,14 @@ + - - \ No newline at end of file diff --git a/ICSharpCode.NRefactory/Accessibility.cs b/ICSharpCode.NRefactory/TypeSystem/Accessibility.cs similarity index 96% rename from ICSharpCode.NRefactory/Accessibility.cs rename to ICSharpCode.NRefactory/TypeSystem/Accessibility.cs index ff6c02056..de7f6775e 100644 --- a/ICSharpCode.NRefactory/Accessibility.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Accessibility.cs @@ -3,7 +3,7 @@ using System; -namespace ICSharpCode.NRefactory +namespace ICSharpCode.NRefactory.TypeSystem { /// /// Enum that describes the accessibility of an entity. diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs new file mode 100644 index 000000000..a661b0969 --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/CecilProjectContent.cs @@ -0,0 +1,183 @@ +// 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; + +using ICSharpCode.NRefactory.TypeSystem.Implementation; +using Mono.Cecil; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Project content that represents an already compiled assembly. + /// + public class CecilProjectContent : IProjectContent + { + IList assemblyAttributes; + + #region Constructor + public CecilProjectContent(AssemblyDefinition assemblyDefinition) + { + this.assemblyAttributes = ReadAttributes(assemblyDefinition, this); + } + #endregion + + #region IProjectContent implementation + public IList AssemblyAttributes { + get { return assemblyAttributes; } + } + + public ITypeDefinition GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer) + { + throw new NotImplementedException(); + } + + public ISynchronizedTypeResolveContext Synchronize() + { + // CecilProjectContent is immutable, so we don't need to synchronize + return new DummySynchronizedTypeResolveContext(this); + } + + sealed class DummySynchronizedTypeResolveContext : ProxyTypeResolveContext, ISynchronizedTypeResolveContext + { + public DummySynchronizedTypeResolveContext(ITypeResolveContext context) : base(context) + { + } + + public void Dispose() + { + } + } + #endregion + + #region Load Assembly From Disk + public static CecilProjectContent LoadAssembly(string fileName) + { + if (fileName == null) + throw new ArgumentNullException("fileName"); + AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, new ReaderParameters { AssemblyResolver = new DummyAssemblyResolver() }); + return new CecilProjectContent(asm); + } + + // used to prevent Cecil from loading referenced assemblies + sealed class DummyAssemblyResolver : IAssemblyResolver + { + public AssemblyDefinition Resolve(AssemblyNameReference name) + { + return null; + } + + public AssemblyDefinition Resolve(string fullName) + { + return null; + } + } + #endregion + + #region Read Type Reference + public static ITypeReference ReadTypeReference(TypeReference attributeType, ITypeResolveContext earlyBindContext) + { + throw new NotImplementedException(); + } + #endregion + + #region Read Attributes + public static IList ReadAttributes(ICustomAttributeProvider attributeProvider, ITypeResolveContext earlyBindContext) + { + Contract.Ensures(Contract.Result>() != null); + if (attributeProvider == null || !attributeProvider.HasCustomAttributes) + return EmptyList.Instance; + var cecilAttributes = attributeProvider.CustomAttributes; + IAttribute[] attributes = new IAttribute[cecilAttributes.Count]; + for (int i = 0; i < attributes.Length; i++) { + attributes[i] = new CecilAttribute(cecilAttributes[i], earlyBindContext); + } + return Array.AsReadOnly(attributes); + } + + sealed class CecilAttribute : Immutable, IAttribute + { + ITypeReference attributeType; + volatile CustomAttribute ca; + ITypeResolveContext earlyBindContext; + IList positionalArguments; + IList> namedArguments; + + public CecilAttribute(CustomAttribute ca, ITypeResolveContext earlyBindContext) + { + this.attributeType = ReadTypeReference(ca.AttributeType, earlyBindContext); + this.ca = ca; + this.earlyBindContext = earlyBindContext; + } + + public DomRegion Region { + get { return DomRegion.Empty; } + } + + public ITypeReference AttributeType { + get { return attributeType; } + } + + public IList PositionalArguments { + get { + EnsureArguments(); + return positionalArguments; + } + } + + public IList> NamedArguments { + get { + EnsureArguments(); + return namedArguments; + } + } + + void EnsureArguments() + { + CustomAttribute ca = this.ca; + if (ca != null) { + try { + if (ca.HasConstructorArguments) { + var posArgs = new List(); + foreach (var arg in ca.ConstructorArguments) { + posArgs.Add(ReadConstantValue(arg, earlyBindContext)); + } + this.positionalArguments = posArgs.AsReadOnly(); + } else { + this.positionalArguments = EmptyList.Instance; + } + } catch (InvalidOperationException) { + this.positionalArguments = EmptyList.Instance; + } + try { + if (ca.HasFields || ca.HasProperties) { + var namedArgs = new List>(); + foreach (var arg in ca.Fields) { + namedArgs.Add(new KeyValuePair(arg.Name, ReadConstantValue(arg.Argument, earlyBindContext))); + } + foreach (var arg in ca.Properties) { + namedArgs.Add(new KeyValuePair(arg.Name, ReadConstantValue(arg.Argument, earlyBindContext))); + } + this.namedArguments = namedArgs.AsReadOnly(); + } else { + this.namedArguments = EmptyList>.Instance; + } + } catch (InvalidOperationException) { + this.namedArguments = EmptyList>.Instance; + } + this.ca = null; + } + } + } + #endregion + + #region Read Constant Value + public static IConstantValue ReadConstantValue(CustomAttributeArgument arg, ITypeResolveContext earlyBindContext) + { + throw new NotImplementedException(); + } + #endregion + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/IEntity.cs b/ICSharpCode.NRefactory/TypeSystem/IEntity.cs index d6566599d..9633eb012 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IEntity.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IEntity.cs @@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory.TypeSystem } /// - /// The project content in which this entity is defined. + /// The assembly in which this entity is defined. /// This property never returns null. /// IProjectContent ProjectContent { diff --git a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs index b4d7664c1..274bcfbe3 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IProjectContent.cs @@ -2,6 +2,7 @@ // 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 @@ -12,15 +13,15 @@ namespace ICSharpCode.NRefactory.TypeSystem [ContractClass(typeof(IProjectContentContract))] public interface IProjectContent : ITypeResolveContext { - LanguageProperties Language { get; } + IList AssemblyAttributes { get; } } [ContractClassFor(typeof(IProjectContent))] abstract class IProjectContentContract : ITypeResolveContextContract, IProjectContent { - LanguageProperties IProjectContent.Language { + IList IProjectContent.AssemblyAttributes { get { - Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result>() != null); return null; } } diff --git a/ICSharpCode.NRefactory/TypeSystem/ISynchronizedTypeResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/ISynchronizedTypeResolveContext.cs new file mode 100644 index 000000000..c0de30a2b --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/ISynchronizedTypeResolveContext.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.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace ICSharpCode.NRefactory.TypeSystem +{ + /// + /// Context representing the set of assemblies in which a type is being searched. + /// Guarantees that the list of types available in the context is not changed until Dispose() is called. + /// The Dispose() method must be called from the same thread that create the + /// ISynchronizedTypeResolveContext. + /// + /// + /// A simple implementation might enter a ReaderWriterLock when the synchronized context + /// is created, and releases the lock when Dispose() is called. + /// However, implementations based on immutable data structures are also possible. + /// + public interface ISynchronizedTypeResolveContext : ITypeResolveContext, IDisposable + { + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs index 1c9a808a6..5d671d1fb 100644 --- a/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs +++ b/ICSharpCode.NRefactory/TypeSystem/ITypeResolveContext.cs @@ -14,6 +14,15 @@ namespace ICSharpCode.NRefactory.TypeSystem public interface ITypeResolveContext { ITypeDefinition GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer); + + /// + /// Returns a that + /// represents the same context as this instance, but cannot be modified + /// by other threads. + /// The ISynchronizedTypeResolveContext must be disposed from the same thread + /// that called this method when it is no longer used. + /// + ISynchronizedTypeResolveContext Synchronize(); } [ContractClassFor(typeof(ITypeResolveContext))] @@ -26,5 +35,11 @@ namespace ICSharpCode.NRefactory.TypeSystem Contract.Requires(nameComparer != null); return null; } + + ISynchronizedTypeResolveContext ITypeResolveContext.Synchronize() + { + Contract.Ensures(Contract.Result() != null); + return null; + } } } diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs index b02ae8599..ca2cad3b4 100644 --- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultTypeDefinition.cs @@ -321,13 +321,9 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation throw new NotImplementedException(); } - public ITypeDefinition GetCompoundClass() + public virtual 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; - } + return this; } public virtual IList GetParts() @@ -349,12 +345,12 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation { return this; } - + public IList GetNestedTypes(ITypeResolveContext context) { throw new NotImplementedException(); } - + public IList GetMethods(ITypeResolveContext context) { throw new NotImplementedException(); diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/ProxyTypeResolveContext.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/ProxyTypeResolveContext.cs new file mode 100644 index 000000000..aacd87c0d --- /dev/null +++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/ProxyTypeResolveContext.cs @@ -0,0 +1,36 @@ +// +// +// +// +// $Revision$ +// +using System; + +namespace ICSharpCode.NRefactory.TypeSystem.Implementation +{ + /// + /// Proxy that forwards calls to another TypeResolveContext. + /// Useful as base class for decorators. + /// + public class ProxyTypeResolveContext : ITypeResolveContext + { + ITypeResolveContext target; + + public ProxyTypeResolveContext(ITypeResolveContext target) + { + if (target == null) + throw new ArgumentNullException("target"); + this.target = target; + } + + public virtual ITypeDefinition GetClass(string fullTypeName, int typeParameterCount, StringComparer nameComparer) + { + return target.GetClass(fullTypeName, typeParameterCount, nameComparer); + } + + public virtual ISynchronizedTypeResolveContext Synchronize() + { + return target.Synchronize(); + } + } +} diff --git a/ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs b/ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs deleted file mode 100644 index ffcb07e93..000000000 --- a/ICSharpCode.NRefactory/TypeSystem/LanguageProperties.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 index fa277d257..9b2883558 100644 --- a/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs +++ b/ICSharpCode.NRefactory/TypeSystem/SharedTypes.cs @@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.TypeSystem 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. + /// The null type is used as type of the null literal. It is a reference type without any members; and it 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(); diff --git a/NRefactory.sln b/NRefactory.sln index 267459d96..fff163e3e 100644 --- a/NRefactory.sln +++ b/NRefactory.sln @@ -1,24 +1,29 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -# SharpDevelop 4.0.0.6197 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj", "{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.Tests", "ICSharpCode.NRefactory.Tests\ICSharpCode.NRefactory.Tests.csproj", "{63D3B27A-D966-4902-90B3-30290E1692F1}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.Build.0 = Debug|Any CPU - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.Build.0 = Release|Any CPU - {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.ActiveCfg = Release|Any CPU - {63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {63D3B27A-D966-4902-90B3-30290E1692F1}.Release|Any CPU.Build.0 = Release|Any CPU - {63D3B27A-D966-4902-90B3-30290E1692F1}.Release|Any CPU.ActiveCfg = Release|Any CPU - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +# SharpDevelop 4.0.0.6362 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory", "ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj", "{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ICSharpCode.NRefactory.Tests", "ICSharpCode.NRefactory.Tests\ICSharpCode.NRefactory.Tests.csproj", "{63D3B27A-D966-4902-90B3-30290E1692F1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}" + ProjectSection(SolutionItems) = postProject + README = README + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.Build.0 = Release|Any CPU + {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Release|Any CPU.ActiveCfg = Release|Any CPU + {63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {63D3B27A-D966-4902-90B3-30290E1692F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {63D3B27A-D966-4902-90B3-30290E1692F1}.Release|Any CPU.Build.0 = Release|Any CPU + {63D3B27A-D966-4902-90B3-30290E1692F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/README b/README new file mode 100644 index 000000000..7e2fb708c --- /dev/null +++ b/README @@ -0,0 +1,7 @@ +Overview of the NRefactory library: + +ICSharpCode.NRefactory.TypeSystem: + Contains a language-independent representation of the .NET type system. + +ICSharpCode.NRefactory.TypeSystem.Implementation: + Contains base classes that help implementing the type system interfaces.