From 5c0190b1869f66309204d3053ffc1d7734b69588 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Sat, 23 Jun 2018 22:21:11 +0200 Subject: [PATCH] Rename TypeAttributeOptions -> TypeSystemOptions --- .../TypeSystem/ApplyAttributeTypeVisitor.cs | 20 ++----- .../TypeSystem/DecompilerTypeSystem.cs | 56 +++++++++++++---- .../Implementation/MetadataTypeReference.cs | 60 +++++++++---------- .../TypeSystem/MetadataLoader.cs | 47 ++++----------- 4 files changed, 90 insertions(+), 93 deletions(-) diff --git a/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs b/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs index e38a11829..fee0d5c0d 100644 --- a/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs +++ b/ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs @@ -25,18 +25,6 @@ using SRM = System.Reflection.Metadata; namespace ICSharpCode.Decompiler.TypeSystem { - /// - /// Options for converting builtin - /// - [Flags] - enum TypeAttributeOptions - { - None = 0, - Dynamic = 1, - Tuple = 2, - Default = Dynamic | Tuple - } - /// /// Introduces 'dynamic' and tuple types based on attribute values. /// @@ -47,20 +35,20 @@ namespace ICSharpCode.Decompiler.TypeSystem ICompilation compilation, SRM.CustomAttributeHandleCollection? attributes, SRM.MetadataReader metadata, - TypeAttributeOptions options) + TypeSystemOptions options) { - if (options == TypeAttributeOptions.None) { + if ((options & (TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple)) == TypeSystemOptions.None) { return inputType; } bool hasDynamicAttribute = false; bool[] dynamicAttributeData = null; - bool useTupleTypes = (options & TypeAttributeOptions.Tuple) != 0; + bool useTupleTypes = (options & TypeSystemOptions.Tuple) != 0; string[] tupleElementNames = null; if (attributes != null) { foreach (var attrHandle in attributes.Value) { var attr = metadata.GetCustomAttribute(attrHandle); var attrType = attr.GetAttributeType(metadata); - if ((options & TypeAttributeOptions.Dynamic) != 0 + if ((options & TypeSystemOptions.Dynamic) != 0 && attrType.IsTopLevelType(metadata, "System.Runtime.CompilerServices", "DynamicAttribute")) { hasDynamicAttribute = true; var ctor = attr.DecodeValue(Metadata.MetadataExtensions.minimalCorlibTypeProvider); diff --git a/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs b/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs index 44d8a2352..35a04bad0 100644 --- a/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs +++ b/ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs @@ -29,6 +29,40 @@ using System.Collections.Immutable; namespace ICSharpCode.Decompiler.TypeSystem { + /// + /// Options that control how metadata is represented in the type system. + /// + [Flags] + public enum TypeSystemOptions + { + /// + /// No options enabled; stay as close to the metadata as possible. + /// + None = 0, + /// + /// [DynamicAttribute] is used to replace 'object' types with the 'dynamic' type. + /// + /// If this option is not active, the 'dynamic' type is not used, and the attribute is preserved. + /// + Dynamic = 1, + /// + /// Tuple types are represented using the TupleType class. + /// [TupleElementNames] is used to name the tuple elements. + /// + /// If this option is not active, the tuples are represented using their underlying type, and the attribute is preserved. + /// + Tuple = 2, + /// + /// If this option is active, [ExtensionAttribute] is removed and methods are marked as IsExtensionMethod. + /// Otherwise, the attribute is preserved but the methods are not marked. + /// + ExtensionMethods = 4, + /// + /// Default settings: all features enabled. + /// + Default = Dynamic | Tuple | ExtensionMethods + } + /// /// Manages the NRefactory type system for the decompiler. /// @@ -40,7 +74,7 @@ namespace ICSharpCode.Decompiler.TypeSystem readonly Metadata.PEFile moduleDefinition; readonly ICompilation compilation; readonly ITypeResolveContext context; - readonly TypeAttributeOptions typeAttributeOptions; + readonly TypeSystemOptions typeSystemOptions; Dictionary fieldLookupCache = new Dictionary(); Dictionary propertyLookupCache = new Dictionary(); @@ -58,17 +92,17 @@ namespace ICSharpCode.Decompiler.TypeSystem if (settings == null) throw new ArgumentNullException(nameof(settings)); this.moduleDefinition = moduleDefinition; - typeAttributeOptions = TypeAttributeOptions.None; + typeSystemOptions = TypeSystemOptions.None; if (settings.Dynamic) - typeAttributeOptions |= TypeAttributeOptions.Dynamic; + typeSystemOptions |= TypeSystemOptions.Dynamic; if (settings.TupleTypes) - typeAttributeOptions |= TypeAttributeOptions.Tuple; + typeSystemOptions |= TypeSystemOptions.Tuple; + if (settings.ExtensionMethods) + typeSystemOptions |= TypeSystemOptions.ExtensionMethods; MetadataLoader loader = new MetadataLoader { IncludeInternalMembers = true, ShortenInterfaceImplNames = false, - UseDynamicType = settings.Dynamic, - UseTupleTypes = settings.TupleTypes, - UseExtensionMethods = settings.ExtensionMethods, + Options = typeSystemOptions, }; IUnresolvedAssembly mainAssembly = loader.LoadModule(moduleDefinition); // Load referenced assemblies and type-forwarder references. @@ -160,8 +194,7 @@ namespace ICSharpCode.Decompiler.TypeSystem typeReference, moduleDefinition.Metadata, context, - typeAttributes: null, - typeAttributeOptions + typeSystemOptions ); } @@ -172,8 +205,7 @@ namespace ICSharpCode.Decompiler.TypeSystem declaringTypeReference, moduleDefinition.Metadata, context, - typeAttributes: null, - attributeOptions: TypeAttributeOptions.None + typeSystemOptions & ~(TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple) ); } #endregion @@ -226,7 +258,7 @@ namespace ICSharpCode.Decompiler.TypeSystem field = new FakeField(compilation) { DeclaringType = declaringType, Name = metadata.GetString(fieldDef.Name), - ReturnType = FieldTypeReference.Resolve(fieldDefHandle, metadata, context, typeAttributeOptions), + ReturnType = FieldTypeReference.Resolve(fieldDefHandle, metadata, context, typeSystemOptions), IsStatic = (fieldDef.Attributes & System.Reflection.FieldAttributes.Static) != 0, }; } diff --git a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs index 60fb3f19f..1283c53b6 100644 --- a/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs +++ b/ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeReference.cs @@ -30,30 +30,30 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation readonly SRM.EntityHandle type; readonly SRM.MetadataReader metadata; readonly SRM.CustomAttributeHandleCollection? typeAttributes; - readonly TypeAttributeOptions attributeOptions; + readonly TypeSystemOptions options; public MetadataTypeReference(SRM.EntityHandle type, SRM.MetadataReader metadata, SRM.CustomAttributeHandleCollection? typeAttributes, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options) { this.type = type; this.metadata = metadata; this.typeAttributes = typeAttributes; - this.attributeOptions = attributeOptions; + this.options = options; } public IType Resolve(ITypeResolveContext context) { return Resolve(type, metadata, context, - typeAttributes, attributeOptions); + options, typeAttributes); } public static IType Resolve(SRM.EntityHandle type, SRM.MetadataReader metadata, ITypeResolveContext context, - SRM.CustomAttributeHandleCollection? typeAttributes, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options, + SRM.CustomAttributeHandleCollection? typeAttributes = null) { if (type.IsNil) return SpecialType.UnknownType; @@ -76,7 +76,7 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation break; } ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, context.Compilation, - typeAttributes, metadata, attributeOptions); + typeAttributes, metadata, options); return ty; } } @@ -85,35 +85,35 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation { readonly SRM.EntityHandle fieldHandle; readonly SRM.MetadataReader metadata; - readonly TypeAttributeOptions attributeOptions; + readonly TypeSystemOptions options; public FieldTypeReference(SRM.FieldDefinitionHandle fieldHandle, SRM.MetadataReader metadata, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options) { this.fieldHandle = fieldHandle; this.metadata = metadata; - this.attributeOptions = attributeOptions; + this.options = options; } public FieldTypeReference(SRM.MemberReferenceHandle fieldReferenceHandle, SRM.MetadataReader metadata, - TypeAttributeOptions attributeOptions) + TypeSystemOptions attributeOptions) { this.fieldHandle = fieldReferenceHandle; this.metadata = metadata; - this.attributeOptions = attributeOptions; + this.options = attributeOptions; } IType ITypeReference.Resolve(ITypeResolveContext context) { if (fieldHandle.Kind == SRM.HandleKind.FieldDefinition) { - return Resolve((SRM.FieldDefinitionHandle)fieldHandle, metadata, context, attributeOptions); + return Resolve((SRM.FieldDefinitionHandle)fieldHandle, metadata, context, options); } else { var memberRef = metadata.GetMemberReference((SRM.MemberReferenceHandle)fieldHandle); IType ty = memberRef.DecodeFieldSignature(new TypeProvider(context.CurrentAssembly), context); ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, context.Compilation, - memberRef.GetCustomAttributes(), metadata, attributeOptions); + memberRef.GetCustomAttributes(), metadata, options); return ty; } } @@ -121,12 +121,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public static IType Resolve(SRM.FieldDefinitionHandle fieldHandle, SRM.MetadataReader metadata, ITypeResolveContext context, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options) { var fieldDef = metadata.GetFieldDefinition(fieldHandle); IType ty = fieldDef.DecodeSignature(new TypeProvider(context.CurrentAssembly), context); ty = ApplyAttributeTypeVisitor.ApplyAttributesToType(ty, context.Compilation, - fieldDef.GetCustomAttributes(), metadata, attributeOptions); + fieldDef.GetCustomAttributes(), metadata, options); return ty; } } @@ -138,22 +138,22 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation { readonly SRM.EntityHandle handle; readonly SRM.MetadataReader metadata; - readonly TypeAttributeOptions attributeOptions; + readonly TypeSystemOptions options; public UnresolvedMethodSignature(SRM.MethodDefinitionHandle handle, SRM.MetadataReader metadata, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options) { this.handle = handle; this.metadata = metadata; - this.attributeOptions = attributeOptions; + this.options = options; } public UnresolvedMethodSignature(SRM.PropertyDefinitionHandle handle, SRM.MetadataReader metadata, - TypeAttributeOptions attributeOptions) + TypeSystemOptions attributeOptions) { this.handle = handle; this.metadata = metadata; - this.attributeOptions = attributeOptions; + this.options = attributeOptions; } public SRM.MethodSignature Resolve(ITypeResolveContext context) @@ -165,12 +165,12 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation case SRM.HandleKind.MethodDefinition: return GetSignature( metadata.GetMethodDefinition((SRM.MethodDefinitionHandle)handle), - metadata, context, attributeOptions + metadata, context, options ); case SRM.HandleKind.PropertyDefinition: return GetSignature( metadata.GetPropertyDefinition((SRM.PropertyDefinitionHandle)handle), - metadata, context, attributeOptions + metadata, context, options ); default: throw new InvalidOperationException(); @@ -181,16 +181,16 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation public static SRM.MethodSignature GetSignature(SRM.MethodDefinition methodDef, SRM.MetadataReader metadata, ITypeResolveContext context, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options) { var typeProvider = new TypeProvider(context.CurrentAssembly); var signature = methodDef.DecodeSignature(typeProvider, context); - return ApplyAttributes(signature, methodDef.GetParameters(), context.Compilation, metadata, attributeOptions); + return ApplyAttributes(signature, methodDef.GetParameters(), context.Compilation, metadata, options); } public static SRM.MethodSignature GetSignature(SRM.PropertyDefinition propertyDef, SRM.MetadataReader metadata, ITypeResolveContext context, - TypeAttributeOptions attributeOptions) + TypeSystemOptions options) { var typeProvider = new TypeProvider(context.CurrentAssembly); var signature = propertyDef.DecodeSignature(typeProvider, context); @@ -205,10 +205,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation parameterHandles = setter.GetParameters(); } } - return ApplyAttributes(signature, parameterHandles, context.Compilation, metadata, attributeOptions); + return ApplyAttributes(signature, parameterHandles, context.Compilation, metadata, options); } - static SRM.MethodSignature ApplyAttributes(SRM.MethodSignature signature, SRM.ParameterHandleCollection? parameterHandles, ICompilation compilation, SRM.MetadataReader metadata, TypeAttributeOptions attributeOptions) + static SRM.MethodSignature ApplyAttributes(SRM.MethodSignature signature, SRM.ParameterHandleCollection? parameterHandles, ICompilation compilation, SRM.MetadataReader metadata, TypeSystemOptions options) { SRM.CustomAttributeHandleCollection? returnTypeAttributes = null; var parameterAttributes = new SRM.CustomAttributeHandleCollection?[signature.ParameterTypes.Length]; @@ -223,11 +223,11 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation } } IType returnType = ApplyAttributeTypeVisitor.ApplyAttributesToType( - signature.ReturnType, compilation, returnTypeAttributes, metadata, attributeOptions + signature.ReturnType, compilation, returnTypeAttributes, metadata, options ); var parameterTypes = signature.ParameterTypes.SelectWithIndex( (i, p) => ApplyAttributeTypeVisitor.ApplyAttributesToType( - p, compilation, parameterAttributes[i], metadata, attributeOptions + p, compilation, parameterAttributes[i], metadata, options ) ).ToImmutableArray(); return new SRM.MethodSignature( diff --git a/ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs b/ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs index 8ee73b870..da0d2796d 100644 --- a/ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs +++ b/ICSharpCode.Decompiler/TypeSystem/MetadataLoader.cs @@ -50,19 +50,9 @@ namespace ICSharpCode.Decompiler.TypeSystem public bool IncludeInternalMembers { get; set; } /// - /// Gets/Sets whether to use the dynamic type. + /// Gets/Sets type system options. /// - public bool UseDynamicType { get; set; } = true; - - /// - /// Gets/Sets whether to use the tuple types. - /// - public bool UseTupleTypes { get; set; } = true; - - /// - /// Gets/Sets whether to use extension methods. - /// - public bool UseExtensionMethods { get; set; } = true; + public TypeSystemOptions Options { get; set; } /// /// Gets/Sets the cancellation token used by the assembly loader. @@ -136,9 +126,7 @@ namespace ICSharpCode.Decompiler.TypeSystem this.IncludeInternalMembers = loader.IncludeInternalMembers; this.LazyLoad = loader.LazyLoad; this.ShortenInterfaceImplNames = loader.ShortenInterfaceImplNames; - this.UseDynamicType = loader.UseDynamicType; - this.UseTupleTypes = loader.UseTupleTypes; - this.UseExtensionMethods = loader.UseExtensionMethods; + this.Options = loader.Options; this.currentModule = loader.currentModule; this.currentMetadata = loader.currentMetadata; this.currentAssembly = loader.currentAssembly; @@ -298,18 +286,7 @@ namespace ICSharpCode.Decompiler.TypeSystem /// public ITypeReference ReadTypeReference(EntityHandle type, CustomAttributeHandleCollection? typeAttributes = null) { - return new MetadataTypeReference(type, currentMetadata, typeAttributes, TypeAttributeOptions); - } - - private TypeAttributeOptions TypeAttributeOptions { - get { - TypeAttributeOptions options = TypeAttributeOptions.None; - if (UseDynamicType) - options |= TypeAttributeOptions.Dynamic; - if (UseTupleTypes) - options |= TypeAttributeOptions.Tuple; - return options; - } + return new MetadataTypeReference(type, currentMetadata, typeAttributes, Options); } #endregion @@ -695,11 +672,11 @@ namespace ICSharpCode.Decompiler.TypeSystem case "System.Runtime.CompilerServices": switch (typeName.Name) { case "DynamicAttribute": - return UseDynamicType; + return (Options & TypeSystemOptions.Dynamic) != 0; case "TupleElementNamesAttribute": - return UseTupleTypes; + return (Options & TypeSystemOptions.Tuple) != 0; case "ExtensionAttribute": - return UseExtensionMethods; + return (Options & TypeSystemOptions.ExtensionMethods) != 0; case "DecimalConstantAttribute": return true; default: @@ -827,7 +804,7 @@ namespace ICSharpCode.Decompiler.TypeSystem foreach (FieldDefinitionHandle h in typeDefinition.GetFields()) { var enumField = currentMetadata.GetFieldDefinition(h); if (!enumField.HasFlag(FieldAttributes.Static)) { - baseTypes.Add(new FieldTypeReference(h, currentMetadata, TypeAttributeOptions.None)); + baseTypes.Add(new FieldTypeReference(h, currentMetadata, TypeSystemOptions.None)); break; } } @@ -1233,7 +1210,7 @@ namespace ICSharpCode.Decompiler.TypeSystem TranslateModifiers(handle, m); var signature = method.DecodeSignature(TypeCodeProvider.Instance, default); - var unresolvedSig = new UnresolvedMethodSignature(handle, currentMetadata, TypeAttributeOptions); + var unresolvedSig = new UnresolvedMethodSignature(handle, currentMetadata, Options); var (retType, parameters) = TranslateSignature(signature, unresolvedSig, method.GetParameters()); m.ReturnType = retType; m.Parameters.AddRange(parameters); @@ -1354,7 +1331,7 @@ namespace ICSharpCode.Decompiler.TypeSystem bool HasExtensionAttribute(MetadataReader metadata, CustomAttributeHandleCollection attributes) { - if (!UseExtensionMethods) + if ((Options & TypeSystemOptions.ExtensionMethods) == 0) return false; foreach (var h in attributes) { var attr = metadata.GetCustomAttribute(h); @@ -1506,7 +1483,7 @@ namespace ICSharpCode.Decompiler.TypeSystem f.Accessibility = GetAccessibility(field.Attributes); f.IsReadOnly = (field.Attributes & FieldAttributes.InitOnly) == FieldAttributes.InitOnly; f.IsStatic = (field.Attributes & FieldAttributes.Static) == FieldAttributes.Static; - f.ReturnType = new FieldTypeReference(handle, currentMetadata, TypeAttributeOptions); + f.ReturnType = new FieldTypeReference(handle, currentMetadata, Options); var constantHandle = field.GetDefaultValue(); if (!constantHandle.IsNil) { var constant = currentMetadata.GetConstant(constantHandle); @@ -1629,7 +1606,7 @@ namespace ICSharpCode.Decompiler.TypeSystem } var signature = property.DecodeSignature(TypeCodeProvider.Instance, default); - var unresolvedSig = new UnresolvedMethodSignature(handle, currentMetadata, TypeAttributeOptions); + var unresolvedSig = new UnresolvedMethodSignature(handle, currentMetadata, Options); var (retType, parameters) = TranslateSignature(signature, unresolvedSig, parameterHandles); p.ReturnType = retType; p.Parameters.AddRange(parameters);