Updated Echo for new closure semantics.

This commit is contained in:
JesseBrault0709 2024-05-27 09:58:16 +02:00
parent e112d81ea8
commit bd913e07d3
5 changed files with 36 additions and 61 deletions

View File

@ -0,0 +1,7 @@
---
import groovy.transform.Field
@Field
String greeting = 'Hello, World!'
---
$greeting

View File

@ -123,32 +123,11 @@ public class DefaultGroovyTranspiler implements GroovyTranspiler {
final BlockStatement preambleBlock = convertResult.blockStatement(); final BlockStatement preambleBlock = convertResult.blockStatement();
if (preambleBlock != null) { if (preambleBlock != null) {
// Fields logger.warn(
final List<Statement> preambleStatements = preambleBlock.getStatements(); "{} contains script statements which are not supported. Currently, only classes and"
final List<DeclarationExpression> declarationsWithField = preambleStatements.stream() + " methods are supported. The rest will be ignored.",
.filter(statement -> statement instanceof ExpressionStatement) templateClassName
.map(ExpressionStatement.class::cast) );
.map(ExpressionStatement::getExpression)
.filter(expression -> expression instanceof DeclarationExpression)
.map(DeclarationExpression.class::cast)
.filter(declarationExpression ->
!declarationExpression.getAnnotations(FIELD_ANNOTATION).isEmpty()
)
.toList();
if (declarationsWithField.size() != preambleStatements.size()) {
// TODO: figure out why we have extraneous statements sometimes when it seems otherwise not
logger.warn(
"{} contains script statements which are not supported. " +
"Currently, only classes, methods, and field declarations " +
"(marked with @groovy.transform.Field) " +
"are supported. The rest will be ignored.",
templateClassName
);
}
declarationsWithField.forEach(declaration -> {
declaration.setDeclaringClass(mainClassNode);
positionVisitor.visitDeclarationExpression(declaration);
});
} }
// move methods from script class // move methods from script class

View File

@ -1,6 +1,7 @@
package groowt.view.component.web.lib package groowt.view.component.web.lib
import groowt.view.View import groowt.view.View
import groowt.view.component.runtime.ComponentWriter
import groowt.view.component.runtime.DefaultComponentWriter import groowt.view.component.runtime.DefaultComponentWriter
class Echo extends DelegatingWebViewComponent { class Echo extends DelegatingWebViewComponent {
@ -17,7 +18,16 @@ class Echo extends DelegatingWebViewComponent {
return super.getProperty(propertyName) return super.getProperty(propertyName)
} catch (MissingPropertyException missingPropertyException) { } catch (MissingPropertyException missingPropertyException) {
if (this.attr.containsKey(propertyName)) { if (this.attr.containsKey(propertyName)) {
return this.attr[propertyName] def value = this.attr[propertyName]
if (value instanceof Closure) {
if (value.maximumNumberOfParameters == 0) {
return value
} else {
return value()
}
} else {
return value
}
} else { } else {
throw missingPropertyException throw missingPropertyException
} }
@ -26,12 +36,20 @@ class Echo extends DelegatingWebViewComponent {
@Override @Override
protected View getDelegate() { protected View getDelegate() {
return { return { Writer w ->
def componentWriter = new DefaultComponentWriter(it) def componentWriter = new DefaultComponentWriter(w)
componentWriter.setComponentContext(this.context) componentWriter.setComponentContext(this.context)
componentWriter.setRenderContext(this.context.renderContext) // hacky componentWriter.setRenderContext(this.context.renderContext)
this.children.each { this.children.each {
componentWriter << it if (it instanceof Closure) {
if (it.maximumNumberOfParameters == 1 && ComponentWriter.isAssignableFrom(it.parameterTypes[0])) {
it(componentWriter)
} else {
componentWriter << it()
}
} else {
componentWriter << it
}
} }
} }
} }

View File

@ -24,19 +24,6 @@ class BaseWebViewComponentTests extends AbstractWebViewComponentTests {
} }
@Test
void withPreambleImport() {
this.doTest('''
---
import groovy.transform.Field
@Field
String greeting = 'Hello, World!'
---
$greeting
'''.stripIndent().trim(), "Hello, World!")
}
@Test @Test
void nestedGreeter() { void nestedGreeter() {
def context = this.context() { def context = this.context() {

View File

@ -18,22 +18,6 @@ class SimpleWebViewComponentTests extends AbstractWebViewComponentTests {
) )
} }
@Test
void closureWithPropertyExpressionEvaluatesToValue() {
this.doTest(
'''
---
import groovy.transform.Field
@Field
Map greetings = [hello: 'Hello!']
---
<Echo greeting={greetings.hello}>$greeting</Echo>
'''.stripIndent().trim(),
'Hello!'
)
}
@Test @Test
void closureWithMethodCallIsClosure() { void closureWithMethodCallIsClosure() {
this.doTest( this.doTest(
@ -43,7 +27,7 @@ class SimpleWebViewComponentTests extends AbstractWebViewComponentTests {
input.capitalize() input.capitalize()
} }
--- ---
<Echo subHelper={ helper('lowercase') }>${ -> subHelper.call() }</Echo> <Echo subHelper={ -> helper('lowercase') }>${ -> subHelper.call() }</Echo>
'''.stripIndent().trim(), 'Lowercase' '''.stripIndent().trim(), 'Lowercase'
) )
} }