diff --git a/web-views/src/main/java/groowt/view/web/transpile/DefaultComponentTranspiler.java b/web-views/src/main/java/groowt/view/web/transpile/DefaultComponentTranspiler.java index dd13031..b65b890 100644 --- a/web-views/src/main/java/groowt/view/web/transpile/DefaultComponentTranspiler.java +++ b/web-views/src/main/java/groowt/view/web/transpile/DefaultComponentTranspiler.java @@ -5,6 +5,7 @@ import groowt.view.component.*; import groowt.view.component.context.*; import groowt.view.web.ast.node.*; import groowt.view.web.runtime.WebViewComponentChildCollection; +import groowt.view.web.transpile.resolve.ComponentClassNodeResolver; import groowt.view.web.transpile.util.GroovyUtil; import groowt.view.web.transpile.util.GroovyUtil.ConvertResult; import org.codehaus.groovy.ast.*; @@ -46,6 +47,7 @@ public class DefaultComponentTranspiler implements ComponentTranspiler { private ValueNodeTranspiler valueNodeTranspiler; private BodyTranspiler bodyTranspiler; private AppendOrAddStatementFactory appendOrAddStatementFactory; + private ComponentClassNodeResolver componentClassNodeResolver; public void setValueNodeTranspiler(ValueNodeTranspiler valueNodeTranspiler) { this.valueNodeTranspiler = valueNodeTranspiler; @@ -59,6 +61,10 @@ public class DefaultComponentTranspiler implements ComponentTranspiler { this.appendOrAddStatementFactory = appendOrAddStatementFactory; } + public void setComponentClassNodeResolver(ComponentClassNodeResolver componentClassNodeResolver) { + this.componentClassNodeResolver = componentClassNodeResolver; + } + // ViewComponent c0 protected ExpressionStatement getComponentDeclaration(Variable component) { final var componentDeclaration = new DeclarationExpression( diff --git a/web-views/src/main/java/groowt/view/web/transpile/resolve/ComponentClassNodeResolver.java b/web-views/src/main/java/groowt/view/web/transpile/resolve/ComponentClassNodeResolver.java index 9bdba71..0d9e6de 100644 --- a/web-views/src/main/java/groowt/view/web/transpile/resolve/ComponentClassNodeResolver.java +++ b/web-views/src/main/java/groowt/view/web/transpile/resolve/ComponentClassNodeResolver.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.Nullable; public interface ComponentClassNodeResolver { - record ClassNodeResolveError(ClassIdentifier identifier, String getMessage, @Nullable Throwable getCause) {} + record ClassNodeResolveError(ClassIdentifier identifier, String message, @Nullable Throwable cause) {} Either getClassForFqn(String fqn); Either getClassForNameWithoutPackage(String nameWithoutPackage); diff --git a/web-views/src/main/java/groowt/view/web/transpile/resolve/DefaultComponentClassNodeResolver.java b/web-views/src/main/java/groowt/view/web/transpile/resolve/DefaultComponentClassNodeResolver.java index 4be01e7..ea5b348 100644 --- a/web-views/src/main/java/groowt/view/web/transpile/resolve/DefaultComponentClassNodeResolver.java +++ b/web-views/src/main/java/groowt/view/web/transpile/resolve/DefaultComponentClassNodeResolver.java @@ -135,8 +135,21 @@ public class DefaultComponentClassNodeResolver implements ComponentClassNodeReso final var classLoaderResolved = this.resolveWithClassLoader(identifier); if (classLoaderResolved.isRight()) { this.addToCache(identifier, classLoaderResolved.asRight().get()); + return classLoaderResolved; + } else { + // Return the left only if we had an error that we weren't possibly expecting. + final Throwable cause = classLoaderResolved.asLeft().get().cause(); + if (!(cause instanceof ClassNotFoundException)) { + return classLoaderResolved; + } } - return classLoaderResolved; + + // We have a fqn which is outside the expected packages/classpath + // Make a custom class node and hope that the groovy compiler + // can resolve it later. + final ClassNode classNode = ClassHelper.make(fqn); + this.addToCache(new ClassIdentifierWithFqn(getAlias(fqn), fqn), classNode); + return Either.right(classNode); } @Override @@ -148,7 +161,7 @@ public class DefaultComponentClassNodeResolver implements ComponentClassNodeReso return Either.right(fromCache); } - // try imports + // try given imports (not from compilation customizer) final var importedClassNode = this.moduleNode.getImportType(nameWithoutPackage); if (importedClassNode != null) { this.addToCache( diff --git a/web-views/src/tools/groovy/groowt/view/web/tools/AstFileMaker.groovy b/web-views/src/tools/groovy/groowt/view/web/tools/AstFileMaker.groovy index 10c0f5b..00bb83b 100644 --- a/web-views/src/tools/groovy/groowt/view/web/tools/AstFileMaker.groovy +++ b/web-views/src/tools/groovy/groowt/view/web/tools/AstFileMaker.groovy @@ -2,7 +2,7 @@ package groowt.view.web.tools import groovy.transform.InheritConstructors import groovy.transform.MapConstructor -import groowt.view.web.analysis.MismatchedComponentTypeAnalyzer +import groowt.view.web.analysis.MismatchedComponentTypeErrorAnalysis import groowt.view.web.antlr.AntlrUtil import groowt.view.web.antlr.ParserUtil import groowt.view.web.antlr.TokenList @@ -96,12 +96,11 @@ final class AstFileMaker extends AbstractTreeFileMaker { ) } - def mismatchedTypeAnalyzer = new MismatchedComponentTypeAnalyzer() - def mismatchedTypeErrors = mismatchedTypeAnalyzer.analyze(cuContext) + def mismatchedTypeErrors = MismatchedComponentTypeErrorAnalysis.check(cuContext) if (!mismatchedTypeErrors.isEmpty()) { def message = 'There were mismatched type errors: \n' + mismatchedTypeErrors.collect { - it.message() + it.getMessage() }.join('\n') return new BuildFailure( compilationUnitContext: cuContext,