├── .editorconfig ├── .github └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .travis.yml ├── BUILD.bazel ├── CHANGES.txt ├── LICENSE.txt ├── README.md ├── WORKSPACE.bazel ├── benchmark └── org │ └── stringtemplate │ └── v4 │ └── benchmark │ ├── Attributes.java │ ├── Benchmark.java │ ├── Misc.java │ ├── OliverTest.java │ ├── WriteFixedTemplates.java │ ├── email.stg │ ├── home.benchmark.txt │ ├── maniac.benchmark.txt │ └── oliver │ ├── Article.java │ ├── Customer.java │ ├── Helper.java │ ├── Item.java │ └── Order.java ├── build.xml ├── developer-cert-of-origin.txt ├── doc ├── 3to4.md ├── adaptors.md ├── bytecode.md ├── cheatsheet.md ├── expr-options.md ├── faq │ └── index.md ├── groups.md ├── images │ ├── AST.png │ ├── attrstack.gif │ ├── bytecode.png │ ├── outputclick.gif │ ├── startup.gif │ └── trace.png ├── indent.md ├── index.md ├── inheritance.md ├── inspector.md ├── introduction.md ├── java.md ├── listeners.md ├── motivation.md ├── null-vs-empty-previous.md ├── null-vs-empty.md ├── regions.md ├── release-notes │ ├── 4.0.1.md │ ├── 4.0.2.md │ ├── 4.0.3.md │ ├── 4.0.4.md │ ├── 4.0.5.md │ ├── 4.0.6.md │ ├── 4.0.7.md │ └── 4.0.md ├── releasing-st4.md ├── renderers.md ├── scala-model-adaptor.md ├── templates.md └── wrapping.md ├── doxyfile ├── historical-contributors-agreement.txt ├── nb-configuration.xml ├── pom.xml ├── scripts └── github_release_notes.py ├── src ├── BUILD.bazel └── org │ └── stringtemplate │ └── v4 │ ├── AttributeRenderer.java │ ├── AutoIndentWriter.java │ ├── DateRenderer.java │ ├── InstanceScope.java │ ├── Interpreter.java │ ├── ModelAdaptor.java │ ├── NoIndentWriter.java │ ├── NumberRenderer.java │ ├── ST.java │ ├── STErrorListener.java │ ├── STGroup.java │ ├── STGroupDir.java │ ├── STGroupFile.java │ ├── STGroupString.java │ ├── STRawGroupDir.java │ ├── STWriter.java │ ├── StringRenderer.java │ ├── compiler │ ├── Bytecode.java │ ├── BytecodeDisassembler.java │ ├── CodeGenerator.g │ ├── CompilationState.java │ ├── CompiledST.java │ ├── Compiler.java │ ├── FormalArgument.java │ ├── Group.g │ ├── STException.java │ ├── STLexer.java │ ├── STLexer.tokens │ ├── STParser.g │ └── StringTable.java │ ├── debug │ ├── AddAttributeEvent.java │ ├── ConstructionEvent.java │ ├── EvalExprEvent.java │ ├── EvalTemplateEvent.java │ ├── IndentEvent.java │ └── InterpEvent.java │ ├── gui │ ├── JTreeASTModel.java │ ├── JTreeSTModel.java │ ├── JTreeScopeStackModel.java │ ├── STViewFrame.java │ ├── STViewFrame.jfd │ └── STViz.java │ └── misc │ ├── Aggregate.java │ ├── AggregateModelAdaptor.java │ ├── AmbiguousMatchException.java │ ├── ArrayIterator.java │ ├── Coordinate.java │ ├── ErrorBuffer.java │ ├── ErrorManager.java │ ├── ErrorType.java │ ├── Interval.java │ ├── MapModelAdaptor.java │ ├── Misc.java │ ├── MultiMap.java │ ├── ObjectModelAdaptor.java │ ├── STCompiletimeMessage.java │ ├── STGroupCompiletimeMessage.java │ ├── STLexerMessage.java │ ├── STMessage.java │ ├── STModelAdaptor.java │ ├── STNoSuchAttributeException.java │ ├── STNoSuchPropertyException.java │ ├── STRuntimeMessage.java │ └── TypeRegistry.java └── test ├── BUILD.bazel ├── org └── stringtemplate │ └── v4 │ └── test │ ├── BaseTest.java │ ├── ErrorBufferAllErrors.java │ ├── Playground.java │ ├── TestAggregates.java │ ├── TestAttributes.java │ ├── TestBuggyDefaultValueRaisesNPETest.java │ ├── TestCompiler.java │ ├── TestCoreBasics.java │ ├── TestDebugEvents.java │ ├── TestDictionaries.java │ ├── TestDollarDelimiters.java │ ├── TestEarlyEvaluation.java │ ├── TestFunctions.java │ ├── TestGroupSyntax.java │ ├── TestGroupSyntaxErrors.java │ ├── TestGroups.java │ ├── TestGroupsFromCLASSPATH.java │ ├── TestImports.java │ ├── TestIndentation.java │ ├── TestIndirectionAndEarlyEval.java │ ├── TestInterptimeErrors.java │ ├── TestLexer.java │ ├── TestLineWrap.java │ ├── TestLists.java │ ├── TestModelAdaptors.java │ ├── TestNoNewlineTemplates.java │ ├── TestNullAndEmptyValues.java │ ├── TestOptions.java │ ├── TestRegions.java │ ├── TestRenderers.java │ ├── TestSTRawGroupDir.java │ ├── TestScopes.java │ ├── TestSubtemplates.java │ ├── TestSyntaxErrors.java │ ├── TestTemplateNames.java │ ├── TestTokensForDollarDelimiters.java │ ├── TestTreeConstruction.gunit │ ├── TestTreeConstruction.java │ ├── TestTypeRegistry.java │ ├── TestWhitespace.java │ └── gUnitBase.java ├── resources └── org │ └── antlr │ └── templates │ ├── dir1 │ └── sample.st │ └── testgroupfile.stg └── test.jar /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 4 7 | indent_style = space 8 | insert_final_newline = true 9 | max_line_length = 120 10 | tab_width = 4 11 | 12 | [{*.yml, *.yaml, *.json}] 13 | indent_size = 2 14 | tab_width = 2 15 | 16 | [*.java] 17 | ij_java_block_brace_style = end_of_line 18 | ij_java_class_brace_style = end_of_line 19 | ij_java_method_brace_style = end_of_line 20 | ij_java_lambda_brace_style = end_of_line 21 | 22 | ij_java_spaces_around_assignment_operators = true 23 | ij_java_spaces_around_additive_operators = false 24 | ij_java_spaces_around_multiplicative_operators = false 25 | ij_java_spaces_around_bitwise_operators = false 26 | ij_java_spaces_around_shift_operators = false 27 | ij_java_spaces_around_equality_operators = false 28 | ij_java_spaces_around_relational_operators = false 29 | ij_java_spaces_around_logical_operators = true 30 | 31 | ij_java_spaces_within_if_parentheses = true 32 | ij_java_spaces_within_while_parentheses = true 33 | ij_java_spaces_within_switch_parentheses = true 34 | 35 | ij_java_space_after_type_cast = false 36 | 37 | ij_java_indent_case_from_switch = true 38 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Maven build folders 2 | /target/ 3 | 4 | # Ant build folders 5 | /build/ 6 | /dist/ 7 | /lib/ 8 | user.build.properties 9 | 10 | # NetBeans user configuration 11 | nbactions*.xml 12 | 13 | # IntelliJ project files 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # Eclipse project files 20 | .project 21 | .classpath 22 | .settings/ 23 | 24 | # Bazel 25 | bazel-bin 26 | bazel-out 27 | bazel-stringtemplate4 28 | bazel-testlogs 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # --------------- General Settings --------------- 2 | 3 | dist: xenial 4 | language: java 5 | 6 | jdk: 7 | # unfortunately JDK 6 is no longer support by Travis CI 8 | # - openjdk6 # minimum 9 | - openjdk8 # LTS 10 | - openjdk11 # LTS 11 | # disabled because the maven compiler for JDK 13 no longer supports source/target compatibility 6 12 | # - openjdk13 # latest 13 | 14 | # required for UI tests 15 | services: 16 | - xvfb 17 | 18 | # --------------- Maven Cache --------------- 19 | 20 | cache: 21 | directories: 22 | - .autoconf 23 | - $HOME/.m2 24 | -------------------------------------------------------------------------------- /BUILD.bazel: -------------------------------------------------------------------------------- 1 | """BUILD.bazel file for StringTemplate 4.""" 2 | 3 | package(default_visibility = ["//visibility:private"]) 4 | 5 | alias( 6 | name = "stringtemplate4", 7 | actual = "//src:stringtemplate4", 8 | visibility = ["//visibility:public"], 9 | ) 10 | 11 | test_suite( 12 | name = "tests", 13 | tests = ["//test:tests"], 14 | ) 15 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | [The "BSD license"] 2 | Copyright (c) 2011-2022 Terence Parr 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 3. The name of the author may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ST (StringTemplate) is a java template engine (with ports for C#, Python, and Objective-C coming) for generating source code, web pages, emails, or any other formatted text output. ST is particularly good at multi-targeted code generators, multiple site skins, and internationalization / localization. It evolved over years of effort developing jGuru.com and then ANTLR v3. 2 | 3 | The main website is: 4 | 5 | > https://www.stringtemplate.org 6 | 7 | Its distinguishing characteristic is that it strictly enforces 8 | model-view separation, unlike other engines. See: 9 | 10 | > https://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf 11 | 12 | The documentation is in this repo 13 | 14 | > https://github.com/antlr/stringtemplate4/tree/master/doc/index.md 15 | 16 | Per the BSD license in [LICENSE.txt](LICENSE.txt), this software is not 17 | guaranteed to work and might even destroy all life on this planet. 18 | 19 | ## INSTALLATION 20 | 21 | ### Manual Installation 22 | 23 | All you need to do is get the StringTemplate jar into your `CLASSPATH`. See [Java StringTemplate](doc/java.md). 24 | 25 | ### Maven 26 | 27 | To reference StringTemplate from a project built using Maven, add the following 28 | to the `` element in your **pom.xml** file. 29 | 30 | ```xml 31 | 32 | org.antlr 33 | ST4 34 | 4.3.4 35 | compile 36 | 37 | ``` 38 | 39 | ### Gradle 40 | 41 | In `build.gradle`, add the following dependency: 42 | 43 | ```groovy 44 | dependencies { 45 | // ... 46 | 47 | // https://mvnrepository.com/artifact/org.antlr/ST4 48 | compile group: 'org.antlr', name: 'ST4', version: '4.3.4' 49 | } 50 | ``` 51 | 52 | Make sure you are using the `mavenCentral` repository by adding it if necessary: 53 | 54 | ```groovy 55 | repositories { 56 | // ... 57 | mavenCentral() 58 | } 59 | ``` 60 | 61 | ### Other 62 | 63 | Select a version on [mvnrepository](https://mvnrepository.com/artifact/org.antlr/ST4), 64 | and copy the snippet relevant to your build tool. 65 | 66 | ## BUILDING FROM SOURCE 67 | 68 | The source is at github.com: 69 | 70 | > https://github.com/antlr/stringtemplate4 71 | 72 | If you would like to make changes to ST and build it yourself, 73 | just run `mvn install` from the root directory of the repo. 74 | 75 | You can also run `ant` from the root dir. 76 | 77 | ## Dev Tools 78 | 79 | [IntelliJ plugin](https://plugins.jetbrains.com/plugin/8041-stringtemplate-v4) 80 | 81 | [Neovim plugin](https://github.com/Tralalero-Tralalal/nvim-stg) 82 | 83 | -------------------------------------------------------------------------------- /WORKSPACE.bazel: -------------------------------------------------------------------------------- 1 | workspace(name = "stringtemplate4") 2 | 3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_jar") 4 | load("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") 5 | 6 | # This needs to be identical to the one used in https://github.com/antlr/antlr3/blob/master/WORKSPACE.bazel. 7 | http_jar( 8 | name = "antlr3_bootstrap", 9 | sha256 = "46531814ba9739cdf20c6c1789c252d3d95b68932813d79fb8bbfdf8d5840417", 10 | url = "http://www.antlr3.org/download/antlr-3.5.2-complete-no-st3.jar", 11 | ) 12 | 13 | http_jar( 14 | name = "junit", 15 | sha256 = "8e495b634469d64fb8acfa3495a065cbacc8a0fff55ce1e31007be4c16dc57d3", 16 | url = "https://repo1.maven.org/maven2/junit/junit/4.13.2/junit-4.13.2.jar", 17 | ) 18 | 19 | http_jar( 20 | name = "hamcrest_core", 21 | sha256 = "66fdef91e9739348df7a096aa384a5685f4e875584cce89386a7a47251c4d8e9", 22 | url = "https://repo1.maven.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar", 23 | ) 24 | 25 | # TODO: Switch to http_archive once antlr3 has Bazel support. This approach is necessary to avoid 26 | # an awkward situation where we need to update stringtemplate4 and antlr3 simultaneously. 27 | new_git_repository( 28 | name = "antlr3", 29 | branch = "master", 30 | remote = "https://github.com/antlr/antlr3.git", 31 | ) 32 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/Misc.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.benchmark; 30 | 31 | import java.io.BufferedWriter; 32 | import java.io.File; 33 | import java.io.FileWriter; 34 | import java.io.IOException; 35 | 36 | public class Misc { 37 | public static void writeFile(String dir, String fileName, String content) { 38 | try { 39 | File f = new File(dir, fileName); 40 | if ( !f.getParentFile().exists() ) f.getParentFile().mkdirs(); 41 | FileWriter w = new FileWriter(f); 42 | BufferedWriter bw = new BufferedWriter(w); 43 | bw.write(content); 44 | bw.close(); 45 | w.close(); 46 | } 47 | catch (IOException ioe) { 48 | System.err.println("can't write file"); 49 | ioe.printStackTrace(System.err); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/OliverTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** Borrowed from Oliver Zeigermann */ 30 | 31 | package org.stringtemplate.v4.benchmark; 32 | 33 | import org.stringtemplate.v4.*; 34 | import org.stringtemplate.v4.benchmark.oliver.Helper; 35 | 36 | import java.io.IOException; 37 | import java.io.StringWriter; 38 | import java.math.BigDecimal; 39 | import java.text.DecimalFormat; 40 | import java.text.DecimalFormatSymbols; 41 | import java.text.NumberFormat; 42 | import java.util.Date; 43 | import java.util.Locale; 44 | 45 | /** Adapted from Oliver Zeigermann benchmarking */ 46 | public class OliverTest { 47 | static STGroup test = new STGroupFile("email.stg"); 48 | 49 | public void timeEmail(int reps) { 50 | ST st = test.getInstanceOf("email"); 51 | st.add("order", Helper.order); 52 | st.add("separator", "----------------"); 53 | for (int i = 0; i < reps; i++) { 54 | st.render(); 55 | } 56 | } 57 | 58 | public void timeEmailWriteToStringBuffer(int reps) { 59 | ST st = test.getInstanceOf("email"); 60 | st.add("order", Helper.order); 61 | st.add("separator", "----------------"); 62 | for (int i = 0; i < reps; i++) { 63 | StringWriter sw = new StringWriter(); 64 | AutoIndentWriter w = new AutoIndentWriter(sw); 65 | try {st.write(w);} catch (IOException ioe) {;} 66 | } 67 | } 68 | 69 | public void timeEmailWithRenderers(int reps) { 70 | STGroup test = new STGroupFile("email.stg"); 71 | test.registerRenderer(Date.class, new DateRenderer()); 72 | test.registerRenderer(BigDecimal.class, new BigDecimalRenderer()); 73 | ST st = test.getInstanceOf("email"); 74 | st.add("order", Helper.order); 75 | st.add("separator", "----------------"); 76 | for (int i = 0; i < reps; i++) { 77 | st.render(); 78 | } 79 | } 80 | 81 | public static class BigDecimalRenderer implements AttributeRenderer { 82 | private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat( 83 | "##,##0.00", DecimalFormatSymbols.getInstance(Locale.GERMANY)); 84 | private static final String EURO_CHARACTER = "\u20AC"; 85 | 86 | public String toString(Object o, String formatString, Locale locale) { 87 | if (formatString.equals("currency")) { 88 | if (o instanceof BigDecimal) { 89 | NumberFormat numberFormat = DECIMAL_FORMAT; 90 | String formatted = numberFormat.format(o) + " " 91 | + EURO_CHARACTER; 92 | return formatted; 93 | } 94 | } 95 | return o.toString(); 96 | } 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/WriteFixedTemplates.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.benchmark; 30 | 31 | import org.stringtemplate.v4.ST; 32 | 33 | public class WriteFixedTemplates { 34 | String bigTemplate; 35 | 36 | public WriteFixedTemplates() { 37 | StringBuilder buf = new StringBuilder(); 38 | for (int i=1; i<=1000; i++) buf.append("some text"); 39 | bigTemplate = buf.toString(); 40 | } 41 | 42 | public void timeSingle(int reps) { 43 | String template = 44 | "A smallish string to write out"; 45 | ST st = new ST(template); 46 | for (int i = 0; i < reps; i++) { 47 | st.render(); 48 | } 49 | } 50 | 51 | public void timeSingleBigger(int reps) { 52 | ST st = new ST(bigTemplate); 53 | for (int i = 0; i < reps; i++) { 54 | st.render(); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/email.stg: -------------------------------------------------------------------------------- 1 | email(order,separator) ::= << 2 | Hello, dear customer! 4 | 5 | On we received the following order: 6 | 7 | Shipping address: 8 | 9 | 10 | 11 | x à = };separator="\n"> 12 | plus shipping = 13 | 14 | Total = 15 | 16 | Thank you for ordering! 17 | >> 18 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/home.benchmark.txt: -------------------------------------------------------------------------------- 1 | # Env Host terence.local, Dec 26, 2010 11:57:52 AM, Java 1.6.0_22-b04-307-10M3261, Mac OS X 10.6.5 on x86_64 2 | # HotSpot warmup 3 | # Computing number of reps per trial 4 | # time2Args benchmarking 5 | # timeLotsOfArgs benchmarking 6 | # timeSimplePropsOfArgs benchmarking 7 | # timeDynamicAttributeLookup benchmarking 8 | # timeDeepDynamicLookup benchmarking 9 | timeSimplePropsOfArgs : 386.81 392.62 393.54 396.98 398.90 = 393.77 units of work / ms 10 | timeDeepDynamicLookup : 72.32 73.84 74.28 75.82 75.80 = 74.41 units of work / ms 11 | timeDynamicAttributeLookup : 775.80 775.18 786.06 785.49 788.14 = 782.13 units of work / ms 12 | time2Args : 685.35 692.77 735.37 877.76 873.88 = 773.03 units of work / ms warning: variable average work 13 | timeLotsOfArgs : 132.92 135.32 134.53 136.08 136.27 = 135.02 units of work / ms 14 | 15 | # HotSpot warmup 16 | # Computing number of reps per trial 17 | # timeSingle benchmarking 18 | # timeSingleBigger benchmarking 19 | timeSingleBigger : 9.20 9.20 9.21 9.24 9.22 = 9.22 units of work / ms 20 | timeSingle : 840.15 848.22 857.10 856.69 854.94 = 851.42 units of work / ms 21 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/oliver/Article.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** Borrowed from Oliver Zeigermann */ 30 | 31 | package org.stringtemplate.v4.benchmark.oliver; 32 | 33 | import java.math.BigDecimal; 34 | 35 | public class Article { 36 | public final String name; 37 | public final BigDecimal price; 38 | 39 | public Article(String name, BigDecimal price) { 40 | super(); 41 | this.name = name; 42 | this.price = price; 43 | } 44 | 45 | // all getters created for freemarker as it can not access the fields 46 | // directly (JMTE and ST can) 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public BigDecimal getPrice() { 52 | return price; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/oliver/Customer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** Borrowed from Oliver Zeigermann */ 30 | 31 | package org.stringtemplate.v4.benchmark.oliver; 32 | 33 | public class Customer { 34 | public final String firstName; 35 | public final String lastName; 36 | public final String address; 37 | 38 | public Customer(String firstName, String lastName, String address) { 39 | this.firstName = firstName; 40 | this.lastName = lastName; 41 | this.address = address; 42 | } 43 | 44 | // all getters created for freemarker as it can not access the fields directly (JMTE and ST can) 45 | public String getFirstName() { 46 | return firstName; 47 | } 48 | 49 | public String getLastName() { 50 | return lastName; 51 | } 52 | 53 | public String getAddress() { 54 | return address; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/oliver/Helper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** Borrowed from Oliver Zeigermann */ 30 | 31 | package org.stringtemplate.v4.benchmark.oliver; 32 | 33 | import java.math.BigDecimal; 34 | import java.util.*; 35 | 36 | public class Helper { 37 | 38 | public static String unifyNewlines(String source) { 39 | final String regex = "\\r?\\n"; 40 | final String clearedSource = source.replaceAll(regex, "\n"); 41 | return clearedSource; 42 | } 43 | 44 | public static Order order; 45 | static { 46 | Calendar instance = GregorianCalendar.getInstance(Locale.GERMAN); 47 | instance.set(2011, Calendar.JANUARY, 28); 48 | Date orderDate = instance.getTime(); 49 | 50 | Customer customer = new Customer("Oliver", "Zeigermann", 51 | "Gaußstraße 180\n" + "22765 Hamburg\n" + "GERMANY"); 52 | order = new Order(customer, orderDate); 53 | 54 | Article article1 = new Article("How to become famous", new BigDecimal( 55 | "17.80")); 56 | order.getItems().add(new Item(1, article1)); 57 | 58 | Article article2 = new Article("Cool stuff", new BigDecimal("1.00")); 59 | order.getItems().add(new Item(2, article2)); 60 | } 61 | 62 | public static Map model = new HashMap(); 63 | static { 64 | model.put("order", Helper.order); 65 | model.put("separator", "----------------"); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/oliver/Item.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** Borrowed from Oliver Zeigermann */ 30 | 31 | package org.stringtemplate.v4.benchmark.oliver; 32 | 33 | import java.math.BigDecimal; 34 | 35 | public class Item { 36 | public final int amount; 37 | public final Article article; 38 | 39 | public Item(int amount, Article article) { 40 | super(); 41 | this.amount = amount; 42 | this.article = article; 43 | } 44 | 45 | public BigDecimal getSubTotal() { 46 | return article.price.multiply(new BigDecimal(amount)); 47 | } 48 | 49 | // all getters created for freemarker as it can not access the fields 50 | // directly (JMTE and ST can) 51 | public int getAmount() { 52 | return amount; 53 | } 54 | 55 | public Article getArticle() { 56 | return article; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /benchmark/org/stringtemplate/v4/benchmark/oliver/Order.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | /** Borrowed from Oliver Zeigermann */ 30 | 31 | package org.stringtemplate.v4.benchmark.oliver; 32 | 33 | import java.math.BigDecimal; 34 | import java.util.ArrayList; 35 | import java.util.Date; 36 | import java.util.List; 37 | 38 | public class Order { 39 | public final static BigDecimal FREE_SHIPPING_THRESHOLD = new BigDecimal("20.00"); 40 | public final static BigDecimal SHIPPING_COSTS = new BigDecimal("3.00"); 41 | 42 | private final Customer customer; 43 | private final Date orderDate; 44 | private final List items = new ArrayList(); 45 | 46 | public Order(Customer customer, Date orderDate) { 47 | super(); 48 | this.customer = customer; 49 | this.orderDate = orderDate; 50 | } 51 | 52 | public Customer getCustomer() { 53 | return customer; 54 | } 55 | 56 | public Date getOrderDate() { 57 | return orderDate; 58 | } 59 | 60 | public List getItems() { 61 | return items; 62 | } 63 | 64 | public BigDecimal getTotal() { 65 | return getTotalWithoutShipping().add(getShippingCost()); 66 | } 67 | 68 | public BigDecimal getShippingCost() { 69 | if (isFreeShipping()) { 70 | return new BigDecimal("0"); 71 | } else { 72 | return SHIPPING_COSTS; 73 | } 74 | } 75 | 76 | public BigDecimal getTotalWithoutShipping() { 77 | BigDecimal total = new BigDecimal(0); 78 | for (Item item : items) { 79 | BigDecimal part = item.getSubTotal(); 80 | total = total.add(part); 81 | } 82 | return total; 83 | } 84 | 85 | // introduced for st3 and st4 as they can not compare values 86 | public boolean isFreeShipping() { 87 | return getTotalWithoutShipping().compareTo(FREE_SHIPPING_THRESHOLD) == 1; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /developer-cert-of-origin.txt: -------------------------------------------------------------------------------- 1 | As of 4.3.2, StringTemplate uses the Linux Foundation's Developer 2 | Certificate of Origin, DCO, version 1.1. See either 3 | https://developercertificate.org/ or the text below. 4 | 5 | Each commit requires a "signature", which is simple as 6 | using `-s` (not `-S`) to the git commit command: 7 | 8 | git commit -s -m 'This is my commit message' 9 | 10 | Github's pull request process enforces the sig and gives 11 | instructions on how to fix any commits that lack the sig. 12 | See https://github.com/apps/dco for more info. 13 | 14 | No signature is required in this file (unlike the 15 | previous StringTemplate contributor's certificate of origin.) 16 | 17 | ----- https://developercertificate.org/ ------ 18 | 19 | Developer Certificate of Origin 20 | Version 1.1 21 | 22 | Copyright (C) 2004, 2006 The Linux Foundation and its contributors. 23 | 24 | Everyone is permitted to copy and distribute verbatim copies of this 25 | license document, but changing it is not allowed. 26 | 27 | 28 | Developer's Certificate of Origin 1.1 29 | 30 | By making a contribution to this project, I certify that: 31 | 32 | (a) The contribution was created in whole or in part by me and I 33 | have the right to submit it under the open source license 34 | indicated in the file; or 35 | 36 | (b) The contribution is based upon previous work that, to the best 37 | of my knowledge, is covered under an appropriate open source 38 | license and I have the right under that license to submit that 39 | work with modifications, whether created in whole or in part 40 | by me, under the same open source license (unless I am 41 | permitted to submit under a different license), as indicated 42 | in the file; or 43 | 44 | (c) The contribution was provided directly to me by some other 45 | person who certified (a), (b) or (c) and I have not modified 46 | it. 47 | 48 | (d) I understand and agree that this project and the contribution 49 | are public and that a record of the contribution (including all 50 | personal information I submit with it, including my sign-off) is 51 | maintained indefinitely and may be redistributed consistent with 52 | this project or the open source license(s) involved. 53 | -------------------------------------------------------------------------------- /doc/adaptors.md: -------------------------------------------------------------------------------- 1 | # Model adaptors 2 | 3 | StringTemplate lets you access the properties of injected attributes, but only if they follow the JavaBeans naming pattern ("getters") or are publicly visible fields. 4 | This works well if you control the attribute class definitions, but falls apart for some models. 5 | Some models, though, don't follow the getter method naming convention and so template expressions cannot access properties. 6 | To get around this, we need a model adaptor that makes external models look like the kind StringTemplate needs. 7 | If object `o` is of type `T`, we register a model adaptor object, `a`, for `T` that converts property references on `o`. 8 | Given ``, StringTemplate will ask `a` to get the value of property `foo`. 9 | As with renderers, `a` is a suitable adaptor if "`o` is instance of `a`'s associated type". 10 | For the statically typed language ports, here are the interfaces: 11 | 12 | ```java 13 | public interface ModelAdaptor { 14 | Object getProperty(Interpreter interpreter, ST self, T model, Object property, String propertyName) 15 | throws STNoSuchPropertyException; 16 | } 17 | ``` 18 | 19 | |Property name type| 20 | |------------------| 21 | |Property names are usually strings but they don't have to be. For example, if `o` is a dictionary, the property could be of any key type. The string value of the property name is always passed to the renderer by StringTemplate.| 22 | 23 | ## Example 1 24 | 25 | ```java 26 | class UserAdaptor implements ModelAdaptor { 27 | public Object getProperty(Interpreter interpreter, ST self, User model, Object property, String propertyName) 28 | throws STNoSuchPropertyException 29 | { 30 | if ( propertyName.equals("id") ) return model.id; 31 | if ( propertyName.equals("name") ) return model.theName(); 32 | throw new STNoSuchPropertyException(null, "User."+propertyName); 33 | } 34 | } 35 | 36 | public static class User { 37 | private int id; // ST can't see; it's private 38 | private String name; 39 | public User(int id, String name) { this.id = id; this.name = name; } 40 | public String theName() { return name; } // doesn't follow naming conventions 41 | } 42 | ``` 43 | 44 | ```java 45 | String template = "foo(x) ::= \": \"\n"; 46 | STGroup g = new STGroupString(template); 47 | g.registerModelAdaptor(User.class, new UserAdaptor()); 48 | ST st = g.getInstanceOf("foo"); 49 | st.add("x", new User(100, "parrt")); 50 | String expecting = "100: parrt"; 51 | String result = st.render(); 52 | ``` 53 | 54 | |Inheriting from `ObjectModelAdaptor`| 55 | |---| 56 | |You can inherit your ModelAdaptor from `ObjectModelAdaptor` to leverage its ability to handle "normal" attributes. You can choose to override the results of any given property or to handle properties that would not normally be handled by the default `ObjectModelAdaptor`.| 57 | 58 | ## Example 2 59 | 60 | ```java 61 | class UserAdaptor extends ObjectModelAdaptor { 62 | public Object getProperty(Interpreter interpreter, ST self, User model, Object property, String propertyName) 63 | throws STNoSuchPropertyException 64 | { 65 | // intercept handling of "name" property and capitalize first character 66 | if ( propertyName.equals("name") ) return model.name.substring(0,1).toUpperCase()+model.name.substring(1); 67 | // respond to "description" property by composing desired result 68 | if ( propertyName.equals("description") ) return "User object with id:" + model.id; 69 | // let "id" be handled by ObjectModelAdaptor 70 | return super.getProperty(interpreter,self,model,property,propertyName); 71 | } 72 | } 73 | 74 | public static class User { 75 | public int id; // ST can see this and we'll let ObjectModelAdaptor handle it 76 | public String name; // ST can see this, but we'll override to capitalize 77 | public User(int id, String name) { this.id = id; this.name = name; } 78 | } 79 | ``` 80 | 81 | ```java 82 | String template = "foo(x) ::= \": ()\"\n"; 83 | STGroup g = new STGroupString(template); 84 | g.registerModelAdaptor(User.class, new UserAdaptor()); 85 | ST st = g.getInstanceOf("foo"); 86 | st.add("x", new User(100, "parrt")); 87 | String expecting = "100: Parrt (User object with id:100)"; 88 | String result = st.render(); 89 | ``` 90 | -------------------------------------------------------------------------------- /doc/bytecode.md: -------------------------------------------------------------------------------- 1 | # Template to Bytecode mapping 2 | 3 | ## Expressions 4 | 5 | |expression|bytecode| 6 | |----------|--------| 7 | |``|expr
write| 8 | |`<(expr)>`|expr
tostr
write| 9 | |``| expr
options
e1
store\_option o1-option-index
e2
store\_option o2-option-index
write\_opt
| 10 | |text| load\_str string-pool-index| 11 | |`true`| true| 12 | |`false`| false| 13 | |`a`| load\_local attribute-index ; if a is template argument| 14 | |`i`| load\_local attribute-index| 15 | |`i0`| load\_local attribute-index| 16 | |`a`| load\_attr a-string-pool-index| 17 | |`a.b`| load\_attr a ; from now now, a means its string index
load\_prop b| 18 | |`a.(b)`| load\_attr a
load\_attr b
load\_prop\_ind| 19 | |`t()`| new t,0 ; string pool index of t| 20 | |`super.r()`| super\_new region\_t\_r,0 ; region r in template t| 21 | |`t(e1,e2,e3)`| e1
e2
e3
new t,3| 22 | |`t(...)`| args
passthru t
new\_box\_args t| 23 | |`t(a1=e1,a2=e2,a3=e3)`| args
e1
store\_arg a1
e2
store\_arg a2
e3
store\_arg a3
new\_box\_args t| 24 | |`t(a1=e1,a2=e2,...)`| args
e1
store\_arg a1
e2
store\_arg a2
passthru t
new\_box\_args t| 25 | |`(expr)(args)`| expr
tostr
args
new\_ind num-args| 26 | |`a:t()`| load\_attr a
null
new t,1
map| 27 | |`a:t(x)`| load\_attr a
null
x
new t,2
map| 28 | |`a:t(),u()`| load\_attr a
null
new t,1
null
new u,1
rot\_map 2| 29 | |`a,b:t()`| load\_attr a
load\_attr b
null
null
new t,2
zip\_map 2| 30 | |`first(expr)`| expr
first ; predefined function| 31 | |`[`*a*`,`*b*`,`*c*`]`|list
a
add
b
add
c
add| 32 | 33 | ## Anonymous templates 34 | 35 | |expression|bytecode| 36 | |----------|--------| 37 | |`{t}`|new \_subN,0| 38 | |`a:{x | ...}`|load\_attr a
null
new \_subN, 1
map| 39 | |`a,b:{x,y | ...}`|load\_attr a
load\_attr b
null
null
new \_subN,2
zip\_map 2| 40 | 41 | ## If statements 42 | 43 | upon if, create 'end' label.
44 | upon else, create 'else' label. 45 | 46 | `t`: 47 | 48 | ``` 49 | load_attr a 50 | brf end 51 | t 52 | write 53 | end: 54 | ``` 55 | 56 | `tu`: 57 | 58 | ``` 59 | load_attr a 60 | brf else 61 | t 62 | write 63 | br end 64 | else: 65 | u 66 | write 67 | end: 68 | ``` 69 | 70 | `tuv`: 71 | 72 | ``` 73 | load_attr a 74 | brf lab1 75 | t 76 | write 77 | br end 78 | lab1: 79 | load_attr b 80 | brf lab2 81 | u 82 | write 83 | br end 84 | lab2: 85 | v 86 | write 87 | end: 88 | ``` 89 | 90 | `t`: 91 | 92 | ``` 93 | load_attr a 94 | not 95 | brf end 96 | t 97 | write 98 | end: 99 | ``` 100 | 101 | `a||b`: 102 | 103 | ``` 104 | load_attr a 105 | load_attr b 106 | or 107 | ``` 108 | 109 | `a&&b`: 110 | 111 | ``` 112 | load_attr a 113 | load_attr b 114 | and 115 | ``` 116 | 117 | ## Auto-indentation 118 | 119 | ``\n: 120 | 121 | ``` 122 | expr 123 | write 124 | newline 125 | ``` 126 | 127 | \n\t``: 128 | 129 | ``` 130 | newline 131 | indent "\t" 132 | expr 133 | write 134 | dedent 135 | ``` 136 | 137 | ## Size limitations 138 | 139 | I use unsigned shorts not ints for the bytecode operands and addresses. This limits size of templates but not the output size. In single template, you can have only 64k of: 140 | 141 | * attributes 142 | * unique property name refs 143 | * unique template name refs 144 | * options (there are only about 5 now) 145 | * lists or template names in a map/iteration operation 146 | * bytecodes (short addressed) 147 | * chunks of text outside of expressions. effectively same thing as saying can have at most 64k / n expressions where n is avg size of bytecode to emit an expression. E.g., 3 bytes to write a chunk of text. 148 | -------------------------------------------------------------------------------- /doc/expr-options.md: -------------------------------------------------------------------------------- 1 | # Expression options 2 | 3 | There are 5 expression options at the moment: 4 | 5 | * `separator`. Specify text to be emitted between multiple values emitted for a single expression. For example, given a list of names, `` spits them out right next to each other. Using a separator can put a comma in between automatically: ``. This is by far the most commonly used option. You can use `separator={...}` too. 6 | * `format`. Used in conjunction with the `AttributeRenderer` interface, which describes an object that knows how to format or otherwise render an object appropriately. The `toString(Object,String,Locale)` method is used when the user uses the format option: `$o; format="f"$`. Renderers check the `formatName` and apply the appropriate formatting. If the format string passed to the renderer is not recognized, then it should simply call `toString()` on the attribute. 7 | 8 | This option is very effective for locale changes and for choosing the display characteristics of an object in the template rather than encode. 9 | 10 | Each template may have a renderer for each object type or can default to the group's renderer or the super group's renderer if the group doesn't have one. See [Object rendering](renderers.md#format). 11 | 12 | * `null`. Emit a special value for each null element. For example, given `values=[9,6,null,2,null]`, 13 | ``` 14 | $values; null="-1", separator=", "$ 15 | ``` 16 | emits: 17 | ``` 18 | 9, 6, -1, 2, -1 19 | ``` 20 | See [Expressions](templates.md#expression-literals). 21 | * `wrap`. Tell ST that it is okay to wrapped lines to get too long. The wrap option may also take an argument but it's default is simply a newline string. You must specify an integer width using the `render(int)` method to get ST to actually wrap expressions modified with this option. For example, given a list of names and expression ``, a call to `render(72)` will emit the names until it surpasses 72 characters in with and then inserts a new line and begins emitting names again. Naturally this can be used in conjunction with the `separator` option. ST never breaks in between a real element and the separator; the wrap occurs only after a separator. See [Automatic line wrapping](wrapping.md). 22 | * `anchor`. Line up all wrapped lines with left edge of expression when wrapping. Default is `anchor="true"` (any non-null value means anchor). See [Automatic line wrapping](wrapping.md). 23 | 24 | The option values are all full expressions, which can include references to templates, anonymous templates, and so on. For example here is a separator that invokes another template: 25 | ``` 26 | $name; separator=bulletSeparator(foo=" ")+" "$ 27 | ``` 28 | 29 | The wrap and anchor options are implemented via the [STWriter class](https://github.com/antlr/stringtemplate4/blob/master/src/org/stringtemplate/v4/STWriter.java). The others are handled during interpretation by ST. Well, the filters also are notified that a separator vs regular string is coming out to prevent newlines between real elements and separators. 30 | -------------------------------------------------------------------------------- /doc/faq/index.md: -------------------------------------------------------------------------------- 1 | # Frequently-Asked Questions (FAQ) 2 | 3 | This is the main landing page for the StringTemplate 4 FAQ. The links below will take you to the appropriate file containing all answers for that subcategory. 4 | 5 | *To add to or improve this FAQ, [fork](https://help.github.com/articles/fork-a-repo/) the [antlr/stringtemplate4 repo](https://github.com/antlr/stringtemplate4) then update this `doc/faq/index.md` or file(s) in that directory. Submit a [pull request](https://help.github.com/articles/creating-a-pull-request/) to get your changes incorporated into the main repository. Do not mix code and FAQ updates in the sample pull request.* **You must sign the contributors.txt certificate of origin with your pull request if you've not done so before.** 6 | 7 | ## Getting Started 8 | 9 | * ok, so somebody needs to help build this faq ;) 10 | 11 | ## Object models 12 | 13 | * [Altering property lookup for Scala](../scala-model-adaptor.md) 14 | 15 | -------------------------------------------------------------------------------- /doc/images/AST.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/doc/images/AST.png -------------------------------------------------------------------------------- /doc/images/attrstack.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/doc/images/attrstack.gif -------------------------------------------------------------------------------- /doc/images/bytecode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/doc/images/bytecode.png -------------------------------------------------------------------------------- /doc/images/outputclick.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/doc/images/outputclick.gif -------------------------------------------------------------------------------- /doc/images/startup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/doc/images/startup.gif -------------------------------------------------------------------------------- /doc/images/trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/doc/images/trace.png -------------------------------------------------------------------------------- /doc/indent.md: -------------------------------------------------------------------------------- 1 | # Auto-indentation 2 | 3 | Properly-indented text is a very desirable generation outcome, but it is often difficult to achieve--particularly when the programmer must do this manually. StringTemplate automatically and naturally indents output by tracking the nesting level of all attribute expression evaluations and associated whitespace prefixes. For example, in the following slist template, all output generated from the `` expression will be indented by two spaces because the expression itself is indented. 4 | 5 | ``` 6 | slist(statements) ::= << 7 | { 8 | 9 | } 10 | >> 11 | ``` 12 | 13 | If one of the statement attributes is itself an slist then those enclosed statements will be indented four spaces. The auto-indentation mechanism is actually an implementation of an output filter that programmers may override to tweak text right before it is written. 14 | 15 | StringTemplate performs auto indentation as the text gets emitted during rendering using class AutoIndentWriter, which is an implementation of a generic STWriter (interface, protocol, or nothing depending on the port implementation language). 16 | 17 | To turn off auto indentation, tell StringTemplate to use NoIndentWriter by invoking the write(writer) method instead of the usual render method: 18 | 19 | ```java 20 | StringWriter sw = new StringWriter(); 21 | NoIndentWriter w = new NoIndentWriter(sw); 22 | st.write(w); // same as render() except with a different writer 23 | String result = sw.toString(); 24 | ``` 25 | -------------------------------------------------------------------------------- /doc/index.md: -------------------------------------------------------------------------------- 1 | # StringTemplate 4 Documentation 2 | 3 | Please check [Frequently asked questions (FAQ)](faq/index.md) before asking questions on stackoverflow or StringTemplate-discussion list. 4 | 5 | Notes: To add to or improve this documentation, fork the antlr/stringtemplate4 repo then update this `doc/index.md` or file(s) in that directory. Submit a pull request to get your changes incorporated into the main repository. Do not mix code and documentation updates in the same pull request. You must sign the contributors.txt certificate of origin with your pull request if you've not done so before. 6 | 7 | ## Installation 8 | 9 | * [Java](java.md) 10 | * [C#](https://github.com/antlr/antlrcs) 11 | * [JavaScript--not stable](https://github.com/jsnyders/StringTemplate-js) 12 | * Python 13 | * [Objective-C](https://github.com/muggins/ST4-ObjC2.0-Runtime) 14 | 15 | ## Introductory material 16 | 17 | * [Introduction](introduction.md) 18 | * [StringTemplate cheat sheet](cheatsheet.md) 19 | * [Motivation and philosophy](motivation.md) 20 | 21 | ## Groups 22 | 23 | * [Group file syntax](groups.md) 24 | * [Group inheritance](inheritance.md) 25 | * [Template regions](regions.md) 26 | 27 | ## Templates 28 | 29 | * [Literals](templates.md#literals) 30 | * [Expressions](templates.md#expressions) 31 | * [Template includes](templates.md#includes) 32 | * [Expression options](expr-options.md) 33 | * [Conditionals](templates.md#conditionals) 34 | * [Anonymous templates](templates.md#subtemplates) 35 | * [Map operations](templates.md#map) 36 | * [Functions](templates.md#functions) 37 | * [Lazy evaluation](templates.md#lazy) 38 | * [Missing and null attribute evaluation](null-vs-empty.md) 39 | 40 | ## Whitespace and formatting 41 | 42 | * [Auto-indentation](indent.md) 43 | * [Automatic line wrapping](wrapping.md) 44 | 45 | ## Customizing StringTemplate behavior 46 | 47 | * [Error listeners](listeners.md) 48 | * [Renderers](renderers.md) 49 | * [Model adaptors](adaptors.md) 50 | 51 | ## Debugging 52 | 53 | * [StringTemplate Inspector GUI](inspector.md) 54 | 55 | ## Misc 56 | 57 | * [Template to Bytecode mapping](bytecode.md) 58 | * [Differences between v3 and v4](3to4.md) 59 | * [Releasing ST4](releasing-st4.md) 60 | 61 | ## Release Notes 62 | 63 | For just 4.0.0 - 4.0.7. Now look at [github for release notes](https://github.com/antlr/stringtemplate4/releases). 64 | 65 | * [4.0 Release Notes](release-notes/4.0.md) 66 | * [4.0.1 Release Notes](release-notes/4.0.1.md) 67 | * [4.0.2 Release Notes](release-notes/4.0.2.md) 68 | * [4.0.3 Release Notes](release-notes/4.0.3.md) 69 | * [4.0.4 Release Notes](release-notes/4.0.4.md) 70 | * [4.0.5 Release Notes](release-notes/4.0.5.md) 71 | * [4.0.6 Release Notes](release-notes/4.0.6.md) 72 | * [4.0.7 Release Notes](release-notes/4.0.7.md) 73 | -------------------------------------------------------------------------------- /doc/java.md: -------------------------------------------------------------------------------- 1 | # Using StringTemplate with Java 2 | 3 | ## Installation 4 | 5 | All you need to do is get the StringTemplate jar into your CLASSPATH as well as its dependent ANTLR jar. [Download Java StringTemplate 4.3.4 binary jar](https://www.stringtemplate.org/download.html) and put into your favorite lib directory such as `/usr/local/lib` on UNIX. Add to your CLASSPATH. On UNIX that looks like 6 | 7 | ```bash 8 | $ export CLASSPATH="/usr/local/lib/ST-4.3.4.jar:$CLASSPATH" 9 | ``` 10 | 11 | Java will now see all the libraries necessary to execute ST stuff. Also, check out the [StringTemplate repo](https://github.com/antlr/stringtemplate4). 12 | 13 | ## Hello world 14 | 15 | Here's a simple, complete program to test your installation. 16 | 17 | ```java 18 | import org.stringtemplate.v4.*; 19 | 20 | public class Hello { 21 | public static void main(String[] args) { 22 | ST hello = new ST("Hello, "); 23 | hello.add("name", "World"); 24 | System.out.println(hello.render()); 25 | } 26 | } 27 | ``` 28 | 29 | Here's how to compile and run it from the command line: 30 | 31 | ```bash 32 | /tmp $ javac Hello.java 33 | /tmp $ java Hello 34 | Hello, World 35 | ``` 36 | 37 | ## Loading template groups 38 | 39 | ### Group files 40 | 41 | To load a group file, use the STGroupFile subclass of STGroup: 42 | 43 | ```java 44 | //load file name 45 | STGroup g = new STGroupFile("test.stg"); 46 | ``` 47 | 48 | This tells StringTemplate to look in the current directory for test.stg. If not found, STGroupFile looks in the CLASSPATH. You can also use a relative path. The following looks for subdirectory templates in the current directory or, if not found, in a directory of the CLASSPATH. 49 | 50 | ```java 51 | // load relative file name 52 | STGroup g = new STGroupFile("templates/test.stg"); 53 | ``` 54 | 55 | You can also use a fully qualified name: 56 | 57 | ``` 58 | // load fully qualified file name 59 | STGroup g = new STGroupFile("/usr/local/share/templates/test.stg"); 60 | ``` 61 | 62 | ### Group directories 63 | 64 | Group files, described above, are like directories of templates packed together into a single file (like text-based jars). To load templates stored within a directory as separate .st files, use STGroupDir instances: 65 | 66 | ```java 67 | // load relative directory of templates 68 | STGroup g = new STGroupDir("templates"); 69 | ``` 70 | 71 | If templates is not found in the current directory, StringTemplate looks in the CLASSPATH. Or, you can specify the exact fully qualified name: 72 | 73 | ``` 74 | // load fully qualified directory of templates 75 | STGroup g = new STGroupDir("/usr/local/share/templates"); 76 | ``` 77 | 78 | ### Group strings 79 | 80 | For small groups, it sometimes makes sense to use a string within Java code: 81 | 82 | ```java 83 | String g = 84 | "a(x) ::= <>\n"+ 85 | "b() ::= <>\n"; 86 | STGroup group = new STGroupString(g); 87 | ST st = group.getInstanceOf("a"); 88 | String expected = "foo"; 89 | String result = st.render(); 90 | assertEquals(expected, result); 91 | ``` 92 | 93 | ### URL/URI/Path quagmire 94 | 95 | Make sure to pass either a valid file name as a string or a valid URL object. File/dir names are relative like `foo.stg`, `foo`, `org/foo/templates/main.stg`, or `org/foo/templates` OR they are absolute like `/tmp/foo`. This is incorrect: 96 | 97 | ``` 98 | // BAD 99 | STGroup modelSTG = new STGroupFile(url.getPath()); 100 | ``` 101 | 102 | because it yields a file path to a jar and then inside: 103 | 104 | ``` 105 | file:/somedirectory/AJARFILE.jar!/foo/main.stg 106 | ``` 107 | 108 | This isn't a valid file system identifier. To use URL stuff, pass in a URL object not a string. See [Converting between URLs and Filesystem Paths](https://maven.apache.org/plugin-developers/common-bugs.html#Converting_between_URLs_and_Filesystem_Paths) for more information. 109 | 110 | ## API documentation 111 | 112 | [Java API](https://www.stringtemplate.org/api/index.html) 113 | -------------------------------------------------------------------------------- /doc/listeners.md: -------------------------------------------------------------------------------- 1 | # Error listeners 2 | 3 | To get notified when StringTemplate detects a problem during compilation of templates or, at runtime, when interpreting templates, provide StringTemplate with an error listener. The default listener sends messages to standard error/output, which are generally not what you want in a larger application. Here are the listener definitions in the various ports: 4 | 5 | ```java 6 | public interface STErrorListener { 7 | public void compileTimeError(STMessage msg); 8 | public void runTimeError(STMessage msg); 9 | public void IOError(STMessage msg); 10 | public void internalError(STMessage msg); 11 | } 12 | ``` 13 | 14 | The STMessage instances include information such as the ErrorType and any arguments. Evaluating the message to a string, as appropriate for the port language, yields a suitable message or you can pull it apart yourself. 15 | 16 | You can specify a listener per group or per execution of the interpreter. To catch compile errors, make sure to set the listener before you trigger an action that processes the group file or loads templates: 17 | 18 | ```java 19 | // listener per group 20 | STGroup g = ...; 21 | g.setListener(myListener); 22 | g.getInstance("foo"); 23 | ... 24 | ``` 25 | 26 | If you want to track interpretation errors with a particular listener, use the appropriate ST.write() method: 27 | 28 | ```java 29 | // listener per rendering 30 | STGroup g = ...; 31 | ST st = g.getInstance("foo"); 32 | st.write(myWriter, myListener); 33 | ``` 34 | 35 | Imported groups automatically use the listener of the importing group. 36 | -------------------------------------------------------------------------------- /doc/null-vs-empty-previous.md: -------------------------------------------------------------------------------- 1 | # null vs missing vs empty vs nonexistent in ST 4 2 | 3 | *October 15, 2009* 4 | 5 | ## Part 1: Null-valued attributes 6 | 7 | Let's consider values inside arrays. If names=`{"Tom", null, null, "Ter"}`, what should we get here: 8 | 9 | ``` 10 | 11 | ``` 12 | 13 | or here 14 | 15 | ``` 16 | 17 | ``` 18 | 19 | My preference would be: TomTer and Tom, Ter. That is what v3 does now. We recently introduced the null option so we can say: 20 | 21 | ``` 22 | 23 | ``` 24 | 25 | to get `foo` instead of an missing element when `names[i]` is null. 26 | 27 | HOWEVER, you cannot set an attribute to null. So, if instead of passing the list, we set them individually, we get a different answer. 28 | 29 | ```java 30 | st.add(names, "Tom"); 31 | st.add(names, null); // do nothing 32 | st.add(names, null); // do-nothing 33 | st.add(names, "Ter"); 34 | ``` 35 | 36 | We get a list of {"Tom", "Ter"} sent to ST previously. All null values are ignored by add (actually called setAttribute in v3). The output would be "TomTer" even with null option. ooops. 37 | 38 | I'm proposing that we allow null valued attributes in v4 to normalize the handling of single and multivalued attributes. In other words null and a list of one element with null in it should be the same. 39 | 40 | ## Part 2. Missing versus null versus non-null 41 | 42 | In v4, I want to clearly identify the exact meetings of: missing versus null versus non-null means. Consider what this means: 43 | 44 | ``` 45 | 46 | ``` 47 | 48 | There are three situations: 49 | 50 | 1. name doesn't exist as an attribute 51 | 1. name exists but has no value (it's null) 52 | 1. name exists and has a value 53 | 54 | Similarly, what about properties (using getProp or isProp or the actual field name): 55 | 56 | ``` 57 | 58 | ``` 59 | 60 | again, there are three situations: 61 | 62 | 1. name doesn't exist as a property of the user object 63 | 1. name exists but has no value (it's null) 64 | 1. name exists and has a value 65 | 66 | Currently, is no problem if it doesn't exist, but throws an exception if name is not a valid property. The reason I did this was that it's okay to have an attribute you don't set but accessing a nonexistent field is most likely a programming error. (I think I'm going to set up a list of flags you can set in order to throw exceptions upon certain conditions, otherwise ST will be fairly permissive). 67 | 68 | Anyway, given that we are going to allow null-valued attributes, plain old could be missing, could be null, or could have a value. Given this, what does the following yield? 69 | 70 | ``` 71 | 72 | ``` 73 | 74 | Personally, I think it should be: 75 | 76 | 1. EMPTY if name doesn't exist as an attribute 77 | 1. foo if name exists but has no value (it's null) 78 | 1. name's value if name exists and has a value 79 | 80 | So null option literally means the attribute exists but is null (has no value). If the attribute is simply missing, null option has no effect. 81 | 82 | This is then consistent with lists and arrays. null applies to all null-valued elements because they exist physically in the list, they just have no value. 83 | 84 | Ok, I think I just convinced myself that we'll allow null-valued attributes and that we will treat them differently than missing attributes. Secondly, `null` option only applies to present but null-valued attributes. 85 | -------------------------------------------------------------------------------- /doc/release-notes/4.0.2.md: -------------------------------------------------------------------------------- 1 | # 4.0.2 Release Notes 2 | 3 | This is a bug fix release. Download ST v4 here 4 | 5 | 4.0.2 – May 3, 2011 6 | 7 | * Backing out change from 4/17; don't want Serializable implementation. 8 | * Improved error msg for out of order required parameters (after optional ones) 9 | 10 | April 26, 2011 11 | 12 | * rest() stripped nulls, which it shouldn't. Was inconsistent with trunc(), etc... 13 | 14 | April 21, 2011 15 | 16 | * Made STGroup.iterateAcrossValues an instance variable not static. 17 | That needed a change to convertAnythingIteratableToIterator, etc.. 18 | to non-static. 19 | * Removed STDump as unneeded; Use STViz. 20 | 21 | April 17, 2011 22 | 23 | * Added implements Serializable to ST, STGroup. 24 | 25 | April 16, 2011 26 | 27 | * Made compatible with Java 1.5; removed Arrays.copyOf() ref. 28 | * Updated ANT build to ref ant lib dir not /usr/local/lib/ 29 | 30 | April 11, 2011 31 | 32 | * Dictionaries weren't inherited. Added unit test. 33 | -------------------------------------------------------------------------------- /doc/release-notes/4.0.3.md: -------------------------------------------------------------------------------- 1 | # 4.0.3 Release Notes 2 | 3 | June 21, 2011 4 | 5 | This is a bug fix release, many done by Udo Borkowski. Download ST v4 here 6 | 7 | * Major overhaul of template names: 8 | * '/' allowed as starting ID letter like 9 | * getInstanceOf names must be fully qualified. If you don't put / on 10 | front, one is added for you. 11 | * template refs in expr are relative to location of surrounding template 12 | unless prefixed with /. In that case they are relative to root of group. 13 | * import statement no longer allows fully qualified file name. 14 | * Changed all unit tests to use fully qualified names and see results that way. 15 | * Also note that import statement no longer interprets fully qualified path to location on disk. A fully qualified path is now interpreted as relative to group root to be consistent. 16 | 17 | * {} wasn't allowed as a template 18 | * STGroup.unload() calls unload() on each group in the imports list 19 | instead of clearing the list. (Thanks to Sam...wait, did Udo already 20 | try this?) 21 | * STRuntimeMessage got NPE upon ST.impl == null 22 | * ctor ST() is protected; not for users. bad users! 23 | * Removed warning (access static member through instance) 24 | * Fixed and added tests 25 | * Fixed test case for <\n> to handle different line.separator sizes 26 | * BUG: On Windows wrapped lines are separated with \r\r\n 27 | * made tests run on Windows and non-US locales 28 | * STGroupDir.load(String name) no longer checks for (parent) group file when name specifies no parent (no '/') 29 | * unload in STGroup now also unloads the import relationships 30 | * Fixed test testRendererWithPredefinedFormat2 to also work in non-PDT timezones 31 | * Fixed tests testArg1, testArg2 in TestGroupSyntaxErrors 32 | * Fixed "URI is not hierarchical" issue when STGroupFile is imported from jar file 33 | * Added getTemplateNames to STGroup 34 | * passthru() didn't watch for empty formal args 35 | * fixed bug raising a NullPointerException when a formalArg's default value has a syntax error. 36 | Example: main(a={(<"")>}) ::= "" 37 | * STGroupFile.getName() returns group name also for imported groups (was null before). 38 | 39 | -------------------------------------------------------------------------------- /doc/release-notes/4.0.4.md: -------------------------------------------------------------------------------- 1 | # 4.0.4 Release Notes 2 | 3 | July 18, 2011 4 | 5 | This is a bug fix release with a new "delimiters" group file feature. Download ST v4 here 6 | 7 | New feature: 8 | 9 | * Added `delimiters "<", ">"` notation to group file. 10 | 11 | Bug fixes: 12 | 13 | * added "get import list" method. 14 | * added methods to allow deep vs shallow setting of renderers; interp always 15 | asks native group defining template for the renderer. 16 | * STGroup.getInstanceOf was not auto-adding "/" to front if none was present 17 | * Updated javadoc on getAttributeRenderer() 18 | * Updated javadoc on unload/importTemplates in STGroup() (ub) 19 | * Added test case for unload of groups specified in group file imports. (ub) 20 | * STGroup.unload() now removes imports that were specified in the group 21 | file, but only calls unload() on templates that were explicitly added 22 | in the program. Resolves both Sam's and Udo's concerns. 23 | * subtemplates {...} in subdirectories didn't work. 24 | 25 | -------------------------------------------------------------------------------- /doc/release-notes/4.0.5.md: -------------------------------------------------------------------------------- 1 | # 4.0.5 Release Notes 2 | 3 | February 8, 2012 4 | 5 | This is a bug fix release with a new STRawGroupDir class. Download ST v4 here 6 | 7 | New feature: 8 | 9 | * Added STRawGroupDir that expects pure templates in .st files not template defs 10 | with headers as is usually the case. So use $name$ not 11 | * 12 | * foo(name) ::= "$name" 13 | 14 | This makes it much easier to use raw HTML files, for example, with ST. 15 | Bug fixes: 16 | * STLexer.tokens was missing from src build 17 | * synchronized object model adaptor 18 | * import is now considered illegal in group files embedded in STGroupDirs; they lead to trouble and make no sense. 19 | * Fixed Misc.newline issue in test code (Udo) 20 | 21 | -------------------------------------------------------------------------------- /doc/release-notes/4.0.6.md: -------------------------------------------------------------------------------- 1 | # 4.0.6 Release Notes 2 | 3 | September 26, 2012 4 | 5 | This is a bug fix release. (Download ST v4 here) 6 | 7 | * STRawGroupDir problem and ST("template") issue. When there are no formal args for template t and you map t across some values, t implicitly gets arg "it". E.g., `$names:bold()$` and bold as `$it$`. 8 | * Fixed https://github.com/antlr/stringtemplate4/issues/5 9 | * Made fields in the error messages public 10 | -------------------------------------------------------------------------------- /doc/release-notes/4.0.7.md: -------------------------------------------------------------------------------- 1 | # 4.0.7 Release Notes 2 | 3 | ## Improvements 4 | 5 | * Improved error location reporting 6 | * Allow [] as a dictionary value, resolves antlr/stringtemplate4#33 7 | * Several STViz updates: 8 | * Highlight template subexpressions and literal text responsible for output 9 | * Gray out hidden (inherited+aliased) attributes 10 | * Highlight user-instanced templates in bold 11 | 12 | ## Bug fixes 13 | 14 | * Escapes: `>\>` means `>>` inside of `<<...>>`. 15 | * Escapes: `\>>` means `>>` inside of `<<...>>` unless at end like `<<...\>>>>`. In that case, use `<%..>>%>` instead. 16 | * Added warning about: "Missing newline after newline escape <\\>" 17 | * `%\>` is the escape to avoid end of string 18 | * Fix issues with bytecode to source mapping 19 | * Fix several STViz bugs 20 | * Fix several unit tests 21 | * Explicit InstanceScope tracking in the interpreter 22 | * throw exceptionWhen the attribute name is no to be consistent with the 23 | * other check for '.' in the name. 24 | * Allow [] as a default value for formal arguments (fixes antlr/stringtemplate4#20) 25 | * Add method STViz.waitForClose() 26 | * Specify -Dtest.interactive to have STViz tests leave the window open for the user 27 | * Don't cache the STNoSuchPropertyException and STNoSuchAttributeException instances. 28 | * Add ErrorType.NO_SUCH_ATTRIBUTE_PASS_THROUGH, reported on where foo contains a parameter with no default value and no matching attribute exists in the surrounding scope. 29 | * Improved message when reporting ErrorType.NO_SUCH_PROPERTY. 30 | * DateRenderer and StringRenderer now use the provided locale (fixes antlr/stringtemplate4#11) 31 | * Fixes for handling of arrays (fixes antlr/stringtemplate4#12 and other unreported issues) 32 | * Try to load template file (.st) if group file (.stg) failed with IOException (fixes antlr/stringtemplate4#14) 33 | * Add STGroup.GROUP_FILE_EXTENSION and STGroup.TEMPLATE_FILE_EXTENSION 34 | * Updated documentation, code cleanup 35 | -------------------------------------------------------------------------------- /doc/renderers.md: -------------------------------------------------------------------------------- 1 | # Attribute Renderers 2 | 3 | The atomic element of a template is a simple attribute (object) that is rendered to text by its the appropriate string evaluation method for the port's language (toString, ToString, `_str_`, ...). 4 | For example, an integer object is converted to text as a sequence of characters representing the numeric value. 5 | What if we want commas to separate the 1000's places like 1,000,000? 6 | What if we want commas and sometimes periods depending on the locale? 7 | For more, see [The Internationalization and Localization of Web Applications](https://www.cs.usfca.edu/~parrt/papers/i18n.pdf). 8 | 9 | StringTemplate lets you register objects that know how to format or otherwise render attributes to text appropriately. 10 | There is one registered renderer per type per group. 11 | In the statically type port languages like Java and C#, we use an interface to describe these renderers: 12 | 13 | ``` 14 | public interface AttributeRenderer { 15 | public String toString(T value, String formatString, Locale locale); 16 | } 17 | ``` 18 | 19 | To render expression ``, StringTemplate looks for a renderer associated with the object type of `e`, say, *t*. 20 | If *t* is associated with a registered renderer, *r*, it is suitable and StringTemplate invokes the renderer method: 21 | 22 | | Expression syntax | How interpreter invokes renderer r | 23 | |-------------------|------------------------------------| 24 | | `` | `r.toString(e, null, locale)` | 25 | | `` | `r.toString(e, "f", locale)` | 26 | 27 | StringTemplate supplies either the default locale, or whatever locale was set by the programmer. 28 | If the format string passed to the renderer is not recognized then the renderer should simply call the usual string evaluation method. 29 | 30 | To register a renderer, we tell the group to associate an object type with a renderer object. 31 | Here's an example that tells StringTemplate to render numbers with an instance of NumberRenderer using the Polish locale: 32 | 33 | ```java 34 | String template = 35 | "foo(x,y) ::= << >>\n"; 36 | STGroup g = new STGroupString(template); 37 | g.registerRenderer(Number.class, new NumberRenderer()); 38 | ST st = group.getInstanceOf("foo"); 39 | st.add("x", -2100); 40 | st.add("y", 3.14159); 41 | String result = st.render(new Locale("pl")); 42 | // resulted is " -2 100 3,142 " since Polish uses ' ' for ',' and ',' for '.' 43 | ``` 44 | 45 | **StringTemplate matches the types of expressions with the renderers using the "is instance of" relationship.** 46 | As in this example, we registered a renderer for numbers and StringTemplate used it for subclasses such as integers and floating-point numbers. 47 | Here's the renderer definition: 48 | 49 | ```java 50 | /** Works with Byte, Short, Integer, Long, and BigInteger as well as 51 | * Float, Double, and BigDecimal. You pass in a format string suitable 52 | * for Formatter object: 53 | * 54 | * https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html 55 | * 56 | * For example, "%10d" emits a number as a decimal int padding to 10 char. 57 | * This can even do long to date conversions using the format string. 58 | */ 59 | public class NumberRenderer implements AttributeRenderer { 60 | public String toString(Number o, String formatString, Locale locale) { 61 | if ( formatString==null ) return o.toString(); 62 | Formatter f = new Formatter(locale); 63 | f.format(formatString, o); 64 | return f.toString(); 65 | } 66 | } 67 | ``` 68 | 69 | You can register this renderer for `Number` or any subtype of it, but not unrelated types: 70 | 71 | ```java 72 | STGroup g = ...; 73 | g.registerRenderer(Number.class, new NumberRenderer()); // ok 74 | g.registerRenderer(Integer.class, new NumberRenderer()); // ok 75 | g.registerRenderer(Double.class, new NumberRenderer()); // ok 76 | g.registerRenderer(String.class, new NumberRenderer()); // error 77 | ``` 78 | 79 | StringTemplate comes with three predefined renderers: `DateRenderer`, `StringRenderer`, and `NumberRenderer`. 80 | -------------------------------------------------------------------------------- /historical-contributors-agreement.txt: -------------------------------------------------------------------------------- 1 | ANTLR Project Contributors Certification of Origin and Rights 2 | 3 | All contributors to StringTemplate v4 must formally agree to abide by this 4 | certificate of origin by signing on the bottom with their github 5 | userid, full name, email address (you can obscure your e-mail, but it 6 | must be computable by human), and date. 7 | 8 | By signing this agreement, you are warranting and representing that 9 | you have the right to release code contributions or other content free 10 | of any obligations to third parties and are granting Terence Parr and 11 | ANTLR project contributors, henceforth referred to as The ANTLR 12 | Project, a license to incorporate it into The ANTLR Project tools 13 | (such as ANTLRWorks and StringTemplate) or related works under the BSD 14 | license. You understand that The ANTLR Project may or may not 15 | incorporate your contribution and you warrant and represent the 16 | following: 17 | 18 | 1. I am the creator of all my contributions. I am the author of all 19 | contributed work submitted and further warrant and represent that 20 | such work is my original creation and I have the right to license 21 | it to The ANTLR Project for release under the 3-clause BSD 22 | license. I hereby grant The ANTLR Project a nonexclusive, 23 | irrevocable, royalty-free, worldwide license to reproduce, 24 | distribute, prepare derivative works, and otherwise use this 25 | contribution as part of the ANTLR project, associated 26 | documentation, books, and tools at no cost to The ANTLR Project. 27 | 28 | 2. I have the right to submit. This submission does not violate the 29 | rights of any person or entity and that I have legal authority over 30 | this submission and to make this certification. 31 | 32 | 3. If I violate another's rights, liability lies with me. I agree to 33 | defend, indemnify, and hold The ANTLR Project and ANTLR users 34 | harmless from any claim or demand, including reasonable attorney 35 | fees, made by any third party due to or arising out of my violation 36 | of these terms and conditions or my violation of the rights of 37 | another person or entity. 38 | 39 | 4. I understand and agree that this project and the contribution are 40 | public and that a record of the contribution (including all 41 | personal information I submit with it, including my sign-off) is 42 | maintained indefinitely and may be redistributed consistent with 43 | this project or the open source license indicated in the file. 44 | 45 | I have read this agreement and do so certify by adding my signoff to 46 | the end of the following contributors list. 47 | 48 | CONTRIBUTORS: 49 | 50 | YYYY/MM/DD, github id, Full name, email 51 | 2012/07/12, parrt, Terence Parr, parrt@antlr.org 52 | 2012/08/13, pgelinas, Pascal Gélinas, pascal.gelinas@polymtl.ca 53 | 2015/05/28, jsnyders, John Snyders, jjsnyders at rcn.com 54 | 2015/12/07, sharwell, Sam Harwell, sam@tunnelvisionlabs.com 55 | 2016/08/23, BurtHarris, Burt Harris, Burt_Harris.github@azxs.33mail.com 56 | 2016/07/18, jeff5, Jeff Allen, ja.py@farowl.co.uk 57 | 2018/11/06, drealeed , Drea Leed, drealeed2@yahoo.com 58 | 2018/11/08, leonlee, Leon Lee, blackicebird@gmail.com 59 | 2018/11/11, adityanarkar, Aditya Narkar, aditya.narkar25@gmail.com 60 | 2019/01/21, cfraizer, Colin Frazier, colin.fraizer@gmail.com 61 | 2019/09/09, seanabraham, Sean Abraham, Sean.A208@gmail.com 62 | 2019/12/22, Clashsoft, Adrian Kunz, clashsoft at hotmail dot com 63 | 2020/04/21, steinybot, Jason Pickens, jasonpickensnz@gmail.com 64 | 2020/07/23, mma-tapad, Marvin Ma, marvin.ma@tapad.com 65 | 2020/07/23, zjzsliyang, Yang Li, zjzsliyang@gmail.com 66 | 2020/07/23, jamesmahler2, James Mahler, jmahler@andrew.cmu.edu 67 | 2020/07/23, dyuan0226, David Yuan, dyuan1@andrew.cmu.edu 68 | 2020/09/06, peteruhnak, Peter Uhnak, i.uhnak@gmail.com 69 | 2020/09/16, Dvoreth, Jarmila Emanuela Panwitz, jaremapan@gmail.com 70 | 2020/10/01, beccagaspard, Becca Gaspard, beccagaspard at gmail dot com 71 | 2021/11/10, StephanRichter, Stephan Richter, postbox: s.richter domain: srsoftware.de 72 | -------------------------------------------------------------------------------- /scripts/github_release_notes.py: -------------------------------------------------------------------------------- 1 | # pip install PyGithub 2 | # Get github issues / PR for a release 3 | # Exec with "python github_release_notes.py YOUR_GITHUB_API_ACCESS_TOKEN 4.1" 4 | 5 | from github import Github 6 | from collections import Counter 7 | import sys 8 | 9 | TOKEN=sys.argv[1] 10 | MILESTONE=sys.argv[2] 11 | g = Github(login_or_token=TOKEN) 12 | 13 | # Then play with your Github objects: 14 | org = g.get_organization("antlr") 15 | repo = org.get_repo("stringtemplate4") 16 | milestone = [x for x in repo.get_milestones() if x.title==MILESTONE] 17 | milestone = milestone[0] 18 | 19 | issues = repo.get_issues(state="closed", milestone=milestone, sort="created", direction="desc") 20 | 21 | # dump bugs fixed 22 | print() 23 | print("## Issues fixed") 24 | for x in issues: 25 | labels = [l.name for l in x.labels] 26 | if x.pull_request is None and not ("type:improvement" in labels or "type:feature" in labels): 27 | print("* [%s](%s) (%s)" % (x.title, x.html_url, ", ".join([l.name for l in x.labels]))) 28 | 29 | 30 | print() 31 | # dump improvements closed for this release (issues or pulls) 32 | print("## Improvements, features") 33 | for x in issues: 34 | labels = [l.name for l in x.labels] 35 | if ("type:improvement" in labels or "type:feature" in labels): 36 | print("* [%s](%s) (%s)" % (x.title, x.html_url, ", ".join(labels))) 37 | 38 | print() 39 | 40 | 41 | # dump PRs closed for this release 42 | print("## Pull requests") 43 | for x in issues: 44 | labels = [l.name for l in x.labels] 45 | print("* [%s](%s) (%s)" % (x.title, x.html_url, ", ".join(labels))) 46 | 47 | 48 | # dump contributors 49 | print() 50 | print("## Contributors") 51 | user_counts = Counter([x.user.login for x in issues]) 52 | users = {x.user.login:x.user for x in issues} 53 | for login,count in user_counts.most_common(10000): 54 | name = users[login].name 55 | logins = f" ({users[login].login})" 56 | if name is None: 57 | name = users[login].login 58 | logins = "" 59 | print(f"* {count:3d} items: [{name}]({users[login].html_url}){logins}") 60 | -------------------------------------------------------------------------------- /src/BUILD.bazel: -------------------------------------------------------------------------------- 1 | """BUILD.bazel file for StringTemplate 4.""" 2 | 3 | load("@rules_java//java:defs.bzl", "java_library") 4 | 5 | package(default_visibility = ["//:__pkg__"]) 6 | 7 | java_library( 8 | name = "stringtemplate4", 9 | srcs = glob(["**/*.java"]) + [ 10 | "org/stringtemplate/v4/compiler/CodeGenerator.java", 11 | "org/stringtemplate/v4/compiler/GroupLexer.java", 12 | "org/stringtemplate/v4/compiler/GroupParser.java", 13 | "org/stringtemplate/v4/compiler/STParser.java", 14 | ], 15 | resources = glob(["**/*.jfd"]), 16 | deps = ["@antlr3//:java_runtime"], 17 | ) 18 | 19 | genrule( 20 | name = "stringtemplate4_bootstrap", 21 | srcs = [ 22 | "org/stringtemplate/v4/compiler/CodeGenerator.g", 23 | "org/stringtemplate/v4/compiler/Group.g", 24 | "org/stringtemplate/v4/compiler/STParser.g", 25 | "org/stringtemplate/v4/compiler/STLexer.tokens", 26 | ], 27 | outs = [ 28 | "org/stringtemplate/v4/compiler/CodeGenerator.java", 29 | "org/stringtemplate/v4/compiler/GroupLexer.java", 30 | "org/stringtemplate/v4/compiler/GroupParser.java", 31 | "org/stringtemplate/v4/compiler/STParser.java", 32 | ], 33 | cmd = """ 34 | cp $(location :org/stringtemplate/v4/compiler/STLexer.tokens) $(RULEDIR)/org/stringtemplate/v4/compiler/STLexer.tokens 35 | $(JAVA) -cp $(location @antlr3_bootstrap//jar) org.antlr.Tool -fo $(RULEDIR)/org/stringtemplate/v4/compiler $(location :org/stringtemplate/v4/compiler/STParser.g) 36 | $(JAVA) -cp $(location @antlr3_bootstrap//jar) org.antlr.Tool -fo $(RULEDIR)/org/stringtemplate/v4/compiler $(location :org/stringtemplate/v4/compiler/Group.g) 37 | $(JAVA) -cp $(location @antlr3_bootstrap//jar) org.antlr.Tool -fo $(RULEDIR)/org/stringtemplate/v4/compiler $(location :org/stringtemplate/v4/compiler/CodeGenerator.g) 38 | rm -f $(RULEDIR)/org/stringtemplate/v4/compiler/STLexer.tokens 39 | """, 40 | toolchains = ["@bazel_tools//tools/jdk:current_host_java_runtime"], 41 | tools = ["@antlr3_bootstrap//jar"], 42 | ) 43 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/AttributeRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import java.util.Locale; 31 | 32 | /** 33 | * This interface describes an object that knows how to format or otherwise 34 | * render an object appropriately. There is one renderer registered per group 35 | * for a given Java type. 36 | * 37 | *

38 | * If the format string passed to the renderer is not recognized then simply 39 | * call {@link Object#toString}.

40 | * 41 | *

42 | * {@code formatString} can be {@code null} but {@code locale} will at least be 43 | * {@link Locale#getDefault}.

44 | * 45 | * @param 46 | * the type of values this renderer can handle. 47 | */ 48 | public interface AttributeRenderer { 49 | String toString(T value, String formatString, Locale locale); 50 | } 51 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/DateRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import java.text.DateFormat; 31 | import java.text.SimpleDateFormat; 32 | import java.util.*; 33 | 34 | /** 35 | * A renderer for {@link Date} and {@link Calendar} objects. It understands a 36 | * variety of format names as shown in {@link #formatToInt} field. By default it 37 | * assumes {@code "short"} format. A prefix of {@code "date:"} or 38 | * {@code "time:"} shows only those components of the time object. 39 | */ 40 | // using because this can handle Date and Calendar objects, which don't have a common supertype. 41 | public class DateRenderer implements AttributeRenderer { 42 | public static final Map formatToInt; 43 | 44 | static { 45 | final Map map = new HashMap(); 46 | 47 | map.put("short", DateFormat.SHORT); 48 | map.put("medium", DateFormat.MEDIUM); 49 | map.put("long", DateFormat.LONG); 50 | map.put("full", DateFormat.FULL); 51 | 52 | map.put("date:short", DateFormat.SHORT); 53 | map.put("date:medium", DateFormat.MEDIUM); 54 | map.put("date:long", DateFormat.LONG); 55 | map.put("date:full", DateFormat.FULL); 56 | 57 | map.put("time:short", DateFormat.SHORT); 58 | map.put("time:medium", DateFormat.MEDIUM); 59 | map.put("time:long", DateFormat.LONG); 60 | map.put("time:full", DateFormat.FULL); 61 | 62 | formatToInt = Collections.unmodifiableMap(map); 63 | } 64 | 65 | @Override 66 | public String toString(Object value, String formatString, Locale locale) { 67 | Date d; 68 | if ( formatString==null ) formatString = "short"; 69 | if ( value instanceof Calendar ) d = ((Calendar)value).getTime(); 70 | else d = (Date)value; 71 | Integer styleI = formatToInt.get(formatString); 72 | DateFormat f; 73 | if ( styleI==null ) f = new SimpleDateFormat(formatString, locale); 74 | else { 75 | int style = styleI.intValue(); 76 | if ( formatString.startsWith("date:") ) f = DateFormat.getDateInstance(style, locale); 77 | else if ( formatString.startsWith("time:") ) f = DateFormat.getTimeInstance(style, locale); 78 | else f = DateFormat.getDateTimeInstance(style, style, locale); 79 | } 80 | return f.format(d); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/InstanceScope.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4; 30 | 31 | import org.stringtemplate.v4.debug.EvalTemplateEvent; 32 | import org.stringtemplate.v4.debug.InterpEvent; 33 | import org.stringtemplate.v4.gui.STViz; 34 | 35 | import java.util.ArrayList; 36 | import java.util.List; 37 | 38 | /** */ 39 | public class InstanceScope { 40 | /** Template that invoked us. */ 41 | public final InstanceScope parent; 42 | /** Template we're executing. */ 43 | public final ST st; 44 | /** Current instruction pointer. */ 45 | public int ip; 46 | 47 | /** 48 | * Includes the {@link EvalTemplateEvent} for this template. This is a 49 | * subset of {@link Interpreter#events} field. The final 50 | * {@link EvalTemplateEvent} is stored in 3 places: 51 | * 52 | *
    53 | *
  1. In {@link #parent}'s {@link #childEvalTemplateEvents} list
  2. 54 | *
  3. In this list
  4. 55 | *
  5. In the {@link Interpreter#events} list
  6. 56 | *
57 | * 58 | * The root ST has the final {@link EvalTemplateEvent} in its list. 59 | *

60 | * All events get added to the {@link #parent}'s event list.

61 | */ 62 | public List events = new ArrayList(); 63 | 64 | /** All templates evaluated and embedded in this {@link ST}. Used 65 | * for tree view in {@link STViz}. 66 | */ 67 | public List childEvalTemplateEvents = 68 | new ArrayList(); 69 | 70 | public boolean earlyEval; 71 | 72 | public InstanceScope(InstanceScope parent, ST st) { 73 | this.parent = parent; 74 | this.st = st; 75 | this.earlyEval = parent != null && parent.earlyEval; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/ModelAdaptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import org.stringtemplate.v4.misc.STNoSuchPropertyException; 31 | 32 | import java.util.Map; 33 | 34 | /** 35 | * An object that knows how to convert property references to appropriate 36 | * actions on a model object. Some models, like JDBC, are interface based (we 37 | * aren't supposed to care about implementation classes). Some other models 38 | * don't follow StringTemplate's getter method naming convention. So, if we have 39 | * an object of type {@code M} with property method {@code M.foo()} (as opposed 40 | * to {@code M.getFoo()}), we can register a model adaptor object, {@code adap}, 41 | * that converts a lookup for property {@code foo} into a call to 42 | * {@code M.foo()}. 43 | *

44 | * Given {@code }, we look up {@code foo} via the adaptor if 45 | * {@code a instanceof M}.

46 | * 47 | * @param 48 | * the type of values this adaptor can handle. 49 | */ 50 | public interface ModelAdaptor { 51 | /** 52 | * Lookup property name in {@code o} and return its value. 53 | *

54 | * {@code property} is normally a {@code String} but doesn't have to be. 55 | * E.g., if {@code o} is {@link Map}, {@code property} could be 56 | * any key type. If we need to convert to {@code String}, then it's done by 57 | * {@code ST} and passed in here.

58 | */ 59 | Object getProperty(Interpreter interp, ST self, T model, Object property, String propertyName) 60 | throws STNoSuchPropertyException; 61 | } 62 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/NoIndentWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import java.io.IOException; 31 | import java.io.Writer; 32 | 33 | /** Just pass through the text. */ 34 | public class NoIndentWriter extends AutoIndentWriter { 35 | public NoIndentWriter(Writer out) { 36 | super(out); 37 | } 38 | 39 | @Override 40 | public int write(String str) throws IOException { 41 | out.write(str); 42 | return str.length(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/NumberRenderer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import java.math.BigDecimal; 31 | import java.math.BigInteger; 32 | import java.util.Formatter; 33 | import java.util.Locale; 34 | 35 | /** Works with {@link Byte}, {@link Short}, {@link Integer}, {@link Long}, and {@link BigInteger} as well as 36 | * {@link Float}, {@link Double}, and {@link BigDecimal}. You pass in a format string suitable 37 | * for {@link Formatter#format}. 38 | *

39 | * For example, {@code %10d} emits a number as a decimal int padding to 10 char. 40 | * This can even do {@code long} to {@code Date} conversions using the format string.

41 | */ 42 | public class NumberRenderer implements AttributeRenderer { 43 | @Override 44 | public String toString(Object value, String formatString, Locale locale) { 45 | if ( formatString==null ) return value.toString(); 46 | Formatter f = new Formatter(locale); 47 | try { 48 | f.format(formatString, value); 49 | return f.toString(); 50 | } 51 | finally { 52 | f.close(); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/STErrorListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import org.stringtemplate.v4.misc.STMessage; 31 | 32 | /** How to handle messages. */ 33 | public interface STErrorListener { 34 | void compileTimeError(STMessage msg); 35 | void runTimeError(STMessage msg); 36 | void IOError(STMessage msg); 37 | void internalError(STMessage msg); 38 | } 39 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/STGroupString.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4; 30 | 31 | import org.antlr.runtime.ANTLRStringStream; 32 | import org.antlr.runtime.CommonTokenStream; 33 | import org.stringtemplate.v4.compiler.CompiledST; 34 | import org.stringtemplate.v4.compiler.GroupLexer; 35 | import org.stringtemplate.v4.compiler.GroupParser; 36 | import org.stringtemplate.v4.misc.ErrorType; 37 | 38 | /** A group derived from a string not a file or directory. */ 39 | public class STGroupString extends STGroup { 40 | public String sourceName; 41 | public String text; 42 | protected boolean alreadyLoaded = false; 43 | 44 | public STGroupString(String text) { this("", text, '<', '>'); } 45 | 46 | public STGroupString(String sourceName, String text) { this(sourceName, text, '<', '>'); } 47 | 48 | public STGroupString(String sourceName, String text, char delimiterStartChar, char delimiterStopChar) { 49 | super(delimiterStartChar, delimiterStopChar); 50 | this.sourceName = sourceName; 51 | this.text = text; 52 | } 53 | 54 | @Override 55 | public boolean isDictionary(String name) { 56 | if ( !alreadyLoaded ) load(); 57 | return super.isDictionary(name); 58 | } 59 | 60 | @Override 61 | public boolean isDefined(String name) { 62 | if ( !alreadyLoaded ) load(); 63 | return super.isDefined(name); 64 | } 65 | 66 | @Override 67 | protected synchronized CompiledST load(String name) { 68 | if ( !alreadyLoaded ) load(); 69 | return rawGetTemplate(name); 70 | } 71 | 72 | @Override 73 | public synchronized void load() { 74 | if (alreadyLoaded) return; 75 | alreadyLoaded = true; 76 | GroupParser parser; 77 | try { 78 | ANTLRStringStream fs = new ANTLRStringStream(text); 79 | fs.name = sourceName; 80 | GroupLexer lexer = new GroupLexer(fs); 81 | CommonTokenStream tokens = new CommonTokenStream(lexer); 82 | parser = new GroupParser(tokens); 83 | // no prefix since this group file is the entire group, nothing lives 84 | // beneath it. 85 | parser.group(this, "/"); 86 | } 87 | catch (Exception e) { 88 | errMgr.IOError(null, ErrorType.CANT_LOAD_GROUP_FILE, e, ""); 89 | } 90 | } 91 | 92 | @Override 93 | public String getFileName() { return ""; } 94 | } 95 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/STRawGroupDir.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4; 2 | 3 | import org.antlr.runtime.CharStream; 4 | import org.antlr.runtime.CommonToken; 5 | import org.stringtemplate.v4.compiler.*; 6 | import org.stringtemplate.v4.compiler.Compiler; 7 | import org.stringtemplate.v4.misc.Misc; 8 | 9 | import java.net.URL; 10 | 11 | /** A directory of templates without headers like ST v3 had. Still allows group 12 | * files in directory though like {@link STGroupDir} parent. 13 | */ 14 | public class STRawGroupDir extends STGroupDir { 15 | public STRawGroupDir(String dirName) { 16 | super(dirName); 17 | } 18 | 19 | public STRawGroupDir(String dirName, char delimiterStartChar, char delimiterStopChar) { 20 | super(dirName, delimiterStartChar, delimiterStopChar); 21 | } 22 | 23 | public STRawGroupDir(String dirName, String encoding) { 24 | super(dirName, encoding); 25 | } 26 | 27 | public STRawGroupDir(String dirName, String encoding, char delimiterStartChar, char delimiterStopChar) { 28 | super(dirName, encoding, delimiterStartChar, delimiterStopChar); 29 | } 30 | 31 | public STRawGroupDir(URL root, String encoding, char delimiterStartChar, char delimiterStopChar) { 32 | super(root, encoding, delimiterStartChar, delimiterStopChar); 33 | } 34 | 35 | @Override 36 | public CompiledST loadTemplateFile(String prefix, String unqualifiedFileName, 37 | CharStream templateStream) 38 | { 39 | String template = templateStream.substring(0, templateStream.size() - 1); 40 | String templateName = Misc.getFileNameNoSuffix(unqualifiedFileName); 41 | String fullyQualifiedTemplateName = prefix + templateName; 42 | CompiledST impl = new Compiler(this).compile(fullyQualifiedTemplateName, template); 43 | CommonToken nameT = new CommonToken(STLexer.SEMI); // Seems like a hack, best I could come up with. 44 | nameT.setInputStream(templateStream); 45 | rawDefineTemplate(fullyQualifiedTemplateName, impl, nameT); 46 | impl.defineImplicitlyDefinedTemplates(this); 47 | return impl; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/STWriter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4; 29 | 30 | import org.stringtemplate.v4.compiler.Bytecode; 31 | 32 | import java.io.IOException; 33 | 34 | /** Generic StringTemplate output writer filter. 35 | *

36 | * Literals and the elements of expressions are emitted via {@link #write(String)}. 37 | * Separators are emitted via {@link #writeSeparator(String)} because they must be 38 | * handled specially when wrapping lines (we don't want to wrap 39 | * in between an element and it's separator).

40 | */ 41 | public interface STWriter { 42 | int NO_WRAP = -1; 43 | 44 | void pushIndentation(String indent); 45 | 46 | String popIndentation(); 47 | 48 | void pushAnchorPoint(); 49 | 50 | void popAnchorPoint(); 51 | 52 | void setLineWidth(int lineWidth); 53 | 54 | /** Write the string and return how many actual characters were written. 55 | * With auto-indentation and wrapping, more chars than {@code str.length()} 56 | * can be emitted. No wrapping is done. 57 | */ 58 | int write(String str) throws IOException; 59 | 60 | /** Same as write, but wrap lines using the indicated string as the 61 | * wrap character (such as {@code "\n"}). 62 | */ 63 | int write(String str, String wrap) throws IOException; 64 | 65 | /** 66 | * Because we evaluate ST instance by invoking 67 | * {@link Interpreter#exec(STWriter, InstanceScope)} again, we can't pass options in. 68 | * So the {@link Bytecode#INSTR_WRITE} instruction of an applied template 69 | * (such as when we wrap in between template applications like 70 | * {@code ]}; wrap>}) we need to write the {@code wrap} string 71 | * before calling {@link Interpreter#exec}. We expose just like for the 72 | * separator. See {@link Interpreter#writeObject} where it checks for ST 73 | * instance. If POJO, {@link Interpreter#writePOJO} passes {@code wrap} to 74 | * {@link STWriter#write(String str, String wrap)}. Can't pass to 75 | * {@link Interpreter#exec}. 76 | */ 77 | int writeWrap(String wrap) throws IOException; 78 | 79 | /** Write a separator. Same as {@link #write(String)} except that a {@code "\n"} 80 | * cannot be inserted before emitting a separator. 81 | */ 82 | int writeSeparator(String str) throws IOException; 83 | 84 | /** Return the absolute char index into the output of the char 85 | * we're about to write. Returns 0 if no char written yet. 86 | */ 87 | int index(); 88 | } 89 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/compiler/STException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.compiler; 29 | 30 | public class STException extends RuntimeException { // no checking damnit! 31 | public STException() { } 32 | public STException(String msg, Exception cause) { super(msg,cause); } 33 | } 34 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/compiler/STLexer.tokens: -------------------------------------------------------------------------------- 1 | RBRACK=17 2 | LBRACK=16 3 | ELSE=5 4 | ELLIPSIS=11 5 | LCURLY=20 6 | BANG=10 7 | EQUALS=12 8 | TEXT=22 9 | ID=25 10 | SEMI=9 11 | LPAREN=14 12 | IF=4 13 | ELSEIF=6 14 | COLON=13 15 | RPAREN=15 16 | WS=27 17 | COMMA=18 18 | RCURLY=21 19 | ENDIF=7 20 | RDELIM=24 21 | SUPER=8 22 | DOT=19 23 | LDELIM=23 24 | STRING=26 25 | PIPE=28 26 | OR=29 27 | AND=30 28 | INDENT=31 29 | NEWLINE=32 30 | AT=33 31 | END=34 32 | TRUE=35 33 | FALSE=36 34 | COMMENT=37 35 | SLASH=38 36 | '...'=11 37 | 'super'=8 38 | '|'=28 39 | '!'=10 40 | '}'=21 41 | 'else'=5 42 | 'if'=4 43 | '{'=20 44 | '...'=11 45 | 'elseif'=6 46 | ';'=9 47 | '='=12 48 | ':'=13 49 | '('=14 50 | '['=16 51 | ','=18 52 | '.'=19 53 | 'endif'=7 54 | ')'=15 55 | ']'=17 56 | '||'=29 57 | '&&'=30 58 | '@'=33 59 | '@end'=34 60 | '/'=38 61 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/compiler/StringTable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.compiler; 29 | 30 | import java.util.LinkedHashMap; 31 | 32 | /** A unique set of strings where we can get a string's index. 33 | * We can also get them back out in original order. 34 | */ 35 | public class StringTable { 36 | protected LinkedHashMap table = new LinkedHashMap(); 37 | protected int i = -1; 38 | 39 | public int add(String s) { 40 | Integer I = table.get(s); 41 | if ( I!=null ) return I; 42 | i++; 43 | table.put(s, i); 44 | return i; 45 | } 46 | 47 | public String[] toArray() { 48 | String[] a = new String[table.size()]; 49 | int i = 0; 50 | for (String s : table.keySet()) a[i++] = s; 51 | return a; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/debug/AddAttributeEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.debug; 29 | 30 | public class AddAttributeEvent extends ConstructionEvent { 31 | String name; 32 | /** Reserved for future use. */ 33 | Object value; 34 | public AddAttributeEvent(String name, Object value) { 35 | this.name = name; 36 | this.value = value; 37 | } 38 | 39 | @Override 40 | public String toString() { 41 | return "addEvent{" + 42 | ", name='" + name + '\'' + 43 | ", value=" + value + 44 | ", location=" + getFileName()+":"+getLine()+ 45 | '}'; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/debug/ConstructionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.debug; 29 | 30 | /** An event that happens when building ST trees, adding attributes etc... */ 31 | public class ConstructionEvent { 32 | public Throwable stack; 33 | public ConstructionEvent() { stack = new Throwable(); } 34 | 35 | public String getFileName() { return getSTEntryPoint().getFileName(); } 36 | public int getLine() { return getSTEntryPoint().getLineNumber(); } 37 | 38 | public StackTraceElement getSTEntryPoint() { 39 | StackTraceElement[] trace = stack.getStackTrace(); 40 | for (StackTraceElement e : trace) { 41 | String name = e.toString(); 42 | if ( !name.startsWith("org.stringtemplate.v4") ) return e; 43 | } 44 | return trace[0]; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/debug/EvalExprEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.debug; 29 | 30 | import org.stringtemplate.v4.InstanceScope; 31 | 32 | public class EvalExprEvent extends InterpEvent { 33 | /** Index of first char in template. */ 34 | public final int exprStartChar; 35 | /** Index of last char in template (inclusive). */ 36 | public final int exprStopChar; 37 | public final String expr; 38 | public EvalExprEvent(InstanceScope scope, int start, int stop, 39 | int exprStartChar, int exprStopChar) 40 | { 41 | super(scope, start, stop); 42 | this.exprStartChar = exprStartChar; 43 | this.exprStopChar = exprStopChar; 44 | if ( exprStartChar >=0 && exprStopChar >=0 ) { 45 | expr = scope.st.impl.template.substring(exprStartChar, exprStopChar +1); 46 | } 47 | else { 48 | expr = ""; 49 | } 50 | } 51 | 52 | @Override 53 | public String toString() { 54 | return getClass().getSimpleName()+"{" + 55 | "self=" + scope.st + 56 | ", expr='" + expr + '\'' + 57 | ", exprStartChar=" + exprStartChar + 58 | ", exprStopChar=" + exprStopChar + 59 | ", start=" + outputStartChar + 60 | ", stop=" + outputStopChar + 61 | '}'; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/debug/EvalTemplateEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.debug; 29 | 30 | import org.stringtemplate.v4.InstanceScope; 31 | 32 | public class EvalTemplateEvent extends InterpEvent { 33 | public EvalTemplateEvent(InstanceScope scope, int exprStartChar, int exprStopChar) { 34 | super(scope, exprStartChar, exprStopChar); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/debug/IndentEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.debug; 30 | 31 | import org.stringtemplate.v4.InstanceScope; 32 | 33 | public class IndentEvent extends EvalExprEvent { 34 | public IndentEvent(InstanceScope scope, int start, int stop, int exprStartChar, int exprStopChar) { 35 | super(scope, start, stop, exprStartChar, exprStopChar); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/debug/InterpEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.debug; 29 | 30 | import org.stringtemplate.v4.InstanceScope; 31 | 32 | public class InterpEvent { 33 | public InstanceScope scope; 34 | /** Index of first char into output stream. */ 35 | public final int outputStartChar; 36 | /** Index of last char into output stream (inclusive). */ 37 | public final int outputStopChar; 38 | public InterpEvent(InstanceScope scope, int outputStartChar, int outputStopChar) { 39 | this.scope = scope; 40 | this.outputStartChar = outputStartChar; 41 | this.outputStopChar = outputStopChar; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return getClass().getSimpleName()+"{" + 47 | "self=" + scope.st + 48 | ", start=" + outputStartChar + 49 | ", stop=" + outputStopChar + 50 | '}'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/gui/JTreeASTModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.gui; 30 | 31 | import org.antlr.runtime.tree.CommonTreeAdaptor; 32 | import org.antlr.runtime.tree.TreeAdaptor; 33 | 34 | import javax.swing.event.TreeModelListener; 35 | import javax.swing.tree.TreeModel; 36 | import javax.swing.tree.TreePath; 37 | 38 | // TODO: copied from ANTLR v4; rm when upgraded to v4 39 | public class JTreeASTModel implements TreeModel { 40 | TreeAdaptor adaptor; 41 | Object root; 42 | 43 | public JTreeASTModel(TreeAdaptor adaptor, Object root) { 44 | this.adaptor = adaptor; 45 | this.root = root; 46 | } 47 | 48 | public JTreeASTModel(Object root) { 49 | this.adaptor = new CommonTreeAdaptor(); 50 | this.root = root; 51 | } 52 | 53 | @Override 54 | public int getChildCount(Object parent) { 55 | return adaptor.getChildCount(parent); 56 | } 57 | 58 | @Override 59 | public int getIndexOfChild(Object parent, Object child){ 60 | if ( parent==null ) return -1; 61 | return adaptor.getChildIndex(child); 62 | } 63 | 64 | @Override 65 | public Object getChild(Object parent, int index){ 66 | return adaptor.getChild(parent, index); 67 | } 68 | 69 | @Override 70 | public boolean isLeaf(Object node) { 71 | return getChildCount(node)==0; 72 | } 73 | 74 | @Override 75 | public Object getRoot() { return root; } 76 | 77 | @Override 78 | public void valueForPathChanged(TreePath treePath, Object o) { 79 | } 80 | 81 | @Override 82 | public void addTreeModelListener(TreeModelListener treeModelListener) { 83 | } 84 | 85 | @Override 86 | public void removeTreeModelListener(TreeModelListener treeModelListener) { 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/Aggregate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.misc; 30 | 31 | import java.util.HashMap; 32 | 33 | /** An automatically created aggregate of properties. 34 | * 35 | *

I often have lists of things that need to be formatted, but the list 36 | * items are actually pieces of data that are not already in an object. I 37 | * need ST to do something like:

38 | *

39 | * Ter=3432
40 | * Tom=32234
41 | * ....

42 | *

43 | * using template:

44 | *

45 | * {@code $items:{it.name$=$it.type$}$}

46 | *

47 | * This example will call {@code getName()} on the objects in items attribute, but 48 | * what if they aren't objects? I have perhaps two parallel arrays 49 | * instead of a single array of objects containing two fields. One 50 | * solution is allow {@code Map}s to be handled like properties so that {@code it.name} 51 | * would fail {@code getName()} but then see that it's a {@code Map} and do 52 | * {@code it.get("name")} instead.

53 | *

54 | * This very clean approach is espoused by some, but the problem is that 55 | * it's a hole in my separation rules. People can put the logic in the 56 | * view because you could say: "go get bob's data" in the view:

57 | *

58 | * Bob's Phone: {@code $db.bob.phone$}

59 | *

60 | * A view should not be part of the program and hence should never be able 61 | * to go ask for a specific person's data.

62 | *

63 | * After much thought, I finally decided on a simple solution. I've 64 | * added setAttribute variants that pass in multiple property values, 65 | * with the property names specified as part of the name using a special 66 | * attribute name syntax: {@code "name.{propName1,propName2,...}"}. This 67 | * object is a special kind of {@code HashMap} that hopefully prevents people 68 | * from passing a subclass or other variant that they have created as 69 | * it would be a loophole. Anyway, the {@link AggregateModelAdaptor#getProperty} 70 | * method looks for {@code Aggregate} as a special case and does a {@link #get} instead 71 | * of {@code getPropertyName}.

72 | */ 73 | public class Aggregate { 74 | public HashMap properties = new HashMap(); 75 | /** Allow StringTemplate to add values, but prevent the end 76 | * user from doing so. 77 | */ 78 | protected void put(String propName, Object propValue) { 79 | properties.put(propName, propValue); 80 | } 81 | public Object get(String propName) { 82 | return properties.get(propName); 83 | } 84 | @Override 85 | public String toString() { 86 | return properties.toString(); 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/AggregateModelAdaptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.misc; 30 | 31 | import org.stringtemplate.v4.Interpreter; 32 | import org.stringtemplate.v4.ModelAdaptor; 33 | import org.stringtemplate.v4.ST; 34 | 35 | /** Deal with structs created via {@link ST#addAggr}{@code ("structname.{prop1, prop2}", ...);}. */ 36 | public class AggregateModelAdaptor implements ModelAdaptor { 37 | private final MapModelAdaptor mapAdaptor = new MapModelAdaptor(); 38 | 39 | @Override 40 | public Object getProperty(Interpreter interp, ST self, Aggregate o, Object property, String propertyName) 41 | throws STNoSuchPropertyException 42 | { 43 | return mapAdaptor.getProperty(interp, self, o.properties, property, propertyName); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/AmbiguousMatchException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2012 Terence Parr 4 | * Copyright (c) 2012 Sam Harwell 5 | * All rights reserved. 6 | * 7 | * Redistribution and use in source and binary forms, with or without 8 | * modification, are permitted provided that the following conditions 9 | * are met: 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. The name of the author may not be used to endorse or promote products 16 | * derived from this software without specific prior written permission. 17 | * 18 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | */ 29 | package org.stringtemplate.v4.misc; 30 | 31 | /** 32 | * 33 | * @author Sam Harwell 34 | */ 35 | public class AmbiguousMatchException extends RuntimeException { 36 | 37 | public AmbiguousMatchException() { 38 | super(); 39 | } 40 | 41 | public AmbiguousMatchException(String message) { 42 | super(message); 43 | } 44 | 45 | public AmbiguousMatchException(Throwable cause) { 46 | super(cause); 47 | } 48 | 49 | public AmbiguousMatchException(String message, Throwable cause) { 50 | super(message, cause); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/ArrayIterator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import java.lang.reflect.Array; 31 | import java.util.Iterator; 32 | import java.util.List; 33 | import java.util.NoSuchElementException; 34 | 35 | /** Iterator for an array so I don't have to copy the array to a {@link List} 36 | * just to make it implement {@link Iterator}. 37 | */ 38 | public class ArrayIterator implements Iterator { 39 | /** Index into the data array */ 40 | protected int i = -1; 41 | protected Object array = null; 42 | /** Arrays are fixed size; precompute. */ 43 | protected int n; 44 | 45 | public ArrayIterator(Object array) { 46 | this.array = array; 47 | n = Array.getLength(array); 48 | } 49 | 50 | @Override 51 | public boolean hasNext() { 52 | return (i+1)0; 53 | } 54 | 55 | @Override 56 | public Object next() { 57 | i++; // move to next element 58 | if ( i >= n ) { 59 | throw new NoSuchElementException(); 60 | } 61 | return Array.get(array, i); 62 | } 63 | 64 | @Override 65 | public void remove() { 66 | throw new UnsupportedOperationException(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/Coordinate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | /** A line number and char position within a line. Used by the source 31 | * mapping stuff to map address to range within a template. 32 | */ 33 | public class Coordinate { 34 | public int line; 35 | public int charPosition; 36 | public Coordinate(int a, int b) { this.line=a; this.charPosition=b; } 37 | @Override 38 | public String toString() { return line+":"+charPosition; } 39 | } 40 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/ErrorBuffer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import org.stringtemplate.v4.STErrorListener; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | /** Used during tests to track all errors. */ 36 | public class ErrorBuffer implements STErrorListener { 37 | public List errors = new ArrayList(); 38 | 39 | @Override 40 | public void compileTimeError(STMessage msg) { 41 | errors.add(msg); 42 | } 43 | 44 | @Override 45 | public void runTimeError(STMessage msg) { 46 | if ( msg.error != ErrorType.NO_SUCH_PROPERTY ) { // ignore these 47 | errors.add(msg); 48 | } 49 | } 50 | 51 | @Override 52 | public void IOError(STMessage msg) { 53 | errors.add(msg); 54 | } 55 | 56 | @Override 57 | public void internalError(STMessage msg) { 58 | errors.add(msg); 59 | } 60 | @Override 61 | public String toString() { 62 | StringBuilder buf = new StringBuilder(); 63 | for (STMessage m : errors) { 64 | buf.append(m.toString()+Misc.newline); 65 | } 66 | return buf.toString(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/ErrorType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | /** All the errors that can happen and how to generate a message. */ 31 | public enum ErrorType { 32 | // RUNTIME SEMANTIC ERRORS 33 | NO_SUCH_TEMPLATE("no such template: %s"), 34 | NO_IMPORTED_TEMPLATE("no such template: super.%s"), 35 | NO_SUCH_ATTRIBUTE("attribute %s isn't defined"), 36 | NO_SUCH_ATTRIBUTE_PASS_THROUGH("could not pass through undefined attribute %s"), 37 | REF_TO_IMPLICIT_ATTRIBUTE_OUT_OF_SCOPE("implicitly-defined attribute %s not visible"), 38 | MISSING_FORMAL_ARGUMENTS("missing argument definitions"), 39 | NO_SUCH_PROPERTY("no such property or can't access: %s"), 40 | MAP_ARGUMENT_COUNT_MISMATCH("iterating through %s values in zip map but template has %s declared arguments"), 41 | ARGUMENT_COUNT_MISMATCH("passed %s arg(s) to template %s with %s declared arg(s)"), 42 | EXPECTING_STRING("function %s expects a string not %s"), 43 | WRITER_CTOR_ISSUE("%s(Writer) constructor doesn't exist"), 44 | CANT_IMPORT("can't find template(s) in import \"%s\""), 45 | 46 | // COMPILE-TIME SYNTAX/SEMANTIC ERRORS 47 | SYNTAX_ERROR("%s"), 48 | TEMPLATE_REDEFINITION("redefinition of template %s"), 49 | EMBEDDED_REGION_REDEFINITION("region %s is embedded and thus already implicitly defined"), 50 | REGION_REDEFINITION("redefinition of region %s"), 51 | MAP_REDEFINITION("redefinition of dictionary %s"), 52 | PARAMETER_REDEFINITION("redefinition of parameter %s"), 53 | ALIAS_TARGET_UNDEFINED("cannot alias %s to undefined template: %s"), 54 | TEMPLATE_REDEFINITION_AS_MAP("redefinition of template %s as a map"), 55 | LEXER_ERROR("%s"), 56 | NO_DEFAULT_VALUE("missing dictionary default value"), 57 | NO_SUCH_FUNCTION("no such function: %s"), 58 | NO_SUCH_REGION("template %s doesn't have a region called %s"), 59 | NO_SUCH_OPTION("no such option: %s"), 60 | INVALID_TEMPLATE_NAME("invalid template name or path: %s"), 61 | ANON_ARGUMENT_MISMATCH("anonymous template has %s arg(s) but mapped across %s value(s)"), 62 | REQUIRED_PARAMETER_AFTER_OPTIONAL("required parameters (%s) must appear before optional parameters"), 63 | UNSUPPORTED_DELIMITER("unsupported delimiter character: %s"), 64 | 65 | // INTERNAL ERRORS 66 | INTERNAL_ERROR("%s"), 67 | WRITE_IO_ERROR("error writing output caused by"), 68 | CANT_LOAD_GROUP_FILE("can't load group file %s"); 69 | 70 | public String message; 71 | 72 | ErrorType(String m) { message = m; } 73 | } 74 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/Interval.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | /** An inclusive interval {@code a..b}. Used to track ranges in output and 31 | * template patterns (for debugging). 32 | */ 33 | public class Interval { 34 | public int a; 35 | public int b; 36 | public Interval(int a, int b) { this.a=a; this.b=b; } 37 | @Override 38 | public String toString() { return a+".."+b; } 39 | } 40 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/MapModelAdaptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import org.stringtemplate.v4.Interpreter; 31 | import org.stringtemplate.v4.ModelAdaptor; 32 | import org.stringtemplate.v4.ST; 33 | import org.stringtemplate.v4.STGroup; 34 | 35 | import java.util.Map; 36 | 37 | public class MapModelAdaptor implements ModelAdaptor> { 38 | @Override 39 | public Object getProperty(Interpreter interp, ST self, Map model, Object property, String propertyName) 40 | throws STNoSuchPropertyException 41 | { 42 | Object value; 43 | if ( property==null ) value = getDefaultValue(model); 44 | else if ( containsKey(model, property) ) value = model.get(property); 45 | else if ( containsKey(model, propertyName) ) { // if can't find the key, try toString version 46 | value = model.get(propertyName); 47 | } 48 | else if ( property.equals("keys") ) value = model.keySet(); 49 | else if ( property.equals("values") ) value = model.values(); 50 | else value = getDefaultValue(model); // not found, use default 51 | if ( value == STGroup.DICT_KEY ) { 52 | value = property; 53 | } 54 | return value; 55 | } 56 | 57 | private static Boolean containsKey(Map map, Object key) { 58 | try { 59 | return map.containsKey(key); 60 | } 61 | catch (ClassCastException ex) { 62 | // Map.containsKey is allowed to throw ClassCastException if the key 63 | // cannot be compared to keys already in the map. 64 | return false; 65 | } 66 | } 67 | 68 | private static Object getDefaultValue(Map map) { 69 | try { 70 | return map.get(STGroup.DEFAULT_KEY); 71 | } 72 | catch (ClassCastException ex) { 73 | // Map.containsKey is allowed to throw ClassCastException if the key 74 | // cannot be compared to keys already in the map. 75 | return false; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/MultiMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import java.util.*; 31 | 32 | /** A hash table that maps a key to a list of elements not just a single. */ 33 | public class MultiMap extends LinkedHashMap> { 34 | public void map(K key, V value) { 35 | List elementsForKey = get(key); 36 | if ( elementsForKey==null ) { 37 | elementsForKey = new ArrayList(); 38 | super.put(key, elementsForKey); 39 | } 40 | elementsForKey.add(value); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STCompiletimeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import org.antlr.runtime.Token; 31 | import org.stringtemplate.v4.compiler.GroupParser; 32 | 33 | /** Used for semantic errors that occur at compile time not during 34 | * interpretation. For ST parsing ONLY not group parsing. 35 | */ 36 | public class STCompiletimeMessage extends STMessage { 37 | /** overall token pulled from group file */ 38 | public Token templateToken; 39 | /** token inside template */ 40 | public Token token; 41 | public String srcName; 42 | 43 | public STCompiletimeMessage(ErrorType error, String srcName, Token templateToken, Token t) { 44 | this(error, srcName, templateToken, t, null); 45 | } 46 | public STCompiletimeMessage(ErrorType error, String srcName, Token templateToken, Token t, Throwable cause) { 47 | this(error, srcName, templateToken, t, cause, null); 48 | } 49 | public STCompiletimeMessage(ErrorType error, String srcName, Token templateToken, Token t, 50 | Throwable cause, Object arg) 51 | { 52 | this(error, srcName, templateToken, t, cause, arg, null); 53 | } 54 | public STCompiletimeMessage(ErrorType error, String srcName, Token templateToken, 55 | Token t, Throwable cause, Object arg, Object arg2) 56 | { 57 | super(error, null, cause, arg, arg2); 58 | this.templateToken = templateToken; 59 | this.token = t; 60 | this.srcName = srcName; 61 | } 62 | 63 | @Override 64 | public String toString() { 65 | int line = 0; 66 | int charPos = -1; 67 | if ( token!=null ) { 68 | line = token.getLine(); 69 | charPos = token.getCharPositionInLine(); 70 | // check the input streams - if different then token is embedded in templateToken and we need to adjust the offset 71 | if ( templateToken!=null && !templateToken.getInputStream().equals(token.getInputStream()) ) { 72 | int templateDelimiterSize = 1; 73 | if ( templateToken.getType()== GroupParser.BIGSTRING || templateToken.getType()== GroupParser.BIGSTRING_NO_NL ) { 74 | templateDelimiterSize = 2; 75 | } 76 | line += templateToken.getLine() - 1; 77 | charPos += templateToken.getCharPositionInLine() + templateDelimiterSize; 78 | } 79 | } 80 | String filepos = line+":"+charPos; 81 | if ( srcName!=null ) { 82 | return srcName+" "+filepos+": "+String.format(error.message, arg, arg2); 83 | } 84 | return filepos+": "+String.format(error.message, arg, arg2); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STGroupCompiletimeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.misc; 30 | 31 | import org.antlr.runtime.RecognitionException; 32 | import org.antlr.runtime.Token; 33 | 34 | /** */ 35 | public class STGroupCompiletimeMessage extends STMessage { 36 | /** token inside group file */ 37 | public Token token; 38 | public String srcName; 39 | 40 | public STGroupCompiletimeMessage(ErrorType error, String srcName, Token t, Throwable cause) { 41 | this(error, srcName, t, cause, null); 42 | } 43 | public STGroupCompiletimeMessage(ErrorType error, String srcName, Token t, 44 | Throwable cause, Object arg) 45 | { 46 | this(error, srcName, t, cause, arg, null); 47 | } 48 | public STGroupCompiletimeMessage(ErrorType error, String srcName, 49 | Token t, Throwable cause, Object arg, Object arg2) 50 | { 51 | super(error, null, cause, arg, arg2); 52 | this.token = t; 53 | this.srcName = srcName; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | RecognitionException re = (RecognitionException)cause; 59 | int line = 0; 60 | int charPos = -1; 61 | if ( token!=null ) { 62 | line = token.getLine(); 63 | charPos = token.getCharPositionInLine(); 64 | } 65 | else if ( re!=null ) { 66 | line = re.line; 67 | charPos = re.charPositionInLine; 68 | } 69 | String filepos = line+":"+charPos; 70 | if ( srcName!=null ) { 71 | return srcName+" "+filepos+": "+String.format(error.message, arg, arg2); 72 | } 73 | return filepos+": "+String.format(error.message, arg, arg2); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STLexerMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.misc; 30 | 31 | import org.antlr.runtime.RecognitionException; 32 | import org.antlr.runtime.Token; 33 | import org.stringtemplate.v4.compiler.GroupParser; 34 | 35 | /** */ 36 | public class STLexerMessage extends STMessage { 37 | public String msg; 38 | /** overall token pulled from group file */ 39 | public Token templateToken; 40 | public String srcName; 41 | 42 | public STLexerMessage(String srcName, String msg, Token templateToken, Throwable cause) { 43 | super(ErrorType.LEXER_ERROR, null, cause, null); 44 | this.msg = msg; 45 | this.templateToken = templateToken; 46 | this.srcName = srcName; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | RecognitionException re = (RecognitionException)cause; 52 | int line = re.line; 53 | int charPos = re.charPositionInLine; 54 | if ( templateToken!=null ) { 55 | int templateDelimiterSize = 1; 56 | if ( templateToken.getType()== GroupParser.BIGSTRING ) { 57 | templateDelimiterSize = 2; 58 | } 59 | line += templateToken.getLine() - 1; 60 | charPos += templateToken.getCharPositionInLine() + templateDelimiterSize; 61 | } 62 | String filepos = line+":"+charPos; 63 | if ( srcName!=null ) { 64 | return srcName+" "+filepos+": "+String.format(error.message, msg); 65 | } 66 | return filepos+": "+String.format(error.message, msg); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import org.antlr.runtime.Token; 31 | import org.stringtemplate.v4.ST; 32 | 33 | import java.io.PrintWriter; 34 | import java.io.StringWriter; 35 | 36 | /** Upon error, ST creates an {@link STMessage} or subclass instance and notifies 37 | * the listener. This root class is used for IO and internal errors. 38 | * 39 | * @see STRuntimeMessage 40 | * @see STCompiletimeMessage 41 | */ 42 | public class STMessage { 43 | /** if in debug mode, has created instance, add attr events and eval 44 | * template events. 45 | */ 46 | public ST self; 47 | public ErrorType error; 48 | public Object arg; 49 | public Object arg2; 50 | public Object arg3; 51 | public Throwable cause; 52 | 53 | public STMessage(ErrorType error) { 54 | this.error = error; 55 | } 56 | public STMessage(ErrorType error, ST self) { 57 | this(error); 58 | this.self = self; 59 | } 60 | public STMessage(ErrorType error, ST self, Throwable cause) { 61 | this(error,self); 62 | this.cause = cause; 63 | } 64 | public STMessage(ErrorType error, ST self, Throwable cause, Object arg) { 65 | this(error,self,cause); 66 | this.arg = arg; 67 | } 68 | @SuppressWarnings("ChainingConstructorIgnoresParameter") 69 | public STMessage(ErrorType error, ST self, Throwable cause, Token where, Object arg) { 70 | this(error,self,cause,where); 71 | this.arg = arg; 72 | } 73 | public STMessage(ErrorType error, ST self, Throwable cause, Object arg, Object arg2) { 74 | this(error,self,cause,arg); 75 | this.arg2 = arg2; 76 | } 77 | public STMessage(ErrorType error, ST self, Throwable cause, Object arg, Object arg2, Object arg3) { 78 | this(error,self,cause,arg,arg2); 79 | this.arg3 = arg3; 80 | } 81 | 82 | @Override 83 | public String toString() { 84 | StringWriter sw = new StringWriter(); 85 | PrintWriter pw = new PrintWriter(sw); 86 | String msg = String.format(error.message, arg, arg2, arg3); 87 | pw.print(msg); 88 | if ( cause!=null ) { 89 | pw.print("\nCaused by: "); 90 | cause.printStackTrace(pw); 91 | } 92 | return sw.toString(); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STModelAdaptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import org.stringtemplate.v4.Interpreter; 31 | import org.stringtemplate.v4.ModelAdaptor; 32 | import org.stringtemplate.v4.ST; 33 | 34 | public class STModelAdaptor implements ModelAdaptor { 35 | @Override 36 | public Object getProperty(Interpreter interp, ST self, ST model, Object property, String propertyName) 37 | throws STNoSuchPropertyException 38 | { 39 | return model.getAttribute(propertyName); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STNoSuchAttributeException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.misc; 30 | 31 | import org.stringtemplate.v4.InstanceScope; 32 | import org.stringtemplate.v4.compiler.STException; 33 | 34 | /** {@code } where {@code name} is not found up the dynamic scoping chain. */ 35 | public class STNoSuchAttributeException extends STException { 36 | public InstanceScope scope; 37 | public String name; 38 | 39 | public STNoSuchAttributeException(String name, InstanceScope scope) { 40 | this.name = name; 41 | this.scope = scope; 42 | } 43 | 44 | @Override 45 | public String getMessage() { 46 | return "from template "+scope.st.getName()+" no attribute "+name+" is visible"; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STNoSuchPropertyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.misc; 30 | 31 | import org.stringtemplate.v4.compiler.STException; 32 | 33 | /** For {@code }, object {@code a} does not have a property {@code b}. */ 34 | public class STNoSuchPropertyException extends STException { 35 | public Object o; 36 | public String propertyName; 37 | public STNoSuchPropertyException(Exception e, Object o, String propertyName) { 38 | super(null, e); 39 | this.o = o; 40 | this.propertyName = propertyName; 41 | } 42 | 43 | @Override 44 | public String getMessage() { 45 | if ( o!=null ) return "object "+o.getClass()+" has no "+propertyName+" property"; 46 | else return "no such property: "+propertyName; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/org/stringtemplate/v4/misc/STRuntimeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.misc; 29 | 30 | import org.stringtemplate.v4.InstanceScope; 31 | import org.stringtemplate.v4.Interpreter; 32 | 33 | /** Used to track errors that occur in the ST interpreter. */ 34 | public class STRuntimeMessage extends STMessage { 35 | /** Which interpreter was executing? If {@code null}, can be IO error or 36 | * bad URL etc... 37 | */ 38 | final Interpreter interp; 39 | /** Where error occurred in bytecode memory. */ 40 | public final int ip; 41 | public final InstanceScope scope; 42 | //List enclosingStack; 43 | 44 | public STRuntimeMessage(Interpreter interp, ErrorType error, int ip) { 45 | this(interp, error, ip, null); 46 | } 47 | public STRuntimeMessage(Interpreter interp, ErrorType error, int ip, InstanceScope scope) { 48 | this(interp, error,ip,scope,null); 49 | } 50 | public STRuntimeMessage(Interpreter interp, ErrorType error, int ip, InstanceScope scope, Object arg) { 51 | this(interp, error, ip, scope, null, arg, null); 52 | } 53 | public STRuntimeMessage(Interpreter interp, ErrorType error, int ip, InstanceScope scope, Throwable e, Object arg) { 54 | this(interp, error, ip, scope, e, arg, null); 55 | } 56 | public STRuntimeMessage(Interpreter interp, ErrorType error, int ip, InstanceScope scope, Throwable e, Object arg, Object arg2) { 57 | this(interp, error, ip, scope, e, arg, arg2, null); 58 | } 59 | public STRuntimeMessage(Interpreter interp, ErrorType error, int ip, InstanceScope scope, Throwable e, Object arg, Object arg2, Object arg3) { 60 | super(error, scope != null ? scope.st : null, e, arg, arg2, arg3); 61 | this.interp = interp; 62 | this.ip = ip; 63 | this.scope = scope; 64 | } 65 | 66 | /** Given an IP (code location), get it's range in source template then 67 | * return it's template line:col. 68 | */ 69 | public String getSourceLocation() { 70 | if ( ip<0 || self==null || self.impl==null ) return null; 71 | Interval I = self.impl.sourceMap[ip]; 72 | if ( I==null ) return null; 73 | // get left edge and get line/col 74 | int i = I.a; 75 | Coordinate loc = Misc.getLineCharPosition(self.impl.template, i); 76 | return loc.toString(); 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | StringBuilder buf = new StringBuilder(); 82 | String loc = null; 83 | if ( self!=null ) { 84 | loc = getSourceLocation(); 85 | buf.append("context ["); 86 | if ( interp!=null ) { 87 | buf.append( Interpreter.getEnclosingInstanceStackString(scope) ); 88 | } 89 | buf.append("]"); 90 | } 91 | if ( loc!=null ) buf.append(" "+loc); 92 | buf.append(" "+super.toString()); 93 | return buf.toString(); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /test/BUILD.bazel: -------------------------------------------------------------------------------- 1 | """BUILD.bazel file for StringTemplate 4.""" 2 | 3 | load("@rules_java//java:defs.bzl", "java_test") 4 | 5 | package(default_visibility = ["//:__pkg__"]) 6 | 7 | java_test( 8 | name = "tests", 9 | srcs = glob(["org/stringtemplate/v4/test/*.java"]), 10 | args = [ 11 | "org.stringtemplate.v4.test.TestAggregates", 12 | "org.stringtemplate.v4.test.TestAttributes", 13 | "org.stringtemplate.v4.test.TestBuggyDefaultValueRaisesNPETest", 14 | "org.stringtemplate.v4.test.TestCompiler", 15 | "org.stringtemplate.v4.test.TestCoreBasics", 16 | "org.stringtemplate.v4.test.TestDebugEvents", 17 | "org.stringtemplate.v4.test.TestDictionaries", 18 | "org.stringtemplate.v4.test.TestDollarDelimiters", 19 | # Skip as it uses AWT and the installed JRE is usually headless. 20 | # "org.stringtemplate.v4.test.TestEarlyEvaluation", 21 | "org.stringtemplate.v4.test.TestFunctions", 22 | "org.stringtemplate.v4.test.TestGroupSyntax", 23 | "org.stringtemplate.v4.test.TestGroupSyntaxErrors", 24 | "org.stringtemplate.v4.test.TestGroups", 25 | # Doesn't work for some reason, likely due to environment config. 26 | # "org.stringtemplate.v4.test.TestImports", 27 | "org.stringtemplate.v4.test.TestIndentation", 28 | "org.stringtemplate.v4.test.TestIndirectionAndEarlyEval", 29 | "org.stringtemplate.v4.test.TestInterptimeErrors", 30 | "org.stringtemplate.v4.test.TestLexer", 31 | "org.stringtemplate.v4.test.TestLineWrap", 32 | "org.stringtemplate.v4.test.TestLists", 33 | "org.stringtemplate.v4.test.TestModelAdaptors", 34 | "org.stringtemplate.v4.test.TestNoNewlineTemplates", 35 | "org.stringtemplate.v4.test.TestNullAndEmptyValues", 36 | "org.stringtemplate.v4.test.TestOptions", 37 | "org.stringtemplate.v4.test.TestRegions", 38 | "org.stringtemplate.v4.test.TestRenderers", 39 | "org.stringtemplate.v4.test.TestSTRawGroupDir", 40 | "org.stringtemplate.v4.test.TestScopes", 41 | "org.stringtemplate.v4.test.TestSubtemplates", 42 | "org.stringtemplate.v4.test.TestSyntaxErrors", 43 | "org.stringtemplate.v4.test.TestTemplateNames", 44 | "org.stringtemplate.v4.test.TestTokensForDollarDelimiters", 45 | "org.stringtemplate.v4.test.TestTreeConstruction", 46 | "org.stringtemplate.v4.test.TestWhitespace", 47 | ], 48 | javacopts = [ 49 | "-Xep:JUnit4RunWithMissing:OFF", 50 | ], 51 | main_class = "org.junit.runner.JUnitCore", 52 | use_testrunner = False, 53 | deps = [ 54 | "//:stringtemplate4", 55 | "@antlr3//:java_runtime", 56 | "@hamcrest_core//jar", 57 | "@junit//jar", 58 | ], 59 | ) 60 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/ErrorBufferAllErrors.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.stringtemplate.v4.misc.ErrorBuffer; 4 | import org.stringtemplate.v4.misc.STMessage; 5 | 6 | public class ErrorBufferAllErrors extends ErrorBuffer { 7 | @Override 8 | public void runTimeError(STMessage msg) { 9 | errors.add(msg); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/Playground.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.stringtemplate.v4.*; 4 | 5 | public class Playground { 6 | public static void main(String[] args) { 7 | ErrorBufferAllErrors errors = new ErrorBufferAllErrors(); 8 | STGroup g = new STGroupFile("/tmp/g.stg"); 9 | g.setListener(errors); 10 | ST t = g.getInstanceOf("u"); 11 | if ( t!=null ) System.out.println(t.render()); 12 | System.err.println("errors: "+errors); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestAggregates.java: -------------------------------------------------------------------------------- 1 | /* 2 | * [The "BSD license"] 3 | * Copyright (c) 2011 Terence Parr 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions 8 | * are met: 9 | * 1. Redistributions of source code must retain the above copyright 10 | * notice, this list of conditions and the following disclaimer. 11 | * 2. Redistributions in binary form must reproduce the above copyright 12 | * notice, this list of conditions and the following disclaimer in the 13 | * documentation and/or other materials provided with the distribution. 14 | * 3. The name of the author may not be used to endorse or promote products 15 | * derived from this software without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | 29 | package org.stringtemplate.v4.test; 30 | 31 | import org.junit.Test; 32 | import org.stringtemplate.v4.ST; 33 | import org.stringtemplate.v4.STGroup; 34 | import org.stringtemplate.v4.STGroupString; 35 | 36 | import static org.junit.Assert.assertEquals; 37 | 38 | /** */ 39 | public class TestAggregates extends BaseTest { 40 | @Test public void testApplyAnonymousTemplateToAggregateAttribute() throws Exception { 41 | ST st = 42 | new ST(": , \n}>"); 43 | // also testing wacky spaces in aggregate spec 44 | st.addAggr("items.{ firstName ,lastName, id }", "Ter", "Parr", 99); 45 | st.addAggr("items.{firstName, lastName ,id}", "Tom", "Burns", 34); 46 | String expecting = 47 | "99: Parr, Ter"+newline + 48 | "34: Burns, Tom"+newline; 49 | assertEquals(expecting, st.render()); 50 | } 51 | 52 | public static class Decl { 53 | String name; 54 | String type; 55 | public Decl(String name, String type) {this.name=name; this.type=type;} 56 | public String getName() {return name;} 57 | public String getType() {return type;} 58 | } 59 | 60 | @Test public void testComplicatedIndirectTemplateApplication() throws Exception { 61 | String templates = 62 | "group Java;"+newline + 63 | ""+newline + 64 | "file(variables) ::= <<\n" + 65 | "}; separator=\"\\n\">"+newline + 66 | ">>"+newline+ 67 | "intdecl(decl) ::= \"int = 0;\""+newline + 68 | "intarray(decl) ::= \"int[] = null;\""+newline 69 | ; 70 | STGroup group = new STGroupString(templates); 71 | ST f = group.getInstanceOf("file"); 72 | f.addAggr("variables.{ decl,format }", new Decl("i", "int"), "intdecl"); 73 | f.addAggr("variables.{decl , format}", new Decl("a", "int-array"), "intarray"); 74 | //System.out.println("f='"+f+"'"); 75 | String expecting = "int i = 0;" +newline+ 76 | "int[] a = null;"; 77 | assertEquals(expecting, f.render()); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestAttributes.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.junit.Test; 4 | import org.stringtemplate.v4.ST; 5 | 6 | import static org.junit.Assert.assertTrue; 7 | 8 | public class TestAttributes extends BaseTest { 9 | @Test 10 | public void testRedefOfKeyInClone() { 11 | ST a = new ST("x"); 12 | // a has no formal args 13 | 14 | ST b = new ST(a); 15 | b.add("x", "foo"); 16 | 17 | ST c = new ST(a); 18 | c.add("x", "bar"); 19 | assertTrue(true); // should not get exception 20 | } 21 | 22 | // See https://github.com/antlr/stringtemplate4/issues/72 and 23 | // https://github.com/antlr/stringtemplate4/issues/98 24 | @Test 25 | public void testRedefOfKeyInCloneAfterAddingAttribute() { 26 | ST a = new ST("x"); 27 | a.add("y", "eh?"); // This forces formal def of "y" attribute 28 | 29 | ST b = new ST(a); 30 | b.add("x", "foo"); 31 | 32 | ST c = new ST(a); 33 | c.add("x", "bar"); 34 | assertTrue(true); // should not get exception 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestBuggyDefaultValueRaisesNPETest.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | import org.stringtemplate.v4.ST; 6 | import org.stringtemplate.v4.STGroup; 7 | import org.stringtemplate.v4.STGroupFile; 8 | import org.stringtemplate.v4.misc.ErrorBuffer; 9 | 10 | public class TestBuggyDefaultValueRaisesNPETest extends BaseTest { 11 | /** 12 | * When the anonymous template specified as a default value for a formalArg 13 | * contains a syntax error ST 4.0.2 emits a NullPointerException error 14 | * (after the syntax error) 15 | * 16 | * @throws Exception 17 | */ 18 | @Test 19 | public void testHandleBuggyDefaultArgument() throws Exception { 20 | String templates = "main(a={(<\"\")>}) ::= \"\""; 21 | writeFile(tmpdir, "t.stg", templates); 22 | 23 | final ErrorBuffer errors = new ErrorBuffer(); 24 | STGroup group = new STGroupFile(tmpdir + "/t.stg"); 25 | group.setListener(errors); 26 | 27 | ST st = group.getInstanceOf("main"); 28 | String s = st.render(); 29 | 30 | // Check the errors. This contained an "NullPointerException" before 31 | Assert.assertEquals( 32 | "t.stg 1:12: mismatched input ')' expecting RDELIM"+newline, 33 | errors.toString()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestGroupsFromCLASSPATH.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.junit.Test; 4 | import org.stringtemplate.v4.ST; 5 | import org.stringtemplate.v4.STGroupDir; 6 | import org.stringtemplate.v4.STGroupFile; 7 | 8 | import java.net.URL; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | public class TestGroupsFromCLASSPATH extends BaseTest { 13 | @Test 14 | public void testLoadTemplateFileFromDir() { 15 | STGroupDir stg = new STGroupDir("org/antlr/templates/dir1"); 16 | ST st = stg.getInstanceOf("sample"); 17 | String result = st.render(); 18 | String expecting = "a test"; 19 | assertEquals(expecting, result); 20 | } 21 | 22 | @Test 23 | public void testLoadTemplateFileInSubdir() { 24 | STGroupDir stg = new STGroupDir("org/antlr/templates"); 25 | ST st = stg.getInstanceOf("dir1/sample"); 26 | String result = st.render(); 27 | String expecting = "a test"; 28 | assertEquals(expecting, result); 29 | } 30 | 31 | /** 32 | * $ test/resources $ jar cvf test.jar jarbase 33 | * added manifest 34 | * adding: jarbase/(in = 0) (out= 0)(stored 0%) 35 | * adding: jarbase/dir1/(in = 0) (out= 0)(stored 0%) 36 | * adding: jarbase/dir1/sample.st(in = 24) (out= 26)(deflated -8%) 37 | * adding: jarbase/testgroupfile.stg(in = 18) (out= 20)(deflated -11%) 38 | * 39 | * I set it up so the jar is in the CLASSPATH and URL of group file should be this 40 | * at runtime: 41 | * 42 | * jar:file:/Users/parrt/antlr/code/stringtemplate4/test/test.jar!/jarbase/testgroupfile.stg 43 | */ 44 | @Test 45 | public void testLoadTemplateGroupFileFromJar() { 46 | // load jarbase/testgroupfile.stg from test.jar that is in CLASSPATH 47 | STGroupFile stg = new STGroupFile("jarbase/testgroupfile.stg"); 48 | ST st = stg.getInstanceOf("t"); 49 | String result = st.render(); 50 | String expecting = "foo"; 51 | assertEquals(expecting, result); 52 | } 53 | 54 | /** URL of jarbase/dir1 should be 55 | * 56 | * jar:file:/Users/parrt/antlr/code/stringtemplate4/test/test.jar!/jarbase/dir1 57 | */ 58 | @Test 59 | public void testLoadTemplateGroupDirFromJar() { 60 | // load jarbase/testgroupfile.stg from test.jar that is in CLASSPATH 61 | STGroupDir stg = new STGroupDir("jarbase/dir1"); 62 | ST st = stg.getInstanceOf("sample"); 63 | String result = st.render(); 64 | String expecting = "a test"; 65 | assertEquals(expecting, result); 66 | } 67 | 68 | @Test 69 | public void testLoadTemplateGroupDirViaURL() { 70 | // Compute URL of dir inside test.jar that is in CLASSPATH 71 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 72 | URL url = cl.getResource("jarbase/dir1"); 73 | STGroupDir stg = new STGroupDir(url); 74 | ST st = stg.getInstanceOf("sample"); 75 | String result = st.render(); 76 | String expecting = "a test"; 77 | assertEquals(expecting, result); 78 | } 79 | 80 | @Test 81 | public void testLoadTemplateGroupDirViaURLWithTrailingSlash() { 82 | // Compute URL of dir inside test.jar that is in CLASSPATH 83 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 84 | URL url = cl.getResource("jarbase/dir1/"); // <----- extra slash 85 | STGroupDir stg = new STGroupDir(url); 86 | ST st = stg.getInstanceOf("sample"); 87 | String result = st.render(); 88 | String expecting = "a test"; 89 | assertEquals(expecting, result); 90 | } 91 | 92 | @Test 93 | public void testLoadTemplateGroupFileFromCLASSPATH() { 94 | STGroupFile stg = new STGroupFile("org/antlr/templates/testgroupfile.stg"); 95 | ST st = stg.getInstanceOf("t"); 96 | String result = st.render(); 97 | String expecting = "foo"; 98 | assertEquals(expecting, result); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestScopes.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.junit.Test; 4 | import org.stringtemplate.v4.*; 5 | import org.stringtemplate.v4.misc.*; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | 9 | public class TestScopes extends BaseTest { 10 | @Test public void testSeesEnclosingAttr() throws Exception { 11 | String templates = 12 | "t(x,y) ::= \"\"\n" + 13 | "u() ::= \"\""; 14 | ErrorBuffer errors = new ErrorBuffer(); 15 | writeFile(tmpdir, "t.stg", templates); 16 | STGroup group = new STGroupFile(tmpdir+"/"+"t.stg"); 17 | group.setListener(errors); 18 | ST st = group.getInstanceOf("t"); 19 | st.add("x", "x"); 20 | st.add("y", "y"); 21 | String result = st.render(); 22 | 23 | String expectedError = ""; 24 | assertEquals(expectedError, errors.toString()); 25 | 26 | String expected = "xy"; 27 | assertEquals(expected, result); 28 | } 29 | 30 | @Test public void testMissingArg() throws Exception { 31 | String templates = 32 | "t() ::= \"\"\n" + 33 | "u(z) ::= \"\""; 34 | ErrorBuffer errors = new ErrorBuffer(); 35 | writeFile(tmpdir, "t.stg", templates); 36 | STGroup group = new STGroupFile(tmpdir+"/"+"t.stg"); 37 | group.setListener(errors); 38 | ST st = group.getInstanceOf("t"); 39 | String result = st.render(); 40 | 41 | String expectedError = "context [/t] 1:1 passed 0 arg(s) to template /u with 1 declared arg(s)"+newline; 42 | assertEquals(expectedError, errors.toString()); 43 | } 44 | 45 | @Test public void testUnknownAttr() throws Exception { 46 | String templates = 47 | "t() ::= \"\"\n"; 48 | ErrorBuffer errors = new ErrorBuffer(); 49 | writeFile(tmpdir, "t.stg", templates); 50 | STGroup group = new STGroupFile(tmpdir+"/"+"t.stg"); 51 | group.setListener(errors); 52 | ST st = group.getInstanceOf("t"); 53 | String result = st.render(); 54 | 55 | String expectedError = "context [/t] 1:1 attribute x isn't defined"+newline; 56 | assertEquals(expectedError, errors.toString()); 57 | } 58 | 59 | @Test public void testArgWithSameNameAsEnclosing() throws Exception { 60 | String templates = 61 | "t(x,y) ::= \"\"\n" + 62 | "u(y) ::= \"\""; 63 | ErrorBuffer errors = new ErrorBuffer(); 64 | writeFile(tmpdir, "t.stg", templates); 65 | STGroup group = new STGroupFile(tmpdir+"/"+"t.stg"); 66 | group.setListener(errors); 67 | ST st = group.getInstanceOf("t"); 68 | st.add("x", "x"); 69 | st.add("y", "y"); 70 | String result = st.render(); 71 | 72 | String expectedError = ""; 73 | assertEquals(expectedError, errors.toString()); 74 | 75 | String expected = "xx"; 76 | assertEquals(expected, result); 77 | group.setListener(ErrorManager.DEFAULT_ERROR_LISTENER); 78 | } 79 | 80 | @Test public void testIndexAttrVisibleLocallyOnly() throws Exception { 81 | String templates = 82 | "t(names) ::= \"}>\"\n" + 83 | "u(x) ::= \":\""; 84 | ErrorBuffer errors = new ErrorBuffer(); 85 | writeFile(tmpdir, "t.stg", templates); 86 | STGroup group = new STGroupFile(tmpdir+"/"+"t.stg"); 87 | group.setListener(errors); 88 | ST st = group.getInstanceOf("t"); 89 | st.add("names", "Ter"); 90 | String result = st.render(); 91 | group.getInstanceOf("u").impl.dump(); 92 | 93 | String expectedError = "t.stg 2:11: implicitly-defined attribute i not visible"+newline; 94 | assertEquals(expectedError, errors.toString()); 95 | 96 | String expected = ":Ter"; 97 | assertEquals(expected, result); 98 | group.setListener(ErrorManager.DEFAULT_ERROR_LISTENER); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestTokensForDollarDelimiters.java: -------------------------------------------------------------------------------- 1 | /* 2 | [The "BSD license"] 3 | Copyright (c) 2009 Terence Parr 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions 8 | are met: 9 | 1. Redistributions of source code must retain the above copyright 10 | notice, this list of conditions and the following disclaimer. 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 3. The name of the author may not be used to endorse or promote products 15 | derived from this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 | IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | */ 28 | package org.stringtemplate.v4.test; 29 | 30 | import org.junit.Test; 31 | 32 | public class TestTokensForDollarDelimiters extends BaseTest { 33 | @Test public void testSimpleAttr() throws Exception { 34 | String template = "hi $name$"; 35 | String expected = "[[@0,0:2='hi ',,1:0], [@1,3:3='$',,1:3], [@2,4:7='name',,1:4], [@3,8:8='$',,1:8]]"; 36 | checkTokens(template, expected, '$', '$'); 37 | } 38 | 39 | @Test public void testString() throws Exception { 40 | String template = "hi $foo(a=\"$\")$"; 41 | String expected = "[[@0,0:2='hi ',,1:0], [@1,3:3='$',,1:3], [@2,4:6='foo',,1:4], [@3,7:7='(',,1:7], [@4,8:8='a',,1:8], [@5,9:9='=',,1:9], [@6,10:12='\"$\"',,1:10], [@7,13:13=')',,1:13], [@8,14:14='$',,1:14]]"; 42 | checkTokens(template, expected, '$', '$'); 43 | } 44 | 45 | @Test public void testEscInString() throws Exception { 46 | String template = "hi $foo(a=\"$\\\"\")$"; // "hi $foo(a="$\"")$" 47 | String expected = "[[@0,0:2='hi ',,1:0], [@1,3:3='$',,1:3], [@2,4:6='foo',,1:4], [@3,7:7='(',,1:7], [@4,8:8='a',,1:8], [@5,9:9='=',,1:9], [@6,10:14='\"$\"\"',,1:10], [@7,15:15=')',,1:15], [@8,16:16='$',,1:16]]"; 48 | checkTokens(template, expected, '$', '$'); 49 | } 50 | 51 | @Test public void testSubtemplate() throws Exception { 52 | String template = "hi $names:{n | $n$}$"; 53 | String expected = 54 | "[[@0,0:2='hi ',,1:0], [@1,3:3='$',,1:3], [@2,4:8='names',,1:4], " + 55 | "[@3,9:9=':',,1:9], [@4,10:10='{',,1:10], [@5,11:11='n',,1:11], " + 56 | "[@6,13:13='|',,1:13], [@7,15:15='$',,1:15], [@8,16:16='n',,1:16], " + 57 | "[@9,17:17='$',,1:17], [@10,18:18='}',,1:18], [@11,19:19='$',,1:19]]"; 58 | checkTokens(template, expected, '$', '$'); 59 | } 60 | 61 | @Test public void testNestedSubtemplate() throws Exception { 62 | String template = "hi $names:{n | $n:{$it$}$}$"; 63 | String expected = "[[@0,0:2='hi ',,1:0], [@1,3:3='$',,1:3], [@2,4:8='names',,1:4], [@3,9:9=':',,1:9], [@4,10:10='{',,1:10], [@5,11:11='n',,1:11], [@6,13:13='|',,1:13], [@7,15:15='$',,1:15], [@8,16:16='n',,1:16], [@9,17:17=':',,1:17], [@10,18:18='{',,1:18], [@11,19:19='$',,1:19], [@12,20:21='it',,1:20], [@13,22:22='$',,1:22], [@14,23:23='}',,1:23], [@15,24:24='$',,1:24], [@16,25:25='}',,1:25], [@17,26:26='$',,1:26]]"; 64 | checkTokens(template, expected, '$', '$'); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestTreeConstruction.gunit: -------------------------------------------------------------------------------- 1 | /** Test ST's AST construction. Translate to junit tests with: 2 | * 3 | * $ java org.antlr.v4.gunit.Gen TestTreeConstruction.gunit 4 | * 5 | * Use local version of gUnitBase to avoid dependency on v4 antlr. 6 | */ 7 | gunit TestTreeConstruction; 8 | 9 | @header{package org.stringtemplate.v4.test;} 10 | options { 11 | parser = org.stringtemplate.v4.compiler.STParser; 12 | lexer = org.stringtemplate.v4.compiler.STLexer; 13 | } 14 | 15 | template: 16 | "<[]>" -> (EXPR [) 17 | "<[a,b]>" -> (EXPR ([ a b)) 18 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestTreeConstruction.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.antlr.runtime.RuleReturnScope; 4 | import org.antlr.runtime.tree.Tree; 5 | 6 | import org.junit.*; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | 10 | public class TestTreeConstruction extends gUnitBase { 11 | @Before public void setup() { 12 | lexerClassName = "org.stringtemplate.v4.compiler.STLexer"; 13 | parserClassName = "org.stringtemplate.v4.compiler.STParser"; 14 | } 15 | @Test public void test_template1() throws Exception { 16 | // gunit test on line 16 17 | RuleReturnScope rstruct = (RuleReturnScope)execParser("template", "<[]>", 16); 18 | Object actual = ((Tree)rstruct.getTree()).toStringTree(); 19 | Object expecting = "(EXPR [)"; 20 | assertEquals("testing rule template", expecting, actual); 21 | } 22 | 23 | @Test public void test_template2() throws Exception { 24 | // gunit test on line 17 25 | RuleReturnScope rstruct = (RuleReturnScope)execParser("template", "<[a,b]>", 17); 26 | Object actual = ((Tree)rstruct.getTree()).toStringTree(); 27 | Object expecting = "(EXPR ([ a b))"; 28 | assertEquals("testing rule template", expecting, actual); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/TestTypeRegistry.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.junit.Test; 4 | import org.stringtemplate.v4.misc.TypeRegistry; 5 | 6 | import static org.junit.Assert.assertEquals; 7 | import static org.junit.Assert.assertNull; 8 | 9 | public class TestTypeRegistry { 10 | // https://github.com/antlr/stringtemplate4/issues/122 11 | 12 | static class A {} 13 | 14 | static class B extends A {} 15 | 16 | @Test 17 | public void registryWithObject() { 18 | TypeRegistry registry = new TypeRegistry(); 19 | registry.put(Object.class, "Object"); 20 | assertEquals("Object", registry.get(Object.class)); 21 | assertEquals("Object", registry.get(A.class)); 22 | assertEquals("Object", registry.get(B.class)); 23 | } 24 | 25 | @Test 26 | public void registryWithA() { 27 | TypeRegistry registry = new TypeRegistry(); 28 | registry.put(A.class, "A"); 29 | assertNull(registry.get(Object.class)); 30 | assertEquals("A", registry.get(A.class)); 31 | assertEquals("A", registry.get(B.class)); 32 | } 33 | 34 | @Test 35 | public void registryWithB() { 36 | TypeRegistry registry = new TypeRegistry(); 37 | registry.put(B.class, "B"); 38 | assertNull(registry.get(Object.class)); 39 | assertNull(registry.get(A.class)); 40 | assertEquals("B", registry.get(B.class)); 41 | } 42 | 43 | @Test 44 | public void registryWithObjectAndA() { 45 | TypeRegistry registry = new TypeRegistry(); 46 | registry.put(Object.class, "Object"); 47 | registry.put(A.class, "A"); 48 | assertEquals("Object", registry.get(Object.class)); 49 | assertEquals("A", registry.get(A.class)); 50 | assertEquals("A", registry.get(B.class)); 51 | } 52 | 53 | @Test 54 | public void registryWithObjectAndB() { 55 | TypeRegistry registry = new TypeRegistry(); 56 | registry.put(Object.class, "Object"); 57 | registry.put(B.class, "B"); 58 | assertEquals("Object", registry.get(Object.class)); 59 | assertEquals("Object", registry.get(A.class)); 60 | assertEquals("B", registry.get(B.class)); 61 | } 62 | 63 | @Test 64 | public void registryWithAAndB() { 65 | TypeRegistry registry = new TypeRegistry(); 66 | registry.put(A.class, "A"); 67 | registry.put(B.class, "B"); 68 | assertNull(registry.get(Object.class)); 69 | assertEquals("A", registry.get(A.class)); 70 | assertEquals("B", registry.get(B.class)); 71 | } 72 | 73 | @Test 74 | public void registryWithObjectAndAAndB() { 75 | TypeRegistry registry = new TypeRegistry(); 76 | registry.put(Object.class, "Object"); 77 | registry.put(A.class, "A"); 78 | registry.put(B.class, "B"); 79 | assertEquals("Object", registry.get(Object.class)); 80 | assertEquals("A", registry.get(A.class)); 81 | assertEquals("B", registry.get(B.class)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /test/org/stringtemplate/v4/test/gUnitBase.java: -------------------------------------------------------------------------------- 1 | package org.stringtemplate.v4.test; 2 | 3 | import org.antlr.runtime.ANTLRStringStream; 4 | import org.antlr.runtime.CharStream; 5 | import org.antlr.runtime.CommonTokenStream; 6 | import org.antlr.runtime.Parser; 7 | import org.antlr.runtime.TokenSource; 8 | import org.antlr.runtime.TokenStream; 9 | import org.antlr.runtime.tree.TreeAdaptor; 10 | 11 | import java.lang.reflect.Constructor; 12 | import java.lang.reflect.Method; 13 | 14 | public class gUnitBase { 15 | public String lexerClassName; 16 | public String parserClassName; 17 | public String adaptorClassName; 18 | 19 | public Object execParser( 20 | String ruleName, 21 | String input, 22 | int scriptLine) 23 | throws Exception 24 | { 25 | ANTLRStringStream is = new ANTLRStringStream(input); 26 | Class lexerClass = Class.forName(lexerClassName).asSubclass(TokenSource.class); 27 | Constructor lexConstructor = lexerClass.getConstructor(CharStream.class); 28 | TokenSource lexer = lexConstructor.newInstance(is); 29 | is.setLine(scriptLine); 30 | 31 | CommonTokenStream tokens = new CommonTokenStream(lexer); 32 | 33 | Class parserClass = Class.forName(parserClassName).asSubclass(Parser.class); 34 | Constructor parConstructor = parserClass.getConstructor(TokenStream.class); 35 | Parser parser = parConstructor.newInstance(tokens); 36 | 37 | // set up customized tree adaptor if necessary 38 | if ( adaptorClassName!=null ) { 39 | Method m = parserClass.getMethod("setTreeAdaptor", TreeAdaptor.class); 40 | Class adaptorClass = Class.forName(adaptorClassName).asSubclass(TreeAdaptor.class); 41 | m.invoke(parser, adaptorClass.newInstance()); 42 | } 43 | 44 | Method ruleMethod = parserClass.getMethod(ruleName); 45 | 46 | // INVOKE RULE 47 | return ruleMethod.invoke(parser); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test/resources/org/antlr/templates/dir1/sample.st: -------------------------------------------------------------------------------- 1 | sample() ::= <> 2 | -------------------------------------------------------------------------------- /test/resources/org/antlr/templates/testgroupfile.stg: -------------------------------------------------------------------------------- 1 | t() ::= << 2 | foo 3 | >> 4 | -------------------------------------------------------------------------------- /test/test.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antlr/stringtemplate4/06c44e70ed265671802799ba69ff05fa2610eac1/test/test.jar --------------------------------------------------------------------------------