Moved TranspilerState to its own file.
This commit is contained in:
parent
3f45609236
commit
dd92d99afd
@ -1,7 +1,6 @@
|
||||
package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.web.ast.node.BodyChildNode;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import org.codehaus.groovy.ast.expr.Expression;
|
||||
import org.codehaus.groovy.ast.stmt.Statement;
|
||||
|
||||
|
@ -2,7 +2,6 @@ package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.web.ast.node.BodyChildNode;
|
||||
import groowt.view.component.web.ast.node.BodyNode;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import org.codehaus.groovy.ast.expr.Expression;
|
||||
import org.codehaus.groovy.ast.stmt.BlockStatement;
|
||||
import org.codehaus.groovy.ast.stmt.Statement;
|
||||
|
@ -1,7 +1,6 @@
|
||||
package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.web.ast.node.ComponentNode;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import org.codehaus.groovy.ast.stmt.Statement;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -2,7 +2,6 @@ package groowt.view.component.web.transpile;
|
||||
|
||||
import groovy.lang.Tuple2;
|
||||
import groowt.view.component.web.ast.node.BodyChildNode;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import org.codehaus.groovy.ast.expr.*;
|
||||
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
|
||||
import org.codehaus.groovy.ast.stmt.Statement;
|
||||
|
@ -2,7 +2,6 @@ package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.web.WebViewComponentBugError;
|
||||
import groowt.view.component.web.ast.node.*;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import jakarta.inject.Inject;
|
||||
import org.codehaus.groovy.ast.expr.GStringExpression;
|
||||
import org.codehaus.groovy.ast.stmt.BlockStatement;
|
||||
|
@ -2,7 +2,6 @@ package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.web.WebViewComponentBugError;
|
||||
import groowt.view.component.web.ast.node.*;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import groowt.view.component.web.transpile.groovy.GroovyUtil;
|
||||
import groowt.view.component.web.transpile.groovy.GroovyUtil.ConvertResult;
|
||||
import org.codehaus.groovy.ast.Parameter;
|
||||
|
@ -0,0 +1,161 @@
|
||||
package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
||||
import org.codehaus.groovy.ast.Parameter;
|
||||
import org.codehaus.groovy.ast.Variable;
|
||||
import org.codehaus.groovy.ast.VariableScope;
|
||||
import org.codehaus.groovy.ast.expr.VariableExpression;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class TranspilerState {
|
||||
|
||||
public static TranspilerState withRootScope(
|
||||
Parameter componentContext,
|
||||
Parameter writer,
|
||||
Variable renderContext
|
||||
) {
|
||||
final VariableScope rootScope = new VariableScope();
|
||||
rootScope.putDeclaredVariable(componentContext);
|
||||
rootScope.putDeclaredVariable(writer);
|
||||
rootScope.putDeclaredVariable(renderContext);
|
||||
|
||||
return new TranspilerState(rootScope);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static TranspilerState withDefaultRootScope() {
|
||||
final VariableScope rootScope = new VariableScope();
|
||||
rootScope.putDeclaredVariable(new Parameter(
|
||||
TranspilerUtil.COMPONENT_CONTEXT_TYPE,
|
||||
TranspilerUtil.COMPONENT_CONTEXT_NAME
|
||||
));
|
||||
rootScope.putDeclaredVariable(new Parameter(
|
||||
TranspilerUtil.COMPONENT_WRITER_TYPE,
|
||||
TranspilerUtil.COMPONENT_WRITER_NAME
|
||||
));
|
||||
rootScope.putDeclaredVariable(new VariableExpression(
|
||||
TranspilerUtil.RENDER_CONTEXT_NAME,
|
||||
TranspilerUtil.WEB_VIEW_COMPONENT_RENDER_CONTEXT_TYPE
|
||||
));
|
||||
return new TranspilerState(rootScope);
|
||||
}
|
||||
|
||||
private final AtomicInteger componentNumberCounter = new AtomicInteger();
|
||||
private final Deque<VariableScope> scopeStack = new LinkedList<>();
|
||||
private final Deque<VariableExpression> componentStack = new LinkedList<>();
|
||||
private final Deque<VariableExpression> resolvedStack = new LinkedList<>();
|
||||
private final Deque<Parameter> childListStack = new LinkedList<>();
|
||||
private final List<ComponentTemplateCompileException> errors = new ArrayList<>();
|
||||
|
||||
private int lastComponentNumber;
|
||||
|
||||
private TranspilerState(VariableScope rootScope) {
|
||||
this.scopeStack.push(rootScope);
|
||||
}
|
||||
|
||||
public int getCurrentComponentNumber() {
|
||||
return this.lastComponentNumber;
|
||||
}
|
||||
|
||||
public int newComponentNumber() {
|
||||
this.lastComponentNumber = this.componentNumberCounter.getAndIncrement();
|
||||
return this.lastComponentNumber;
|
||||
}
|
||||
|
||||
public VariableScope pushScope() {
|
||||
final VariableScope parent = this.scopeStack.peek();
|
||||
final VariableScope result = new VariableScope(parent);
|
||||
this.scopeStack.push(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void popScope() {
|
||||
this.scopeStack.pop();
|
||||
}
|
||||
|
||||
public VariableScope getCurrentScope() {
|
||||
return Objects.requireNonNull(this.scopeStack.peek());
|
||||
}
|
||||
|
||||
private Variable getDeclaredVariable(String name) {
|
||||
VariableScope scope = this.getCurrentScope();
|
||||
while (scope != null) {
|
||||
final Variable potential = scope.getDeclaredVariable(name);
|
||||
if (potential != null) {
|
||||
return potential;
|
||||
} else {
|
||||
scope = scope.getParent();
|
||||
}
|
||||
}
|
||||
throw new NullPointerException("Cannot find variable: " + name);
|
||||
}
|
||||
|
||||
public VariableExpression getWriter() {
|
||||
return new VariableExpression(this.getDeclaredVariable(TranspilerUtil.COMPONENT_WRITER_NAME));
|
||||
}
|
||||
|
||||
public VariableExpression getRenderContext() {
|
||||
return (VariableExpression) this.getDeclaredVariable(TranspilerUtil.RENDER_CONTEXT_NAME);
|
||||
}
|
||||
|
||||
public void pushComponent(VariableExpression componentVariable) {
|
||||
this.componentStack.push(componentVariable);
|
||||
}
|
||||
|
||||
public void popComponent() {
|
||||
this.componentStack.pop();
|
||||
}
|
||||
|
||||
public VariableExpression getCurrentComponent() {
|
||||
return Objects.requireNonNull(this.componentStack.peek());
|
||||
}
|
||||
|
||||
public void pushResolved(VariableExpression resolvedVariable) {
|
||||
this.resolvedStack.push(resolvedVariable);
|
||||
}
|
||||
|
||||
public void popResolved() {
|
||||
this.resolvedStack.pop();
|
||||
}
|
||||
|
||||
public VariableExpression getCurrentResolved() {
|
||||
return Objects.requireNonNull(this.resolvedStack.peek());
|
||||
}
|
||||
|
||||
public void pushChildList(Parameter childCollector) {
|
||||
this.childListStack.push(childCollector);
|
||||
}
|
||||
|
||||
public void popChildList() {
|
||||
this.childListStack.pop();
|
||||
}
|
||||
|
||||
public VariableExpression getCurrentChildList() {
|
||||
final Parameter childCollectorParam = Objects.requireNonNull(this.childListStack.peek());
|
||||
return new VariableExpression(childCollectorParam);
|
||||
}
|
||||
|
||||
public boolean hasCurrentChildList() {
|
||||
return this.childListStack.peek() != null;
|
||||
}
|
||||
|
||||
public void addError(ComponentTemplateCompileException error) {
|
||||
this.errors.add(error);
|
||||
}
|
||||
|
||||
public void addErrors(Collection<? extends ComponentTemplateCompileException> errors) {
|
||||
this.errors.addAll(errors);
|
||||
}
|
||||
|
||||
public boolean hasErrors() {
|
||||
return !this.errors.isEmpty();
|
||||
}
|
||||
|
||||
public List<ComponentTemplateCompileException> getErrors() {
|
||||
return new ArrayList<>(this.errors);
|
||||
}
|
||||
|
||||
}
|
@ -2,21 +2,16 @@ package groowt.view.component.web.transpile;
|
||||
|
||||
import groovy.lang.Tuple2;
|
||||
import groowt.view.component.ComponentTemplate;
|
||||
import groowt.view.component.compiler.ComponentTemplateCompileException;
|
||||
import groowt.view.component.context.ComponentContext;
|
||||
import groowt.view.component.runtime.ComponentWriter;
|
||||
import groowt.view.component.web.runtime.DefaultWebViewRenderContext;
|
||||
import groowt.view.component.web.runtime.WebViewComponentRenderContext;
|
||||
import groowt.view.component.web.util.SourcePosition;
|
||||
import org.codehaus.groovy.ast.*;
|
||||
import org.codehaus.groovy.ast.ClassHelper;
|
||||
import org.codehaus.groovy.ast.ClassNode;
|
||||
import org.codehaus.groovy.ast.expr.ConstantExpression;
|
||||
import org.codehaus.groovy.ast.expr.VariableExpression;
|
||||
import org.codehaus.groovy.syntax.Token;
|
||||
import org.codehaus.groovy.syntax.Types;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public final class TranspilerUtil {
|
||||
|
||||
@ -57,149 +52,6 @@ public final class TranspilerUtil {
|
||||
return new Token(Types.LEFT_SHIFT, "<<", -1, -1);
|
||||
}
|
||||
|
||||
public static final class TranspilerState {
|
||||
|
||||
public static TranspilerState withRootScope(
|
||||
Parameter componentContext,
|
||||
Parameter writer,
|
||||
Variable renderContext
|
||||
) {
|
||||
final VariableScope rootScope = new VariableScope();
|
||||
rootScope.putDeclaredVariable(componentContext);
|
||||
rootScope.putDeclaredVariable(writer);
|
||||
rootScope.putDeclaredVariable(renderContext);
|
||||
|
||||
return new TranspilerState(rootScope);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public static TranspilerState withDefaultRootScope() {
|
||||
final VariableScope rootScope = new VariableScope();
|
||||
rootScope.putDeclaredVariable(new Parameter(COMPONENT_CONTEXT_TYPE, COMPONENT_CONTEXT_NAME));
|
||||
rootScope.putDeclaredVariable(new Parameter(COMPONENT_WRITER_TYPE, COMPONENT_WRITER_NAME));
|
||||
rootScope.putDeclaredVariable(new VariableExpression(RENDER_CONTEXT_NAME,
|
||||
WEB_VIEW_COMPONENT_RENDER_CONTEXT_TYPE
|
||||
));
|
||||
return new TranspilerState(rootScope);
|
||||
}
|
||||
|
||||
private final AtomicInteger componentNumberCounter = new AtomicInteger();
|
||||
private final Deque<VariableScope> scopeStack = new LinkedList<>();
|
||||
private final Deque<VariableExpression> componentStack = new LinkedList<>();
|
||||
private final Deque<VariableExpression> resolvedStack = new LinkedList<>();
|
||||
private final Deque<Parameter> childListStack = new LinkedList<>();
|
||||
private final List<ComponentTemplateCompileException> errors = new ArrayList<>();
|
||||
|
||||
private int lastComponentNumber;
|
||||
|
||||
private TranspilerState(VariableScope rootScope) {
|
||||
this.scopeStack.push(rootScope);
|
||||
}
|
||||
|
||||
public int getCurrentComponentNumber() {
|
||||
return this.lastComponentNumber;
|
||||
}
|
||||
|
||||
public int newComponentNumber() {
|
||||
this.lastComponentNumber = this.componentNumberCounter.getAndIncrement();
|
||||
return this.lastComponentNumber;
|
||||
}
|
||||
|
||||
public VariableScope pushScope() {
|
||||
final VariableScope parent = this.scopeStack.peek();
|
||||
final VariableScope result = new VariableScope(parent);
|
||||
this.scopeStack.push(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void popScope() {
|
||||
this.scopeStack.pop();
|
||||
}
|
||||
|
||||
public VariableScope getCurrentScope() {
|
||||
return Objects.requireNonNull(this.scopeStack.peek());
|
||||
}
|
||||
|
||||
private Variable getDeclaredVariable(String name) {
|
||||
VariableScope scope = this.getCurrentScope();
|
||||
while (scope != null) {
|
||||
final Variable potential = scope.getDeclaredVariable(name);
|
||||
if (potential != null) {
|
||||
return potential;
|
||||
} else {
|
||||
scope = scope.getParent();
|
||||
}
|
||||
}
|
||||
throw new NullPointerException("Cannot find variable: " + name);
|
||||
}
|
||||
|
||||
public VariableExpression getWriter() {
|
||||
return new VariableExpression(this.getDeclaredVariable(COMPONENT_WRITER_NAME));
|
||||
}
|
||||
|
||||
public VariableExpression getRenderContext() {
|
||||
return (VariableExpression) this.getDeclaredVariable(RENDER_CONTEXT_NAME);
|
||||
}
|
||||
|
||||
public void pushComponent(VariableExpression componentVariable) {
|
||||
this.componentStack.push(componentVariable);
|
||||
}
|
||||
|
||||
public void popComponent() {
|
||||
this.componentStack.pop();
|
||||
}
|
||||
|
||||
public VariableExpression getCurrentComponent() {
|
||||
return Objects.requireNonNull(this.componentStack.peek());
|
||||
}
|
||||
|
||||
public void pushResolved(VariableExpression resolvedVariable) {
|
||||
this.resolvedStack.push(resolvedVariable);
|
||||
}
|
||||
|
||||
public void popResolved() {
|
||||
this.resolvedStack.pop();
|
||||
}
|
||||
|
||||
public VariableExpression getCurrentResolved() {
|
||||
return Objects.requireNonNull(this.resolvedStack.peek());
|
||||
}
|
||||
|
||||
public void pushChildList(Parameter childCollector) {
|
||||
this.childListStack.push(childCollector);
|
||||
}
|
||||
|
||||
public void popChildList() {
|
||||
this.childListStack.pop();
|
||||
}
|
||||
|
||||
public VariableExpression getCurrentChildList() {
|
||||
final Parameter childCollectorParam = Objects.requireNonNull(this.childListStack.peek());
|
||||
return new VariableExpression(childCollectorParam);
|
||||
}
|
||||
|
||||
public boolean hasCurrentChildList() {
|
||||
return this.childListStack.peek() != null;
|
||||
}
|
||||
|
||||
public void addError(ComponentTemplateCompileException error) {
|
||||
this.errors.add(error);
|
||||
}
|
||||
|
||||
public void addErrors(Collection<? extends ComponentTemplateCompileException> errors) {
|
||||
this.errors.addAll(errors);
|
||||
}
|
||||
|
||||
public boolean hasErrors() {
|
||||
return !this.errors.isEmpty();
|
||||
}
|
||||
|
||||
public List<ComponentTemplateCompileException> getErrors() {
|
||||
return new ArrayList<>(this.errors);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private TranspilerUtil() {}
|
||||
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package groowt.view.component.web.transpile;
|
||||
|
||||
import groowt.view.component.web.ast.node.ValueNode;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil.TranspilerState;
|
||||
import org.codehaus.groovy.ast.expr.Expression;
|
||||
|
||||
public interface ValueNodeTranspiler {
|
||||
|
@ -8,7 +8,7 @@ import groowt.view.component.web.ast.node.BodyNode;
|
||||
import groowt.view.component.web.compiler.WebViewComponentTemplateCompileUnit;
|
||||
import groowt.view.component.web.transpile.BodyTranspiler;
|
||||
import groowt.view.component.web.transpile.TranspilerConfiguration;
|
||||
import groowt.view.component.web.transpile.TranspilerUtil;
|
||||
import groowt.view.component.web.transpile.TranspilerState;
|
||||
import org.codehaus.groovy.ast.ModuleNode;
|
||||
import org.codehaus.groovy.ast.expr.ConstantExpression;
|
||||
import org.codehaus.groovy.ast.expr.MethodCallExpression;
|
||||
@ -67,12 +67,12 @@ public abstract class BodyTranspilerTests {
|
||||
final var buildResult = this.build(source);
|
||||
final var configuration = this.getConfiguration(compileUnit, moduleNode);
|
||||
final var transpiler = this.getBodyTranspiler(configuration);
|
||||
final var state = TranspilerUtil.TranspilerState.withDefaultRootScope();
|
||||
final var state = TranspilerState.withDefaultRootScope();
|
||||
final var addOrAppend = configuration.getAppendOrAddStatementFactory();
|
||||
final BlockStatement blockStatement = transpiler.transpileBody(
|
||||
buildResult.bodyNode(),
|
||||
(node, expression) -> addOrAppend.addOrAppend(node, state, ignored -> expression),
|
||||
TranspilerUtil.TranspilerState.withDefaultRootScope()
|
||||
TranspilerState.withDefaultRootScope()
|
||||
);
|
||||
assertEquals(1, blockStatement.getStatements().size());
|
||||
}
|
||||
@ -86,12 +86,12 @@ public abstract class BodyTranspilerTests {
|
||||
final var buildResult = this.build(source);
|
||||
final var configuration = this.getConfiguration(compileUnit, moduleNode);
|
||||
final var transpiler = this.getBodyTranspiler(configuration);
|
||||
final var state = TranspilerUtil.TranspilerState.withDefaultRootScope();
|
||||
final var state = TranspilerState.withDefaultRootScope();
|
||||
final var addOrAppend = configuration.getAppendOrAddStatementFactory();
|
||||
final BlockStatement blockStatement = transpiler.transpileBody(
|
||||
buildResult.bodyNode(),
|
||||
(node, expression) -> addOrAppend.addOrAppend(node, state, ignored -> expression),
|
||||
TranspilerUtil.TranspilerState.withDefaultRootScope()
|
||||
TranspilerState.withDefaultRootScope()
|
||||
);
|
||||
assertEquals(1, blockStatement.getStatements().size());
|
||||
final var s0 = (ExpressionStatement) blockStatement.getStatements().getFirst();
|
||||
|
Loading…
Reference in New Issue
Block a user