Auto-imports working for both Groovyc configuration and independent API.

This commit is contained in:
Jesse Brault 2025-01-26 15:34:45 -06:00
parent bd4dee98fa
commit 45d188d064
18 changed files with 54 additions and 164 deletions

View File

@ -10,41 +10,8 @@ public abstract class CachingComponentTemplateCompiler<U extends ComponentTempla
private final Map<Class<? extends ViewComponent>, ComponentTemplateCompileResult> cache = new HashMap<>();
// private ComponentTemplate instantiate(
// GroovyClassLoader groovyClassLoader,
// CompileResult compileResult
// ) {
// for (final var groovyClass : compileResult.otherClasses()) {
// // Try to find it. If we can't, we need to load it via the groovy loader
// try {
// Class.forName(groovyClass.getName(), true, groovyClassLoader);
// } catch (ClassNotFoundException ignored) {
// groovyClassLoader.defineClass(groovyClass.getName(), groovyClass.getBytes());
// } catch (LinkageError ignored) {
// // no-op, because we already have it
// }
// }
// final GroovyClass templateGroovyClass = compileResult.templateClass();
// Class<?> templateClass;
// // Try to find it. If we can't, we need to load it via the groovy loader
// try {
// templateClass = Class.forName(templateGroovyClass.getName(), true, groovyClassLoader);
// } catch (ClassNotFoundException ignored) {
// templateClass = groovyClassLoader.defineClass(
// templateGroovyClass.getName(),
// templateGroovyClass.getBytes()
// );
// }
// try {
// return (ComponentTemplate) templateClass.getConstructor().newInstance();
// } catch (Exception e) {
// throw new RuntimeException("Unable to instantiate ComponentTemplate " + templateClass.getName(), e);
// }
// }
@Override
public final ComponentTemplateCompileResult compile(U compileUnit)
throws ComponentTemplateCompileException {
public final ComponentTemplateCompileResult compile(U compileUnit) throws ComponentTemplateCompileException {
if (this.cache.containsKey(compileUnit.getForClass())) {
return this.cache.get(compileUnit.getForClass());
} else {

View File

@ -4,16 +4,9 @@ import groowt.view.component.ViewComponent;
import groowt.view.component.compiler.source.ComponentTemplateSource;
public interface ComponentTemplateCompileUnit {
String getDescriptiveName();
Class<? extends ViewComponent> getForClass();
String getDefaultPackageName();
ComponentTemplateSource getSource();
ComponentTemplateCompileResult compile(ComponentTemplateCompilerConfiguration configuration)
throws ComponentTemplateCompileException;
default ComponentTemplateCompileResult compile() throws ComponentTemplateCompileException {
return this.compile(new DefaultComponentTemplateCompilerConfiguration());
}
ComponentTemplateCompileResult compile() throws ComponentTemplateCompileException;
}

View File

@ -1,11 +0,0 @@
package groowt.view.component.compiler;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.CompilerConfiguration;
public interface ComponentTemplateCompilerConfiguration {
GroovyClassLoader getGroovyClassLoader();
CompilerConfiguration getGroovyCompilerConfiguration();
CompilePhase getToCompilePhase();
}

View File

@ -1,48 +0,0 @@
package groowt.view.component.compiler;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.CompilerConfiguration;
import static java.util.Objects.requireNonNull;
public class DefaultComponentTemplateCompilerConfiguration implements ComponentTemplateCompilerConfiguration {
private GroovyClassLoader groovyClassLoader;
private CompilerConfiguration groovyCompilerConfiguration;
private CompilePhase toCompilePhase;
public DefaultComponentTemplateCompilerConfiguration() {
this.groovyClassLoader = new GroovyClassLoader(Thread.currentThread().getContextClassLoader());
this.groovyCompilerConfiguration = new CompilerConfiguration();
this.toCompilePhase = CompilePhase.CLASS_GENERATION;
}
@Override
public GroovyClassLoader getGroovyClassLoader() {
return this.groovyClassLoader;
}
public void setGroovyClassLoader(GroovyClassLoader groovyClassLoader) {
this.groovyClassLoader = requireNonNull(groovyClassLoader);
}
@Override
public CompilerConfiguration getGroovyCompilerConfiguration() {
return this.groovyCompilerConfiguration;
}
public void setGroovyCompilerConfiguration(CompilerConfiguration groovyCompilerConfiguration) {
this.groovyCompilerConfiguration = requireNonNull(groovyCompilerConfiguration);
}
@Override
public CompilePhase getToCompilePhase() {
return this.toCompilePhase;
}
public void setToCompilePhase(CompilePhase toCompilePhase) {
this.toCompilePhase = requireNonNull(toCompilePhase);
}
}

View File

@ -201,7 +201,6 @@ tasks.register('uberJar', Jar) {
from sourceSets.main.output
from sourceSets.main.runtimeClasspath
.filter(File.&exists)
.filter { !(it.name =~ /groovy.*.jar/) }
.collect { it.isDirectory() ? it : zipTree(it) }
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

View File

@ -11,7 +11,8 @@ if [ "$1" == "--debug" ]; then
"$@"
else
gradle -q uberJar && \
groovyc -cp build/libs/web-view-components-uber-0.1.2.jar \
java -cp build/libs/web-view-components-uber-0.1.2.jar \
org.codehaus.groovy.tools.FileSystemCompiler \
--configscript src/main/resources/groowt/view/component/web/groovyc/groovycConfigurationScript.groovy \
-d groovyc-out \
"$@"

View File

@ -0,0 +1 @@
<Echo>Hello, World!</Echo>

View File

@ -4,7 +4,6 @@ import groowt.view.component.compiler.*;
import groowt.view.component.web.WebViewComponentBugError;
import groowt.view.component.web.ast.node.CompilationUnitNode;
import groowt.view.component.web.transpile.DefaultGroovyTranspiler;
import org.antlr.v4.runtime.ParserRuleContext;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.tools.GroovyClass;
@ -16,25 +15,12 @@ public class DefaultWebViewComponentTemplateCompiler
extends CachingComponentTemplateCompiler<WebViewComponentTemplateCompileUnit>
implements WebViewComponentTemplateCompiler {
private final ComponentTemplateCompilerConfiguration configuration;
private final WebViewComponentTemplateCompilerConfiguration configuration;
public DefaultWebViewComponentTemplateCompiler(ComponentTemplateCompilerConfiguration configuration) {
public DefaultWebViewComponentTemplateCompiler(WebViewComponentTemplateCompilerConfiguration configuration) {
this.configuration = configuration;
}
protected WebViewComponentTemplateCompileException getException(
WebViewComponentTemplateCompileUnit compileUnit,
ParserRuleContext parserRuleContext
) {
final var exception = new WebViewComponentTemplateCompileException(
compileUnit,
"Parser error: " + parserRuleContext.exception.getMessage(),
parserRuleContext.exception
);
exception.setParserRuleContext(parserRuleContext);
return exception;
}
@Override
protected ComponentTemplateCompileResult doCompile(WebViewComponentTemplateCompileUnit compileUnit)
throws ComponentTemplateCompileException {
@ -49,22 +35,12 @@ public class DefaultWebViewComponentTemplateCompiler
: "AnonymousWebViewComponent" + System.nanoTime();
final var templateClassSimpleName = ownerComponentName + "Template";
final SourceUnit sourceUnit = transpiler.transpile(
this.configuration,
compileUnit,
cuNode,
templateClassSimpleName
);
final SourceUnit sourceUnit = transpiler.transpile(compileUnit, cuNode, templateClassSimpleName);
compileUnit.getGroovyCompilationUnit().addSource(sourceUnit);
// set the groovy compile unit's class loader to the configuration's classloader.
compileUnit.getGroovyCompilationUnit().setClassLoader(
this.configuration.getGroovyClassLoader()
);
// compile groovy
try {
compileUnit.getGroovyCompilationUnit().compile(this.configuration.getToCompilePhase().getPhaseNumber());
compileUnit.getGroovyCompilationUnit().compile(this.configuration.getCompilePhase().getPhaseNumber());
} catch (CompilationFailedException compilationFailedException) {
throw new WebViewComponentTemplateCompileException(
compileUnit,

View File

@ -1,11 +1,9 @@
package groowt.view.component.web.compiler;
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
public class DefaultWebViewComponentTemplateCompilerFactory implements WebViewComponentTemplateCompilerFactory {
@Override
public WebViewComponentTemplateCompiler create(ComponentTemplateCompilerConfiguration configuration) {
public WebViewComponentTemplateCompiler create(WebViewComponentTemplateCompilerConfiguration configuration) {
return new DefaultWebViewComponentTemplateCompiler(configuration);
}

View File

@ -1,7 +1,6 @@
package groowt.view.component.web.groovyc;
import groowt.view.component.compiler.ComponentTemplateCompileException;
import groowt.view.component.compiler.DefaultComponentTemplateCompilerConfiguration;
import groowt.view.component.compiler.source.ComponentTemplateSource;
import groowt.view.component.web.WebViewComponentBugError;
import groowt.view.component.web.ast.node.CompilationUnitNode;
@ -80,13 +79,12 @@ public class DelegatingWebViewComponentTemplateParserPlugin implements ParserPlu
}
final var groovyTranspiler = new DefaultGroovyTranspiler();
final String teplateClassSimpleName = sourceUnitFileName.substring(0, sourceUnitFileName.length() - 4);
final String templateClassName = sourceUnitFileName.substring(0, sourceUnitFileName.length() - 4);
try {
final SourceUnit transpiledSourceUnit = groovyTranspiler.transpile(
new DefaultComponentTemplateCompilerConfiguration(),
compileUnit,
cuNode,
teplateClassSimpleName
templateClassName
);
return transpiledSourceUnit.getAST();
} catch (ComponentTemplateCompileException e) {

View File

@ -2,7 +2,6 @@ package groowt.view.component.web.transpile;
import groowt.view.component.compiler.ComponentTemplateCompileException;
import groowt.view.component.compiler.ComponentTemplateCompileUnit;
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
import groowt.view.component.web.ast.node.BodyNode;
import groowt.view.component.web.ast.node.CompilationUnitNode;
import groowt.view.component.web.ast.node.PreambleNode;
@ -49,18 +48,13 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
return moduleNode;
}
protected ClassNode initMainClassNode(
ComponentTemplateCompileUnit compileUnit,
String templateClassName,
WebViewComponentModuleNode moduleNode
) {
protected ClassNode initMainClassNode(ComponentTemplateCompileUnit compileUnit, String templateClassName) {
final ClassNode mainClassNode = new ClassNode(
compileUnit.getDefaultPackageName() + templateClassName,
ACC_PUBLIC,
ClassHelper.OBJECT_TYPE
);
mainClassNode.addInterface(TranspilerUtil.COMPONENT_TEMPLATE);
moduleNode.addClass(mainClassNode);
return mainClassNode;
}
@ -202,7 +196,6 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
@Override
public WebViewComponentSourceUnit transpile(
ComponentTemplateCompilerConfiguration compilerConfiguration,
WebViewComponentTemplateCompileUnit compileUnit,
CompilationUnitNode compilationUnitNode,
String templateClassSimpleName
@ -212,13 +205,13 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
final PositionSetter positionSetter = transpilerConfiguration.getPositionSetter();
// prepare sourceUnit
final CompilerConfiguration groovyCompilerConfiguration =
compilerConfiguration.getGroovyCompilerConfiguration();
final CompilerConfiguration groovyCompilerConfiguration = compileUnit.getGroovyCompilationUnit()
.getConfiguration();
final WebViewComponentSourceUnit sourceUnit = new WebViewComponentSourceUnit(
compileUnit.getDescriptiveName(),
compileUnit.getGroovyReaderSource(),
groovyCompilerConfiguration,
compilerConfiguration.getGroovyClassLoader(),
compileUnit.getGroovyCompilationUnit().getClassLoader(),
new ErrorCollector(groovyCompilerConfiguration)
);
@ -228,7 +221,7 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
);
// prepare mainClassNode
final ClassNode mainClassNode = this.initMainClassNode(compileUnit, templateClassSimpleName, moduleNode);
final ClassNode mainClassNode = this.initMainClassNode(compileUnit, templateClassSimpleName);
// handle preamble
final PreambleNode preambleNode = compilationUnitNode.getPreambleNode();
@ -236,6 +229,9 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
this.handlePreamble(templateClassSimpleName, preambleNode, mainClassNode, moduleNode, positionSetter);
}
// Moved here so that moduleNode#getMainClassName reflects fqn of mainClassName
moduleNode.addClass(mainClassNode);
// getRenderer method and render closure
// first, getRenderer params
final Parameter componentContextParam = new Parameter(COMPONENT_CONTEXT_TYPE, COMPONENT_CONTEXT_NAME);

View File

@ -1,14 +1,12 @@
package groowt.view.component.web.transpile;
import groowt.view.component.compiler.ComponentTemplateCompileException;
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
import groowt.view.component.web.ast.node.CompilationUnitNode;
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
public interface GroovyTranspiler {
WebViewComponentSourceUnit transpile(
ComponentTemplateCompilerConfiguration compilerConfiguration,
WebViewComponentTemplateCompileUnit compileUnit,
CompilationUnitNode compilationUnitNode,
String templateClassSimpleName

View File

@ -1,5 +1,16 @@
package groowt.view.component.web.groovyc
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.customizers.ImportCustomizer
(configuration as CompilerConfiguration).tap {
pluginFactory = new WebViewComponentParserPluginFactory()
addCompilationCustomizers(new ImportCustomizer().tap {
addStarImports(
"groowt.view.component.web.lib",
"groowt.view.component.web.runtime",
"groowt.view.component.runtime"
)
})
}
(configuration as CompilerConfiguration).pluginFactory = new WebViewComponentParserPluginFactory()

View File

@ -2,7 +2,6 @@ package groowt.view.component.web.transpiler;
import groovy.lang.Tuple2;
import groowt.view.component.compiler.ComponentTemplateCompileException;
import groowt.view.component.compiler.DefaultComponentTemplateCompilerConfiguration;
import groowt.view.component.compiler.source.StringSource;
import groowt.view.component.web.BaseWebViewComponent;
import groowt.view.component.web.antlr.ParserUtil;
@ -55,7 +54,6 @@ public abstract class GroovyTranspilerTests {
final var cuNode = astBuilder.buildCompilationUnit(parseResult.getCompilationUnitContext());
try {
this.transpiler.transpile(
new DefaultComponentTemplateCompilerConfiguration(),
new DefaultWebViewComponentTemplateCompileUnit(
"<anonymous string source>",
AnonymousWebViewComponent.class,

View File

@ -4,7 +4,6 @@ import groowt.view.component.ViewComponent;
import groowt.view.component.compiler.AbstractComponentTemplateCompileUnit;
import groowt.view.component.compiler.ComponentTemplateCompileException;
import groowt.view.component.compiler.ComponentTemplateCompileResult;
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
import groowt.view.component.compiler.source.ComponentTemplateSource;
import groowt.view.component.compiler.source.FileSource;
import groowt.view.component.compiler.source.URISource;
@ -68,9 +67,8 @@ public class DefaultWebViewComponentTemplateCompileUnit extends AbstractComponen
}
@Override
public ComponentTemplateCompileResult compile(ComponentTemplateCompilerConfiguration configuration)
throws ComponentTemplateCompileException {
final WebViewComponentTemplateCompiler compiler = WebViewComponentTemplateCompiler.get(configuration);
public ComponentTemplateCompileResult compile() throws ComponentTemplateCompileException {
final WebViewComponentTemplateCompiler compiler = WebViewComponentTemplateCompiler.get();
return compiler.compile(this);
}

View File

@ -9,10 +9,10 @@ public interface WebViewComponentTemplateCompiler
extends ComponentTemplateCompiler<WebViewComponentTemplateCompileUnit> {
static WebViewComponentTemplateCompiler get() {
return get(new DefaultComponentTemplateCompilerConfiguration());
return get(new WebViewComponentTemplateCompilerConfiguration());
}
static WebViewComponentTemplateCompiler get(ComponentTemplateCompilerConfiguration configuration) {
static WebViewComponentTemplateCompiler get(WebViewComponentTemplateCompilerConfiguration configuration) {
final ServiceLoader<WebViewComponentTemplateCompilerFactory> factoryServiceLoader =
ServiceLoader.load(WebViewComponentTemplateCompilerFactory.class);
final var factory = factoryServiceLoader.findFirst()

View File

@ -0,0 +1,17 @@
package groowt.view.component.web.compiler;
import org.codehaus.groovy.control.CompilePhase;
public class WebViewComponentTemplateCompilerConfiguration {
private CompilePhase compilePhase = CompilePhase.CLASS_GENERATION;
public CompilePhase getCompilePhase() {
return this.compilePhase;
}
public void setCompilePhase(CompilePhase compilePhase) {
this.compilePhase = compilePhase;
}
}

View File

@ -1,7 +1,5 @@
package groowt.view.component.web.compiler;
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
public interface WebViewComponentTemplateCompilerFactory {
WebViewComponentTemplateCompiler create(ComponentTemplateCompilerConfiguration configuration);
WebViewComponentTemplateCompiler create(WebViewComponentTemplateCompilerConfiguration configuration);
}