diff --git a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs index cb1620dbd..2cdd5a530 100644 --- a/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs +++ b/ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs @@ -159,7 +159,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem [Test] public void AssemblyAttribute() { - var attributes = compilation.MainAssembly.AssemblyAttributes; + var attributes = compilation.MainAssembly.GetAssemblyAttributes().ToList(); var typeTest = attributes.Single(a => a.AttributeType.FullName == typeof(TypeTestAttribute).FullName); Assert.AreEqual(3, typeTest.FixedArguments.Length); // first argument is (int)42 @@ -185,7 +185,7 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem [Test] public void TypeForwardedTo_Attribute() { - var attributes = compilation.MainAssembly.AssemblyAttributes; + var attributes = compilation.MainAssembly.GetAssemblyAttributes().ToList(); var forwardAttribute = attributes.Single(a => a.AttributeType.FullName == typeof(TypeForwardedToAttribute).FullName); Assert.AreEqual(1, forwardAttribute.FixedArguments.Length); var rt = (IType)forwardAttribute.FixedArguments[0].Value; diff --git a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs index 6ccf8a334..4acee1656 100644 --- a/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs +++ b/ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs @@ -394,13 +394,13 @@ namespace ICSharpCode.Decompiler.CSharp void DoDecompileModuleAndAssemblyAttributes(DecompileRun decompileRun, ITypeResolveContext decompilationContext, SyntaxTree syntaxTree) { - foreach (var a in typeSystem.Compilation.MainAssembly.AssemblyAttributes) { + foreach (var a in typeSystem.Compilation.MainAssembly.GetAssemblyAttributes()) { var astBuilder = CreateAstBuilder(decompilationContext); var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); attrSection.AttributeTarget = "assembly"; syntaxTree.AddChild(attrSection, SyntaxTree.MemberRole); } - foreach (var a in typeSystem.Compilation.MainAssembly.ModuleAttributes) { + foreach (var a in typeSystem.Compilation.MainAssembly.GetModuleAttributes()) { var astBuilder = CreateAstBuilder(decompilationContext); var attrSection = new AttributeSection(astBuilder.ConvertAttribute(a)); attrSection.AttributeTarget = "module"; diff --git a/ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs b/ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs index 99c9bbb17..dfdcc8605 100644 --- a/ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs +++ b/ICSharpCode.Decompiler/CSharp/RequiredNamespaceCollector.cs @@ -29,8 +29,8 @@ namespace ICSharpCode.Decompiler.CSharp public static void CollectAttributeNamespaces(DecompilerTypeSystem typeSystem, HashSet namespaces) { - HandleAttributes(typeSystem.MainAssembly.AssemblyAttributes, namespaces); - HandleAttributes(typeSystem.MainAssembly.ModuleAttributes, namespaces); + HandleAttributes(typeSystem.MainAssembly.GetAssemblyAttributes(), namespaces); + HandleAttributes(typeSystem.MainAssembly.GetModuleAttributes(), namespaces); } public static void CollectNamespaces(IEntity entity, DecompilerTypeSystem typeSystem, HashSet namespaces, bool scanningFullType = false) diff --git a/ICSharpCode.Decompiler/CSharp/Transforms/RemoveCLSCompliantAttribute.cs b/ICSharpCode.Decompiler/CSharp/Transforms/RemoveCLSCompliantAttribute.cs index f0d27e054..56c35ae12 100644 --- a/ICSharpCode.Decompiler/CSharp/Transforms/RemoveCLSCompliantAttribute.cs +++ b/ICSharpCode.Decompiler/CSharp/Transforms/RemoveCLSCompliantAttribute.cs @@ -34,10 +34,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms { public void Run(AstNode rootNode, TransformContext context) { - if (context.DecompiledAssembly.AssemblyAttributes.Any(a => a.AttributeType.FullName == "System.CLSCompliantAttribute")) - return; - - foreach (var section in rootNode.Descendants.OfType()) { + foreach (var section in rootNode.Children.OfType()) { if (section.AttributeTarget == "assembly") continue; foreach (var attribute in section.Attributes) { diff --git a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs index 251ce890f..82de99f52 100644 --- a/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs +++ b/ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs @@ -115,7 +115,7 @@ namespace ICSharpCode.Decompiler.Metadata } internal static readonly TypeProvider minimalCorlibTypeProvider = - new TypeProvider(MinimalCorlib.Instance.CreateCompilation()); + new TypeProvider(new SimpleCompilation(MinimalCorlib.Instance)); /// /// An attribute type provider that can be used to decode attribute signatures diff --git a/ICSharpCode.Decompiler/TypeSystem/IAssembly.cs b/ICSharpCode.Decompiler/TypeSystem/IAssembly.cs index e82032161..d682e18fa 100644 --- a/ICSharpCode.Decompiler/TypeSystem/IAssembly.cs +++ b/ICSharpCode.Decompiler/TypeSystem/IAssembly.cs @@ -89,12 +89,12 @@ namespace ICSharpCode.Decompiler.TypeSystem /// /// Gets the list of all assembly attributes in the project. /// - IReadOnlyList AssemblyAttributes { get; } + IEnumerable GetAssemblyAttributes(); /// /// Gets the list of all module attributes in the project. /// - IReadOnlyList ModuleAttributes { get; } + IEnumerable GetModuleAttributes(); /// /// Gets whether the internals of this assembly are visible in the specified assembly. diff --git a/ICSharpCode.Decompiler/TypeSystem/IType.cs b/ICSharpCode.Decompiler/TypeSystem/IType.cs index f4473a4a5..b2018d7cd 100644 --- a/ICSharpCode.Decompiler/TypeSystem/IType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/IType.cs @@ -122,15 +122,6 @@ namespace ICSharpCode.Decompiler.TypeSystem /// TypeParameterSubstitution GetSubstitution(); - /// - /// Gets a type visitor that performs the substitution of class type parameters with the type arguments - /// of this parameterized type, - /// and also substitutes method type parameters with the specified method type arguments. - /// Returns TypeParameterSubstitution.Identity if the type is not parametrized. - /// - TypeParameterSubstitution GetSubstitution(IReadOnlyList methodTypeArguments); - - /// /// Gets inner classes (including inherited inner classes). /// diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs index e6c681745..134700b21 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/AbstractResolvedTypeParameter.cs @@ -328,11 +328,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation return TypeParameterSubstitution.Identity; } - TypeParameterSubstitution IType.GetSubstitution(IReadOnlyList methodTypeArguments) - { - return TypeParameterSubstitution.Identity; - } - static Predicate FilterNonStatic(Predicate filter) where T : class, IMember { if (filter == null) diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs index 33d485691..2bec8135c 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedAssembly.cs @@ -149,7 +149,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation if (referencedType == null) throw new ArgumentNullException("referencedType"); FreezableHelper.ThrowIfFrozen(this); - var attribute = new DefaultUnresolvedAttribute(typeForwardedToAttributeTypeRef, new[] { KnownTypeReference.Type }); + var attribute = new DefaultUnresolvedAttribute(typeForwardedToAttributeTypeRef, new[] { KnownTypeReference.Get(KnownTypeCode.Type) }); attribute.PositionalArguments.Add(new TypeOfConstantValue(referencedType)); assemblyAttributes.Add(attribute); @@ -480,6 +480,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation { return "[DefaultResolvedAssembly " + AssemblyName + "]"; } + + IEnumerable IAssembly.GetAssemblyAttributes() + { + throw new NotImplementedException(); + } + + IEnumerable IAssembly.GetModuleAttributes() + { + throw new NotImplementedException(); + } sealed class NS : INamespace { diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedMethod.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedMethod.cs index 2ae6497fd..fea491d7d 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedMethod.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/DefaultUnresolvedMethod.cs @@ -223,7 +223,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation Accessibility = typeDefinition.IsAbstract ? Accessibility.Protected : Accessibility.Public, HasBody = true, MetadataToken = System.Reflection.Metadata.Ecma335.MetadataTokens.MethodDefinitionHandle(0), // initialize with properly typed nil token, to avoid InvalidCastExceptions - ReturnType = KnownTypeReference.Void + ReturnType = KnownTypeReference.Get(KnownTypeCode.Void) }; } @@ -245,7 +245,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation SymbolKind = SymbolKind.Constructor, Name = ".ctor", Accessibility = Accessibility.Public, - ReturnType = KnownTypeReference.Void + ReturnType = KnownTypeReference.Get(KnownTypeCode.Void) }; m.Freeze(); return m; diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs index 43e6de017..cfb33ff7e 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs @@ -416,7 +416,6 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation ITypeDefinition IType.GetDefinition() => this; TypeParameterSubstitution IType.GetSubstitution() => TypeParameterSubstitution.Identity; - TypeParameterSubstitution IType.GetSubstitution(IReadOnlyList methodTypeArguments) => TypeParameterSubstitution.Identity; public IType AcceptVisitor(TypeVisitor visitor) { diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs index 2bbfb1fa6..3b2ad26c5 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MinimalCorlib.cs @@ -17,49 +17,275 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection.Metadata; +using System.Reflection.Metadata.Ecma335; +using ICSharpCode.Decompiler.Util; namespace ICSharpCode.Decompiler.TypeSystem.Implementation { /// - /// Resolve context represents the minimal mscorlib required for evaluating constants. - /// This contains all known types () and no other types. + /// An artificial "assembly" that contains all known types () and no other types. + /// It does not contain any members. /// - public sealed class MinimalCorlib : DefaultUnresolvedAssembly + public sealed class MinimalCorlib : IAssembly { - static readonly Lazy instance = new Lazy(() => new MinimalCorlib()); - - public static MinimalCorlib Instance { - get { return instance.Value; } + public static readonly IAssemblyReference Instance = new CorlibAssemblyReference(); + + public ICompilation Compilation { get; } + CorlibTypeDefinition[] typeDefinitions; + readonly CorlibNamespace rootNamespace; + + private MinimalCorlib(ICompilation compilation) + { + this.Compilation = compilation; + this.typeDefinitions = new CorlibTypeDefinition[KnownTypeReference.KnownTypeCodeCount]; + this.rootNamespace = new CorlibNamespace(this, null, string.Empty, string.Empty); + for (int i = 0; i < KnownTypeReference.KnownTypeCodeCount; i++) { + if (KnownTypeReference.Get((KnownTypeCode)i) != null) { + typeDefinitions[i] = new CorlibTypeDefinition(this, (KnownTypeCode)i); + } + } + } + + bool IAssembly.IsMainAssembly => Compilation.MainAssembly == this; + + string IAssembly.AssemblyName => "corlib"; + string IAssembly.FullAssemblyName => "corlib"; + + Metadata.PEFile IAssembly.PEFile => null; + INamespace IAssembly.RootNamespace => rootNamespace; + + public IEnumerable TopLevelTypeDefinitions => typeDefinitions.Where(td => td != null); + public IEnumerable TypeDefinitions => TopLevelTypeDefinitions; + + public ITypeDefinition GetTypeDefinition(TopLevelTypeName topLevelTypeName) + { + foreach (var typeDef in typeDefinitions) { + if (typeDef != null && typeDef.FullTypeName == topLevelTypeName) + return typeDef; + } + return null; + } + + IEnumerable IAssembly.GetAssemblyAttributes() => EmptyList.Instance; + IEnumerable IAssembly.GetModuleAttributes() => EmptyList.Instance; + + bool IAssembly.InternalsVisibleTo(IAssembly assembly) + { + return assembly == this; } - - public ICompilation CreateCompilation() + + sealed class CorlibAssemblyReference : IAssemblyReference + { + IAssembly IAssemblyReference.Resolve(ITypeResolveContext context) + { + return new MinimalCorlib(context.Compilation); + } + } + + sealed class CorlibNamespace : INamespace { - return new SimpleCompilation(this); + readonly MinimalCorlib corlib; + internal List childNamespaces = new List(); + public INamespace ParentNamespace { get; } + public string FullName { get; } + public string Name { get; } + + public CorlibNamespace(MinimalCorlib corlib, INamespace parentNamespace, string fullName, string name) + { + this.corlib = corlib; + this.ParentNamespace = parentNamespace; + this.FullName = fullName; + this.Name = name; + } + + string INamespace.ExternAlias => string.Empty; + + IEnumerable INamespace.ChildNamespaces => childNamespaces; + IEnumerable INamespace.Types => corlib.TopLevelTypeDefinitions.Where(td => td.Namespace == FullName); + + IEnumerable INamespace.ContributingAssemblies => new[] { corlib }; + + SymbolKind ISymbol.SymbolKind => SymbolKind.Namespace; + ICompilation ICompilationProvider.Compilation => corlib.Compilation; + + INamespace INamespace.GetChildNamespace(string name) + { + return childNamespaces.FirstOrDefault(ns => ns.Name == name); + } + + ITypeDefinition INamespace.GetTypeDefinition(string name, int typeParameterCount) + { + return corlib.GetTypeDefinition(this.FullName, name, typeParameterCount); + } } - - private MinimalCorlib() : base("corlib") + + sealed class CorlibTypeDefinition : ITypeDefinition { - var types = new DefaultUnresolvedTypeDefinition[KnownTypeReference.KnownTypeCodeCount]; - for (int i = 0; i < types.Length; i++) { - var typeRef = KnownTypeReference.Get((KnownTypeCode)i); - if (typeRef != null) { - types[i] = new DefaultUnresolvedTypeDefinition(typeRef.Namespace, typeRef.Name); - for (int j = 0; j < typeRef.TypeParameterCount; j++) { - types[i].TypeParameters.Add(new DefaultUnresolvedTypeParameter(SymbolKind.TypeDefinition, j)); + readonly MinimalCorlib corlib; + readonly KnownTypeCode typeCode; + readonly TypeKind typeKind; + + public CorlibTypeDefinition(MinimalCorlib corlib, KnownTypeCode typeCode) + { + this.corlib = corlib; + this.typeCode = typeCode; + this.typeKind = KnownTypeReference.Get(typeCode).typeKind; + } + + IReadOnlyList ITypeDefinition.NestedTypes => EmptyList.Instance; + IReadOnlyList ITypeDefinition.Members => EmptyList.Instance; + IEnumerable ITypeDefinition.Fields => EmptyList.Instance; + IEnumerable ITypeDefinition.Methods => EmptyList.Instance; + IEnumerable ITypeDefinition.Properties => EmptyList.Instance; + IEnumerable ITypeDefinition.Events => EmptyList.Instance; + + KnownTypeCode ITypeDefinition.KnownTypeCode => typeCode; + + IType ITypeDefinition.EnumUnderlyingType => SpecialType.UnknownType; + + public FullTypeName FullTypeName => KnownTypeReference.Get(typeCode).TypeName; + + ITypeDefinition IEntity.DeclaringTypeDefinition => null; + IType ITypeDefinition.DeclaringType => null; + IType IType.DeclaringType => null; + IType IEntity.DeclaringType => null; + + bool ITypeDefinition.HasExtensionMethods => false; + + TypeKind IType.Kind => typeKind; + + bool? IType.IsReferenceType { + get { + switch (typeKind) { + case TypeKind.Class: + case TypeKind.Interface: + return true; + case TypeKind.Struct: + case TypeKind.Enum: + return false; + default: + return null; } - AddTypeDefinition(types[i]); } } - for (int i = 0; i < types.Length; i++) { - var typeRef = KnownTypeReference.Get((KnownTypeCode)i); - if (typeRef != null && typeRef.baseType != KnownTypeCode.None) { - types[i].BaseTypes.Add(types[(int)typeRef.baseType]); - if (typeRef.baseType == KnownTypeCode.ValueType && i != (int)KnownTypeCode.Enum) { - types[i].Kind = TypeKind.Struct; - } + + int IType.TypeParameterCount => KnownTypeReference.Get(typeCode).TypeParameterCount; + + IReadOnlyList IType.TypeParameters => DummyTypeParameter.GetClassTypeParameterList(KnownTypeReference.Get(typeCode).TypeParameterCount); + IReadOnlyList IType.TypeArguments => DummyTypeParameter.GetClassTypeParameterList(KnownTypeReference.Get(typeCode).TypeParameterCount); + + IEnumerable IType.DirectBaseTypes { + get { + var baseType = KnownTypeReference.Get(typeCode).baseType; + if (baseType != KnownTypeCode.None) + return new[] { corlib.typeDefinitions[(int)baseType] }; + else + return EmptyList.Instance; + } + } + + EntityHandle IEntity.MetadataToken => MetadataTokens.TypeDefinitionHandle(0); + + public string Name => KnownTypeReference.Get(typeCode).Name; + + IAssembly IEntity.ParentAssembly => corlib; + + Accessibility IEntity.Accessibility => Accessibility.Public; + + bool IEntity.IsStatic => false; + bool IEntity.IsAbstract => typeKind == TypeKind.Interface; + bool IEntity.IsSealed => typeKind == TypeKind.Struct; + + SymbolKind ISymbol.SymbolKind => SymbolKind.TypeDefinition; + + ICompilation ICompilationProvider.Compilation => corlib.Compilation; + + string INamedElement.FullName { + get { + var ktr = KnownTypeReference.Get(typeCode); + return ktr.Namespace + "." + ktr.Name; } } - Freeze(); + + string INamedElement.ReflectionName => KnownTypeReference.Get(typeCode).TypeName.ReflectionName; + + string INamedElement.Namespace => KnownTypeReference.Get(typeCode).Namespace; + + bool IEquatable.Equals(IType other) + { + return this == other; + } + + IEnumerable IType.GetAccessors(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IEntity.GetAttributes() + { + return EmptyList.Instance; + } + + IEnumerable IType.GetConstructors(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetEvents(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetFields(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetMembers(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetMethods(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetMethods(IReadOnlyList typeArguments, Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetNestedTypes(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetNestedTypes(IReadOnlyList typeArguments, Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + IEnumerable IType.GetProperties(Predicate filter, GetMemberOptions options) + { + return EmptyList.Instance; + } + + ITypeDefinition IType.GetDefinition() => this; + TypeParameterSubstitution IType.GetSubstitution() => TypeParameterSubstitution.Identity; + + IType IType.AcceptVisitor(TypeVisitor visitor) + { + return visitor.VisitTypeDefinition(this); + } + + IType IType.VisitChildren(TypeVisitor visitor) + { + return this; + } } } } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs index 6d6f75575..b45b49568 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/TypeSpecification.cs @@ -134,7 +134,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public ITypeReference GetFunctionPointerType(SRM.MethodSignature signature) { - return KnownTypeReference.IntPtr; + return KnownTypeReference.Get(KnownTypeCode.IntPtr); } public ITypeReference GetGenericInstantiation(ITypeReference genericType, ImmutableArray typeArguments) diff --git a/ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs b/ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs index a85fbbb8d..793158e34 100644 --- a/ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs +++ b/ICSharpCode.Decompiler/TypeSystem/KnownTypeReference.cs @@ -137,54 +137,54 @@ namespace ICSharpCode.Decompiler.TypeSystem static readonly KnownTypeReference[] knownTypeReferences = new KnownTypeReference[KnownTypeCodeCount] { null, // None - new KnownTypeReference(KnownTypeCode.Object, "System", "Object", baseType: KnownTypeCode.None), - new KnownTypeReference(KnownTypeCode.DBNull, "System", "DBNull"), - new KnownTypeReference(KnownTypeCode.Boolean, "System", "Boolean", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Char, "System", "Char", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.SByte, "System", "SByte", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Byte, "System", "Byte", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Int16, "System", "Int16", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.UInt16, "System", "UInt16", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Int32, "System", "Int32", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.UInt32, "System", "UInt32", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Int64, "System", "Int64", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.UInt64, "System", "UInt64", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Single, "System", "Single", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Double, "System", "Double", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Decimal, "System", "Decimal", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.DateTime, "System", "DateTime", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Object, TypeKind.Class, "System", "Object", baseType: KnownTypeCode.None), + new KnownTypeReference(KnownTypeCode.DBNull, TypeKind.Class, "System", "DBNull"), + new KnownTypeReference(KnownTypeCode.Boolean, TypeKind.Struct, "System", "Boolean"), + new KnownTypeReference(KnownTypeCode.Char, TypeKind.Struct, "System", "Char"), + new KnownTypeReference(KnownTypeCode.SByte, TypeKind.Struct, "System", "SByte"), + new KnownTypeReference(KnownTypeCode.Byte, TypeKind.Struct, "System", "Byte"), + new KnownTypeReference(KnownTypeCode.Int16, TypeKind.Struct, "System", "Int16"), + new KnownTypeReference(KnownTypeCode.UInt16, TypeKind.Struct, "System", "UInt16"), + new KnownTypeReference(KnownTypeCode.Int32, TypeKind.Struct, "System", "Int32"), + new KnownTypeReference(KnownTypeCode.UInt32, TypeKind.Struct, "System", "UInt32"), + new KnownTypeReference(KnownTypeCode.Int64, TypeKind.Struct, "System", "Int64"), + new KnownTypeReference(KnownTypeCode.UInt64, TypeKind.Struct, "System", "UInt64"), + new KnownTypeReference(KnownTypeCode.Single, TypeKind.Struct, "System", "Single"), + new KnownTypeReference(KnownTypeCode.Double, TypeKind.Struct, "System", "Double"), + new KnownTypeReference(KnownTypeCode.Decimal, TypeKind.Struct, "System", "Decimal"), + new KnownTypeReference(KnownTypeCode.DateTime, TypeKind.Struct, "System", "DateTime"), null, - new KnownTypeReference(KnownTypeCode.String, "System", "String"), - new KnownTypeReference(KnownTypeCode.Void, "System", "Void"), - new KnownTypeReference(KnownTypeCode.Type, "System", "Type"), - new KnownTypeReference(KnownTypeCode.Array, "System", "Array"), - new KnownTypeReference(KnownTypeCode.Attribute, "System", "Attribute"), - new KnownTypeReference(KnownTypeCode.ValueType, "System", "ValueType"), - new KnownTypeReference(KnownTypeCode.Enum, "System", "Enum", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.Delegate, "System", "Delegate"), - new KnownTypeReference(KnownTypeCode.MulticastDelegate, "System", "MulticastDelegate", baseType: KnownTypeCode.Delegate), - new KnownTypeReference(KnownTypeCode.Exception, "System", "Exception"), - new KnownTypeReference(KnownTypeCode.IntPtr, "System", "IntPtr", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.UIntPtr, "System", "UIntPtr", baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.IEnumerable, "System.Collections", "IEnumerable"), - new KnownTypeReference(KnownTypeCode.IEnumerator, "System.Collections", "IEnumerator"), - new KnownTypeReference(KnownTypeCode.IEnumerableOfT, "System.Collections.Generic", "IEnumerable", 1), - new KnownTypeReference(KnownTypeCode.IEnumeratorOfT, "System.Collections.Generic", "IEnumerator", 1), - new KnownTypeReference(KnownTypeCode.ICollection, "System.Collections", "ICollection"), - new KnownTypeReference(KnownTypeCode.ICollectionOfT, "System.Collections.Generic", "ICollection", 1), - new KnownTypeReference(KnownTypeCode.IList, "System.Collections", "IList"), - new KnownTypeReference(KnownTypeCode.IListOfT, "System.Collections.Generic", "IList", 1), + new KnownTypeReference(KnownTypeCode.String, TypeKind.Class, "System", "String"), + new KnownTypeReference(KnownTypeCode.Void, TypeKind.Void, "System", "Void", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Type, TypeKind.Class, "System", "Type"), + new KnownTypeReference(KnownTypeCode.Array, TypeKind.Class, "System", "Array"), + new KnownTypeReference(KnownTypeCode.Attribute, TypeKind.Class, "System", "Attribute"), + new KnownTypeReference(KnownTypeCode.ValueType, TypeKind.Class, "System", "ValueType"), + new KnownTypeReference(KnownTypeCode.Enum, TypeKind.Class, "System", "Enum", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.Delegate, TypeKind.Class, "System", "Delegate"), + new KnownTypeReference(KnownTypeCode.MulticastDelegate, TypeKind.Class, "System", "MulticastDelegate", baseType: KnownTypeCode.Delegate), + new KnownTypeReference(KnownTypeCode.Exception, TypeKind.Class, "System", "Exception"), + new KnownTypeReference(KnownTypeCode.IntPtr, TypeKind.Struct, "System", "IntPtr"), + new KnownTypeReference(KnownTypeCode.UIntPtr, TypeKind.Struct, "System", "UIntPtr"), + new KnownTypeReference(KnownTypeCode.IEnumerable, TypeKind.Interface, "System.Collections", "IEnumerable"), + new KnownTypeReference(KnownTypeCode.IEnumerator, TypeKind.Interface, "System.Collections", "IEnumerator"), + new KnownTypeReference(KnownTypeCode.IEnumerableOfT, TypeKind.Interface, "System.Collections.Generic", "IEnumerable", 1), + new KnownTypeReference(KnownTypeCode.IEnumeratorOfT, TypeKind.Interface, "System.Collections.Generic", "IEnumerator", 1), + new KnownTypeReference(KnownTypeCode.ICollection, TypeKind.Interface, "System.Collections", "ICollection"), + new KnownTypeReference(KnownTypeCode.ICollectionOfT, TypeKind.Interface, "System.Collections.Generic", "ICollection", 1), + new KnownTypeReference(KnownTypeCode.IList, TypeKind.Interface, "System.Collections", "IList"), + new KnownTypeReference(KnownTypeCode.IListOfT, TypeKind.Interface, "System.Collections.Generic", "IList", 1), - new KnownTypeReference(KnownTypeCode.IReadOnlyCollectionOfT, "System.Collections.Generic", "IReadOnlyCollection", 1), - new KnownTypeReference(KnownTypeCode.IReadOnlyListOfT, "System.Collections.Generic", "IReadOnlyList", 1), - new KnownTypeReference(KnownTypeCode.Task, "System.Threading.Tasks", "Task"), - new KnownTypeReference(KnownTypeCode.TaskOfT, "System.Threading.Tasks", "Task", 1, baseType: KnownTypeCode.Task), - new KnownTypeReference(KnownTypeCode.NullableOfT, "System", "Nullable", 1, baseType: KnownTypeCode.ValueType), - new KnownTypeReference(KnownTypeCode.IDisposable, "System", "IDisposable"), - new KnownTypeReference(KnownTypeCode.INotifyCompletion, "System.Runtime.CompilerServices", "INotifyCompletion"), - new KnownTypeReference(KnownTypeCode.ICriticalNotifyCompletion, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion"), + new KnownTypeReference(KnownTypeCode.IReadOnlyCollectionOfT, TypeKind.Interface, "System.Collections.Generic", "IReadOnlyCollection", 1), + new KnownTypeReference(KnownTypeCode.IReadOnlyListOfT, TypeKind.Interface, "System.Collections.Generic", "IReadOnlyList", 1), + new KnownTypeReference(KnownTypeCode.Task, TypeKind.Class, "System.Threading.Tasks", "Task"), + new KnownTypeReference(KnownTypeCode.TaskOfT, TypeKind.Class, "System.Threading.Tasks", "Task", 1, baseType: KnownTypeCode.Task), + new KnownTypeReference(KnownTypeCode.NullableOfT, TypeKind.Struct, "System", "Nullable", 1), + new KnownTypeReference(KnownTypeCode.IDisposable, TypeKind.Interface, "System", "IDisposable"), + new KnownTypeReference(KnownTypeCode.INotifyCompletion, TypeKind.Interface, "System.Runtime.CompilerServices", "INotifyCompletion"), + new KnownTypeReference(KnownTypeCode.ICriticalNotifyCompletion, TypeKind.Interface, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion"), - new KnownTypeReference(KnownTypeCode.TypedReference, "System", "TypedReference", baseType: KnownTypeCode.ValueType), + new KnownTypeReference(KnownTypeCode.TypedReference, TypeKind.Struct, "System", "TypedReference"), }; /// @@ -196,243 +196,22 @@ namespace ICSharpCode.Decompiler.TypeSystem return knownTypeReferences[(int)typeCode]; } - /// - /// Gets a type reference pointing to the object type. - /// - public static readonly KnownTypeReference Object = Get(KnownTypeCode.Object); - - /// - /// Gets a type reference pointing to the System.DBNull type. - /// - public static readonly KnownTypeReference DBNull = Get(KnownTypeCode.DBNull); - - /// - /// Gets a type reference pointing to the bool type. - /// - public static readonly KnownTypeReference Boolean = Get(KnownTypeCode.Boolean); - - /// - /// Gets a type reference pointing to the char type. - /// - public static readonly KnownTypeReference Char = Get(KnownTypeCode.Char); - - /// - /// Gets a type reference pointing to the sbyte type. - /// - public static readonly KnownTypeReference SByte = Get(KnownTypeCode.SByte); - - /// - /// Gets a type reference pointing to the byte type. - /// - public static readonly KnownTypeReference Byte = Get(KnownTypeCode.Byte); - - /// - /// Gets a type reference pointing to the short type. - /// - public static readonly KnownTypeReference Int16 = Get(KnownTypeCode.Int16); - - /// - /// Gets a type reference pointing to the ushort type. - /// - public static readonly KnownTypeReference UInt16 = Get(KnownTypeCode.UInt16); - - /// - /// Gets a type reference pointing to the int type. - /// - public static readonly KnownTypeReference Int32 = Get(KnownTypeCode.Int32); - - /// - /// Gets a type reference pointing to the uint type. - /// - public static readonly KnownTypeReference UInt32 = Get(KnownTypeCode.UInt32); - - /// - /// Gets a type reference pointing to the long type. - /// - public static readonly KnownTypeReference Int64 = Get(KnownTypeCode.Int64); - - /// - /// Gets a type reference pointing to the ulong type. - /// - public static readonly KnownTypeReference UInt64 = Get(KnownTypeCode.UInt64); - - /// - /// Gets a type reference pointing to the float type. - /// - public static readonly KnownTypeReference Single = Get(KnownTypeCode.Single); - - /// - /// Gets a type reference pointing to the double type. - /// - public static readonly KnownTypeReference Double = Get(KnownTypeCode.Double); - - /// - /// Gets a type reference pointing to the decimal type. - /// - public static readonly KnownTypeReference Decimal = Get(KnownTypeCode.Decimal); - - /// - /// Gets a type reference pointing to the System.DateTime type. - /// - public static readonly KnownTypeReference DateTime = Get(KnownTypeCode.DateTime); - - /// - /// Gets a type reference pointing to the string type. - /// - public static readonly KnownTypeReference String = Get(KnownTypeCode.String); - - /// - /// Gets a type reference pointing to the void type. - /// - public static readonly KnownTypeReference Void = Get(KnownTypeCode.Void); - - /// - /// Gets a type reference pointing to the System.Type type. - /// - public static readonly KnownTypeReference Type = Get(KnownTypeCode.Type); - - /// - /// Gets a type reference pointing to the System.Array type. - /// - public static readonly KnownTypeReference Array = Get(KnownTypeCode.Array); - - /// - /// Gets a type reference pointing to the System.Attribute type. - /// - public static readonly KnownTypeReference Attribute = Get(KnownTypeCode.Attribute); - - /// - /// Gets a type reference pointing to the System.ValueType type. - /// - public static readonly KnownTypeReference ValueType = Get(KnownTypeCode.ValueType); - - /// - /// Gets a type reference pointing to the System.Enum type. - /// - public static readonly KnownTypeReference Enum = Get(KnownTypeCode.Enum); - - /// - /// Gets a type reference pointing to the System.Delegate type. - /// - public static readonly KnownTypeReference Delegate = Get(KnownTypeCode.Delegate); - - /// - /// Gets a type reference pointing to the System.MulticastDelegate type. - /// - public static readonly KnownTypeReference MulticastDelegate = Get(KnownTypeCode.MulticastDelegate); - - /// - /// Gets a type reference pointing to the System.Exception type. - /// - public static readonly KnownTypeReference Exception = Get(KnownTypeCode.Exception); - - /// - /// Gets a type reference pointing to the System.IntPtr type. - /// - public static readonly KnownTypeReference IntPtr = Get(KnownTypeCode.IntPtr); - - /// - /// Gets a type reference pointing to the System.UIntPtr type. - /// - public static readonly KnownTypeReference UIntPtr = Get(KnownTypeCode.UIntPtr); - - /// - /// Gets a type reference pointing to the System.Collections.IEnumerable type. - /// - public static readonly KnownTypeReference IEnumerable = Get(KnownTypeCode.IEnumerable); - - /// - /// Gets a type reference pointing to the System.Collections.IEnumerator type. - /// - public static readonly KnownTypeReference IEnumerator = Get(KnownTypeCode.IEnumerator); - - /// - /// Gets a type reference pointing to the System.Collections.Generic.IEnumerable{T} type. - /// - public static readonly KnownTypeReference IEnumerableOfT = Get(KnownTypeCode.IEnumerableOfT); - - /// - /// Gets a type reference pointing to the System.Collections.Generic.IEnumerator{T} type. - /// - public static readonly KnownTypeReference IEnumeratorOfT = Get(KnownTypeCode.IEnumeratorOfT); - - /// - /// Gets a type reference pointing to the System.Collections.ICollection type. - /// - public static readonly KnownTypeReference ICollection = Get(KnownTypeCode.ICollection); - - /// - /// Gets a type reference pointing to the System.Collections.Generic.ICollection{T} type. - /// - public static readonly KnownTypeReference ICollectionOfT = Get(KnownTypeCode.ICollectionOfT); - - /// - /// Gets a type reference pointing to the System.Collections.IList type. - /// - public static readonly KnownTypeReference IList = Get(KnownTypeCode.IList); - - /// - /// Gets a type reference pointing to the System.Collections.Generic.IList{T} type. - /// - public static readonly KnownTypeReference IListOfT = Get(KnownTypeCode.IListOfT); - - /// - /// Gets a type reference pointing to the System.Collections.Generic.IReadOnlyCollection{T} type. - /// - public static readonly KnownTypeReference IReadOnlyCollectionOfT = Get(KnownTypeCode.IReadOnlyCollectionOfT); - - /// - /// Gets a type reference pointing to the System.Collections.Generic.IReadOnlyList{T} type. - /// - public static readonly KnownTypeReference IReadOnlyListOfT = Get(KnownTypeCode.IReadOnlyListOfT); - - /// - /// Gets a type reference pointing to the System.Threading.Tasks.Task type. - /// - public static readonly KnownTypeReference Task = Get(KnownTypeCode.Task); - - /// - /// Gets a type reference pointing to the System.Threading.Tasks.Task{T} type. - /// - public static readonly KnownTypeReference TaskOfT = Get(KnownTypeCode.TaskOfT); - - /// - /// Gets a type reference pointing to the System.Nullable{T} type. - /// - public static readonly KnownTypeReference NullableOfT = Get(KnownTypeCode.NullableOfT); - - /// - /// Gets a type reference pointing to the System.IDisposable type. - /// - public static readonly KnownTypeReference IDisposable = Get(KnownTypeCode.IDisposable); - - /// - /// Gets a type reference pointing to the System.Runtime.CompilerServices.INotifyCompletion type. - /// - public static readonly KnownTypeReference INotifyCompletion = Get(KnownTypeCode.INotifyCompletion); - - /// - /// Gets a type reference pointing to the System.Runtime.CompilerServices.ICriticalNotifyCompletion type. - /// - public static readonly KnownTypeReference ICriticalNotifyCompletion = Get(KnownTypeCode.ICriticalNotifyCompletion); - - /// - /// Gets a type reference pointing to the System.TypedReference type. - /// - public static readonly KnownTypeReference TypedReference = Get(KnownTypeCode.TypedReference); - readonly KnownTypeCode knownTypeCode; readonly string namespaceName; readonly string name; readonly int typeParameterCount; internal readonly KnownTypeCode baseType; - - private KnownTypeReference(KnownTypeCode knownTypeCode, string namespaceName, string name, int typeParameterCount = 0, KnownTypeCode baseType = KnownTypeCode.Object) + internal readonly TypeKind typeKind; + + private KnownTypeReference(KnownTypeCode knownTypeCode, TypeKind typeKind, string namespaceName, string name, int typeParameterCount = 0, KnownTypeCode baseType = KnownTypeCode.Object) { + if (typeKind == TypeKind.Struct && baseType == KnownTypeCode.Object) + baseType = KnownTypeCode.ValueType; this.knownTypeCode = knownTypeCode; this.namespaceName = namespaceName; this.name = name; this.typeParameterCount = typeParameterCount; + this.typeKind = typeKind; this.baseType = baseType; } diff --git a/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs b/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs index aa00e4290..4dd19dc71 100644 --- a/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs +++ b/ICSharpCode.Decompiler/TypeSystem/MetadataAssembly.cs @@ -524,49 +524,38 @@ namespace ICSharpCode.Decompiler.TypeSystem #endregion #region Module / Assembly attributes - IAttribute[] assemblyAttributes; - IAttribute[] moduleAttributes; - /// /// Gets the list of all assembly attributes in the project. /// - public IReadOnlyList AssemblyAttributes { - get { - var attrs = LazyInit.VolatileRead(ref this.assemblyAttributes); - if (attrs != null) - return attrs; - var b = new AttributeListBuilder(this); - if (metadata.IsAssembly) { - var assembly = metadata.GetAssemblyDefinition(); - b.Add(metadata.GetCustomAttributes(Handle.AssemblyDefinition)); - b.AddSecurityAttributes(assembly.GetDeclarativeSecurityAttributes()); - - // AssemblyVersionAttribute - if (assembly.Version != null) { - b.Add(KnownAttribute.AssemblyVersion, KnownTypeCode.String, assembly.Version.ToString()); - } + public IEnumerable GetAssemblyAttributes() + { + var b = new AttributeListBuilder(this); + if (metadata.IsAssembly) { + var assembly = metadata.GetAssemblyDefinition(); + b.Add(metadata.GetCustomAttributes(Handle.AssemblyDefinition)); + b.AddSecurityAttributes(assembly.GetDeclarativeSecurityAttributes()); - AddTypeForwarderAttributes(ref b); + // AssemblyVersionAttribute + if (assembly.Version != null) { + b.Add(KnownAttribute.AssemblyVersion, KnownTypeCode.String, assembly.Version.ToString()); } - return LazyInit.GetOrSet(ref this.assemblyAttributes, b.Build()); + + AddTypeForwarderAttributes(ref b); } + return b.Build(); } /// /// Gets the list of all module attributes in the project. /// - public IReadOnlyList ModuleAttributes { - get { - var attrs = LazyInit.VolatileRead(ref this.moduleAttributes); - if (attrs != null) - return attrs; - var b = new AttributeListBuilder(this); - b.Add(metadata.GetCustomAttributes(Handle.ModuleDefinition)); - if (!metadata.IsAssembly) { - AddTypeForwarderAttributes(ref b); - } - return LazyInit.GetOrSet(ref this.moduleAttributes, b.Build()); + public IEnumerable GetModuleAttributes() + { + var b = new AttributeListBuilder(this); + b.Add(metadata.GetCustomAttributes(Handle.ModuleDefinition)); + if (!metadata.IsAssembly) { + AddTypeForwarderAttributes(ref b); } + return b.Build(); } void AddTypeForwarderAttributes(ref AttributeListBuilder b) diff --git a/ICSharpCode.Decompiler/TypeSystem/NullableType.cs b/ICSharpCode.Decompiler/TypeSystem/NullableType.cs index 27a7322ba..ec3e91281 100644 --- a/ICSharpCode.Decompiler/TypeSystem/NullableType.cs +++ b/ICSharpCode.Decompiler/TypeSystem/NullableType.cs @@ -81,7 +81,7 @@ namespace ICSharpCode.Decompiler.TypeSystem { if (elementType == null) throw new ArgumentNullException("elementType"); - return new ParameterizedTypeReference(KnownTypeReference.NullableOfT, new [] { elementType }); + return new ParameterizedTypeReference(KnownTypeReference.Get(KnownTypeCode.NullableOfT), new [] { elementType }); } } }