Browse Source

Merge branch 'master' of https://github.com/icsharpcode/ILSpy into ref

pull/1596/head
Siegfried Pammer 6 years ago
parent
commit
5237965619
  1. 20
      ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs
  2. 24
      ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs
  3. 6
      ICSharpCode.Decompiler/IL/ILReader.cs
  4. 4
      ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs
  5. 2
      ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs
  6. 8
      ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

20
ICSharpCode.Decompiler.Tests/TestCases/Pretty/TupleTests.cs

@ -38,6 +38,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -38,6 +38,15 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
}
}
public struct GenericStruct<T>
{
public T Field;
public T Property {
get;
set;
}
}
public ValueTuple VT0;
public ValueTuple<int> VT1;
public ValueTuple<int, int, int, int, int, int, int, ValueTuple> VT7EmptyRest;
@ -171,6 +180,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty @@ -171,6 +180,17 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Pretty
});
}
public void DynamicTuple((dynamic A, dynamic B) a)
{
a.A.DynamicCall();
a.B.Dynamic = 42;
}
public void GenericStructWithElementNames(GenericStruct<(int A, int B)> s)
{
Console.WriteLine(s.Field.A + s.Property.B);
}
public void RefCallSites(out (int, string, Action, dynamic) tuple)
{
UnnamedTupleOut(out tuple);

24
ICSharpCode.Decompiler/CSharp/ExpressionBuilder.cs

@ -248,19 +248,20 @@ namespace ICSharpCode.Decompiler.CSharp @@ -248,19 +248,20 @@ namespace ICSharpCode.Decompiler.CSharp
bool targetCasted = false;
var targetResolveResult = requireTarget ? target.ResolveResult : null;
bool IsUnambiguousAccess()
bool IsUnambiguousAccess(out MemberResolveResult result)
{
if (targetResolveResult == null) {
var result = resolver.ResolveSimpleName(field.Name, EmptyList<IType>.Instance, isInvocationTarget: false) as MemberResolveResult;
result = resolver.ResolveSimpleName(field.Name, EmptyList<IType>.Instance, isInvocationTarget: false) as MemberResolveResult;
return !(result == null || result.IsError || !result.Member.Equals(field, NormalizeTypeVisitor.TypeErasure));
} else {
var lookup = new MemberLookup(resolver.CurrentTypeDefinition, resolver.CurrentTypeDefinition.ParentModule);
var result = lookup.Lookup(target.ResolveResult, field.Name, EmptyList<IType>.Instance, false) as MemberResolveResult;
result = lookup.Lookup(target.ResolveResult, field.Name, EmptyList<IType>.Instance, false) as MemberResolveResult;
return !(result == null || result.IsError || !result.Member.Equals(field, NormalizeTypeVisitor.TypeErasure));
}
}
while (!IsUnambiguousAccess()) {
MemberResolveResult mrr;
while (!IsUnambiguousAccess(out mrr)) {
if (!requireTarget) {
requireTarget = true;
targetResolveResult = target.ResolveResult;
@ -272,13 +273,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -272,13 +273,16 @@ namespace ICSharpCode.Decompiler.CSharp
break;
}
}
if (mrr == null) {
mrr = new MemberResolveResult(target.ResolveResult, field);
}
if (requireTarget) {
return new MemberReferenceExpression(target, field.Name)
.WithRR(new MemberResolveResult(target.ResolveResult, field));
.WithRR(mrr);
} else {
return new IdentifierExpression(field.Name)
.WithRR(new MemberResolveResult(target.ResolveResult, field));
.WithRR(mrr);
}
}
@ -2086,14 +2090,16 @@ namespace ICSharpCode.Decompiler.CSharp @@ -2086,14 +2090,16 @@ namespace ICSharpCode.Decompiler.CSharp
nonVirtualInvocation: true,
memberStatic: false,
memberDeclaringType: underlyingTupleType);
if (translatedTarget.Type is TupleType tupleType && tupleType.UnderlyingType.Equals(underlyingTupleType) && position <= tupleType.ElementNames.Length) {
if (translatedTarget.Type is TupleType tupleType && NormalizeTypeVisitor.TypeErasure.EquivalentTypes(tupleType, underlyingTupleType) && position <= tupleType.ElementNames.Length) {
string elementName = tupleType.ElementNames[position - 1];
if (elementName == null) {
elementName = "Item" + position;
}
// tupleType.ElementTypes are more accurate w.r.t. nullability/dynamic than inst.Field.Type
var rr = new MemberResolveResult(translatedTarget.ResolveResult, inst.Field,
returnTypeOverride: tupleType.ElementTypes[position - 1]);
expr = new MemberReferenceExpression(translatedTarget, elementName)
.WithRR(new MemberResolveResult(translatedTarget.ResolveResult, inst.Field))
.WithILInstruction(inst);
.WithRR(rr).WithILInstruction(inst);
} else {
expr = ConvertField(inst.Field, inst.Target).WithILInstruction(inst);
}

6
ICSharpCode.Decompiler/IL/ILReader.cs

@ -1187,14 +1187,14 @@ namespace ICSharpCode.Decompiler.IL @@ -1187,14 +1187,14 @@ namespace ICSharpCode.Decompiler.IL
return Pop(StackType.O);
case false:
// field of value type: ldfld can handle temporaries
if (PeekStackType() == StackType.O)
if (PeekStackType() == StackType.O || PeekStackType() == StackType.Unknown)
return new AddressOf(Pop());
else
return PopPointer();
default:
// field in unresolved type
if (PeekStackType() == StackType.O)
return Pop(StackType.O);
if (PeekStackType() == StackType.O || PeekStackType() == StackType.Unknown)
return Pop();
else
return PopPointer();
}

4
ICSharpCode.Decompiler/IL/Instructions/LdFlda.cs

@ -36,7 +36,9 @@ namespace ICSharpCode.Decompiler.IL @@ -36,7 +36,9 @@ namespace ICSharpCode.Decompiler.IL
break;
case null:
// field of unresolved type
Debug.Assert(target.ResultType == StackType.O || target.ResultType == StackType.I || target.ResultType == StackType.Ref);
Debug.Assert(target.ResultType == StackType.O || target.ResultType == StackType.I
|| target.ResultType == StackType.Ref || target.ResultType == StackType.Unknown,
"Field of unresolved type with invalid target");
break;
}
}

2
ICSharpCode.Decompiler/IL/Transforms/NullableLiftingTransform.cs

@ -710,7 +710,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -710,7 +710,7 @@ namespace ICSharpCode.Decompiler.IL.Transforms
return (newInst, bits);
}
} else if (inst is Comp comp && !comp.IsLifted && comp.Kind == ComparisonKind.Equality
&& MatchGetValueOrDefault(comp.Left, out ILVariable v)
&& MatchGetValueOrDefault(comp.Left, out ILVariable v) && nullableVars.Contains(v)
&& NullableType.GetUnderlyingType(v.Type).IsKnownType(KnownTypeCode.Boolean)
&& comp.Right.MatchLdcI4(0)
) {

8
ICSharpCode.Decompiler/TypeSystem/MetadataModule.cs

@ -477,7 +477,9 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -477,7 +477,9 @@ namespace ICSharpCode.Decompiler.TypeSystem
typeParameters.Add(new DefaultTypeParameter(m, i));
}
m.TypeParameters = typeParameters;
substitution = new TypeParameterSubstitution(null, typeParameters);
substitution = new TypeParameterSubstitution(declaringType.TypeArguments, typeParameters);
} else if (declaringType.TypeArguments.Count > 0) {
substitution = declaringType.GetSubstitution();
}
var parameters = new List<IParameter>();
for (int i = 0; i < signature.RequiredParameterCount; i++) {
@ -553,6 +555,10 @@ namespace ICSharpCode.Decompiler.TypeSystem @@ -553,6 +555,10 @@ namespace ICSharpCode.Decompiler.TypeSystem
var field = declaringType.GetFields(f => f.Name == name && CompareTypes(f.ReturnType, signature),
GetMemberOptions.IgnoreInheritedMembers).FirstOrDefault();
if (field == null) {
// If it's a field in a generic type, we need to substitute the type arguments:
if (declaringType.TypeArguments.Count > 0) {
signature = signature.AcceptVisitor(declaringType.GetSubstitution());
}
field = new FakeField(Compilation) {
ReturnType = signature,
Name = name,

Loading…
Cancel
Save