创建新对象的 ByteBuddy 方法实现

ByteBuddy method implementation that creates a new object

我正在使用 Byte Buddy 1.9.0 作为基于 Xtext 的编程语言的代码生成器,并且我正在努力为实例化 "anonymous" class 的方法生成字节码。出于所有意图和目的,我正在尝试让 Byte Buddy 创建一个方法来执行与此等效的操作:

package fxxx.test;
class DummyUser
{
  DummyOperator dummy()
  {
    return new DummyUser();
  }
}

我的编译器已经创建了嵌套的 "anonymous" class DummyUser,但是,对于我来说,我无法想出正确的 Byte Buddy 指令序列来创建一个该 class 的新对象,然后 return 该对象。 经过一些搜索,我遇到了 MethodCall.construct(MethodDescription),但我当前的代码只产生以下异常:

java.lang.IllegalStateException: Cannot return void from public fxxx.test.DummyOperator fxxx.test.DummyUser_.dummy()
    at net.bytebuddy.implementation.MethodCall$TerminationHandler.resolve(MethodCall.java:2189)
    at net.bytebuddy.implementation.MethodCall.toStackManipulation(MethodCall.java:2405)
    at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:2434)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyCode(TypeWriter.java:698)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod$WithBody.applyBody(TypeWriter.java:683)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$MethodPool$Record$ForDefinedMethod.apply(TypeWriter.java:590)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForCreation.create(TypeWriter.java:5114)
    at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:1915)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:197)
    at net.bytebuddy.dynamic.scaffold.subclass.SubclassDynamicTypeBuilder.make(SubclassDynamicTypeBuilder.java:174)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3376)
    at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase$Delegator.make(DynamicType.java:3565)
...

这个错误似乎告诉我,有点可以理解,因为 class 的构造函数有一个 <init>()V 签名,技术上 returns void 这是等价的从一个方法 returning 一个 void 值,该方法实际上应该 return DummyOperator 的一些子 class。我试图将 MethodCall.construct 与复制堆栈顶部的 StackManipulation 结合起来,但是由于 TypeCreation 通过 new 字节码已经被烘焙到 MethodCall.construct 我似乎无法访问新创建的原始对象实例。 该项目尚未开源,但我可以提供这个片段(使用 Xtend 语法)来说明我的代码在做什么:

    val Builder<?> anonymousClass = ... // the anonymous class that has already been created
    val TypeDescription declaringType = describe(anonymousClass) // basically .make.typeDescription
    val MethodDescription constructor = method(declaringType, new TypeDescription.ForLoadedType(void), "<init>", #[]) // new Latent declaringType/returnType
    val MethodCall construct = MethodCall.construct(constructor)
    // ^^^ this value gets return as the new method's Implementation

我缺少什么才能使该方法正确 return 新创建的实例?

所以,看来我并没有遗漏任何步骤,也没有必要对对象实例化本身做任何错误。当我在调试器中 运行 this 时,我注意到无效的堆栈操作是由类型不匹配引起的,这表明 return 类型的方法实际上与匿名 [= 的类型不兼容13=](我的错误;语言的类型系统比普通的 Java 复杂一点,并且这两种类型在微妙的方式上不兼容)。 我想,吸取的教训是在遇到上述异常时仔细检查类型兼容性。