Skip to content

Commit ed41f38

Browse files
mkoubapull[bot]
authored andcommitted
Qute - fix origin of an expression used as a section param
- there is no easy way to reliably identify the column of an expression used as a section param, therefore, we'll report the column of the containing section/block for the moment - related to #26479
1 parent 813331d commit ed41f38

File tree

7 files changed

+64
-22
lines changed

7 files changed

+64
-22
lines changed

independent-projects/qute/core/src/main/java/io/quarkus/qute/Parser.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.quarkus.qute;
22

33
import io.quarkus.qute.Expression.Part;
4+
import io.quarkus.qute.SectionHelperFactory.BlockInfo;
45
import io.quarkus.qute.SectionHelperFactory.ParametersInfo;
56
import io.quarkus.qute.SectionHelperFactory.ParserDelegate;
67
import io.quarkus.qute.TemplateNode.Origin;
@@ -31,7 +32,7 @@
3132
/**
3233
* Simple non-reusable parser.
3334
*/
34-
class Parser implements Function<String, Expression>, ParserHelper, ParserDelegate, WithOrigin, ErrorInitializer {
35+
class Parser implements ParserHelper, ParserDelegate, WithOrigin, ErrorInitializer {
3536

3637
private static final Logger LOGGER = Logger.getLogger(Parser.class);
3738
static final String ROOT_HELPER_NAME = "$root";
@@ -414,7 +415,7 @@ private void flushTag() {
414415
} else {
415416
// Expression
416417
sectionStack.peek().currentBlock()
417-
.addNode(new ExpressionNode(apply(content), engine));
418+
.addNode(new ExpressionNode(createExpression(content), engine));
418419
}
419420
this.buffer = new StringBuilder();
420421
}
@@ -446,7 +447,7 @@ private void sectionStart(String content, String tag) {
446447

447448
// => New section block
448449
SectionBlock.Builder block = SectionBlock.builder("" + sectionBlockIdx++, this, this)
449-
.setOrigin(origin(0)).setLabel(sectionName);
450+
.setOrigin(origin(tag.length() - 1)).setLabel(sectionName);
450451
lastSection.addBlock(block);
451452

452453
processParams(tag, sectionName, iter, block);
@@ -465,7 +466,7 @@ private void sectionStart(String content, String tag) {
465466
.build();
466467
}
467468
SectionNode.Builder sectionNode = SectionNode
468-
.builder(sectionName, origin(0), this, this)
469+
.builder(sectionName, origin(tag.length() - 1), this, this)
469470
.setEngine(engine)
470471
.setHelperFactory(factory);
471472

@@ -578,7 +579,8 @@ private void parameterDeclaration(String content, String tag) {
578579
String typeInfo = Expressions.typeInfoFrom(value);
579580
currentScope.putBinding(key, typeInfo);
580581
sectionStack.peek().currentBlock().addNode(
581-
new ParameterDeclarationNode(typeInfo, key, defaultValue != null ? apply(defaultValue) : null, origin(0)));
582+
new ParameterDeclarationNode(typeInfo, key, defaultValue != null ? createExpression(defaultValue) : null,
583+
origin(0)));
582584

583585
// If a default value is set we add a synthetic {#let} section to define local variables with default values
584586
if (defaultValue != null) {
@@ -988,8 +990,11 @@ static boolean isRightBracket(char character) {
988990
return character == ')';
989991
}
990992

991-
@Override
992-
public ExpressionImpl apply(String value) {
993+
ExpressionImpl createSectionBlockExpression(BlockInfo block, String value) {
994+
return parseExpression(expressionIdGenerator::incrementAndGet, value, scopeStack.peek(), block.getOrigin());
995+
}
996+
997+
ExpressionImpl createExpression(String value) {
993998
return parseExpression(expressionIdGenerator::incrementAndGet, value, scopeStack.peek(), origin(value.length() + 1));
994999
}
9951000

independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionBlock.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import java.util.List;
99
import java.util.Map;
1010
import java.util.Set;
11-
import java.util.function.Function;
1211
import java.util.function.Predicate;
1312

1413
/**
@@ -180,9 +179,9 @@ private void collapseGroup(List<TextNode> group, List<TemplateNode> finalNodes)
180179
}
181180
}
182181

183-
static SectionBlock.Builder builder(String id, Function<String, Expression> expressionFunc,
182+
static SectionBlock.Builder builder(String id, Parser parser,
184183
ErrorInitializer errorInitializer) {
185-
return new Builder(id, expressionFunc, errorInitializer).setLabel(id);
184+
return new Builder(id, parser, errorInitializer).setLabel(id);
186185
}
187186

188187
static class Builder implements BlockInfo {
@@ -193,14 +192,13 @@ static class Builder implements BlockInfo {
193192
private Map<String, String> parameters;
194193
private final List<TemplateNode> nodes;
195194
private Map<String, Expression> expressions;
196-
private final Function<String, Expression> expressionFun;
195+
private final Parser parser;
197196
private final ErrorInitializer errorInitializer;
198197

199-
public Builder(String id, Function<String, Expression> expressionFun,
200-
ErrorInitializer errorInitializer) {
198+
public Builder(String id, Parser parser, ErrorInitializer errorInitializer) {
201199
this.id = id;
202200
this.nodes = new ArrayList<>();
203-
this.expressionFun = expressionFun;
201+
this.parser = parser;
204202
this.errorInitializer = errorInitializer;
205203
}
206204

@@ -229,7 +227,7 @@ SectionBlock.Builder addParameter(String name, String value) {
229227

230228
@Override
231229
public Expression addExpression(String param, String value) {
232-
Expression expression = expressionFun.apply(value);
230+
Expression expression = parser.createSectionBlockExpression(this, value);
233231
if (expressions == null) {
234232
expressions = new LinkedHashMap<>();
235233
}

independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionHelperFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,8 @@ default boolean hasParameter(String name) {
140140
* Parse and register an expression for the specified parameter.
141141
* <p>
142142
* A registered expression contributes to the {@link Template#getExpressions()}, i.e. can be validated at build time.
143+
* <p>
144+
* The origin of the returned expression is the origin of the containing block.
143145
*
144146
* @param param
145147
* @param value

independent-projects/qute/core/src/main/java/io/quarkus/qute/SectionNode.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import java.util.Map;
88
import java.util.Set;
99
import java.util.concurrent.CompletionStage;
10-
import java.util.function.Function;
1110
import java.util.function.Predicate;
1211
import org.jboss.logging.Logger;
1312

@@ -18,9 +17,9 @@ class SectionNode implements TemplateNode {
1817

1918
private static final Logger LOG = Logger.getLogger("io.quarkus.qute.nodeResolve");
2019

21-
static Builder builder(String helperName, Origin origin, Function<String, Expression> expressionFun,
20+
static Builder builder(String helperName, Origin origin, Parser parser,
2221
ErrorInitializer errorFun) {
23-
return new Builder(helperName, origin, expressionFun, errorFun);
22+
return new Builder(helperName, origin, parser, errorFun);
2423
}
2524

2625
final String name;
@@ -110,15 +109,14 @@ static class Builder {
110109
private EngineImpl engine;
111110
private final ErrorInitializer errorInitializer;
112111

113-
Builder(String helperName, Origin origin, Function<String, Expression> expressionFun,
114-
ErrorInitializer errorInitializer) {
112+
Builder(String helperName, Origin origin, Parser parser, ErrorInitializer errorInitializer) {
115113
this.helperName = helperName;
116114
this.origin = origin;
117115
this.blocks = new ArrayList<>();
118116
this.errorInitializer = errorInitializer;
119117
// The main block is always present
120118
addBlock(SectionBlock
121-
.builder(SectionHelperFactory.MAIN_BLOCK_NAME, expressionFun, errorInitializer)
119+
.builder(SectionHelperFactory.MAIN_BLOCK_NAME, parser, errorInitializer)
122120
.setOrigin(origin));
123121
}
124122

independent-projects/qute/core/src/test/java/io/quarkus/qute/IfSectionTest.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,25 @@ public void testFromageCondition() {
240240
.data("user", "Stef", "target", new Target(ContentStatus.NEW)).render());
241241
}
242242

243+
@Test
244+
public void testParameterOrigin() {
245+
Engine engine = Engine.builder().addDefaults().build();
246+
Template template = engine.parse(" {#if item.price > 1}{/if}");
247+
List<Expression> expressions = template.getExpressions();
248+
assertEquals(2, expressions.size());
249+
for (Expression expression : expressions) {
250+
if (expression.isLiteral()) {
251+
assertEquals(1, expression.getLiteralValue().getNow(false));
252+
assertEquals(1, expression.getOrigin().getLine());
253+
assertEquals(3, expression.getOrigin().getLineCharacterStart());
254+
} else {
255+
assertEquals("item.price", expression.toOriginalString());
256+
assertEquals(1, expression.getOrigin().getLine());
257+
assertEquals(3, expression.getOrigin().getLineCharacterStart());
258+
}
259+
}
260+
}
261+
243262
public static class Target {
244263

245264
public ContentStatus status;

independent-projects/qute/core/src/test/java/io/quarkus/qute/ParserTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public void testLines() {
157157
+ "{/}");
158158
Origin fooItemsOrigin = find(template.getExpressions(), "foo.items").getOrigin();
159159
assertEquals(6, fooItemsOrigin.getLine());
160-
assertEquals(14, fooItemsOrigin.getLineCharacterStart());
160+
assertEquals(1, fooItemsOrigin.getLineCharacterStart());
161161
assertEquals(24, fooItemsOrigin.getLineCharacterEnd());
162162
Origin itemNameOrigin = find(template.getExpressions(), "item.name").getOrigin();
163163
assertEquals(8, itemNameOrigin.getLine());

independent-projects/qute/core/src/test/java/io/quarkus/qute/SetSectionTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
44

5+
import java.util.List;
56
import org.junit.jupiter.api.Test;
67

78
public class SetSectionTest {
@@ -41,4 +42,23 @@ public void testDefaultValues() {
4142
.data("bar", "42", "baz", "no").render());
4243
}
4344

45+
@Test
46+
public void testParameterOrigin() {
47+
Engine engine = Engine.builder().addDefaults().build();
48+
Template template = engine.parse(" {#let item=1 foo=bar}{/let}");
49+
List<Expression> expressions = template.getExpressions();
50+
assertEquals(2, expressions.size());
51+
for (Expression expression : expressions) {
52+
if (expression.isLiteral()) {
53+
assertEquals(1, expression.getLiteralValue().getNow(false));
54+
assertEquals(1, expression.getOrigin().getLine());
55+
assertEquals(3, expression.getOrigin().getLineCharacterStart());
56+
} else {
57+
assertEquals("bar", expression.toOriginalString());
58+
assertEquals(1, expression.getOrigin().getLine());
59+
assertEquals(3, expression.getOrigin().getLineCharacterStart());
60+
}
61+
}
62+
}
63+
4464
}

0 commit comments

Comments
 (0)