gpt4 book ai didi

intellij-idea - 通过具有委托(delegate)闭包参数的 GDSL 脚本创建方法

转载 作者:行者123 更新时间:2023-12-02 03:05:28 29 4
gpt4 key购买 nike

使用 Intellij 的(很少记录的)gdsl 脚本,可以将动态方法添加到类中:

contributor(context(ctype: "my.Type")) {
method name: "doIt", params: [body: {}], type: void
}

还可以配置闭包的委托(delegate):
contributor(context(scope: closureScope())) {
def call = enclosingCall("doIt")
if (call) {
def method = call.bind()
def clazz = method?.containingClass
if (clazz?.qualName == 'my.Type') {
delegatesTo(findClass('my.Inner'))
}
}
}

其中,当 doIt是在代码中定义的方法(不是动态添加的),也可以按设计工作。

但是,当使用 closureScope与之前的 已创建 方法, containing类方法总是 null ,这意味着我不能安全地将闭包内部委托(delegate)给已寻址的 my.Inner类(class)。

我想要的是添加一个等效于的动态方法:
void doIt(@DelegatesTo(my.Inner) Closure)...

IE。我希望该方法在代码完成中可用(这有效),并且在如此创建的闭包中,我希望在处理 my.Inner 的方法时正确的代码完成.

到目前为止,我尝试了各种方法:
  • 在参数定义中包含@DelegatesTo 注释
  • 尝试更深奥的方法来查找闭包的所有者,但失败是因为 GrMethodCall 根本没有父
  • 无条件委托(delegate)所有名为 doIt 的闭包至my.Inner可行,但不是可行的解决方案,因为我确实有多个 doIt委托(delegate)给不同目标的方法(在不同的类上)。

  • 那么,我怎样才能让 IDEA 按预期行事并委托(delegate)给正确的目标呢?

    编辑使其更清晰:

    给定以下类:
    package my
    class Type {
    void doIt(Closure) {}
    }
    class Inner {
    void inInner() {}
    }

    和以下gdsl:
    contributor(context(scope: closureScope())) {
    def call = enclosingCall("doIt")
    if (call) {
    def method = call.bind()
    def clazz = method?.containingClass
    println clazz?.qualName
    if (clazz?.qualName == 'my.Type') {
    delegatesTo(findClass('my.Inner'))
    }
    }
    }

    当我开始输入新脚本时:
    new Type().doIt {
    inInner()
    }

    在封闭内时,我得到以下信息:
  • inInner 的代码完成
  • inInner显示为有效
  • 从命令行使用 idea.bat 启动时的控制台输出显示行 my.Type (来自 println )
  • inInner 上按 Ctrl-B正确链接到源代码。

  • (在使用 doIt 注释 @DelegatesTo(Inner) 方法中的闭包参数时,可以在没有 gdsl 的情况下达到相同的行为)

    但是,我不想手动包含 doIt Type 源中的方法,它是由 AST Transformation 生成的,所以我的源文件现在看起来像这样:
    package my
    class Type {
    }
    class Inner {
    void inInner() {}
    }

    我可以使用以下 gdsl 片段告诉 IntelliJ 新方法
    contributor(context(ctype: "my.Type")) {
    method name: "doIt", params: [body: {}], type: void
    }

    现在 IDE 可以正确识别带有闭包参数的 doIt 方法。但是,在闭包内部,会发生以下情况:
  • 有时代码完成显示 inInner ,有时在更改某些内容后,它不会(使用原始代码修复类型时,它被显示,但后来声明“未解决”,经过此编辑示例的代码更改后,它不再显示...... )
  • 即使显示,inInner显示“无法解析符号”装饰
  • 控制台显示 nullclazz ,即找到方法,但未链接到所有者 ASTNode
  • Ctrl-B 不链接到Inner 中的对应方法

  • 所以我想要的是注入(inject) doIt 的相同行为。方法(通过 Gdsl)与源中包含的方法一样,即我希望 gdsl 注入(inject) doIt带有委托(delegate)闭包(到 Inner)的方法到 type类(class)。

    最佳答案

    这对我将 ctype 添加到范围而不是从方法

    contributor(context(scope: closureScope(), ctype: 'my.Type')) {
    def call = enclosingCall("doIt")
    if (call) {
    delegatesTo(findClass('my.Inner'))
    }
    }
    中查找类类型有用。

    关于intellij-idea - 通过具有委托(delegate)闭包参数的 GDSL 脚本创建方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43008413/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com