Groovyc can compile all sketching wvc.

This commit is contained in:
JesseBrault0709 2024-05-17 13:14:44 +02:00
parent 63720693a3
commit cdc96ffdff
16 changed files with 103 additions and 30 deletions

View File

@ -1 +1,2 @@
bin
groovyc-out

View File

@ -137,6 +137,7 @@ tasks.register('uberJar', Jar) {
group = 'build'
archiveBaseName = 'web-views-uber'
from sourceSets.main.output
from sourceSets.sketching.output
from sourceSets.main.runtimeClasspath.filter(File.&exists).collect {
it.isDirectory() ? it : zipTree(it)
}

View File

@ -1,17 +1,18 @@
#!/usr/bin/env bash
if [ "$1" == "--debug" ]; then
shift
gradle -q uberJar && \
java -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=*:8192 \
-cp build/libs/web-views-uber-0.1.0.jar \
org.codehaus.groovy.tools.FileSystemCompiler \
--configscript src/main/resources/groowt/view/web/groovyc/GroovycConfigurationScript.groovy \
-d groovyc-out \
sketching/helloTarget.wvc
"$@"
else
gradle -q uberJar && \
groovyc -cp build/libs/web-views-uber-0.1.0.jar \
--configscript src/main/resources/groowt/view/web/groovyc/GroovycConfigurationScript.groovy \
-d groovyc-out \
sketching/helloTarget.wvc
"$@"
fi

View File

@ -1,4 +1,4 @@
---
import groowt.view.web.lib.Echo
package sketching
---
<Echo><p>$cliGreeting</p></Echo>

View File

@ -1,9 +1,13 @@
---
package sketching
import groovy.transform.Field
void consume(out) {
out << 'World'
}
@groovy.transform.Field
@Field
String greeting = 'Hello'
---
$greeting, ${consume(it)}!

View File

@ -1,4 +1,6 @@
---
package sketching
class Greeter extends BaseWebViewComponent {
String target

View File

@ -0,0 +1,6 @@
---
package groowt.view.web.sketching
---
<>
<Greeters.Simple greeting='Hello, one!' />&nbsp;<Greeters.Simple greeting='Hello, two!' />
</>

View File

@ -0,0 +1,4 @@
---
package sketching
---
${new Helper().help('My God, it works')}

View File

@ -1,3 +0,0 @@
<>
<Greeter greeting='Hello, one!' />&nbsp;<Greeter greeting='Hello, two!' />
</>

View File

@ -16,7 +16,7 @@ public class MultipleWebViewComponentCompileErrorsException extends ComponentTem
ComponentTemplateCompileUnit compileUnit,
List<? extends Throwable> errors
) {
super(compileUnit, "There were multiple errors during compilation.");
super(compileUnit, "There were multiple errors during compilation/transpilation.");
this.errors.addAll(errors);
}

View File

@ -28,7 +28,11 @@ public class WebViewComponentTemplateCompileUnit extends AbstractComponentTempla
String defaultPackageName
) {
super(forClass, source);
this.defaultPackageName = defaultPackageName;
if (!defaultPackageName.isEmpty() && !defaultPackageName.endsWith(".")) {
this.defaultPackageName = defaultPackageName + ".";
} else {
this.defaultPackageName = defaultPackageName;
}
}
@Override

View File

@ -3,6 +3,7 @@ package groowt.view.web.groovyc;
import groowt.view.component.compiler.ComponentTemplateCompileException;
import groowt.view.component.compiler.DefaultComponentTemplateCompilerConfiguration;
import groowt.view.component.compiler.source.ComponentTemplateSource;
import groowt.view.web.WebViewComponentBugError;
import groowt.view.web.analysis.MismatchedComponentTypeAnalysis;
import groowt.view.web.analysis.MismatchedComponentTypeError;
import groowt.view.web.antlr.*;
@ -26,13 +27,18 @@ import org.codehaus.groovy.control.ParserPlugin;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.syntax.ParserException;
import org.codehaus.groovy.syntax.Reduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
public class DelegatingWvcParserPlugin implements ParserPlugin {
private static final Logger logger = LoggerFactory.getLogger(DelegatingWvcParserPlugin.class);
private final Antlr4ParserPlugin groovyParserPlugin;
public DelegatingWvcParserPlugin(Antlr4ParserPlugin groovyParserPlugin) {
@ -98,23 +104,41 @@ public class DelegatingWvcParserPlugin implements ParserPlugin {
}
protected ParserException translateException(ComponentTemplateCompileException e) {
final var actual = (WebViewComponentTemplateCompileException) e;
final SourcePosition sourcePosition = actual.getSourcePosition();
if (sourcePosition != null) {
return new ParserException(e.getMessage(), e, sourcePosition.line(), sourcePosition.column());
if (e instanceof WebViewComponentTemplateCompileException single) {
final SourcePosition sourcePosition = single.getSourcePosition();
if (sourcePosition != null) {
return new ParserException(e.getMessage(), e, sourcePosition.line(), sourcePosition.column());
} else {
return new ParserException(e.getMessage(), e, 1, 1);
}
} else if (e instanceof MultipleWebViewComponentCompileErrorsException multiple) {
return new ParserException("There were multiple errors during compilation/transpilation.", multiple, 1, 1);
} else {
return new ParserException(e.getMessage(), e, -1, -1);
throw new WebViewComponentBugError(
"Cannot determine the type of non-WebViewComponent compile exception: "
+ e.getClass().getName()
);
}
}
protected void logException(WebViewComponentTemplateCompileException e) {
logger.error(e.getMessage());
}
protected void logException(MultipleWebViewComponentCompileErrorsException e) {
logger.error(e.getMessage());
}
@Override
public ModuleNode buildAST(SourceUnit sourceUnit, ClassLoader classLoader, Reduction cst) throws ParserException {
final String sourceUnitName = sourceUnit.getName();
if (sourceUnitName.endsWith(".wvc")) {
final String sourceUnitFullName = sourceUnit.getName();
final int lastSlashIndex = sourceUnitFullName.lastIndexOf(File.separator);
final String sourceUnitFileName = sourceUnitFullName.substring(lastSlashIndex + 1);
if (sourceUnitFileName.endsWith(".wvc")) {
final var compileUnit = new WebViewComponentTemplateCompileUnit(
AnonymousWebViewComponent.class,
ComponentTemplateSource.of(sourceUnit.getSource().getURI()),
"groowt.view.web.groovyc"
"" // default package
);
final CompilationUnitParseResult parseResult;
@ -134,10 +158,12 @@ public class DelegatingWvcParserPlugin implements ParserPlugin {
final var errorExceptions = parseErrors.getAll().stream()
.map(errorNode -> getException(compileUnit, errorNode))
.toList();
throw this.translateException(new MultipleWebViewComponentCompileErrorsException(
final var multiple = new MultipleWebViewComponentCompileErrorsException(
compileUnit,
errorExceptions
));
);
this.logException(multiple);
throw this.translateException(multiple);
}
}
@ -152,10 +178,12 @@ public class DelegatingWvcParserPlugin implements ParserPlugin {
final var errorExceptions = mismatchedComponentTypeErrors.stream()
.map(error -> getException(compileUnit, error))
.toList();
throw this.translateException(new MultipleWebViewComponentCompileErrorsException(
final var multiple = new MultipleWebViewComponentCompileErrorsException(
compileUnit,
errorExceptions
));
);
this.logException(multiple);
throw this.translateException(multiple);
}
}
@ -165,15 +193,26 @@ public class DelegatingWvcParserPlugin implements ParserPlugin {
final var cuNode = (CompilationUnitNode) astBuilder.build(parseResult.getCompilationUnitContext());
final var groovyTranspiler = new DefaultGroovyTranspiler();
final String nameWithoutExtension = sourceUnitFileName.substring(0, sourceUnitFileName.length() - 4);
try {
final SourceUnit transpiledSourceUnit = groovyTranspiler.transpile(
new DefaultComponentTemplateCompilerConfiguration(),
compileUnit,
cuNode,
sourceUnitName.substring(0, sourceUnitName.length() - 4)
nameWithoutExtension
);
return transpiledSourceUnit.getAST();
} catch (ComponentTemplateCompileException e) {
if (e instanceof WebViewComponentTemplateCompileException single) {
this.logException(single);
} else if (e instanceof MultipleWebViewComponentCompileErrorsException multiple) {
this.logException(multiple);
} else {
throw new WebViewComponentBugError(
"Could not determine type of non-WebViewComponent compile exception: "
+ e.getClass().getName()
);
}
throw this.translateException(e);
}
} else {

View File

@ -87,6 +87,7 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
classNode.getMixins()
);
icn.setDeclaringClass(mainClassNode);
result.add(icn);
}
}
return result;
@ -178,7 +179,10 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
final var moduleNode = new WebViewComponentModuleNode(sourceUnit);
sourceUnit.setModuleNode(moduleNode);
moduleNode.setPackageName(compileUnit.getDefaultPackageName());
final String defaultPackageName = compileUnit.getDefaultPackageName();
if (!defaultPackageName.trim().isEmpty()) {
moduleNode.setPackageName(defaultPackageName);
}
moduleNode.addStarImport(GROOWT_VIEW_WEB + ".lib");
moduleNode.addImport(COMPONENT_TEMPLATE.getNameWithoutPackage(), COMPONENT_TEMPLATE);
@ -187,7 +191,7 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
moduleNode.addStarImport(GROOWT_VIEW_WEB + ".runtime");
final ClassNode mainClassNode = new ClassNode(
compileUnit.getDefaultPackageName() + "." + templateClassName,
compileUnit.getDefaultPackageName() + templateClassName,
ACC_PUBLIC,
ClassHelper.OBJECT_TYPE
);

View File

@ -32,7 +32,7 @@ public class ModuleNodeComponentClassNodeResolver extends CachingComponentClassN
for (final var starImport : starImports) {
final var packageName = starImport.getPackageName();
final String fqn;
if (packageName.endsWith(".")) {
if (!packageName.equals(".") && packageName.endsWith(".")) {
fqn = packageName + nameWithoutPackage;
} else {
fqn = packageName + "." + nameWithoutPackage;
@ -44,13 +44,23 @@ public class ModuleNodeComponentClassNodeResolver extends CachingComponentClassN
}
// try pre-pending package and asking for fqn
final var packageName = this.moduleNode.getPackageName();
final String fqn;
if (packageName.endsWith(".")) {
fqn = this.moduleNode.getPackageName() + nameWithoutPackage;
final String moduleNodePackageName = this.moduleNode.getPackageName();
final String packageName;
if (moduleNodePackageName != null) {
packageName = moduleNodePackageName;
} else {
fqn = this.moduleNode.getPackageName() + "." + nameWithoutPackage;
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;