Browse Source

#1195: Remove modopts/modreqs from the type system; they confuse the decompiler.

pull/1243/head
Daniel Grunwald 7 years ago
parent
commit
79352d18d7
  1. 34
      ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs
  2. 13
      ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs
  3. 2
      ILSpy/LoadedAssembly.cs

34
ICSharpCode.Decompiler/TypeSystem/ApplyAttributeTypeVisitor.cs

@ -39,15 +39,12 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -39,15 +39,12 @@ namespace ICSharpCode.Decompiler.TypeSystem
TypeSystemOptions options,
bool typeChildrenOnly = false)
{
if ((options & (TypeSystemOptions.Dynamic | TypeSystemOptions.Tuple)) == TypeSystemOptions.None) {
return inputType;
}
bool useDynamicType = (options & TypeSystemOptions.Dynamic) != 0;
bool useTupleTypes = (options & TypeSystemOptions.Tuple) != 0;
bool hasDynamicAttribute = false;
bool[] dynamicAttributeData = null;
string[] tupleElementNames = null;
if (attributes != null) {
if (attributes != null && (useDynamicType || useTupleTypes)) {
foreach (var attrHandle in attributes.Value) {
var attr = metadata.GetCustomAttribute(attrHandle);
var attrType = attr.GetAttributeType(metadata);
@ -73,9 +70,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -73,9 +70,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
}
if (hasDynamicAttribute || useTupleTypes) {
if (hasDynamicAttribute || (options & (TypeSystemOptions.Tuple | TypeSystemOptions.KeepModifiers)) != TypeSystemOptions.KeepModifiers) {
var visitor = new ApplyAttributeTypeVisitor(
compilation, hasDynamicAttribute, dynamicAttributeData, useTupleTypes, tupleElementNames
compilation, hasDynamicAttribute, dynamicAttributeData, options, tupleElementNames
);
if (typeChildrenOnly) {
return inputType.VisitChildren(visitor);
@ -90,20 +87,36 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -90,20 +87,36 @@ namespace ICSharpCode.Decompiler.TypeSystem
readonly ICompilation compilation;
readonly bool hasDynamicAttribute;
readonly bool[] dynamicAttributeData;
readonly bool useTupleTypes;
readonly TypeSystemOptions options;
readonly string[] tupleElementNames;
int dynamicTypeIndex = 0;
int tupleTypeIndex = 0;
private ApplyAttributeTypeVisitor(ICompilation compilation, bool hasDynamicAttribute, bool[] dynamicAttributeData, bool useTupleTypes, string[] tupleElementNames)
private ApplyAttributeTypeVisitor(ICompilation compilation, bool hasDynamicAttribute, bool[] dynamicAttributeData, TypeSystemOptions options, string[] tupleElementNames)
{
this.compilation = compilation ?? throw new ArgumentNullException(nameof(compilation));
this.hasDynamicAttribute = hasDynamicAttribute;
this.dynamicAttributeData = dynamicAttributeData;
this.useTupleTypes = useTupleTypes;
this.options = options;
this.tupleElementNames = tupleElementNames;
}
public override IType VisitModOpt(ModifiedType type)
{
if ((options & TypeSystemOptions.KeepModifiers) != 0)
return base.VisitModOpt(type);
else
return type.ElementType.AcceptVisitor(this);
}
public override IType VisitModReq(ModifiedType type)
{
if ((options & TypeSystemOptions.KeepModifiers) != 0)
return base.VisitModReq(type);
else
return type.ElementType.AcceptVisitor(this);
}
public override IType VisitPointerType(PointerType type)
{
dynamicTypeIndex++;
@ -124,6 +137,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -124,6 +137,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
public override IType VisitParameterizedType(ParameterizedType type)
{
bool useTupleTypes = (options & TypeSystemOptions.Tuple) != 0;
if (useTupleTypes && TupleType.IsTupleCompatible(type, out int tupleCardinality)) {
if (tupleCardinality > 1) {
var valueTupleAssembly = type.GetDefinition()?.ParentModule;
@ -168,7 +182,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -168,7 +182,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
}
}
// Visit generic type and type arguments.
// Like base implementation, except that it increments typeIndex.
// Like base implementation, except that it increments dynamicTypeIndex.
var genericType = type.GenericType.AcceptVisitor(this);
bool changed = type.GenericType != genericType;
var arguments = new IType[type.TypeArguments.Count];

13
ICSharpCode.Decompiler/TypeSystem/DecompilerTypeSystem.cs

@ -71,13 +71,20 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -71,13 +71,20 @@ namespace ICSharpCode.Decompiler.TypeSystem
/// Also, some code in the decompiler expects to be able to compare type/member definitions by reference equality,
/// and thus will fail with uncached type systems.
/// </summary>
Uncached = 16,
Uncached = 0x10,
/// <summary>
/// If this option is active, [DecimalConstantAttribute] is removed and constant values are transformed into simple decimal literals.
/// </summary>
DecimalConstants = 32,
DecimalConstants = 0x20,
/// <summary>
/// Default settings: all features enabled.
/// If this option is active, modopt and modreq types are preserved in the type system.
///
/// Note: the decompiler currently does not support handling modified types;
/// activating this option may lead to incorrect decompilation or internal errors.
/// </summary>
KeepModifiers = 0x40,
/// <summary>
/// Default settings: typical options for the decompiler, with all C# languages features enabled.
/// </summary>
Default = Dynamic | Tuple | ExtensionMethods | DecimalConstants
}

2
ILSpy/LoadedAssembly.cs

@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy @@ -111,7 +111,7 @@ namespace ICSharpCode.ILSpy
if (module == null)
return null;
return typeSystem = new SimpleCompilation(
module.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.Uncached),
module.WithOptions(TypeSystemOptions.Default | TypeSystemOptions.Uncached | TypeSystemOptions.KeepModifiers),
MinimalCorlib.Instance);
}

Loading…
Cancel
Save