mirror of
https://github.com/icsharpcode/ILSpy.git
synced 2026-10-12 02:15:58 +00:00
Merge pull request #4158 from icsharpcode/ldmembertoken
Invent a syntax for `ldtoken`.
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
@@ -19,7 +18,7 @@ namespace ICSharpCode.Decompiler.Tests.TestCases.Ugly
|
||||
public int[] LiteralArray()
|
||||
{
|
||||
int[] array = new int[3];
|
||||
RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/);
|
||||
RuntimeHelpers.InitializeArray(array, __ldtoken(_003CPrivateImplementationDetails_003E._4636993D3E1DA4E9D6B8F87B79E8F7C6D018580D52661950EABC3845C5897A4D));
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
@@ -5132,6 +5132,36 @@ namespace ICSharpCode.Decompiler.CSharp
|
||||
.WithILInstruction(inst);
|
||||
}
|
||||
|
||||
protected internal override TranslatedExpression VisitLdMemberToken(LdMemberToken inst, TranslationContext context)
|
||||
{
|
||||
// C# does not have syntax for obtaining a member token; so we emit pseudo-syntax:
|
||||
// fields: __ldtoken(DeclaringType.Member)
|
||||
// methods: __ldtoken(DeclaringType.Member(parameter-types))
|
||||
var classType = astBuilder.ConvertType(inst.Member.DeclaringType);
|
||||
var mre = new MemberReferenceExpression(
|
||||
new TypeReferenceExpression(classType),
|
||||
inst.Member.Name
|
||||
);
|
||||
Expression memberExpr = mre.WithRR(new MemberResolveResult(null, inst.Member));
|
||||
if (inst.Member is IMethod method)
|
||||
{
|
||||
foreach (var t in method.TypeArguments)
|
||||
{
|
||||
mre.TypeArguments.Add(astBuilder.ConvertType(t));
|
||||
}
|
||||
var inv = new InvocationExpression(memberExpr);
|
||||
foreach (var param in method.Parameters)
|
||||
{
|
||||
inv.Arguments.Add(new TypeReferenceExpression(astBuilder.ConvertType(param.Type)));
|
||||
}
|
||||
memberExpr = inv;
|
||||
}
|
||||
var tokenType = inst.Member is IField ? KnownTypeCode.RuntimeFieldHandle : KnownTypeCode.RuntimeMethodHandle;
|
||||
return new InvocationExpression(new IdentifierExpression("__ldtoken"), memberExpr)
|
||||
.WithRR(new ResolveResult(compilation.FindType(tokenType)))
|
||||
.WithILInstruction(inst);
|
||||
}
|
||||
|
||||
protected internal override TranslatedExpression VisitCallIndirect(CallIndirect inst, TranslationContext context)
|
||||
{
|
||||
if (inst.IsInstance)
|
||||
|
||||
@@ -152,7 +152,10 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
|
||||
// and using the main assembly can cause a stack overflow if there
|
||||
// are internal assembly attributes.
|
||||
}
|
||||
anyTypeDef = typeDef;
|
||||
// If there's multiple possible matches prefer the first one -- we most likely are
|
||||
// in the context of the assembly being decompiled, which usually is the first in the list,
|
||||
// so this increases the odds of picking the correct type.
|
||||
anyTypeDef ??= typeDef;
|
||||
}
|
||||
}
|
||||
return anyTypeDef;
|
||||
|
||||
Reference in New Issue
Block a user