Skip to content

Commit

Permalink
Merge pull request quarkusio#14302 from mkouba/qute-fix-set-validation
Browse files Browse the repository at this point in the history
Qute type-safe templates - fix validation of expressions in set sections
  • Loading branch information
gsmet authored Jan 19, 2021
2 parents f7c74cc + 78acbac commit c53872a
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
import io.quarkus.qute.ResultNode;
import io.quarkus.qute.SectionHelper;
import io.quarkus.qute.SectionHelperFactory;
import io.quarkus.qute.SetSectionHelper;
import io.quarkus.qute.Template;
import io.quarkus.qute.TemplateException;
import io.quarkus.qute.TemplateExtension;
Expand Down Expand Up @@ -1183,9 +1184,7 @@ static boolean processHints(TemplateAnalysis templateAnalysis, String helperHint
// Map<String,Long> => Entry<String,Long>
processLoopElementHint(match, index, expression, incorrectExpressions);
} else if (helperHint.startsWith(LoopSectionHelper.Factory.HINT_PREFIX)) {
Integer iterableExprId = Integer
.valueOf(helperHint.substring(LoopSectionHelper.Factory.HINT_PREFIX.length(), helperHint.length() - 1));
Expression valueExpr = templateAnalysis.findExpression(iterableExprId);
Expression valueExpr = findExpression(helperHint, LoopSectionHelper.Factory.HINT_PREFIX, templateAnalysis);
if (valueExpr != null) {
Match valueExprMatch = generatedIdsToMatches.get(valueExpr.getGeneratedId());
if (valueExprMatch != null) {
Expand All @@ -1195,20 +1194,31 @@ static boolean processHints(TemplateAnalysis templateAnalysis, String helperHint
} else if (helperHint.startsWith(WhenSectionHelper.Factory.HINT_PREFIX)) {
// If a value expression resolves to an enum we attempt to use the enum type to validate the enum constant
// This basically transforms the type info "ON<when:12345>" into something like "|org.acme.Status|.ON"
Integer valueExprId = Integer
.valueOf(helperHint.substring(WhenSectionHelper.Factory.HINT_PREFIX.length(), helperHint.length() - 1));
Expression valueExpr = templateAnalysis.findExpression(valueExprId);
Expression valueExpr = findExpression(helperHint, WhenSectionHelper.Factory.HINT_PREFIX, templateAnalysis);
if (valueExpr != null) {
Match valueExprMatch = generatedIdsToMatches.get(valueExpr.getGeneratedId());
if (valueExprMatch != null && valueExprMatch.clazz.isEnum()) {
match.setValues(valueExprMatch.clazz, valueExprMatch.type);
return true;
}
}
} else if (helperHint.startsWith(SetSectionHelper.Factory.HINT_PREFIX)) {
Expression valueExpr = findExpression(helperHint, SetSectionHelper.Factory.HINT_PREFIX, templateAnalysis);
if (valueExpr != null) {
Match valueExprMatch = generatedIdsToMatches.get(valueExpr.getGeneratedId());
if (valueExprMatch != null) {
match.setValues(valueExprMatch.clazz, valueExprMatch.type);
}
}
}
return false;
}

private static Expression findExpression(String helperHint, String hintPrefix, TemplateAnalysis templateAnalysis) {
return templateAnalysis
.findExpression(Integer.parseInt(helperHint.substring(hintPrefix.length(), helperHint.length() - 1)));
}

static void processLoopElementHint(Match match, IndexView index, Expression expression,
BuildProducer<IncorrectExpressionBuildItem> incorrectExpressions) {
if (match.type().name().equals(DotNames.INTEGER)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public TemplateAnalysis(String id, String generatedId, List<Expression> expressi
this.path = path;
}

Expression findExpression(Integer id) {
Expression findExpression(int id) {
for (Expression expression : expressions) {
if (expression.getGeneratedId() == id) {
return expression;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package io.quarkus.qute.deployment.typesafe;

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

import javax.inject.Inject;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.qute.Template;
import io.quarkus.test.QuarkusUnitTest;

public class TypeSafeLetTest {

@RegisterExtension
static final QuarkusUnitTest config = new QuarkusUnitTest()
.setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class)
.addClasses(Movie.class)
.addAsResource(new StringAsset("{@io.quarkus.qute.deployment.typesafe.Movie movie}"
+ "{#let service=movie.findService('foo')}"
+ "{service.shortValue}"
+ "{/let}"), "templates/foo.html"));

@Inject
Template foo;

@Test
public void testValidation() {
assertEquals("10",
foo.data("movie", new Movie()).render());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ default boolean isVirtualMethod() {
}

default VirtualMethodPart asVirtualMethod() {
throw new IllegalArgumentException("Not a virtual method");
throw new IllegalStateException("Not a virtual method: " + toString() + " [typeInfo: " + getTypeInfo() + "]");
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public CompletionStage<ResultNode> resolve(SectionResolutionContext context) {

public static class Factory implements SectionHelperFactory<SetSectionHelper> {

public static final String HINT_PREFIX = "<set#";

@Override
public List<String> getDefaultAliases() {
return ImmutableList.of(SET, LET);
Expand All @@ -68,7 +70,11 @@ public Scope initializeBlock(Scope previousScope, BlockInfo block) {
Scope newScope = new Scope(previousScope);
for (Entry<String, String> entry : block.getParameters().entrySet()) {
Expression expr = block.addExpression(entry.getKey(), entry.getValue());
newScope.putBinding(entry.getKey(), expr.collectTypeInfo());
if (expr.hasTypeInfo()) {
newScope.putBinding(entry.getKey(), entry.getKey() + HINT_PREFIX + expr.getGeneratedId() + ">");
} else {
newScope.putBinding(entry.getKey(), null);
}
}
return newScope;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ public void testTypeInfos() {
assertExpr(expressions, "it.value", 2, "it<loop#" + beanLabels.getGeneratedId() + ">.value");

assertExpr(expressions, "foo.bar", 2, "|org.acme.Foo|.bar");
assertExpr(expressions, "baz.name", 2, "|org.acme.Foo|.bar.name");
assertExpr(expressions, "baz.name", 2, "baz<set#10>.name");
assertExpr(expressions, "foo.baz", 2, null);
assertExpr(expressions, "foo.call(labels,bar)", 2, "|org.acme.Foo|.call(labels,bar)");

Expand Down

0 comments on commit c53872a

Please sign in to comment.