[
https://issues.apache.org/jira/browse/GROOVY-11154?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17755621#comment-17755621
]
Jochen Theodorou commented on GROOVY-11154:
-------------------------------------------
Thinking out loud: How and when do you identify the unused constructors?
Normally I would have said that we add the constructors much later, like we do
for normal classes. But GROOVY-8096 sounds like a problem for that. We could
mark them as synthetic and then the ones from @InheritConstrcutors would not be
synthetic... But is a rule "if there is a non-synthetic constructor in a
generated script class remove all synthetic ones" sound? Maybe worth a try.
But if one would indeed use @Field and @InheritConstructors in the phases they
are intended to be used, then this will not work, as field is running first and
would modify the wrong constructor.
Maybe we should instead apply InheritConstructors early? If the script base
class is set, we take it from there, otherwise from the given class... And
then @BaseScript is in the way.. sigh.
Or another idea.... we add a fake constructor to the script, let transforms run
wild with it and then use the contents of that constructor to add it to other
added constructors in a later phase.... That way the base script would be
resolved, Field would have already added its fields to the constructor and that
code would be copied then to the constructors added by the inherit transform...
still sounds messy to me, but could work.
> Script subclasses cannot have constructors with arguments
> ---------------------------------------------------------
>
> Key: GROOVY-11154
> URL: https://issues.apache.org/jira/browse/GROOVY-11154
> Project: Groovy
> Issue Type: Bug
> Components: Compiler
> Affects Versions: 4.0.7
> Reporter: jonny
> Priority: Major
>
> Prior to the fix for GROOVY-9857, subclasses of {{Script}} could have
> constructor arguments and still be used (with a little help from
> {{InheritConstructors}} and {{DefaultGroovyMethods#newInstance}}).
> For example, the following script executes find in Groovy 3.x, but fails
> after Groovy 4.0.7:
> {code}
> import groovy.transform.InheritConstructors
> import org.codehaus.groovy.ast.AnnotationNode
> import org.codehaus.groovy.ast.ClassNode
> import org.codehaus.groovy.classgen.GeneratorContext
> import org.codehaus.groovy.control.CompilationFailedException
> import org.codehaus.groovy.control.CompilePhase
> import org.codehaus.groovy.control.CompilerConfiguration
> import org.codehaus.groovy.control.SourceUnit
> import org.codehaus.groovy.control.customizers.CompilationCustomizer
> import org.codehaus.groovy.runtime.DefaultGroovyMethods
> abstract class NamedScript extends Script {
> NamedScript(String name) {
> }
> }
> def compilerConfig = new CompilerConfiguration()
> compilerConfig.setScriptBaseClass(NamedScript.class.getName())
> compilerConfig.addCompilationCustomizers(new
> CompilationCustomizer(CompilePhase.CONVERSION) {
> @Override
> void call(SourceUnit source, GeneratorContext context, ClassNode
> classNode) throws CompilationFailedException {
> classNode.addAnnotation(new AnnotationNode(new
> ClassNode(InheritConstructors.class)))
> }
> })
> def classLoader = new GroovyClassLoader(new GroovyClassLoader(),
> compilerConfig)
> def parsedClass = classLoader.parseClass('println "Foo"')
> DefaultGroovyMethods.newInstance(parsedClass, "dummy").run()
> {code}
> The error returned is:
> {noformat}
> Implicit super constructor NamedScript() is undefined for generated
> constructor. Must define an explicit constructor.
> {noformat}
> Ratpack relies on this behavior for its custom text template renderer.
> See how script objects are instantiated in the
> [ScriptEngine#create|https://github.com/ratpack/ratpack/blob/503060ab2351a49f6e96416d588607ff7ef63028/ratpack-groovy/src/main/java/ratpack/groovy/script/internal/ScriptEngine.java#L51]
> method.
> I talked this out in the Groovy community Slack with [~blackdrag] (see
> [thread|https://groovy-community.slack.com/archives/C2NEFCM55/p1691783910137829]),
> who suggested that we should skip the check for constructors for Script
> subclasses as a bugfix in Groovy 4, with a potentially breaking change in
> Groovy 5 to make constructor generation for Script subclasses happen in the
> same place as any other class.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)