Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Groovy 如何注释类似于构建器的DSL结构?_Groovy - Fatal编程技术网

Groovy 如何注释类似于构建器的DSL结构?

Groovy 如何注释类似于构建器的DSL结构?,groovy,Groovy,在我的应用程序中,有几个DSL是用groovy构建器实现的。我希望通过示例支持某些节点中的注释: builder.define { @Secure checkService { ... } } 然而,这个脚本在语法上是不正确的,它不能编译,我不能注释方法的调用 是否可以在Groovy中使用AST转换或任何其他方法实现这种DSL?如果有,有人举个例子吗 我临时使用了一些属性,比如checkServicesecure:true,但它并不是很漂亮 批注不能放置在Method

在我的应用程序中,有几个DSL是用groovy构建器实现的。我希望通过示例支持某些节点中的注释:

builder.define {

  @Secure
  checkService {
    ... 
  }

}
然而,这个脚本在语法上是不正确的,它不能编译,我不能注释方法的调用

是否可以在Groovy中使用AST转换或任何其他方法实现这种DSL?如果有,有人举个例子吗


我临时使用了一些属性,比如checkServicesecure:true,但它并不是很漂亮

批注不能放置在MethodCallExpression处。连政府都不允许这样做

正如cfrick所说,你必须寻找其他选择

带闭包和省略大括号的普通groovy 通过将secure定义为方法、从每个方法返回闭包并使用groovys可选大括号,可以创建类似的语法:

class Builder {
    def define(@DelegatesTo(InnerBuilder) Closure defineClosure) {
        println("start define")
        def innerBuilder = new InnerBuilder()
        defineClosure.delegate = innerBuilder
        Closure returnedClosure = defineClosure()

        // also call the returned Closure
        returnedClosure.delegate = innerBuilder
        returnedClosure()
        println("end define")
    }

    class InnerBuilder {
        def secure(Closure c) {
            return { ->
                println("start being secure")
                c()
                println("stop being secure")
            }
        }

        def elegant(Closure c) {
            return { ->
                println("start being elegant")
                c()
                println("stop being elegant")
            }
        }

        def checkService(Closure c) {
            return { ->
                println("start checkService")
                c()
                println("stop checkService")
            }
        }
    }

}

def builder = new Builder()
builder.define {
    checkService {
        println "running a service check"
    }
}

println()
println("with secure")
println()

builder.define {
    secure checkService {
        println "running a service check"
    }
}

//    NOT WORKING
//    println()
//    println("with new-line but missing the backslash")
//    println()
//
//    builder.define {
//        secure // this will NOT be secure!
//        checkService {
//            println "running a service check"
//        }
//    }

println()
println("with new-line and backslash")
println()

builder.define {
    // this WILL be secure!
    secure \
    checkService {
        println "running a service check"
    }
}

println()
println("two")
println()

builder.define {
    // needs braces
    elegant secure(checkService {
        println "running a service check"
    })
}

println()
println("Both orders work")
println()

builder.define {
    secure elegant(checkService {
        println "running a service check"
    })
}

println()
println("Multiple with line-break")
println()

builder.define {
    secure \
    elegant(
    checkService {
        println "running a service check"
    })
}
将打印

start define
start checkService
running a service check
stop checkService
end define

with secure

start define
start being secure
start checkService
running a service check
stop checkService
stop being secure
end define

with new-line and backslash

start define
start being secure
start checkService
running a service check
stop checkService
stop being secure
end define

two

start define
start being elegant
start being secure
start checkService
running a service check
stop checkService
stop being secure
stop being elegant
end define

Both orders work

start define
start being secure
start being elegant
start checkService
running a service check
stop checkService
stop being elegant
stop being secure
end define

Multiple with line-break

start define
start being secure
start being elegant
start checkService
running a service check
stop checkService
stop being elegant
stop being secure
end define
AST变换 这有点复杂,我不认为它提供了值得努力的价值,但是您可以使用AST转换来缓解以前版本的语法问题

class Builder {
    def define(@DelegatesTo(InnerBuilder) Closure defineClosure) {
        println("start define")
        def innerBuilder = new InnerBuilder()
        defineClosure.delegate = innerBuilder
        defineClosure()
        println("end define")
    }

    class InnerBuilder {
        def secure = "just a string"

        def elegant = "just a string"

        def checkService(Closure c) {
            println("start checkService")
            c()
            println("stop checkService")
        }
    }

}

def builder = new Builder()
builder.define {
    secure
    elegant
    checkService {
        println "running a service check"
    }
}
到目前为止,安全没有任何意义,它是一个。您需要编写一个AST转换来更改它。此处,安全且优雅的表达式应为ExpressionStatement内的VariableExpression,作为BlockStatement的一部分,该BlockStatement是周围ClosureExpression的代码属性。实际实现留给读者作为练习

或安全的{checkService{}