diff --git a/gcp/build.gradle b/gcp-api/build.gradle similarity index 79% rename from gcp/build.gradle rename to gcp-api/build.gradle index a16f9c2..b2e673a 100644 --- a/gcp/build.gradle +++ b/gcp-api/build.gradle @@ -8,9 +8,6 @@ repositories { } dependencies { - // https://mvnrepository.com/artifact/org.apache.groovy/groovy - implementation 'org.apache.groovy:groovy:4.0.7' - // https://mvnrepository.com/artifact/org.apache.groovy/groovy-templates implementation 'org.apache.groovy:groovy-templates:4.0.7' @@ -19,8 +16,10 @@ dependencies { // https://archiva.jessebrault.com/#artifact/com.jessebrault.fsm/groovy-extension/0.1.0-SNAPSHOT implementation 'com.jessebrault.fsm:groovy-extension:0.1.0-SNAPSHOT' + + testRuntimeOnly project(':gcp-impl') } jar { - archivesBaseName = 'gcp' + archivesBaseName = 'gcp-api' } \ No newline at end of file diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/Component.groovy b/gcp-api/src/main/groovy/com/jessebrault/gcp/Component.groovy similarity index 65% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/Component.groovy rename to gcp-api/src/main/groovy/com/jessebrault/gcp/Component.groovy index 846c8f0..7cc8026 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/Component.groovy +++ b/gcp-api/src/main/groovy/com/jessebrault/gcp/Component.groovy @@ -1,4 +1,4 @@ -package com.jessebrault.gcp.component +package com.jessebrault.gcp interface Component { String render(Map attr, String body) diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentFactory.groovy b/gcp-api/src/main/groovy/com/jessebrault/gcp/ComponentFactory.groovy similarity index 56% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentFactory.groovy rename to gcp-api/src/main/groovy/com/jessebrault/gcp/ComponentFactory.groovy index 7a76aec..86cb176 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentFactory.groovy +++ b/gcp-api/src/main/groovy/com/jessebrault/gcp/ComponentFactory.groovy @@ -1,4 +1,4 @@ -package com.jessebrault.gcp.component +package com.jessebrault.gcp interface ComponentFactory { Component get() diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentsContainer.groovy b/gcp-api/src/main/groovy/com/jessebrault/gcp/ComponentsContainer.groovy similarity index 97% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentsContainer.groovy rename to gcp-api/src/main/groovy/com/jessebrault/gcp/ComponentsContainer.groovy index e1c3044..43f3f14 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentsContainer.groovy +++ b/gcp-api/src/main/groovy/com/jessebrault/gcp/ComponentsContainer.groovy @@ -1,4 +1,4 @@ -package com.jessebrault.gcp.component +package com.jessebrault.gcp import org.slf4j.Logger import org.slf4j.LoggerFactory diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/GcpTemplate.groovy b/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpTemplate.groovy similarity index 93% rename from gcp/src/main/groovy/com/jessebrault/gcp/GcpTemplate.groovy rename to gcp-api/src/main/groovy/com/jessebrault/gcp/GcpTemplate.groovy index ba72ffa..880e1d5 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/GcpTemplate.groovy +++ b/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpTemplate.groovy @@ -1,6 +1,5 @@ package com.jessebrault.gcp -import com.jessebrault.gcp.component.ComponentsContainer import groovy.text.Template class GcpTemplate implements Template { diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/GcpTemplateEngine.groovy b/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpTemplateEngine.groovy similarity index 87% rename from gcp/src/main/groovy/com/jessebrault/gcp/GcpTemplateEngine.groovy rename to gcp-api/src/main/groovy/com/jessebrault/gcp/GcpTemplateEngine.groovy index be53216..14c41fe 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/GcpTemplateEngine.groovy +++ b/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpTemplateEngine.groovy @@ -1,7 +1,5 @@ package com.jessebrault.gcp -import com.jessebrault.gcp.component.Component -import com.jessebrault.gcp.component.ComponentsContainer import groovy.text.Template import groovy.text.TemplateEngine import groovy.transform.TupleConstructor @@ -16,6 +14,12 @@ final class GcpTemplateEngine extends TemplateEngine { private static final Logger logger = LoggerFactory.getLogger(GcpTemplateEngine) + private static GcpToScriptConverter getConverter() { + ServiceLoader.load(GcpToScriptConverter).findFirst().orElseThrow({ + new NullPointerException('Could not find an implementation of GcpToScriptConverter') + }) + } + @TupleConstructor(defaults = false) static class Configuration { Supplier ssgTemplateSupplier @@ -37,7 +41,7 @@ final class GcpTemplateEngine extends TemplateEngine { Template createTemplate(Reader reader) throws CompilationFailedException, ClassNotFoundException, IOException { def templateSrc = reader.text - def converter = new TemplateToScriptConverter() + def converter = getConverter() def scriptSrc = converter.convert(templateSrc) logger.debug('scriptSrc: {}', scriptSrc) def scriptName = "SsgTemplate${ this.templateCount.getAndIncrement() }.groovy" diff --git a/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpToScriptConverter.groovy b/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpToScriptConverter.groovy new file mode 100644 index 0000000..f7010d6 --- /dev/null +++ b/gcp-api/src/main/groovy/com/jessebrault/gcp/GcpToScriptConverter.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp + +interface GcpToScriptConverter { + String convert(String gcpSrc) +} \ No newline at end of file diff --git a/gcp/src/test/groovy/com/jessebrault/gcp/GcpTemplateEngineTests.groovy b/gcp-api/src/test/groovy/com/jessebrault/gcp/GcpTemplateEngineIntegrationTests.groovy similarity index 98% rename from gcp/src/test/groovy/com/jessebrault/gcp/GcpTemplateEngineTests.groovy rename to gcp-api/src/test/groovy/com/jessebrault/gcp/GcpTemplateEngineIntegrationTests.groovy index eb0f3c0..b15f781 100644 --- a/gcp/src/test/groovy/com/jessebrault/gcp/GcpTemplateEngineTests.groovy +++ b/gcp-api/src/test/groovy/com/jessebrault/gcp/GcpTemplateEngineIntegrationTests.groovy @@ -1,13 +1,12 @@ package com.jessebrault.gcp -import com.jessebrault.gcp.component.Component import groovy.text.TemplateEngine import org.junit.jupiter.api.Test import static org.junit.jupiter.api.Assertions.assertEquals -class GcpTemplateEngineTests { +class GcpTemplateEngineIntegrationTests { private final TemplateEngine engine = new GcpTemplateEngine(new GcpTemplateEngine.Configuration( { new GcpTemplate() }, diff --git a/gcp/src/test/resources/components/Greeting.groovy b/gcp-api/src/test/resources/components/Greeting.groovy similarity index 80% rename from gcp/src/test/resources/components/Greeting.groovy rename to gcp-api/src/test/resources/components/Greeting.groovy index a899fb1..303c43a 100644 --- a/gcp/src/test/resources/components/Greeting.groovy +++ b/gcp-api/src/test/resources/components/Greeting.groovy @@ -1,6 +1,6 @@ package components -import com.jessebrault.gcp.component.Component +import com.jessebrault.gcp.Component class Greeting implements Component { diff --git a/gcp/src/test/resources/components/Head.groovy b/gcp-api/src/test/resources/components/Head.groovy similarity index 86% rename from gcp/src/test/resources/components/Head.groovy rename to gcp-api/src/test/resources/components/Head.groovy index 40bdc34..1923de4 100644 --- a/gcp/src/test/resources/components/Head.groovy +++ b/gcp-api/src/test/resources/components/Head.groovy @@ -1,6 +1,6 @@ package components -import com.jessebrault.gcp.component.Component +import com.jessebrault.gcp.Component class Head implements Component { diff --git a/gcp/src/test/resources/log4j2.xml b/gcp-api/src/test/resources/log4j2.xml similarity index 100% rename from gcp/src/test/resources/log4j2.xml rename to gcp-api/src/test/resources/log4j2.xml diff --git a/gcp/src/test/resources/test.gcp b/gcp-api/src/test/resources/test.gcp similarity index 100% rename from gcp/src/test/resources/test.gcp rename to gcp-api/src/test/resources/test.gcp diff --git a/gcp/src/test/resources/test.ssg b/gcp-api/src/test/resources/test.ssg similarity index 100% rename from gcp/src/test/resources/test.ssg rename to gcp-api/src/test/resources/test.ssg diff --git a/gcp-impl/build.gradle b/gcp-impl/build.gradle new file mode 100644 index 0000000..6d048c0 --- /dev/null +++ b/gcp-impl/build.gradle @@ -0,0 +1,25 @@ +plugins { + id 'ssg.common' + id 'ssg.lib' +} + +repositories { + mavenCentral() +} + +dependencies { + implementation project(':gcp-api') + + // https://mvnrepository.com/artifact/org.apache.groovy/groovy-templates + implementation 'org.apache.groovy:groovy-templates:4.0.7' + + // https://archiva.jessebrault.com/#artifact/com.jessebrault.fsm/lib/0.1.0-SNAPSHOT + implementation 'com.jessebrault.fsm:lib:0.1.0-SNAPSHOT' + + // https://archiva.jessebrault.com/#artifact/com.jessebrault.fsm/groovy-extension/0.1.0-SNAPSHOT + implementation 'com.jessebrault.fsm:groovy-extension:0.1.0-SNAPSHOT' +} + +jar { + archivesBaseName = 'gcp-impl' +} \ No newline at end of file diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/GcpParser.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/GcpParser.groovy new file mode 100644 index 0000000..fd5abd3 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/GcpParser.groovy @@ -0,0 +1,80 @@ +package com.jessebrault.gcp + +import com.jessebrault.gcp.groovy.BlockScriptletParser +import com.jessebrault.gcp.groovy.DollarReferenceParser +import com.jessebrault.gcp.groovy.DollarScriptletParser +import com.jessebrault.gcp.groovy.ExpressionScriptletParser +import com.jessebrault.gcp.node.Document +import com.jessebrault.gcp.node.DollarReference +import com.jessebrault.gcp.node.DollarScriptlet +import com.jessebrault.gcp.node.ExpressionScriptlet +import com.jessebrault.gcp.node.Html +import com.jessebrault.gcp.node.BlockScriptlet + +import java.util.regex.Matcher +import java.util.regex.Pattern + +class GcpParser { + +// private static enum State { +// HTML, DOLLAR_GROOVY, SCRIPTLET, EXPRESSION_SCRIPTLET +// } +// +// private static FunctionFsmBuilder getFsmBuilder() { +// new FunctionFsmBuilderImpl<>() +// } + + private static final Pattern html = ~/^(?:[\w\W&&[^<$]]|<(?![%\p{Lu}]))+/ + + private static final Pattern groovyIdentifier = ~/^[a-zA-Z_\u0024\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\ufff3][a-zA-Z_\u00240-9\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff\u0100-\ufff3]*/ + + + static Document parse(String gcp) { + + } + + private static Document document(String gcp) { + def document = new Document() + def remaining = gcp + while (remaining.length() > 0) { + Matcher m + DollarReferenceParser.Result dollarReferenceResult + DollarScriptletParser.Result dollarScriptletResult + BlockScriptletParser.Result blockScriptletResult + ExpressionScriptletParser.Result expressionScriptletResult + + String match + + if ((m = html.matcher(remaining)).find()) { + match = m.group() + document.children << new Html().tap { + text = match + } + } else if (dollarReferenceResult = DollarReferenceParser.parse(remaining)) { + match = dollarReferenceResult.fullMatch + document.children << new DollarReference().tap { + reference = dollarReferenceResult.reference + } + } else if (dollarScriptletResult = DollarScriptletParser.parseResult(remaining)) { + match = dollarScriptletResult.fullMatch + document.children << new DollarScriptlet().tap { + scriptlet = dollarScriptletResult.scriptlet + } + } else if (blockScriptletResult = BlockScriptletParser.parseResult(remaining)) { + match = blockScriptletResult.fullMatch + document.children << new BlockScriptlet().tap { + scriptlet = blockScriptletResult.scriptlet + } + } else if (expressionScriptletResult = ExpressionScriptletParser.parseResult(remaining)) { + match = expressionScriptletResult.fullMatch + document.children << new ExpressionScriptlet().tap { + scriptlet = expressionScriptletResult.scriptlet + } + } + + remaining = remaining.substring(match.length()) + } + document + } + +} diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/TemplateToScriptConverter.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/GcpToScriptConverterImpl.groovy similarity index 85% rename from gcp/src/main/groovy/com/jessebrault/gcp/TemplateToScriptConverter.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/GcpToScriptConverterImpl.groovy index 8cbccd6..58fa1cc 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/TemplateToScriptConverter.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/GcpToScriptConverterImpl.groovy @@ -2,12 +2,28 @@ package com.jessebrault.gcp import com.jessebrault.fsm.stackfunction.StackFunctionFsmBuilder import com.jessebrault.fsm.stackfunction.StackFunctionFsmBuilderImpl -import groovy.transform.PackageScope +import com.jessebrault.gcp.util.PatternFunction -import static FsmState.* +class GcpToScriptConverterImpl implements GcpToScriptConverter { -@PackageScope -class TemplateToScriptConverter { + enum State { + HTML, + SCRIPTLET, + EXPRESSION_SCRIPTLET, + DOLLAR, + + COMPONENT, + + COMPONENT_IDENTIFIER, + + COMPONENT_ATTR_KEY, + COMPONENT_ATTR_VALUE_OPEN, + + COMPONENT_ATTR_VALUE_STRING, + COMPONENT_ATTR_VALUE_STRING_CLOSE, + + COMPONENT_CLOSE + } private static final PatternFunction html = new PatternFunction(~/^(?:[\w\W&&[^<$]]|<(?!%|\p{Lu})|\$(?!\{))+/) private static final PatternFunction scriptletOpen = new PatternFunction(~/^<%(?!=)/) @@ -25,11 +41,11 @@ class TemplateToScriptConverter { private static final PatternFunction attrValueStringContents = new PatternFunction(~/^(?:[\w\W&&[^\\"]]|\\\\|\\")*(?=")/) private static final PatternFunction attrValueStringClose = new PatternFunction(~/["']/) - private static StackFunctionFsmBuilder getFsmBuilder() { + private static StackFunctionFsmBuilder getFsmBuilder() { new StackFunctionFsmBuilderImpl<>() } - @SuppressWarnings('GrMethodMayBeStatic') + @Override String convert(String src) { def b = new StringBuilder() def stringAcc = new StringBuilder() @@ -37,22 +53,22 @@ class TemplateToScriptConverter { b << 'def getTemplate() {\nreturn { out ->\n' def fsm = getFsmBuilder().with { - initialState = HTML + initialState = State.HTML - whileIn(HTML) { + whileIn(State.HTML) { on html exec { stringAcc << it } - on scriptletOpen shiftTo SCRIPTLET exec { + on scriptletOpen shiftTo State.SCRIPTLET exec { if (stringAcc.length() > 0) { b << 'out << """' << stringAcc.toString() << '""";\n' stringAcc = new StringBuilder() } } - on expressionScriptletOpen shiftTo EXPRESSION_SCRIPTLET exec { + on expressionScriptletOpen shiftTo State.EXPRESSION_SCRIPTLET exec { stringAcc << '${' } - on componentOpen shiftTo COMPONENT_IDENTIFIER exec { + on componentOpen shiftTo State.COMPONENT_IDENTIFIER exec { if (stringAcc.length() > 0) { b << 'out << """' << stringAcc.toString() << '""";\n' stringAcc = new StringBuilder() @@ -60,7 +76,7 @@ class TemplateToScriptConverter { } } - whileIn(SCRIPTLET) { + whileIn(State.SCRIPTLET) { on scriptletText exec { b << it } @@ -69,7 +85,7 @@ class TemplateToScriptConverter { } } - whileIn(EXPRESSION_SCRIPTLET) { + whileIn(State.EXPRESSION_SCRIPTLET) { on scriptletText exec { stringAcc << it } @@ -78,7 +94,7 @@ class TemplateToScriptConverter { } } - whileIn(COMPONENT) { + whileIn(State.COMPONENT) { // tokenize component, figure out body, and tokenize closing component } diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentParser.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentParser.groovy similarity index 94% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentParser.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentParser.groovy index 70afa2c..a1d7c35 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentParser.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentParser.groovy @@ -1,16 +1,17 @@ package com.jessebrault.gcp.component import com.jessebrault.gcp.component.ComponentToken.Type -import com.jessebrault.gcp.component.node.ComponentNode +import com.jessebrault.gcp.component.node.ComponentRoot import com.jessebrault.gcp.component.node.DollarReferenceValue import com.jessebrault.gcp.component.node.DollarScriptletValue import com.jessebrault.gcp.component.node.ExpressionScriptletValue import com.jessebrault.gcp.component.node.GStringValue import com.jessebrault.gcp.component.node.KeyAndValue import com.jessebrault.gcp.component.node.KeysAndValues -import com.jessebrault.gcp.component.node.Node +import com.jessebrault.gcp.component.node.ComponentNode import com.jessebrault.gcp.component.node.ScriptletValue import com.jessebrault.gcp.component.node.StringValue +import com.jessebrault.gcp.util.PeekBefore import groovy.transform.PackageScope import static com.jessebrault.gcp.component.ComponentToken.Type.* @@ -24,7 +25,7 @@ class ComponentParser { private Queue tokens private String currentIdentifier - ComponentNode parse(Queue tokens) { + ComponentRoot parse(Queue tokens) { this.tokens = tokens this.selfClosingComponent() } @@ -72,22 +73,22 @@ class ComponentParser { t && t.type == type } - private ComponentNode selfClosingComponent() { + private ComponentRoot selfClosingComponent() { this.startOfOpeningOrSelfClosingComponent() def keysAndValues = this.keysAndValues() this.expect(FORWARD_SLASH) this.expect(GT) - new ComponentNode().tap { + new ComponentRoot().tap { it.identifier = this.currentIdentifier it.children << keysAndValues } } - private ComponentNode openingComponent() { + private ComponentRoot openingComponent() { this.startOfOpeningOrSelfClosingComponent() def keysAndValues = this.keysAndValues() this.expect(GT) - new ComponentNode().tap { + new ComponentRoot().tap { it.identifier = this.currentIdentifier it.children << keysAndValues } @@ -110,7 +111,7 @@ class ComponentParser { } private KeysAndValues keysAndValues() { - List children = [] + List children = [] while (true) { if (this.peek(KEY)) { def keyAndValue = this.keyAndValue() @@ -137,7 +138,7 @@ class ComponentParser { } } - private Node value() { + private ComponentNode value() { if (this.peek(DOUBLE_QUOTE)) { return this.doubleQuoteStringValue() } else if (this.peek(SINGLE_QUOTE)) { diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentToScriptVisitor.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentToClosureVisitor.groovy similarity index 50% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentToScriptVisitor.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentToClosureVisitor.groovy index 3efd2ee..9a70d5a 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentToScriptVisitor.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentToClosureVisitor.groovy @@ -1,83 +1,77 @@ package com.jessebrault.gcp.component import com.jessebrault.gcp.component.node.BooleanValue -import com.jessebrault.gcp.component.node.ComponentNode +import com.jessebrault.gcp.component.node.ComponentRoot import com.jessebrault.gcp.component.node.DollarReferenceValue import com.jessebrault.gcp.component.node.DollarScriptletValue import com.jessebrault.gcp.component.node.ExpressionScriptletValue import com.jessebrault.gcp.component.node.GStringValue import com.jessebrault.gcp.component.node.KeyAndValue import com.jessebrault.gcp.component.node.KeysAndValues -import com.jessebrault.gcp.component.node.NodeVisitor +import com.jessebrault.gcp.component.node.ComponentNodeVisitor import com.jessebrault.gcp.component.node.ScriptletValue import com.jessebrault.gcp.component.node.StringValue -// NOT THREAD SAFE, and must be used exactly once -class ComponentToScriptVisitor extends NodeVisitor { +// NOT THREAD SAFE +class ComponentToClosureVisitor extends ComponentNodeVisitor { - private final Writer w = new StringWriter() - private final IndentPrinter p = new IndentPrinter(this.w, ' ', true, true) + private StringBuilder b = new StringBuilder() String getResult() { - w.toString() + b.toString() } - void visit(ComponentNode componentNode) { - p.println('{ attr, bodyOut ->') - p.incrementIndent() + void reset() { + b = new StringBuilder() + } + + void visit(ComponentRoot componentNode) { + b << '{ ' super.visit(componentNode) if (componentNode.body != null) { - p.println("bodyOut << ${ componentNode.body };") + b << "bodyOut << ${ componentNode.body }; " } - p.decrementIndent() - p.println('};') + b << '};' } void visit(KeysAndValues keysAndValues) { - p.println('attr {') - p.incrementIndent() + b << 'attr { ' super.visit(keysAndValues) - p.decrementIndent() - p.println('};') + b << '}; ' } void visit(KeyAndValue keyAndValue) { - p.printIndent() - p.print("${ keyAndValue.key } = ") + b << "${ keyAndValue.key } = " super.visit(keyAndValue) - p.print(';\n') + b << '; ' } void visit(GStringValue gStringValue) { - p.print("\"${ gStringValue.gString }\"") + b << "\"${ gStringValue.gString }\"" } void visit(StringValue stringValue) { - p.print("'${ stringValue.string }'") + b << "'${ stringValue.string }'" } void visit(DollarReferenceValue dollarReferenceValue) { - p.print(dollarReferenceValue.reference) + b << dollarReferenceValue.reference } void visit(DollarScriptletValue dollarScriptletValue) { - p.print(dollarScriptletValue.scriptlet) + b << dollarScriptletValue.scriptlet } void visit(ScriptletValue scriptletValue) { - p.println("render { out ->") - p.incrementIndent() - p.print(scriptletValue.scriptlet) - p.decrementIndent() - p.println('}') + b << "render { out -> ${ scriptletValue.scriptlet } }" } void visit(ExpressionScriptletValue expressionScriptletValue) { - p.print(expressionScriptletValue.scriptlet) + b << expressionScriptletValue.scriptlet } void visit(BooleanValue booleanValue) { - p.print(booleanValue.value.toString()) + b << booleanValue.value.toString() } } diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentToken.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentToken.groovy similarity index 100% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentToken.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentToken.groovy diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentTokenizer.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentTokenizer.groovy similarity index 97% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentTokenizer.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentTokenizer.groovy index 7223c4d..fa249fd 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/ComponentTokenizer.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/ComponentTokenizer.groovy @@ -2,7 +2,8 @@ package com.jessebrault.gcp.component import com.jessebrault.fsm.function.FunctionFsmBuilder import com.jessebrault.fsm.function.FunctionFsmBuilderImpl -import com.jessebrault.gcp.PatternFunction +import com.jessebrault.gcp.groovy.DollarScriptletParser +import com.jessebrault.gcp.util.PatternFunction import static ComponentToken.Type @@ -89,7 +90,7 @@ class ComponentTokenizer { tokens << new ComponentToken(Type.GROOVY_IDENTIFIER, s.substring(1)) // skip opening $ } //noinspection GroovyAssignabilityCheck // for some reason IntelliJ is confused by this - on DollarGroovyParser::parse exec { String s -> + on DollarScriptletParser::parse exec { String s -> tokens << new ComponentToken(Type.GROOVY, s.substring(2, s.length() - 1)) } on percent shiftTo State.EXPRESSION_SCRIPTLET_GROOVY exec { diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/BooleanValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/BooleanValue.groovy similarity index 77% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/BooleanValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/BooleanValue.groovy index 509ea04..56ad04c 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/BooleanValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/BooleanValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class BooleanValue extends Node { +class BooleanValue extends ComponentNode { boolean value @Override diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNode.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNode.groovy new file mode 100644 index 0000000..ce7ce01 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNode.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.component.node + +abstract class ComponentNode { + List children = [] +} diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/NodeVisitor.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNodeVisitor.groovy similarity index 57% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/NodeVisitor.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNodeVisitor.groovy index c7aa37e..ec60217 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/NodeVisitor.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNodeVisitor.groovy @@ -1,12 +1,12 @@ package com.jessebrault.gcp.component.node -abstract class NodeVisitor { +abstract class ComponentNodeVisitor { - void visit(Node node) { + void visit(ComponentNode node) { this.visitChildren(node) } - void visitChildren(Node node) { + void visitChildren(ComponentNode node) { node.children.each { this.visit(it) } diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNode.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentRoot.groovy similarity index 84% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNode.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentRoot.groovy index 336b2fd..fbd8bb8 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/ComponentNode.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ComponentRoot.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class ComponentNode extends Node { +class ComponentRoot extends ComponentNode { String identifier String body diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/DollarReferenceValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/DollarReferenceValue.groovy similarity index 76% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/DollarReferenceValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/DollarReferenceValue.groovy index a209165..31d5157 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/DollarReferenceValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/DollarReferenceValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class DollarReferenceValue extends Node { +class DollarReferenceValue extends ComponentNode { String reference diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/DollarScriptletValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/DollarScriptletValue.groovy similarity index 76% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/DollarScriptletValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/DollarScriptletValue.groovy index 797bf32..b777756 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/DollarScriptletValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/DollarScriptletValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class DollarScriptletValue extends Node { +class DollarScriptletValue extends ComponentNode { String scriptlet diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/ExpressionScriptletValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ExpressionScriptletValue.groovy similarity index 75% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/ExpressionScriptletValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ExpressionScriptletValue.groovy index 6fff50f..191c147 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/ExpressionScriptletValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ExpressionScriptletValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class ExpressionScriptletValue extends Node { +class ExpressionScriptletValue extends ComponentNode { String scriptlet diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/GStringValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/GStringValue.groovy similarity index 78% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/GStringValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/GStringValue.groovy index 32b9162..a518247 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/GStringValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/GStringValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class GStringValue extends Node { +class GStringValue extends ComponentNode { String gString diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/KeyAndValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/KeyAndValue.groovy similarity index 81% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/KeyAndValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/KeyAndValue.groovy index 0b00b36..774f167 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/KeyAndValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/KeyAndValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class KeyAndValue extends Node { +class KeyAndValue extends ComponentNode { String key diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/KeysAndValues.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/KeysAndValues.groovy similarity index 75% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/KeysAndValues.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/KeysAndValues.groovy index c2860d3..bdf39df 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/KeysAndValues.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/KeysAndValues.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class KeysAndValues extends Node { +class KeysAndValues extends ComponentNode { @Override String toString() { diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/ScriptletValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ScriptletValue.groovy similarity index 78% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/ScriptletValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ScriptletValue.groovy index 1c2852c..247b81b 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/ScriptletValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/ScriptletValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class ScriptletValue extends Node { +class ScriptletValue extends ComponentNode { String scriptlet diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/StringValue.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/StringValue.groovy similarity index 78% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/node/StringValue.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/StringValue.groovy index 1e73d14..570bbcd 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/StringValue.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/component/node/StringValue.groovy @@ -1,6 +1,6 @@ package com.jessebrault.gcp.component.node -class StringValue extends Node { +class StringValue extends ComponentNode { String string diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/BlockScriptletParser.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/BlockScriptletParser.groovy new file mode 100644 index 0000000..332cabd --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/BlockScriptletParser.groovy @@ -0,0 +1,22 @@ +package com.jessebrault.gcp.groovy + +class BlockScriptletParser { + + static class Result { + String fullMatch + String scriptlet + } + + static String parse(String input) { + + } + + static Result parseResult(String input) { + def match = parse(input) + match != null ? new Result().tap { + fullMatch = match + scriptlet = fullMatch.substring(2, fullMatch.length() - 2) + } : null + } + +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/DollarReferenceParser.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/DollarReferenceParser.groovy new file mode 100644 index 0000000..813ddd4 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/DollarReferenceParser.groovy @@ -0,0 +1,14 @@ +package com.jessebrault.gcp.groovy + +class DollarReferenceParser { + + static class Result { + String fullMatch + String reference + } + + static Result parse(String input) { + + } + +} diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/DollarGroovyParser.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/DollarScriptletParser.groovy similarity index 89% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/DollarGroovyParser.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/DollarScriptletParser.groovy index 09db306..e78f4bc 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/DollarGroovyParser.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/DollarScriptletParser.groovy @@ -1,11 +1,16 @@ -package com.jessebrault.gcp.component +package com.jessebrault.gcp.groovy import org.slf4j.Logger import org.slf4j.LoggerFactory -class DollarGroovyParser { +class DollarScriptletParser { - private static Logger logger = LoggerFactory.getLogger(DollarGroovyParser) + private static Logger logger = LoggerFactory.getLogger(DollarScriptletParser) + + static class Result { + String fullMatch + String scriptlet + } private enum State { NO_STRING, G_STRING, SINGLE_QUOTE_STRING @@ -126,4 +131,16 @@ class DollarGroovyParser { acc.toString() } + static Result parseResult(String input) { + def match = parse(input) + if (match) { + new Result().tap { + fullMatch = match + scriptlet = fullMatch.substring(2, fullMatch.length() - 1) + } + } else { + null + } + } + } diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/ExpressionScriptletParser.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/ExpressionScriptletParser.groovy new file mode 100644 index 0000000..0114279 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/groovy/ExpressionScriptletParser.groovy @@ -0,0 +1,22 @@ +package com.jessebrault.gcp.groovy + +class ExpressionScriptletParser { + + static class Result { + String fullMatch + String scriptlet + } + + static String parse(String input) { + + } + + static Result parseResult(String input) { + def match = parse(input) + match != null ? new Result().tap { + fullMatch = match + scriptlet = fullMatch.substring(3, fullMatch.length() - 2) + } : null + } + +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/BlockScriptlet.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/BlockScriptlet.groovy new file mode 100644 index 0000000..2076642 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/BlockScriptlet.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.node + +class BlockScriptlet extends GcpNode { + String scriptlet +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/ComponentInstance.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/ComponentInstance.groovy new file mode 100644 index 0000000..9599811 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/ComponentInstance.groovy @@ -0,0 +1,6 @@ +package com.jessebrault.gcp.node + +class ComponentInstance extends GcpNode { + String opening + String closing +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/Document.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/Document.groovy new file mode 100644 index 0000000..7df17af --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/Document.groovy @@ -0,0 +1,3 @@ +package com.jessebrault.gcp.node + +class Document extends GcpNode {} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/DollarReference.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/DollarReference.groovy new file mode 100644 index 0000000..652fa1e --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/DollarReference.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.node + +class DollarReference extends GcpNode { + String reference +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/DollarScriptlet.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/DollarScriptlet.groovy new file mode 100644 index 0000000..270888e --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/DollarScriptlet.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.node + +class DollarScriptlet extends GcpNode { + String scriptlet +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/ExpressionScriptlet.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/ExpressionScriptlet.groovy new file mode 100644 index 0000000..a48765a --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/ExpressionScriptlet.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.node + +class ExpressionScriptlet extends GcpNode { + String scriptlet +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/GcpNode.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/GcpNode.groovy new file mode 100644 index 0000000..bce57eb --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/GcpNode.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.node + +abstract class GcpNode { + List children = [] +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/GcpNodeVisitor.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/GcpNodeVisitor.groovy new file mode 100644 index 0000000..2c59eba --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/GcpNodeVisitor.groovy @@ -0,0 +1,13 @@ +package com.jessebrault.gcp.node + +abstract class GcpNodeVisitor { + + void visit(GcpNode node) { + this.visitChildren(node) + } + + void visitChildren(GcpNode node) { + node.children.each(this.&visit) + } + +} diff --git a/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/Html.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/Html.groovy new file mode 100644 index 0000000..9954803 --- /dev/null +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/node/Html.groovy @@ -0,0 +1,5 @@ +package com.jessebrault.gcp.node + +class Html extends GcpNode { + String text +} diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/PatternFunction.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/util/PatternFunction.groovy similarity index 94% rename from gcp/src/main/groovy/com/jessebrault/gcp/PatternFunction.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/util/PatternFunction.groovy index b4c940b..b79df74 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/PatternFunction.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/util/PatternFunction.groovy @@ -1,4 +1,4 @@ -package com.jessebrault.gcp +package com.jessebrault.gcp.util import groovy.transform.PackageScope import groovy.transform.TupleConstructor diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/PeekBefore.groovy b/gcp-impl/src/main/groovy/com/jessebrault/gcp/util/PeekBefore.groovy similarity index 67% rename from gcp/src/main/groovy/com/jessebrault/gcp/component/PeekBefore.groovy rename to gcp-impl/src/main/groovy/com/jessebrault/gcp/util/PeekBefore.groovy index 6b8b15e..bca4528 100644 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/PeekBefore.groovy +++ b/gcp-impl/src/main/groovy/com/jessebrault/gcp/util/PeekBefore.groovy @@ -1,5 +1,6 @@ -package com.jessebrault.gcp.component +package com.jessebrault.gcp.util +import com.jessebrault.gcp.component.ComponentToken import java.lang.annotation.Retention import java.lang.annotation.RetentionPolicy diff --git a/gcp-impl/src/main/resources/META-INF/services/com.jessebrault.gcp.GcpToScriptConverter b/gcp-impl/src/main/resources/META-INF/services/com.jessebrault.gcp.GcpToScriptConverter new file mode 100644 index 0000000..e531eeb --- /dev/null +++ b/gcp-impl/src/main/resources/META-INF/services/com.jessebrault.gcp.GcpToScriptConverter @@ -0,0 +1 @@ +com.jessebrault.gcp.GcpToScriptConverterImpl \ No newline at end of file diff --git a/gcp/src/test/groovy/com/jessebrault/gcp/component/ComponentParserTests.groovy b/gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentParserTests.groovy similarity index 93% rename from gcp/src/test/groovy/com/jessebrault/gcp/component/ComponentParserTests.groovy rename to gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentParserTests.groovy index 8256001..2af67b4 100644 --- a/gcp/src/test/groovy/com/jessebrault/gcp/component/ComponentParserTests.groovy +++ b/gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentParserTests.groovy @@ -9,6 +9,7 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import static com.jessebrault.gcp.component.ComponentToken.Type.* + import static org.junit.jupiter.api.Assertions.assertEquals import static org.junit.jupiter.api.Assertions.assertTrue @@ -16,7 +17,7 @@ class ComponentParserTests { private static final Logger logger = LoggerFactory.getLogger(ComponentParserTests) - private static class NodeSpec { + private static class NodeSpec { Class nodeClass Closure tests @@ -31,7 +32,7 @@ class ComponentParserTests { this.tests = tests } - void test(Node actual) { + void test(ComponentNode actual) { logger.debug('actual: {}', actual) assertTrue(nodeClass.isAssignableFrom(actual.class)) if (this.tests != null) { @@ -60,9 +61,9 @@ class ComponentParserTests { private static class NodeTester { - List> childSpecs = [] + List> childSpecs = [] - def void expect( + def void expect( Class childNodeClass, @DelegatesTo(value = NodeTester, strategy = Closure.DELEGATE_FIRST) @ClosureParams(FirstParam.FirstGenericType) @@ -88,7 +89,7 @@ class ComponentParserTests { def componentNode = this.parser.parse(tokens) logger.debug('componentNode: {}', componentNode) - def componentSpec = new NodeSpec(ComponentNode, tests) + def componentSpec = new NodeSpec(ComponentRoot, tests) logger.debug('nodeSpec: {}', componentSpec) componentSpec.test(componentNode) } diff --git a/gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentToClosureVisitorTests.groovy b/gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentToClosureVisitorTests.groovy new file mode 100644 index 0000000..3ec0b34 --- /dev/null +++ b/gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentToClosureVisitorTests.groovy @@ -0,0 +1,40 @@ +package com.jessebrault.gcp.component + +import com.jessebrault.gcp.component.node.ComponentRoot +import com.jessebrault.gcp.component.node.GStringValue +import com.jessebrault.gcp.component.node.KeyAndValue +import com.jessebrault.gcp.component.node.KeysAndValues +import org.junit.jupiter.api.Test + +import static org.junit.jupiter.api.Assertions.assertEquals + +class ComponentToClosureVisitorTests { + + @Test + void withEmptyKeysAndValues() { + def cn = new ComponentRoot().tap { + it.children << new KeysAndValues() + } + def v = new ComponentToClosureVisitor() + v.visit(cn) + assertEquals('{ attr { }; };', v.result) + } + + @Test + void withGStringKeyAndValue() { + def cn = new ComponentRoot().tap { + it.children << new KeysAndValues().tap { + it.children << new KeyAndValue().tap { + key = 'greeting' + it.children << new GStringValue().tap { + gString = 'Hello, ${ frontMatter.person }!' + } + } + } + } + def v = new ComponentToClosureVisitor() + v.visit(cn) + assertEquals('{ attr { greeting = "Hello, ${ frontMatter.person }!"; }; };', v.result) + } + +} diff --git a/gcp/src/test/groovy/com/jessebrault/gcp/component/ComponentTokenizerTests.groovy b/gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentTokenizerTests.groovy similarity index 100% rename from gcp/src/test/groovy/com/jessebrault/gcp/component/ComponentTokenizerTests.groovy rename to gcp-impl/src/test/groovy/com/jessebrault/gcp/component/ComponentTokenizerTests.groovy diff --git a/gcp/src/test/groovy/com/jessebrault/gcp/component/DollarGroovyParserTests.groovy b/gcp-impl/src/test/groovy/com/jessebrault/gcp/groovy/DollarScriptletParserTests.groovy similarity index 90% rename from gcp/src/test/groovy/com/jessebrault/gcp/component/DollarGroovyParserTests.groovy rename to gcp-impl/src/test/groovy/com/jessebrault/gcp/groovy/DollarScriptletParserTests.groovy index 43e9ed6..295e7a7 100644 --- a/gcp/src/test/groovy/com/jessebrault/gcp/component/DollarGroovyParserTests.groovy +++ b/gcp-impl/src/test/groovy/com/jessebrault/gcp/groovy/DollarScriptletParserTests.groovy @@ -1,11 +1,11 @@ -package com.jessebrault.gcp.component +package com.jessebrault.gcp.groovy import org.junit.jupiter.api.Test -import static com.jessebrault.gcp.component.DollarGroovyParser.parse +import static com.jessebrault.gcp.groovy.DollarScriptletParser.parse import static org.junit.jupiter.api.Assertions.assertEquals -class DollarGroovyParserTests { +class DollarScriptletParserTests { @Test void empty() { diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/FsmState.groovy b/gcp/src/main/groovy/com/jessebrault/gcp/FsmState.groovy deleted file mode 100644 index b5dba24..0000000 --- a/gcp/src/main/groovy/com/jessebrault/gcp/FsmState.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.jessebrault.gcp - -import groovy.transform.PackageScope - -@PackageScope -enum FsmState { - HTML, - SCRIPTLET, - EXPRESSION_SCRIPTLET, - DOLLAR, - - COMPONENT, - - COMPONENT_IDENTIFIER, - - COMPONENT_ATTR_KEY, - COMPONENT_ATTR_VALUE_OPEN, - - COMPONENT_ATTR_VALUE_STRING, - COMPONENT_ATTR_VALUE_STRING_CLOSE, - - COMPONENT_CLOSE -} diff --git a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/Node.groovy b/gcp/src/main/groovy/com/jessebrault/gcp/component/node/Node.groovy deleted file mode 100644 index f7d0185..0000000 --- a/gcp/src/main/groovy/com/jessebrault/gcp/component/node/Node.groovy +++ /dev/null @@ -1,5 +0,0 @@ -package com.jessebrault.gcp.component.node - -abstract class Node { - List children = [] -} diff --git a/settings.gradle b/settings.gradle index 8434275..827f737 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = 'ssg' -include 'cli', 'gcp', 'lib' \ No newline at end of file +include 'cli', 'gcp-api', 'gcp-impl', 'lib' \ No newline at end of file