Browse Source

Improve decompiler behavior is System.ValueTuple exists in multiple referenced assemblies.

This can happen if an application is compiled for .NET 4.6.2 and references
System.ValueTuple.dll; but ILSpy loads the latest mscorlib (e.g. .NET 4.7)
which also contains struct System.ValueTuple.
pull/1425/head
Daniel Grunwald 6 years ago
parent
commit
113acd48c1
  1. 3
      ICSharpCode.Decompiler/CSharp/CallBuilder.cs
  2. 16
      ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs
  3. 5
      ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs
  4. 9
      ICSharpCode.Decompiler/Semantics/TupleResolveResult.cs
  5. 2
      ICSharpCode.Decompiler/TypeSystem/TupleType.cs

3
ICSharpCode.Decompiler/CSharp/CallBuilder.cs

@ -164,7 +164,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -164,7 +164,8 @@ namespace ICSharpCode.Decompiler.CSharp
}
return tuple.WithRR(new TupleResolveResult(
expressionBuilder.compilation,
elementRRs.ToImmutableArray()
elementRRs.ToImmutableArray(),
valueTupleAssembly: inst.Method.DeclaringType.GetDefinition()?.ParentModule
)).WithILInstruction(inst);
}
return Build(inst.OpCode, inst.Method, inst.Arguments, constrainedTo: inst.ConstrainedTo)

16
ICSharpCode.Decompiler/CSharp/Syntax/TypeSystemAstBuilder.cs

@ -384,9 +384,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -384,9 +384,9 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
bool TypeMatches(IType type, ITypeDefinition typeDef, IReadOnlyList<IType> typeArguments)
{
if (typeDef.TypeParameterCount == 0) {
return typeDef.Equals(type);
return TypeDefMatches(typeDef, type);
} else {
if (!typeDef.Equals(type.GetDefinition()))
if (!TypeDefMatches(typeDef, type.GetDefinition()))
return false;
ParameterizedType pt = type as ParameterizedType;
if (pt == null) {
@ -401,6 +401,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax @@ -401,6 +401,18 @@ namespace ICSharpCode.Decompiler.CSharp.Syntax
}
}
bool TypeDefMatches(ITypeDefinition typeDef, IType type)
{
if (type.Name != typeDef.Name || type.Namespace != typeDef.Namespace || type.TypeParameterCount != typeDef.TypeParameterCount)
return false;
bool defIsNested = typeDef.DeclaringTypeDefinition != null;
bool typeIsNested = type.DeclaringType != null;
if (defIsNested && typeIsNested)
return TypeDefMatches(typeDef.DeclaringTypeDefinition, type.DeclaringType);
else
return defIsNested == typeIsNested;
}
/// <summary>
/// Adds type arguments to the result type.
/// </summary>

5
ICSharpCode.Decompiler/CSharp/TranslatedExpression.cs

@ -224,7 +224,10 @@ namespace ICSharpCode.Decompiler.CSharp @@ -224,7 +224,10 @@ namespace ICSharpCode.Decompiler.CSharp
newElementRRs.Add(newElementExpr.ResolveResult);
}
return newTupleExpr.WithILInstruction(this.ILInstructions)
.WithRR(new TupleResolveResult(expressionBuilder.compilation, newElementRRs.ToImmutableArray()));
.WithRR(new TupleResolveResult(
expressionBuilder.compilation, newElementRRs.ToImmutableArray(),
valueTupleAssembly: targetTupleType.GetDefinition()?.ParentModule
));
}
var compilation = expressionBuilder.compilation;
var conversions = Resolver.CSharpConversions.Get(compilation);

9
ICSharpCode.Decompiler/Semantics/TupleResolveResult.cs

@ -35,8 +35,9 @@ namespace ICSharpCode.Decompiler.Semantics @@ -35,8 +35,9 @@ namespace ICSharpCode.Decompiler.Semantics
public TupleResolveResult(ICompilation compilation,
ImmutableArray<ResolveResult> elements,
ImmutableArray<string> elementNames = default(ImmutableArray<string>))
: base(GetTupleType(compilation, elements, elementNames))
ImmutableArray<string> elementNames = default(ImmutableArray<string>),
IModule valueTupleAssembly = null)
: base(GetTupleType(compilation, elements, elementNames, valueTupleAssembly))
{
this.Elements = elements;
}
@ -46,12 +47,12 @@ namespace ICSharpCode.Decompiler.Semantics @@ -46,12 +47,12 @@ namespace ICSharpCode.Decompiler.Semantics
return Elements;
}
static IType GetTupleType(ICompilation compilation, ImmutableArray<ResolveResult> elements, ImmutableArray<string> elementNames)
static IType GetTupleType(ICompilation compilation, ImmutableArray<ResolveResult> elements, ImmutableArray<string> elementNames, IModule valueTupleAssembly)
{
if (elements.Any(e => e.Type.Kind == TypeKind.None || e.Type.Kind == TypeKind.Null))
return SpecialType.NoType;
else
return new TupleType(compilation, elements.Select(e => e.Type).ToImmutableArray(), elementNames);
return new TupleType(compilation, elements.Select(e => e.Type).ToImmutableArray(), elementNames, valueTupleAssembly);
}
}
}

2
ICSharpCode.Decompiler/TypeSystem/TupleType.cs

@ -84,7 +84,7 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -84,7 +84,7 @@ namespace ICSharpCode.Decompiler.TypeSystem
private static IType FindValueTupleType(ICompilation compilation, IModule valueTupleAssembly, int tpc)
{
FullTypeName typeName = new TopLevelTypeName("System", "ValueTuple", tpc);
var typeName = new TopLevelTypeName("System", "ValueTuple", tpc);
if (valueTupleAssembly != null) {
var typeDef = valueTupleAssembly.GetTypeDefinition(typeName);
if (typeDef != null)

Loading…
Cancel
Save