casid / jte

Secure and speedy templates for Java and Kotlin.
https://jte.gg
Apache License 2.0
748 stars 56 forks source link

More than one for-else in the same template causes compilation error #292

Closed erik-alm closed 10 months ago

erik-alm commented 10 months ago

In short:

Using more than one for-else loop in the same template causes a compilation error because a variable "__jte_for_loop_entered_1" is defined once per loop.

Pom.xml:

    <dependency>
        <groupId>gg.jte</groupId>
        <artifactId>jte</artifactId>
        <version>3.0.3</version>
    </dependency>

The error:

gg.jte.TemplateException: Failed to compile template, error at pages/sector.jte:204
[Snip]/jte-classes/gg/jte/generated/ondemand/pages/JtesectorGenerated.java:190: error: variable __jte_for_loop_entered_1 is already defined in method render(HtmlTemplateOutput,HtmlInterceptor,SectorPage)
    boolean __jte_for_loop_entered_1 = false;
            ^
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error

at gg.jte.compiler.java.JavaClassCompiler.runCompiler(JavaClassCompiler.java:49)
at gg.jte.compiler.java.JavaClassCompiler.compile(JavaClassCompiler.java:38)
at gg.jte.compiler.TemplateCompiler.precompileClasses(TemplateCompiler.java:114)
at gg.jte.compiler.TemplateCompiler.precompile(TemplateCompiler.java:94)
at gg.jte.compiler.TemplateCompiler.load(TemplateCompiler.java:50)
at gg.jte.TemplateEngine.lambda$resolveTemplateOnDemand$0(TemplateEngine.java:354)
at java.base/java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1916)
at gg.jte.TemplateEngine.resolveTemplateOnDemand(TemplateEngine.java:347)
at gg.jte.TemplateEngine.resolveTemplate(TemplateEngine.java:337)
at gg.jte.TemplateEngine.render(TemplateEngine.java:210)
at net.blockm.starmap.web.WebRepository.render(WebRepository.java:43)
at net.blockm.starmap.app.WebBuilder.buildSector(WebBuilder.java:523)
at net.blockm.starmap.app.WebBuilder.buildSectors(WebBuilder.java:90)
at net.blockm.starmap.app.WebBuilder.build(WebBuilder.java:54)
at net.blockm.starmap.app.Main.main(Main.java:120)

The template code:

        <h2>Namngivna stjärnsystem i sektorn</h2>
        <div class="cloud">
            @for(var starSystem : ForSupport.of(sector.getPrimaryStarSystems()))
                @if(!starSystem.isFirst())
                    &middot;
                @endif
                $unsafe{PathUtils.path(starSystem.get()).getHtml()}
            @else
                Inga.
            @endfor
        </div>

        <h2>Beboeliga planeter i sektorn</h2>
        <div class="cloud">
            @for(var garden : ForSupport.of(sector.getGardenPlanets()))
                @if(!garden.isFirst())
                    &middot;
                @endif
                $unsafe{PathUtils.path(garden.get()).getHtml()}
            @else
                Inga.
            @endfor
        </div>

The compiled class (JtesectorGenerated.java):

    jteOutput.writeContent("\n            </ul>\n            \n            <h2>Namngivna stjärnsystem i sektorn</h2>\n            <div class=\"cloud\">\n                ");
    boolean __jte_for_loop_entered_1 = false;
    for (var starSystem : ForSupport.of(sector.getPrimaryStarSystems())) {
        __jte_for_loop_entered_1 = true;
        jteOutput.writeContent("\n                    ");
        if (!starSystem.isFirst()) {
            jteOutput.writeContent("\n                        &middot;\n                    ");
        }
        jteOutput.writeContent("\n                    ");
        jteOutput.writeUnsafeContent(PathUtils.path(starSystem.get()).getHtml());
        jteOutput.writeContent("\n                ");
    }
    if (!__jte_for_loop_entered_1) {
        jteOutput.writeContent("\n                    Inga.\n                ");
    }
    jteOutput.writeContent("\n            </div>\n\n\n            <h2>Beboeliga planeter i sektorn</h2>\n            <div class=\"cloud\">\n                ");
    boolean __jte_for_loop_entered_1 = false;
    for (var garden : ForSupport.of(sector.getGardenPlanets())) {
        __jte_for_loop_entered_1 = true;
        jteOutput.writeContent("\n                    ");
        if (!garden.isFirst()) {
            jteOutput.writeContent("\n                        &middot;\n                    ");
        }
        jteOutput.writeContent("\n                    ");
        jteOutput.writeUnsafeContent(PathUtils.path(garden.get()).getHtml());
        jteOutput.writeContent("\n                ");
    }
    if (!__jte_for_loop_entered_1) {
        jteOutput.writeContent("\n                    Inga.\n                ");
    }
    jteOutput.writeContent("\n            </div>\n            ");
casid commented 10 months ago

@erik-alm thank you for reporting! I've pushed a fix for this and will release a new bugfix version start of next week.

casid commented 10 months ago

@erik-alm I just released jte 3.1.4 containing this fix. Thanks!

erik-alm commented 10 months ago

@casid Great! I'll check it out as soon as I'm able! Thank you!