Skip to content

Commit d4bb75b

Browse files
Normalize expression variables (#1146)
* Normalize archetype expression variables ScriptCompiler: - Use absolute context reference in variable expression - Fix NO_OUTPUT - Move mirror outside of Image - Make Image public JsonScriptWriter: - Fix expressions duplications - Exclude empty attributes (I.e. expressions, methods, children) Misc: - Update stager plugin to support incremental staging (I.e. don't fail if output files already exist) * Add test for normalized expressions * Fix ReflectedEngine
1 parent d2fb880 commit d4bb75b

File tree

25 files changed

+465
-317
lines changed

25 files changed

+465
-317
lines changed

archetype/engine-v2-json/src/main/java/io/helidon/build/archetype/v2/json/JsonScriptWriter.java

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
package io.helidon.build.archetype.v2.json;
1717

1818
import java.io.Writer;
19-
import java.util.HashMap;
19+
import java.util.LinkedHashMap;
2020
import java.util.Map;
2121
import java.util.concurrent.atomic.AtomicInteger;
2222

@@ -33,7 +33,7 @@
3333
*/
3434
public class JsonScriptWriter implements Script.Writer {
3535

36-
private final Map<Expression, String> expressions = new HashMap<>();
36+
private final Map<Expression, String> expressions = new LinkedHashMap<>();
3737
private final JsonGenerator generator;
3838

3939
/**
@@ -54,23 +54,40 @@ public void close() {
5454
@Override
5555
public void writeScript(Node script) {
5656
generator.writeStartObject();
57-
generator.writeStartObject("expressions");
58-
for (Node node : script.traverse()) {
59-
if (node.kind() == Kind.CONDITION) {
60-
writeExpression(node.expression());
61-
}
57+
58+
// compute expression ids
59+
for (Node node : script.traverse(Kind.CONDITION::equals)) {
60+
expressions.computeIfAbsent(node.expression(), k -> String.valueOf(expressions.size() + 1));
6261
}
63-
generator.writeEnd();
64-
generator.writeStartObject("methods");
65-
script.script().methods().forEach((k, v) -> {
66-
generator.writeStartArray(k);
67-
writeDirectives(v);
62+
63+
// write expressions
64+
if (!expressions.isEmpty()) {
65+
generator.writeStartObject("expressions");
66+
expressions.forEach(this::writeExpression);
6867
generator.writeEnd();
69-
});
70-
generator.writeEnd();
71-
generator.writeStartArray("children");
72-
writeDirectives(script);
68+
}
69+
70+
// write methods
71+
Map<String, Node> methods = script.script().methods();
72+
if (!methods.isEmpty()) {
73+
generator.writeStartObject("methods");
74+
methods.forEach(this::writeMethod);
75+
generator.writeEnd();
76+
}
77+
78+
// write children
79+
if (!script.children().isEmpty()) {
80+
generator.writeStartArray("children");
81+
writeDirectives(script);
82+
generator.writeEnd();
83+
}
84+
7385
generator.writeEnd();
86+
}
87+
88+
private void writeMethod(String methodName, Node method) {
89+
generator.writeStartArray(methodName);
90+
writeDirectives(method);
7491
generator.writeEnd();
7592
}
7693

@@ -140,8 +157,7 @@ private void writeValue(Node node) {
140157
}
141158
}
142159

143-
private void writeExpression(Expression expr) {
144-
String id = expressions.computeIfAbsent(expr, k -> String.valueOf(expressions.size() + 1));
160+
private void writeExpression(Expression expr, String id) {
145161
generator.writeStartArray(id);
146162
for (Expression.Token token : expr.tokens()) {
147163
generator.writeStartObject();

archetype/engine-v2-json/src/test/resources/writer/expressions.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,6 @@
609609
}
610610
]
611611
},
612-
"methods": {},
613612
"children": [
614613
{
615614
"kind": "step",

archetype/engine-v2-json/src/test/resources/writer/inputs.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
}
88
]
99
},
10-
"methods": {
11-
},
1210
"children": [
1311
{
1412
"kind": "step",

archetype/engine-v2-json/src/test/resources/writer/methods.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
{
2-
"expressions": {
3-
},
42
"methods": {
53
"method1": [
64
{
@@ -24,7 +22,5 @@
2422
]
2523
}
2624
]
27-
},
28-
"children": [
29-
]
25+
}
3026
}

archetype/engine-v2-json/src/test/resources/writer/presets.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
{
2-
"expressions": {
3-
},
4-
"methods": {
5-
},
62
"children": [
73
{
84
"kind": "presets",

archetype/engine-v2-json/src/test/resources/writer/validations.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
{
2-
"expressions": {
3-
},
4-
"methods": {
5-
},
62
"children": [
73
{
84
"kind": "validations",

archetype/engine-v2-json/src/test/resources/writer/variables.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
{
2-
"expressions": {
3-
},
4-
"methods": {
5-
},
62
"children": [
73
{
84
"kind": "variables",

archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/ArchetypeEngineV2.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package io.helidon.build.archetype.engine.v2;
1818

19-
import java.nio.file.FileSystem;
2019
import java.nio.file.Path;
2120
import java.util.Map;
2221
import java.util.function.Function;
@@ -195,13 +194,13 @@ public Builder batch(boolean batch) {
195194
}
196195

197196
/**
198-
* Set the archetype file system.
197+
* Set the current working directory.
199198
*
200-
* @param fileSystem archetype file system
199+
* @param cwd cwd
201200
* @return this builder
202201
*/
203-
public Builder fileSystem(FileSystem fileSystem) {
204-
this.cwd = fileSystem.getPath("/");
202+
public Builder cwd(Path cwd) {
203+
this.cwd = cwd;
205204
return this;
206205
}
207206

archetype/engine-v2/src/main/java/io/helidon/build/archetype/engine/v2/Expression.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Stack;
3636
import java.util.TreeMap;
3737
import java.util.function.Function;
38+
import java.util.function.UnaryOperator;
3839
import java.util.regex.Matcher;
3940
import java.util.regex.Pattern;
4041
import java.util.stream.Collectors;
@@ -87,7 +88,7 @@ public final class Expression implements Comparable<Expression> {
8788
this(parse(expression), false);
8889
}
8990

90-
private Expression(List<Token> tokens, boolean reduced) {
91+
Expression(List<Token> tokens, boolean reduced) {
9192
if (tokens.isEmpty()) {
9293
throw new IllegalArgumentException("Empty expression");
9394
}
@@ -170,6 +171,16 @@ public Set<String> variables() {
170171
return variables.get();
171172
}
172173

174+
/**
175+
* Map this expression.
176+
*
177+
* @param mapper mapper
178+
* @return Expression
179+
*/
180+
public Expression map(UnaryOperator<Token> mapper) {
181+
return new Expression(Lists.map(tokens, mapper), false);
182+
}
183+
173184
/**
174185
* Evaluate this expression.
175186
*

0 commit comments

Comments
 (0)