Remove pre-emptive resolving mechanism, relying instead on built-in Groovyc resolution.
This commit is contained in:
parent
5ce934b3fe
commit
1a528465f9
@ -199,7 +199,10 @@ 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)
|
||||||
|
.filter { !(it.name =~ /groovy.*.jar/) }
|
||||||
|
.collect { it.isDirectory() ? it : zipTree(it) }
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,14 @@ 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 \
|
groovyc -cp build/libs/web-view-components-uber-0.1.2.jar \
|
||||||
--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 \
|
||||||
"$@"
|
"$@"
|
||||||
|
@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,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,10 +30,8 @@ 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) {
|
protected void addAutomaticImports(WebViewComponentModuleNode moduleNode, TranspilerConfiguration configuration) {
|
||||||
@ -227,6 +224,8 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
|
|||||||
compilerConfiguration.getGroovyClassLoader()
|
compilerConfiguration.getGroovyClassLoader()
|
||||||
);
|
);
|
||||||
final var transpilerConfiguration = this.getConfiguration(resolver);
|
final var transpilerConfiguration = this.getConfiguration(resolver);
|
||||||
|
// transpilerConfiguration, and positionSetter
|
||||||
|
final var transpilerConfiguration = this.getConfiguration();
|
||||||
final PositionSetter positionSetter = transpilerConfiguration.getPositionSetter();
|
final PositionSetter positionSetter = transpilerConfiguration.getPositionSetter();
|
||||||
|
|
||||||
// prepare sourceUnit
|
// prepare sourceUnit
|
||||||
@ -245,9 +244,6 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
|
|||||||
compileUnit, sourceUnit, transpilerConfiguration
|
compileUnit, sourceUnit, transpilerConfiguration
|
||||||
);
|
);
|
||||||
|
|
||||||
// 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, moduleNode);
|
||||||
|
|
||||||
|
@ -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(ClassLoaderComponentClassNodeResolver.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 {} via ClassLoader", 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() {}
|
|
||||||
|
|
||||||
}
|
|
@ -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"));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user