Compare commits
8 Commits
04866b4d3a
...
2b935da385
Author | SHA1 | Date | |
---|---|---|---|
![]() |
2b935da385 | ||
![]() |
7a28b0530d | ||
![]() |
45d188d064 | ||
![]() |
bd4dee98fa | ||
![]() |
1a528465f9 | ||
![]() |
5ce934b3fe | ||
![]() |
74c5698d1b | ||
![]() |
525932668f |
9
TODO.md
9
TODO.md
@ -24,9 +24,12 @@ For example:
|
|||||||
- [ ] Get rid of wvc compiler dependency on di
|
- [ ] Get rid of wvc compiler dependency on di
|
||||||
|
|
||||||
## 0.1.3
|
## 0.1.3
|
||||||
- [ ] refactor tools/gradle start scripts to use dist instead of custom bin script
|
- [ ] ~~refactor tools/gradle start scripts to use dist instead of custom bin script~~
|
||||||
- [ ] have custom bin/* scripts which point to dist(s) for convenience
|
- [ ] ~~have custom bin/* scripts which point to dist(s) for convenience~~
|
||||||
- [ ] di bug: @Singleton toSelf() causes stack overflow
|
- [x] di bug: @Singleton toSelf() causes stack overflow
|
||||||
|
- [x] wvcc bug: Nested static view classes are not seen by compiler
|
||||||
|
- This required tweaking how the configurations are passed around. Ultimately, we should strive for less complexity
|
||||||
|
in this regard.
|
||||||
- [ ] `OutletContainer` trait or interface for components which can contain an `<Outlet />` child.
|
- [ ] `OutletContainer` trait or interface for components which can contain an `<Outlet />` child.
|
||||||
- [ ] `Context` should have methods for simply finding an ancestor of a certain type without the need for a predicate.
|
- [ ] `Context` should have methods for simply finding an ancestor of a certain type without the need for a predicate.
|
||||||
|
|
||||||
|
@ -3,31 +3,58 @@ package groowt.util.di;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
import java.lang.annotation.Annotation;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class DefaultRegistry implements Registry {
|
public class DefaultRegistry implements Registry {
|
||||||
|
|
||||||
protected record ClassKeyBinding<T>(Class<T> key, Binding<T> binding) {}
|
protected static class BindingContainer {
|
||||||
|
|
||||||
protected final Collection<ClassKeyBinding<?>> classBindings = new ArrayList<>();
|
private final Map<Class<?>, Binding<?>> bindings = new HashMap<>();
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public <T> @Nullable Binding<T> get(Class<T> key) {
|
||||||
|
for (final var entry : bindings.entrySet()) {
|
||||||
|
if (entry.getKey().isAssignableFrom(key)) {
|
||||||
|
return (Binding<T>) entry.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void put(Class<T> key, Binding<T> binding) {
|
||||||
|
this.bindings.put(key, binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Class<?> key) {
|
||||||
|
this.bindings.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> void removeIf(Class<T> key, Predicate<? super Binding<T>> filter) {
|
||||||
|
if (filter.test(this.get(key))) {
|
||||||
|
this.bindings.remove(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
this.bindings.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final BindingContainer bindingContainer = new BindingContainer();
|
||||||
protected final Collection<RegistryExtension> extensions = new ArrayList<>();
|
protected final Collection<RegistryExtension> extensions = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeBinding(Class<?> key) {
|
public void removeBinding(Class<?> key) {
|
||||||
this.classBindings.removeIf(classKeyBinding -> classKeyBinding.key().equals(key));
|
this.bindingContainer.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public <T> void removeBindingIf(Class<T> key, Predicate<Binding<T>> filter) {
|
public <T> void removeBindingIf(Class<T> key, Predicate<Binding<T>> filter) {
|
||||||
this.classBindings.removeIf(classKeyBinding ->
|
this.bindingContainer.removeIf(key, filter);
|
||||||
classKeyBinding.key().equals(key) && filter.test((Binding<T>) classKeyBinding.binding())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <E extends RegistryExtension> List<E> getAllRegistryExtensions(Class<E> extensionType) {
|
private <E extends RegistryExtension> List<E> getAllRegistryExtensions(Class<E> extensionType) {
|
||||||
@ -117,18 +144,12 @@ public class DefaultRegistry implements Registry {
|
|||||||
public <T> void bind(Class<T> key, Consumer<? super BindingConfigurator<T>> configure) {
|
public <T> void bind(Class<T> key, Consumer<? super BindingConfigurator<T>> configure) {
|
||||||
final var configurator = new SimpleBindingConfigurator<>(key);
|
final var configurator = new SimpleBindingConfigurator<>(key);
|
||||||
configure.accept(configurator);
|
configure.accept(configurator);
|
||||||
this.classBindings.add(new ClassKeyBinding<>(key, configurator.getBinding()));
|
this.bindingContainer.put(key, configurator.getBinding());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable <T> Binding<T> getBinding(Class<T> key) {
|
public <T> @Nullable Binding<T> getBinding(Class<T> key) {
|
||||||
for (final var classKeyBinding : this.classBindings) {
|
return this.bindingContainer.get(key);
|
||||||
if (key.isAssignableFrom(classKeyBinding.key())) {
|
|
||||||
return (Binding<T>) classKeyBinding.binding();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private KeyBinder<?> findKeyBinder(Class<?> keyClass) {
|
private KeyBinder<?> findKeyBinder(Class<?> keyClass) {
|
||||||
@ -189,7 +210,7 @@ public class DefaultRegistry implements Registry {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearAllBindings() {
|
public void clearAllBindings() {
|
||||||
this.classBindings.clear();
|
this.bindingContainer.clear();
|
||||||
for (final var extension : this.extensions) {
|
for (final var extension : this.extensions) {
|
||||||
if (extension instanceof KeyBinder<?> keyBinder) {
|
if (extension instanceof KeyBinder<?> keyBinder) {
|
||||||
keyBinder.clearAllBindings();
|
keyBinder.clearAllBindings();
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package groowt.util.di;
|
package groowt.util.di;
|
||||||
|
|
||||||
|
import jakarta.inject.Provider;
|
||||||
import jakarta.inject.Singleton;
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
import static groowt.util.di.BindingUtil.toSingleton;
|
import static groowt.util.di.BindingUtil.toLazySingleton;
|
||||||
|
|
||||||
public final class SingletonScopeHandler implements ScopeHandler<Singleton> {
|
public final class SingletonScopeHandler implements ScopeHandler<Singleton> {
|
||||||
|
|
||||||
@ -19,12 +20,22 @@ public final class SingletonScopeHandler implements ScopeHandler<Singleton> {
|
|||||||
RegistryObjectFactory objectFactory
|
RegistryObjectFactory objectFactory
|
||||||
) {
|
) {
|
||||||
final Binding<T> potentialBinding = this.owner.getBinding(dependencyClass);
|
final Binding<T> potentialBinding = this.owner.getBinding(dependencyClass);
|
||||||
if (potentialBinding != null) {
|
return switch (potentialBinding) {
|
||||||
return potentialBinding;
|
case ClassBinding<T>(Class<T> from, Class<? extends T> to) -> {
|
||||||
} else {
|
this.owner.bind(from, toLazySingleton(() -> objectFactory.createInstance(to)));
|
||||||
this.owner.bind(dependencyClass, toSingleton(objectFactory.createInstance(dependencyClass)));
|
yield this.owner.getBinding(from);
|
||||||
return this.owner.getBinding(dependencyClass);
|
}
|
||||||
}
|
case ProviderBinding<T>(Class<T> from, Provider<? extends T> provider) -> {
|
||||||
|
this.owner.bind(from, toLazySingleton(provider::get));
|
||||||
|
yield this.owner.getBinding(from);
|
||||||
|
}
|
||||||
|
case SingletonBinding<T> singletonBinding -> singletonBinding;
|
||||||
|
case LazySingletonBinding<T> lazySingletonBinding -> lazySingletonBinding;
|
||||||
|
case null -> {
|
||||||
|
this.owner.bind(dependencyClass, toLazySingleton(() -> objectFactory.createInstance(dependencyClass)));
|
||||||
|
yield this.owner.getBinding(dependencyClass);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -2,6 +2,7 @@ package groowt.util.di;
|
|||||||
|
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static groowt.util.di.BindingUtil.*;
|
import static groowt.util.di.BindingUtil.*;
|
||||||
@ -250,4 +251,25 @@ public class DefaultRegistryObjectFactoryTests {
|
|||||||
assertEquals("Given Greeting", g.greet());
|
assertEquals("Given Greeting", g.greet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public static final class SingletonGreeter implements Greeter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String greet() {
|
||||||
|
return "Hello, World!";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void singletonDoesNotOverflow() {
|
||||||
|
final var b = DefaultRegistryObjectFactory.Builder.withDefaults();
|
||||||
|
b.configureRegistry(r -> {
|
||||||
|
r.bind(SingletonGreeter.class, toSelf());
|
||||||
|
});
|
||||||
|
final var f = b.build();
|
||||||
|
final var g = f.get(SingletonGreeter.class);
|
||||||
|
assertEquals("Hello, World!", g.greet());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,41 +10,8 @@ public abstract class CachingComponentTemplateCompiler<U extends ComponentTempla
|
|||||||
|
|
||||||
private final Map<Class<? extends ViewComponent>, ComponentTemplateCompileResult> cache = new HashMap<>();
|
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
|
@Override
|
||||||
public final ComponentTemplateCompileResult compile(U compileUnit)
|
public final ComponentTemplateCompileResult compile(U compileUnit) throws ComponentTemplateCompileException {
|
||||||
throws ComponentTemplateCompileException {
|
|
||||||
if (this.cache.containsKey(compileUnit.getForClass())) {
|
if (this.cache.containsKey(compileUnit.getForClass())) {
|
||||||
return this.cache.get(compileUnit.getForClass());
|
return this.cache.get(compileUnit.getForClass());
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,16 +4,9 @@ import groowt.view.component.ViewComponent;
|
|||||||
import groowt.view.component.compiler.source.ComponentTemplateSource;
|
import groowt.view.component.compiler.source.ComponentTemplateSource;
|
||||||
|
|
||||||
public interface ComponentTemplateCompileUnit {
|
public interface ComponentTemplateCompileUnit {
|
||||||
|
|
||||||
String getDescriptiveName();
|
String getDescriptiveName();
|
||||||
Class<? extends ViewComponent> getForClass();
|
Class<? extends ViewComponent> getForClass();
|
||||||
String getDefaultPackageName();
|
String getDefaultPackageName();
|
||||||
ComponentTemplateSource getSource();
|
ComponentTemplateSource getSource();
|
||||||
ComponentTemplateCompileResult compile(ComponentTemplateCompilerConfiguration configuration)
|
ComponentTemplateCompileResult compile() throws ComponentTemplateCompileException;
|
||||||
throws ComponentTemplateCompileException;
|
|
||||||
|
|
||||||
default ComponentTemplateCompileResult compile() throws ComponentTemplateCompileException {
|
|
||||||
return this.compile(new DefaultComponentTemplateCompilerConfiguration());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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();
|
|
||||||
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -199,7 +199,9 @@ tasks.register('uberJar', Jar) {
|
|||||||
group 'groovyc'
|
group 'groovyc'
|
||||||
archiveBaseName = 'web-view-components-uber'
|
archiveBaseName = 'web-view-components-uber'
|
||||||
from sourceSets.main.output
|
from sourceSets.main.output
|
||||||
from sourceSets.main.runtimeClasspath.filter(File.&exists).collect { it.isDirectory() ? it : zipTree(it) }
|
from sourceSets.main.runtimeClasspath
|
||||||
|
.filter(File.&exists)
|
||||||
|
.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,15 @@ if [ "$1" == "--debug" ]; then
|
|||||||
shift
|
shift
|
||||||
gradle -q uberJar && \
|
gradle -q uberJar && \
|
||||||
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8192 \
|
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8192 \
|
||||||
-cp build/libs/web-view-components-uber-0.1.0.jar \
|
-cp build/libs/web-view-components-uber-0.1.2.jar \
|
||||||
org.codehaus.groovy.tools.FileSystemCompiler \
|
org.codehaus.groovy.tools.FileSystemCompiler \
|
||||||
--configscript src/main/resources/groowt/view/component/web/groovyc/groovycConfigurationScript.groovy \
|
--configscript src/main/resources/groowt/view/component/web/groovyc/groovycConfigurationScript.groovy \
|
||||||
-d groovyc-out \
|
-d groovyc-out \
|
||||||
"$@"
|
"$@"
|
||||||
else
|
else
|
||||||
gradle -q uberJar && \
|
gradle -q uberJar && \
|
||||||
groovyc -cp build/libs/web-view-components-uber-0.1.0.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 \
|
--configscript src/main/resources/groowt/view/component/web/groovyc/groovycConfigurationScript.groovy \
|
||||||
-d groovyc-out \
|
-d groovyc-out \
|
||||||
"$@"
|
"$@"
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
<Echo>Hello, World!</Echo>
|
@ -4,7 +4,6 @@ import groowt.view.component.compiler.*;
|
|||||||
import groowt.view.component.web.WebViewComponentBugError;
|
import groowt.view.component.web.WebViewComponentBugError;
|
||||||
import groowt.view.component.web.ast.node.CompilationUnitNode;
|
import groowt.view.component.web.ast.node.CompilationUnitNode;
|
||||||
import groowt.view.component.web.transpile.DefaultGroovyTranspiler;
|
import groowt.view.component.web.transpile.DefaultGroovyTranspiler;
|
||||||
import org.antlr.v4.runtime.ParserRuleContext;
|
|
||||||
import org.codehaus.groovy.control.CompilationFailedException;
|
import org.codehaus.groovy.control.CompilationFailedException;
|
||||||
import org.codehaus.groovy.control.SourceUnit;
|
import org.codehaus.groovy.control.SourceUnit;
|
||||||
import org.codehaus.groovy.tools.GroovyClass;
|
import org.codehaus.groovy.tools.GroovyClass;
|
||||||
@ -16,25 +15,12 @@ public class DefaultWebViewComponentTemplateCompiler
|
|||||||
extends CachingComponentTemplateCompiler<WebViewComponentTemplateCompileUnit>
|
extends CachingComponentTemplateCompiler<WebViewComponentTemplateCompileUnit>
|
||||||
implements WebViewComponentTemplateCompiler {
|
implements WebViewComponentTemplateCompiler {
|
||||||
|
|
||||||
private final ComponentTemplateCompilerConfiguration configuration;
|
private final WebViewComponentTemplateCompilerConfiguration configuration;
|
||||||
|
|
||||||
public DefaultWebViewComponentTemplateCompiler(ComponentTemplateCompilerConfiguration configuration) {
|
public DefaultWebViewComponentTemplateCompiler(WebViewComponentTemplateCompilerConfiguration configuration) {
|
||||||
this.configuration = 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
|
@Override
|
||||||
protected ComponentTemplateCompileResult doCompile(WebViewComponentTemplateCompileUnit compileUnit)
|
protected ComponentTemplateCompileResult doCompile(WebViewComponentTemplateCompileUnit compileUnit)
|
||||||
throws ComponentTemplateCompileException {
|
throws ComponentTemplateCompileException {
|
||||||
@ -49,22 +35,12 @@ public class DefaultWebViewComponentTemplateCompiler
|
|||||||
: "AnonymousWebViewComponent" + System.nanoTime();
|
: "AnonymousWebViewComponent" + System.nanoTime();
|
||||||
final var templateClassSimpleName = ownerComponentName + "Template";
|
final var templateClassSimpleName = ownerComponentName + "Template";
|
||||||
|
|
||||||
final SourceUnit sourceUnit = transpiler.transpile(
|
final SourceUnit sourceUnit = transpiler.transpile(compileUnit, cuNode, templateClassSimpleName);
|
||||||
this.configuration,
|
|
||||||
compileUnit,
|
|
||||||
cuNode,
|
|
||||||
templateClassSimpleName
|
|
||||||
);
|
|
||||||
compileUnit.getGroovyCompilationUnit().addSource(sourceUnit);
|
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
|
// compile groovy
|
||||||
try {
|
try {
|
||||||
compileUnit.getGroovyCompilationUnit().compile(this.configuration.getToCompilePhase().getPhaseNumber());
|
compileUnit.getGroovyCompilationUnit().compile(this.configuration.getCompilePhase().getPhaseNumber());
|
||||||
} catch (CompilationFailedException compilationFailedException) {
|
} catch (CompilationFailedException compilationFailedException) {
|
||||||
throw new WebViewComponentTemplateCompileException(
|
throw new WebViewComponentTemplateCompileException(
|
||||||
compileUnit,
|
compileUnit,
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
package groowt.view.component.web.compiler;
|
package groowt.view.component.web.compiler;
|
||||||
|
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
|
|
||||||
|
|
||||||
public class DefaultWebViewComponentTemplateCompilerFactory implements WebViewComponentTemplateCompilerFactory {
|
public class DefaultWebViewComponentTemplateCompilerFactory implements WebViewComponentTemplateCompilerFactory {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WebViewComponentTemplateCompiler create(ComponentTemplateCompilerConfiguration configuration) {
|
public WebViewComponentTemplateCompiler create(WebViewComponentTemplateCompilerConfiguration configuration) {
|
||||||
return new DefaultWebViewComponentTemplateCompiler(configuration);
|
return new DefaultWebViewComponentTemplateCompiler(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package groowt.view.component.web.groovyc;
|
package groowt.view.component.web.groovyc;
|
||||||
|
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
||||||
import groowt.view.component.compiler.DefaultComponentTemplateCompilerConfiguration;
|
|
||||||
import groowt.view.component.compiler.source.ComponentTemplateSource;
|
import groowt.view.component.compiler.source.ComponentTemplateSource;
|
||||||
import groowt.view.component.web.WebViewComponentBugError;
|
import groowt.view.component.web.WebViewComponentBugError;
|
||||||
import groowt.view.component.web.ast.node.CompilationUnitNode;
|
import groowt.view.component.web.ast.node.CompilationUnitNode;
|
||||||
@ -80,13 +79,12 @@ public class DelegatingWebViewComponentTemplateParserPlugin implements ParserPlu
|
|||||||
}
|
}
|
||||||
|
|
||||||
final var groovyTranspiler = new DefaultGroovyTranspiler();
|
final var groovyTranspiler = new DefaultGroovyTranspiler();
|
||||||
final String teplateClassSimpleName = sourceUnitFileName.substring(0, sourceUnitFileName.length() - 4);
|
final String templateClassName = sourceUnitFileName.substring(0, sourceUnitFileName.length() - 4);
|
||||||
try {
|
try {
|
||||||
final SourceUnit transpiledSourceUnit = groovyTranspiler.transpile(
|
final SourceUnit transpiledSourceUnit = groovyTranspiler.transpile(
|
||||||
new DefaultComponentTemplateCompilerConfiguration(),
|
|
||||||
compileUnit,
|
compileUnit,
|
||||||
cuNode,
|
cuNode,
|
||||||
teplateClassSimpleName
|
templateClassName
|
||||||
);
|
);
|
||||||
return transpiledSourceUnit.getAST();
|
return transpiledSourceUnit.getAST();
|
||||||
} catch (ComponentTemplateCompileException e) {
|
} catch (ComponentTemplateCompileException e) {
|
||||||
|
@ -6,7 +6,6 @@ import groowt.view.component.web.WebViewComponentBugError;
|
|||||||
import groowt.view.component.web.ast.node.*;
|
import groowt.view.component.web.ast.node.*;
|
||||||
import groowt.view.component.web.transpile.groovy.GroovyUtil;
|
import groowt.view.component.web.transpile.groovy.GroovyUtil;
|
||||||
import groowt.view.component.web.transpile.groovy.GroovyUtil.ConvertResult;
|
import groowt.view.component.web.transpile.groovy.GroovyUtil.ConvertResult;
|
||||||
import groowt.view.component.web.transpile.resolve.ComponentClassNodeResolver;
|
|
||||||
import groowt.view.component.web.util.SourcePosition;
|
import groowt.view.component.web.util.SourcePosition;
|
||||||
import org.codehaus.groovy.ast.*;
|
import org.codehaus.groovy.ast.*;
|
||||||
import org.codehaus.groovy.ast.expr.*;
|
import org.codehaus.groovy.ast.expr.*;
|
||||||
@ -15,7 +14,6 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import static groowt.view.component.web.transpile.TranspilerUtil.*;
|
import static groowt.view.component.web.transpile.TranspilerUtil.*;
|
||||||
|
|
||||||
@ -25,13 +23,9 @@ public class DefaultComponentTranspiler implements ComponentTranspiler {
|
|||||||
private static final ClassNode COMPONENT_RESOLVE_EXCEPTION_TYPE = ClassHelper.make(ComponentResolveException.class);
|
private static final ClassNode COMPONENT_RESOLVE_EXCEPTION_TYPE = ClassHelper.make(ComponentResolveException.class);
|
||||||
private static final ClassNode COMPONENT_CREATE_EXCEPTION_TYPE = ClassHelper.make(ComponentCreateException.class);
|
private static final ClassNode COMPONENT_CREATE_EXCEPTION_TYPE = ClassHelper.make(ComponentCreateException.class);
|
||||||
|
|
||||||
private static final Pattern isFqn = Pattern.compile("^(\\p{Ll}.+\\.)+\\p{Lu}.+$");
|
|
||||||
private static final Pattern isWithPackage = Pattern.compile("^\\p{Ll}.+\\.");
|
|
||||||
|
|
||||||
private LeftShiftFactory leftShiftFactory;
|
private LeftShiftFactory leftShiftFactory;
|
||||||
private ValueNodeTranspiler valueNodeTranspiler;
|
private ValueNodeTranspiler valueNodeTranspiler;
|
||||||
private BodyTranspiler bodyTranspiler;
|
private BodyTranspiler bodyTranspiler;
|
||||||
private ComponentClassNodeResolver componentClassNodeResolver;
|
|
||||||
|
|
||||||
public void setLeftShiftFactory(LeftShiftFactory leftShiftFactory) {
|
public void setLeftShiftFactory(LeftShiftFactory leftShiftFactory) {
|
||||||
this.leftShiftFactory = leftShiftFactory;
|
this.leftShiftFactory = leftShiftFactory;
|
||||||
@ -45,10 +39,6 @@ public class DefaultComponentTranspiler implements ComponentTranspiler {
|
|||||||
this.bodyTranspiler = bodyTranspiler;
|
this.bodyTranspiler = bodyTranspiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setComponentClassNodeResolver(ComponentClassNodeResolver componentClassNodeResolver) {
|
|
||||||
this.componentClassNodeResolver = componentClassNodeResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* UTIL */
|
/* UTIL */
|
||||||
|
|
||||||
protected String getComponentName(int componentNumber) {
|
protected String getComponentName(int componentNumber) {
|
||||||
@ -74,49 +64,14 @@ public class DefaultComponentTranspiler implements ComponentTranspiler {
|
|||||||
|
|
||||||
/* RESOLVE */
|
/* RESOLVE */
|
||||||
|
|
||||||
protected List<Expression> getArgsAsList(
|
protected List<Expression> getArgsAsList(TypedComponentNode componentNode) {
|
||||||
TypedComponentNode componentNode,
|
|
||||||
TranspilerState state
|
|
||||||
) {
|
|
||||||
return switch (componentNode.getArgs().getType()) {
|
return switch (componentNode.getArgs().getType()) {
|
||||||
case ClassComponentTypeNode classComponentTypeNode -> {
|
case ClassComponentTypeNode classComponentTypeNode -> {
|
||||||
final String identifier = classComponentTypeNode.getIdentifier();
|
final String identifier = classComponentTypeNode.getIdentifier();
|
||||||
final ConstantExpression alias = getStringLiteral(identifier);
|
final ConstantExpression alias = getStringLiteral(identifier);
|
||||||
final var matcher = isFqn.matcher(identifier);
|
final ClassNode classNode = ClassHelper.make(identifier);
|
||||||
if (matcher.matches()) {
|
final var classExpression = new ClassExpression(classNode);
|
||||||
final ClassNode classNode = ClassHelper.make(identifier);
|
yield List.of(alias, classExpression);
|
||||||
final ClassExpression classExpression = new ClassExpression(classNode);
|
|
||||||
yield List.of(alias, classExpression);
|
|
||||||
} else {
|
|
||||||
// we need to resolve it
|
|
||||||
final var isWithPackageMatcher = isWithPackage.matcher(identifier);
|
|
||||||
if (isWithPackageMatcher.matches()) {
|
|
||||||
final var resolveResult = this.componentClassNodeResolver.getClassForFqn(identifier);
|
|
||||||
if (resolveResult.isLeft()) {
|
|
||||||
final var error = resolveResult.getLeft();
|
|
||||||
error.setNode(componentNode.getArgs().getType());
|
|
||||||
state.addError(error);
|
|
||||||
yield List.of();
|
|
||||||
} else {
|
|
||||||
final ClassNode classNode = resolveResult.getRight();
|
|
||||||
final ClassExpression classExpression = new ClassExpression(classNode); // TODO: pos
|
|
||||||
yield List.of(alias, classExpression);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
final var resolveResult =
|
|
||||||
this.componentClassNodeResolver.getClassForNameWithoutPackage(identifier);
|
|
||||||
if (resolveResult.isLeft()) {
|
|
||||||
final var error = resolveResult.getLeft();
|
|
||||||
error.setNode(componentNode.getArgs().getType());
|
|
||||||
state.addError(error);
|
|
||||||
yield List.of();
|
|
||||||
} else {
|
|
||||||
final ClassNode classNode = resolveResult.getRight();
|
|
||||||
final ClassExpression classExpression = new ClassExpression(classNode); // TODO: pos
|
|
||||||
yield List.of(alias, classExpression);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
case StringComponentTypeNode stringComponentTypeNode -> {
|
case StringComponentTypeNode stringComponentTypeNode -> {
|
||||||
final String identifier = stringComponentTypeNode.getIdentifier();
|
final String identifier = stringComponentTypeNode.getIdentifier();
|
||||||
@ -127,8 +82,8 @@ public class DefaultComponentTranspiler implements ComponentTranspiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 'h1' | 'MyComponent', MyComponent(.class)
|
// 'h1' | 'MyComponent', MyComponent(.class)
|
||||||
protected ArgumentListExpression getResolveArgs(TypedComponentNode componentNode, TranspilerState state) {
|
protected ArgumentListExpression getResolveArgs(TypedComponentNode componentNode) {
|
||||||
final List<Expression> args = this.getArgsAsList(componentNode, state);
|
final List<Expression> args = this.getArgsAsList(componentNode);
|
||||||
final ArgumentListExpression argsListExpr = new ArgumentListExpression();
|
final ArgumentListExpression argsListExpr = new ArgumentListExpression();
|
||||||
args.forEach(argsListExpr::addExpression);
|
args.forEach(argsListExpr::addExpression);
|
||||||
return argsListExpr;
|
return argsListExpr;
|
||||||
@ -142,7 +97,7 @@ public class DefaultComponentTranspiler implements ComponentTranspiler {
|
|||||||
return new MethodCallExpression(
|
return new MethodCallExpression(
|
||||||
new VariableExpression(state.getRenderContext()),
|
new VariableExpression(state.getRenderContext()),
|
||||||
"resolve",
|
"resolve",
|
||||||
this.getResolveArgs(componentNode, state)
|
this.getResolveArgs(componentNode)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package groowt.view.component.web.transpile;
|
|||||||
|
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileUnit;
|
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.BodyNode;
|
||||||
import groowt.view.component.web.ast.node.CompilationUnitNode;
|
import groowt.view.component.web.ast.node.CompilationUnitNode;
|
||||||
import groowt.view.component.web.ast.node.PreambleNode;
|
import groowt.view.component.web.ast.node.PreambleNode;
|
||||||
@ -10,7 +9,6 @@ import groowt.view.component.web.compiler.MultipleWebViewComponentCompileErrorsE
|
|||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileException;
|
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileException;
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
||||||
import groowt.view.component.web.transpile.groovy.GroovyUtil;
|
import groowt.view.component.web.transpile.groovy.GroovyUtil;
|
||||||
import groowt.view.component.web.transpile.resolve.ClassLoaderComponentClassNodeResolver;
|
|
||||||
import org.codehaus.groovy.ast.*;
|
import org.codehaus.groovy.ast.*;
|
||||||
import org.codehaus.groovy.ast.expr.*;
|
import org.codehaus.groovy.ast.expr.*;
|
||||||
import org.codehaus.groovy.ast.stmt.BlockStatement;
|
import org.codehaus.groovy.ast.stmt.BlockStatement;
|
||||||
@ -31,25 +29,13 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
|
|||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(DefaultGroovyTranspiler.class);
|
private static final Logger logger = LoggerFactory.getLogger(DefaultGroovyTranspiler.class);
|
||||||
|
|
||||||
protected TranspilerConfiguration getConfiguration(
|
protected TranspilerConfiguration getConfiguration() {
|
||||||
ClassLoaderComponentClassNodeResolver classLoaderComponentClassNodeResolver
|
return SimpleTranspilerConfiguration.withDefaults();
|
||||||
) {
|
|
||||||
return SimpleTranspilerConfiguration.withDefaults(classLoaderComponentClassNodeResolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addAutomaticImports(WebViewComponentModuleNode moduleNode, TranspilerConfiguration configuration) {
|
|
||||||
configuration.getImports().forEach(moduleNode::addImport);
|
|
||||||
configuration.getStaticImports().forEach(staticImport -> moduleNode.addStaticImport(
|
|
||||||
staticImport.getV1(), staticImport.getV2(), staticImport.getV3()
|
|
||||||
));
|
|
||||||
configuration.getStarImports().forEach(moduleNode::addStarImport);
|
|
||||||
configuration.getStaticStarImports().forEach(moduleNode::addStaticStarImport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected WebViewComponentModuleNode initModuleNode(
|
protected WebViewComponentModuleNode initModuleNode(
|
||||||
ComponentTemplateCompileUnit compileUnit,
|
ComponentTemplateCompileUnit compileUnit,
|
||||||
WebViewComponentSourceUnit sourceUnit,
|
WebViewComponentSourceUnit sourceUnit
|
||||||
TranspilerConfiguration configuration
|
|
||||||
) {
|
) {
|
||||||
final var moduleNode = new WebViewComponentModuleNode(sourceUnit);
|
final var moduleNode = new WebViewComponentModuleNode(sourceUnit);
|
||||||
sourceUnit.setModuleNode(moduleNode);
|
sourceUnit.setModuleNode(moduleNode);
|
||||||
@ -59,22 +45,16 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
|
|||||||
moduleNode.setPackageName(defaultPackageName);
|
moduleNode.setPackageName(defaultPackageName);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addAutomaticImports(moduleNode, configuration);
|
|
||||||
return moduleNode;
|
return moduleNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ClassNode initMainClassNode(
|
protected ClassNode initMainClassNode(ComponentTemplateCompileUnit compileUnit, String templateClassName) {
|
||||||
ComponentTemplateCompileUnit compileUnit,
|
|
||||||
String templateClassName,
|
|
||||||
WebViewComponentModuleNode moduleNode
|
|
||||||
) {
|
|
||||||
final ClassNode mainClassNode = new ClassNode(
|
final ClassNode mainClassNode = new ClassNode(
|
||||||
compileUnit.getDefaultPackageName() + templateClassName,
|
compileUnit.getDefaultPackageName() + templateClassName,
|
||||||
ACC_PUBLIC,
|
ACC_PUBLIC,
|
||||||
ClassHelper.OBJECT_TYPE
|
ClassHelper.OBJECT_TYPE
|
||||||
);
|
);
|
||||||
mainClassNode.addInterface(TranspilerUtil.COMPONENT_TEMPLATE);
|
mainClassNode.addInterface(TranspilerUtil.COMPONENT_TEMPLATE);
|
||||||
moduleNode.addClass(mainClassNode);
|
|
||||||
return mainClassNode;
|
return mainClassNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,40 +196,32 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public WebViewComponentSourceUnit transpile(
|
public WebViewComponentSourceUnit transpile(
|
||||||
ComponentTemplateCompilerConfiguration compilerConfiguration,
|
|
||||||
WebViewComponentTemplateCompileUnit compileUnit,
|
WebViewComponentTemplateCompileUnit compileUnit,
|
||||||
CompilationUnitNode compilationUnitNode,
|
CompilationUnitNode compilationUnitNode,
|
||||||
String templateClassSimpleName
|
String templateClassSimpleName
|
||||||
) throws ComponentTemplateCompileException {
|
) throws ComponentTemplateCompileException {
|
||||||
// resolver, transpilerConfiguration, and positionSetter
|
// transpilerConfiguration, and positionSetter
|
||||||
final ClassLoaderComponentClassNodeResolver resolver = new ClassLoaderComponentClassNodeResolver(
|
final var transpilerConfiguration = this.getConfiguration();
|
||||||
compileUnit,
|
|
||||||
compilerConfiguration.getGroovyClassLoader()
|
|
||||||
);
|
|
||||||
final var transpilerConfiguration = this.getConfiguration(resolver);
|
|
||||||
final PositionSetter positionSetter = transpilerConfiguration.getPositionSetter();
|
final PositionSetter positionSetter = transpilerConfiguration.getPositionSetter();
|
||||||
|
|
||||||
// prepare sourceUnit
|
// prepare sourceUnit
|
||||||
final CompilerConfiguration groovyCompilerConfiguration =
|
final CompilerConfiguration groovyCompilerConfiguration = compileUnit.getGroovyCompilationUnit()
|
||||||
compilerConfiguration.getGroovyCompilerConfiguration();
|
.getConfiguration();
|
||||||
final WebViewComponentSourceUnit sourceUnit = new WebViewComponentSourceUnit(
|
final WebViewComponentSourceUnit sourceUnit = new WebViewComponentSourceUnit(
|
||||||
compileUnit.getDescriptiveName(),
|
compileUnit.getDescriptiveName(),
|
||||||
compileUnit.getGroovyReaderSource(),
|
compileUnit.getGroovyReaderSource(),
|
||||||
groovyCompilerConfiguration,
|
groovyCompilerConfiguration,
|
||||||
compilerConfiguration.getGroovyClassLoader(),
|
compileUnit.getGroovyCompilationUnit().getClassLoader(),
|
||||||
new ErrorCollector(groovyCompilerConfiguration)
|
new ErrorCollector(groovyCompilerConfiguration)
|
||||||
);
|
);
|
||||||
|
|
||||||
// prepare moduleNode
|
// prepare moduleNode
|
||||||
final WebViewComponentModuleNode moduleNode = this.initModuleNode(
|
final WebViewComponentModuleNode moduleNode = this.initModuleNode(
|
||||||
compileUnit, sourceUnit, transpilerConfiguration
|
compileUnit, sourceUnit
|
||||||
);
|
);
|
||||||
|
|
||||||
// set resolver's moduleNode
|
|
||||||
resolver.setModuleNode(moduleNode);
|
|
||||||
|
|
||||||
// prepare mainClassNode
|
// prepare mainClassNode
|
||||||
final ClassNode mainClassNode = this.initMainClassNode(compileUnit, templateClassSimpleName, moduleNode);
|
final ClassNode mainClassNode = this.initMainClassNode(compileUnit, templateClassSimpleName);
|
||||||
|
|
||||||
// handle preamble
|
// handle preamble
|
||||||
final PreambleNode preambleNode = compilationUnitNode.getPreambleNode();
|
final PreambleNode preambleNode = compilationUnitNode.getPreambleNode();
|
||||||
@ -257,6 +229,9 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
|
|||||||
this.handlePreamble(templateClassSimpleName, preambleNode, mainClassNode, moduleNode, positionSetter);
|
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
|
// getRenderer method and render closure
|
||||||
// first, getRenderer params
|
// first, getRenderer params
|
||||||
final Parameter componentContextParam = new Parameter(COMPONENT_CONTEXT_TYPE, COMPONENT_CONTEXT_NAME);
|
final Parameter componentContextParam = new Parameter(COMPONENT_CONTEXT_TYPE, COMPONENT_CONTEXT_NAME);
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package groowt.view.component.web.transpile;
|
package groowt.view.component.web.transpile;
|
||||||
|
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
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.ast.node.CompilationUnitNode;
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
||||||
|
|
||||||
public interface GroovyTranspiler {
|
public interface GroovyTranspiler {
|
||||||
|
|
||||||
WebViewComponentSourceUnit transpile(
|
WebViewComponentSourceUnit transpile(
|
||||||
ComponentTemplateCompilerConfiguration compilerConfiguration,
|
|
||||||
WebViewComponentTemplateCompileUnit compileUnit,
|
WebViewComponentTemplateCompileUnit compileUnit,
|
||||||
CompilationUnitNode compilationUnitNode,
|
CompilationUnitNode compilationUnitNode,
|
||||||
String templateClassSimpleName
|
String templateClassSimpleName
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package groowt.view.component.web.transpile;
|
package groowt.view.component.web.transpile;
|
||||||
|
|
||||||
import groovy.lang.Tuple3;
|
import groovy.lang.Tuple3;
|
||||||
import groowt.view.component.web.transpile.resolve.ComponentClassNodeResolver;
|
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
import org.codehaus.groovy.ast.ClassNode;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -12,9 +11,8 @@ import static groowt.view.component.web.transpile.TranspilerUtil.*;
|
|||||||
|
|
||||||
public class SimpleTranspilerConfiguration implements TranspilerConfiguration {
|
public class SimpleTranspilerConfiguration implements TranspilerConfiguration {
|
||||||
|
|
||||||
public static TranspilerConfiguration withDefaults(ComponentClassNodeResolver componentClassNodeResolver) {
|
public static TranspilerConfiguration withDefaults() {
|
||||||
final var c = new SimpleTranspilerConfiguration();
|
final var c = new SimpleTranspilerConfiguration();
|
||||||
c.setComponentClassNodeResolver(componentClassNodeResolver);
|
|
||||||
|
|
||||||
final var ct = new DefaultComponentTranspiler();
|
final var ct = new DefaultComponentTranspiler();
|
||||||
final PositionSetter ps = new SimplePositionSetter();
|
final PositionSetter ps = new SimplePositionSetter();
|
||||||
@ -27,7 +25,6 @@ public class SimpleTranspilerConfiguration implements TranspilerConfiguration {
|
|||||||
ct.setLeftShiftFactory(lsf);
|
ct.setLeftShiftFactory(lsf);
|
||||||
ct.setBodyTranspiler(bt);
|
ct.setBodyTranspiler(bt);
|
||||||
ct.setValueNodeTranspiler(vnt);
|
ct.setValueNodeTranspiler(vnt);
|
||||||
ct.setComponentClassNodeResolver(componentClassNodeResolver);
|
|
||||||
|
|
||||||
c.setComponentTranspiler(ct);
|
c.setComponentTranspiler(ct);
|
||||||
c.setPositionSetter(ps);
|
c.setPositionSetter(ps);
|
||||||
@ -40,7 +37,6 @@ public class SimpleTranspilerConfiguration implements TranspilerConfiguration {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ComponentClassNodeResolver componentClassNodeResolver;
|
|
||||||
private ComponentTranspiler componentTranspiler;
|
private ComponentTranspiler componentTranspiler;
|
||||||
private PositionSetter positionSetter;
|
private PositionSetter positionSetter;
|
||||||
private LeftShiftFactory leftShiftFactory;
|
private LeftShiftFactory leftShiftFactory;
|
||||||
@ -49,14 +45,6 @@ public class SimpleTranspilerConfiguration implements TranspilerConfiguration {
|
|||||||
private BodyTranspiler bodyTranspiler;
|
private BodyTranspiler bodyTranspiler;
|
||||||
private ValueNodeTranspiler valueNodeTranspiler;
|
private ValueNodeTranspiler valueNodeTranspiler;
|
||||||
|
|
||||||
public ComponentClassNodeResolver getComponentClassNodeResolver() {
|
|
||||||
return Objects.requireNonNull(this.componentClassNodeResolver);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setComponentClassNodeResolver(ComponentClassNodeResolver componentClassNodeResolver) {
|
|
||||||
this.componentClassNodeResolver = componentClassNodeResolver;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ComponentTranspiler getComponentTranspiler() {
|
public ComponentTranspiler getComponentTranspiler() {
|
||||||
return Objects.requireNonNull(this.componentTranspiler);
|
return Objects.requireNonNull(this.componentTranspiler);
|
||||||
}
|
}
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
package groowt.view.component.web.transpile.resolve;
|
|
||||||
|
|
||||||
import groowt.util.fp.either.Either;
|
|
||||||
import groowt.view.component.web.WebViewComponent;
|
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
|
||||||
import org.codehaus.groovy.ast.ClassHelper;
|
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CachingComponentClassNodeResolver implements ComponentClassNodeResolver {
|
|
||||||
|
|
||||||
private final List<ClassNode> classNodes = new ArrayList<>();
|
|
||||||
|
|
||||||
protected final WebViewComponentTemplateCompileUnit compileUnit;
|
|
||||||
|
|
||||||
public CachingComponentClassNodeResolver(WebViewComponentTemplateCompileUnit compileUnit) {
|
|
||||||
this.compileUnit = compileUnit;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClass(Class<? extends WebViewComponent> clazz) {
|
|
||||||
this.classNodes.add(ClassHelper.make(clazz));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addClassNode(ClassNode classNode) {
|
|
||||||
this.classNodes.add(classNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Either<ClassNodeResolveException, ClassNode> getClassForFqn(String fqn) {
|
|
||||||
for (final var classNode : this.classNodes) {
|
|
||||||
if (classNode.getName().equals(fqn)) {
|
|
||||||
return Either.right(classNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Either.left(new ClassNodeResolveException(
|
|
||||||
this.compileUnit,
|
|
||||||
fqn,
|
|
||||||
"Could not resolve ClassNode for fqn: " + fqn,
|
|
||||||
null
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Either<ClassNodeResolveException, ClassNode> getClassForNameWithoutPackage(String nameWithoutPackage) {
|
|
||||||
for (final var classNode : this.classNodes) {
|
|
||||||
if (classNode.getNameWithoutPackage().equals(nameWithoutPackage)) {
|
|
||||||
return Either.right(classNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Either.left(new ClassNodeResolveException(
|
|
||||||
this.compileUnit,
|
|
||||||
nameWithoutPackage,
|
|
||||||
"Could not resolve ClassNode for nameWithoutPackage: " + nameWithoutPackage,
|
|
||||||
null
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
package groowt.view.component.web.transpile.resolve;
|
|
||||||
|
|
||||||
import groowt.util.fp.either.Either;
|
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
public class ClassLoaderComponentClassNodeResolver extends ModuleNodeComponentClassNodeResolver {
|
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ModuleNodeComponentClassNodeResolver.class);
|
|
||||||
|
|
||||||
protected final ClassLoader classLoader;
|
|
||||||
|
|
||||||
public ClassLoaderComponentClassNodeResolver(
|
|
||||||
WebViewComponentTemplateCompileUnit compileUnit,
|
|
||||||
ClassLoader classLoader
|
|
||||||
) {
|
|
||||||
super(compileUnit);
|
|
||||||
this.classLoader = classLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final Either<ClassNodeResolveException, ClassNode> resolveWithClassLoader(String fqn) {
|
|
||||||
logger.debug("Trying to resolve {}", fqn);
|
|
||||||
try {
|
|
||||||
Class<?> clazz = this.classLoader.loadClass(ResolveUtil.convertCanonicalNameToBinaryName(fqn));
|
|
||||||
final var classNode = ResolveUtil.getClassNode(clazz);
|
|
||||||
return Either.right(classNode);
|
|
||||||
} catch (ClassNotFoundException classNotFoundException) {
|
|
||||||
return Either.left(
|
|
||||||
new ClassNodeResolveException(
|
|
||||||
this.compileUnit,
|
|
||||||
fqn,
|
|
||||||
"Could not find class " + fqn + " with classLoader " +
|
|
||||||
this.classLoader,
|
|
||||||
classNotFoundException
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Either<ClassNodeResolveException, ClassNode> getClassForFqn(String fqn) {
|
|
||||||
return super.getClassForFqn(fqn).flatMapLeft(ignored -> {
|
|
||||||
final var classLoaderResult = this.resolveWithClassLoader(fqn);
|
|
||||||
if (classLoaderResult.isRight()) {
|
|
||||||
this.addClassNode(classLoaderResult.getRight());
|
|
||||||
}
|
|
||||||
return classLoaderResult;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
package groowt.view.component.web.transpile.resolve;
|
|
||||||
|
|
||||||
import groowt.util.fp.either.Either;
|
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileException;
|
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
|
||||||
|
|
||||||
public interface ComponentClassNodeResolver {
|
|
||||||
|
|
||||||
final class ClassNodeResolveException extends WebViewComponentTemplateCompileException {
|
|
||||||
|
|
||||||
private final String identifier;
|
|
||||||
|
|
||||||
public ClassNodeResolveException(
|
|
||||||
WebViewComponentTemplateCompileUnit compileUnit,
|
|
||||||
String identifier,
|
|
||||||
String message
|
|
||||||
) {
|
|
||||||
super(compileUnit, message);
|
|
||||||
this.identifier = identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ClassNodeResolveException(
|
|
||||||
WebViewComponentTemplateCompileUnit compileUnit,
|
|
||||||
String identifier,
|
|
||||||
String message,
|
|
||||||
Throwable cause
|
|
||||||
) {
|
|
||||||
super(compileUnit, message, cause);
|
|
||||||
this.identifier = identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdentifier() {
|
|
||||||
return this.identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Either<ClassNodeResolveException, ClassNode> getClassForFqn(String fqn);
|
|
||||||
Either<ClassNodeResolveException, ClassNode> getClassForNameWithoutPackage(String nameWithoutPackage);
|
|
||||||
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
package groowt.view.component.web.transpile.resolve;
|
|
||||||
|
|
||||||
import groowt.util.fp.either.Either;
|
|
||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
|
||||||
import org.codehaus.groovy.ast.ModuleNode;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class ModuleNodeComponentClassNodeResolver extends CachingComponentClassNodeResolver {
|
|
||||||
|
|
||||||
private ModuleNode moduleNode;
|
|
||||||
|
|
||||||
public ModuleNodeComponentClassNodeResolver(WebViewComponentTemplateCompileUnit compileUnit) {
|
|
||||||
super(compileUnit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ModuleNode getModuleNode() {
|
|
||||||
return Objects.requireNonNull(this.moduleNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setModuleNode(ModuleNode moduleNode) {
|
|
||||||
this.moduleNode = Objects.requireNonNull(moduleNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Either<ClassNodeResolveException, ClassNode> getClassForNameWithoutPackage(String nameWithoutPackage) {
|
|
||||||
return super.getClassForNameWithoutPackage(nameWithoutPackage).flatMapLeft(ignored -> {
|
|
||||||
// try regular imports first
|
|
||||||
final var importedClassNode = this.getModuleNode().getImportType(nameWithoutPackage);
|
|
||||||
if (importedClassNode != null) {
|
|
||||||
this.addClassNode(importedClassNode);
|
|
||||||
return Either.right(importedClassNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
// try star imports
|
|
||||||
final var starImports = this.getModuleNode().getStarImports();
|
|
||||||
for (final var starImport : starImports) {
|
|
||||||
final var packageName = starImport.getPackageName();
|
|
||||||
final String fqn;
|
|
||||||
if (!packageName.equals(".") && packageName.endsWith(".")) {
|
|
||||||
fqn = packageName + nameWithoutPackage;
|
|
||||||
} else {
|
|
||||||
fqn = packageName + "." + nameWithoutPackage;
|
|
||||||
}
|
|
||||||
final var withPackage = this.getClassForFqn(fqn);
|
|
||||||
if (withPackage.isRight()) {
|
|
||||||
return withPackage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// try pre-pending package and asking for fqn
|
|
||||||
final String moduleNodePackageName = this.getModuleNode().getPackageName();
|
|
||||||
final String packageName;
|
|
||||||
if (moduleNodePackageName != null) {
|
|
||||||
packageName = moduleNodePackageName;
|
|
||||||
} else {
|
|
||||||
packageName = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
final String fqn;
|
|
||||||
if (packageName.equals(".") || packageName.isEmpty()) {
|
|
||||||
fqn = nameWithoutPackage;
|
|
||||||
} else if (packageName.endsWith(".")) {
|
|
||||||
fqn = packageName + nameWithoutPackage;
|
|
||||||
} else {
|
|
||||||
fqn = packageName + "." + nameWithoutPackage;
|
|
||||||
}
|
|
||||||
|
|
||||||
final var withPackage = this.getClassForFqn(fqn);
|
|
||||||
if (withPackage.isRight()) {
|
|
||||||
return withPackage;
|
|
||||||
} else {
|
|
||||||
return Either.left(new ClassNodeResolveException(
|
|
||||||
this.compileUnit,
|
|
||||||
nameWithoutPackage,
|
|
||||||
"Cannot resolve " + nameWithoutPackage
|
|
||||||
+ " from imports, package-local classes, or pre-added classes."
|
|
||||||
));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
package groowt.view.component.web.transpile.resolve;
|
|
||||||
|
|
||||||
import org.codehaus.groovy.ast.ClassHelper;
|
|
||||||
import org.codehaus.groovy.ast.ClassNode;
|
|
||||||
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public final class ResolveUtil {
|
|
||||||
|
|
||||||
private static final Pattern packageSplitter = Pattern.compile("^(?<package>(?>\\p{Ll}[^.]*\\.)*)(?<top>\\p{Lu}[^.]*)(?<members>(?>\\.\\p{Lu}[^.]*)*)$");
|
|
||||||
|
|
||||||
public static ClassNode getClassNode(Class<?> clazz) {
|
|
||||||
return ClassHelper.makeCached(clazz);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String convertCanonicalNameToBinaryName(String canonicalName) {
|
|
||||||
final var matcher = packageSplitter.matcher(canonicalName);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
return new StringBuilder()
|
|
||||||
.append(matcher.group("package"))
|
|
||||||
.append(matcher.group("top"))
|
|
||||||
.append(matcher.group("members").replaceAll("\\.", "\\$"))
|
|
||||||
.toString();
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("Cannot split apart " + canonicalName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private ResolveUtil() {}
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +1,16 @@
|
|||||||
package groowt.view.component.web.groovyc
|
package groowt.view.component.web.groovyc
|
||||||
|
|
||||||
import org.codehaus.groovy.control.CompilerConfiguration
|
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()
|
|
||||||
|
@ -3,7 +3,6 @@ package groowt.view.component.web.transpiler;
|
|||||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
||||||
import groowt.view.component.web.transpile.SimpleTranspilerConfiguration;
|
import groowt.view.component.web.transpile.SimpleTranspilerConfiguration;
|
||||||
import groowt.view.component.web.transpile.TranspilerConfiguration;
|
import groowt.view.component.web.transpile.TranspilerConfiguration;
|
||||||
import groowt.view.component.web.transpile.resolve.CachingComponentClassNodeResolver;
|
|
||||||
import org.codehaus.groovy.ast.ModuleNode;
|
import org.codehaus.groovy.ast.ModuleNode;
|
||||||
|
|
||||||
public class DefaultBodyTranspilerTests extends BodyTranspilerTests {
|
public class DefaultBodyTranspilerTests extends BodyTranspilerTests {
|
||||||
@ -13,7 +12,7 @@ public class DefaultBodyTranspilerTests extends BodyTranspilerTests {
|
|||||||
WebViewComponentTemplateCompileUnit compileUnit,
|
WebViewComponentTemplateCompileUnit compileUnit,
|
||||||
ModuleNode moduleNode
|
ModuleNode moduleNode
|
||||||
) {
|
) {
|
||||||
return SimpleTranspilerConfiguration.withDefaults(new CachingComponentClassNodeResolver(compileUnit));
|
return SimpleTranspilerConfiguration.withDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
package groowt.view.component.web.transpiler;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
import static groowt.view.component.web.transpile.resolve.ResolveUtil.convertCanonicalNameToBinaryName;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
|
|
||||||
public class ResolveUtilTests {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void abcABC() {
|
|
||||||
assertEquals("a.b.c.A$B$C", convertCanonicalNameToBinaryName("a.b.c.A.B.C"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void ABC() {
|
|
||||||
assertEquals("A$B$C", convertCanonicalNameToBinaryName("A.B.C"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void abcA() {
|
|
||||||
assertEquals("a.b.c.A", convertCanonicalNameToBinaryName("a.b.c.A"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -2,7 +2,6 @@ package groowt.view.component.web.transpiler;
|
|||||||
|
|
||||||
import groovy.lang.Tuple2;
|
import groovy.lang.Tuple2;
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
||||||
import groowt.view.component.compiler.DefaultComponentTemplateCompilerConfiguration;
|
|
||||||
import groowt.view.component.compiler.source.StringSource;
|
import groowt.view.component.compiler.source.StringSource;
|
||||||
import groowt.view.component.web.BaseWebViewComponent;
|
import groowt.view.component.web.BaseWebViewComponent;
|
||||||
import groowt.view.component.web.antlr.ParserUtil;
|
import groowt.view.component.web.antlr.ParserUtil;
|
||||||
@ -55,7 +54,6 @@ public abstract class GroovyTranspilerTests {
|
|||||||
final var cuNode = astBuilder.buildCompilationUnit(parseResult.getCompilationUnitContext());
|
final var cuNode = astBuilder.buildCompilationUnit(parseResult.getCompilationUnitContext());
|
||||||
try {
|
try {
|
||||||
this.transpiler.transpile(
|
this.transpiler.transpile(
|
||||||
new DefaultComponentTemplateCompilerConfiguration(),
|
|
||||||
new DefaultWebViewComponentTemplateCompileUnit(
|
new DefaultWebViewComponentTemplateCompileUnit(
|
||||||
"<anonymous string source>",
|
"<anonymous string source>",
|
||||||
AnonymousWebViewComponent.class,
|
AnonymousWebViewComponent.class,
|
||||||
|
@ -9,6 +9,7 @@ import org.apache.logging.log4j.core.LoggerContext;
|
|||||||
import org.codehaus.groovy.control.CompilationFailedException;
|
import org.codehaus.groovy.control.CompilationFailedException;
|
||||||
import org.codehaus.groovy.control.CompilationUnit;
|
import org.codehaus.groovy.control.CompilationUnit;
|
||||||
import org.codehaus.groovy.control.CompilerConfiguration;
|
import org.codehaus.groovy.control.CompilerConfiguration;
|
||||||
|
import org.codehaus.groovy.control.customizers.ImportCustomizer;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import picocli.CommandLine.Command;
|
import picocli.CommandLine.Command;
|
||||||
|
|
||||||
@ -71,6 +72,15 @@ public final class GroovyWvcCompiler implements Callable<Integer> {
|
|||||||
|
|
||||||
public Integer doCompile() {
|
public Integer doCompile() {
|
||||||
final CompilerConfiguration configuration = new CompilerConfiguration();
|
final CompilerConfiguration configuration = new CompilerConfiguration();
|
||||||
|
|
||||||
|
final var addGroowtImports = new ImportCustomizer();
|
||||||
|
addGroowtImports.addStarImports(
|
||||||
|
"groowt.view.component.web.lib",
|
||||||
|
"groowt.view.component.web.runtime",
|
||||||
|
"groowt.view.component.runtime"
|
||||||
|
);
|
||||||
|
configuration.addCompilationCustomizers(addGroowtImports);
|
||||||
|
|
||||||
configuration.setPluginFactory(new WebViewComponentParserPluginFactory());
|
configuration.setPluginFactory(new WebViewComponentParserPluginFactory());
|
||||||
final CompilationUnit compilationUnit = new CompilationUnit(configuration);
|
final CompilationUnit compilationUnit = new CompilationUnit(configuration);
|
||||||
|
|
||||||
|
@ -4,13 +4,14 @@ import groowt.view.component.ViewComponent;
|
|||||||
import groowt.view.component.compiler.AbstractComponentTemplateCompileUnit;
|
import groowt.view.component.compiler.AbstractComponentTemplateCompileUnit;
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompileResult;
|
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.ComponentTemplateSource;
|
||||||
import groowt.view.component.compiler.source.FileSource;
|
import groowt.view.component.compiler.source.FileSource;
|
||||||
import groowt.view.component.compiler.source.URISource;
|
import groowt.view.component.compiler.source.URISource;
|
||||||
import groowt.view.component.compiler.source.URLSource;
|
import groowt.view.component.compiler.source.URLSource;
|
||||||
import org.codehaus.groovy.control.CompilationUnit;
|
import org.codehaus.groovy.control.CompilationUnit;
|
||||||
|
import org.codehaus.groovy.control.CompilerConfiguration;
|
||||||
import org.codehaus.groovy.control.Janitor;
|
import org.codehaus.groovy.control.Janitor;
|
||||||
|
import org.codehaus.groovy.control.customizers.ImportCustomizer;
|
||||||
import org.codehaus.groovy.control.io.ReaderSource;
|
import org.codehaus.groovy.control.io.ReaderSource;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -20,8 +21,20 @@ import java.net.URI;
|
|||||||
public class DefaultWebViewComponentTemplateCompileUnit extends AbstractComponentTemplateCompileUnit
|
public class DefaultWebViewComponentTemplateCompileUnit extends AbstractComponentTemplateCompileUnit
|
||||||
implements ReaderSource, WebViewComponentTemplateCompileUnit {
|
implements ReaderSource, WebViewComponentTemplateCompileUnit {
|
||||||
|
|
||||||
|
private static CompilationUnit getCompilationUnit() {
|
||||||
|
final var configuration = new CompilerConfiguration();
|
||||||
|
final var addGroowtImports = new ImportCustomizer();
|
||||||
|
addGroowtImports.addStarImports(
|
||||||
|
"groowt.view.component.web.lib",
|
||||||
|
"groowt.view.component.web.runtime",
|
||||||
|
"groowt.view.component.runtime"
|
||||||
|
);
|
||||||
|
configuration.addCompilationCustomizers(addGroowtImports);
|
||||||
|
return new CompilationUnit(configuration);
|
||||||
|
}
|
||||||
|
|
||||||
private final String defaultPackageName;
|
private final String defaultPackageName;
|
||||||
private final CompilationUnit groovyCompilationUnit = new CompilationUnit();
|
private final CompilationUnit groovyCompilationUnit;
|
||||||
|
|
||||||
public DefaultWebViewComponentTemplateCompileUnit(
|
public DefaultWebViewComponentTemplateCompileUnit(
|
||||||
String descriptiveName,
|
String descriptiveName,
|
||||||
@ -35,6 +48,7 @@ public class DefaultWebViewComponentTemplateCompileUnit extends AbstractComponen
|
|||||||
} else {
|
} else {
|
||||||
this.defaultPackageName = defaultPackageName;
|
this.defaultPackageName = defaultPackageName;
|
||||||
}
|
}
|
||||||
|
this.groovyCompilationUnit = getCompilationUnit();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -53,9 +67,8 @@ public class DefaultWebViewComponentTemplateCompileUnit extends AbstractComponen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ComponentTemplateCompileResult compile(ComponentTemplateCompilerConfiguration configuration)
|
public ComponentTemplateCompileResult compile() throws ComponentTemplateCompileException {
|
||||||
throws ComponentTemplateCompileException {
|
final WebViewComponentTemplateCompiler compiler = WebViewComponentTemplateCompiler.get();
|
||||||
final WebViewComponentTemplateCompiler compiler = WebViewComponentTemplateCompiler.get(configuration);
|
|
||||||
return compiler.compile(this);
|
return compiler.compile(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,10 +9,10 @@ public interface WebViewComponentTemplateCompiler
|
|||||||
extends ComponentTemplateCompiler<WebViewComponentTemplateCompileUnit> {
|
extends ComponentTemplateCompiler<WebViewComponentTemplateCompileUnit> {
|
||||||
|
|
||||||
static WebViewComponentTemplateCompiler get() {
|
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 =
|
final ServiceLoader<WebViewComponentTemplateCompilerFactory> factoryServiceLoader =
|
||||||
ServiceLoader.load(WebViewComponentTemplateCompilerFactory.class);
|
ServiceLoader.load(WebViewComponentTemplateCompilerFactory.class);
|
||||||
final var factory = factoryServiceLoader.findFirst()
|
final var factory = factoryServiceLoader.findFirst()
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package groowt.view.component.web.compiler;
|
package groowt.view.component.web.compiler;
|
||||||
|
|
||||||
import groowt.view.component.compiler.ComponentTemplateCompilerConfiguration;
|
|
||||||
|
|
||||||
public interface WebViewComponentTemplateCompilerFactory {
|
public interface WebViewComponentTemplateCompilerFactory {
|
||||||
WebViewComponentTemplateCompiler create(ComponentTemplateCompilerConfiguration configuration);
|
WebViewComponentTemplateCompiler create(WebViewComponentTemplateCompilerConfiguration configuration);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user