diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..76b3e3d --- /dev/null +++ b/.npmignore @@ -0,0 +1,18 @@ +@@ -0,0 +1,10 @@ +.github +.vscode +cli/ +tests/ +coverage/ +dist/*.map +src/ +doc/ + +jest.config.ts +.eslintignore +.eslintrc.json +.project +tsconfig.json +cspell.json +historical-contributors-agreement.txt +developer-cert-of-origin.txt diff --git a/CHANGES.txt b/CHANGES.txt deleted file mode 100644 index 67898a9..0000000 --- a/CHANGES.txt +++ /dev/null @@ -1,468 +0,0 @@ -**************************************************************************** -As of ST 4.0.8, March 25 2014, we are no longer updating this file. Instead, -we are using the github release mechanism. For example, here is -4.0.8 release notes: - -https://github.com/antlr/stringtemplate4/releases/tag/4.0.8 -**************************************************************************** - -Terence Parr, parrt at cs usfca edu -ANTLR project lead and supreme dictator for life -University of San Francisco - -CHANGES - -January 30, 2013 - -* Require EOF in Group.g (rule group) -* Minor cleanup and documentation tweaks -* Improve ObjectModelAdaptor caching performance, eliminate chance of deadlock - -January 4, 2013 -- Release 4.0.7 - -* Fixed README for release - -January 1, 2013 - -* Tweaked escapes in <<...>>. Do NOT replace if it's <\\>. - Escapes: >\> means >> inside of <<...>>. - Escapes: \>> means >> inside of <<...>> unless at end like <<...\>>>>. - In that case, use <%..>>%> instead. - -* Added warning about: "Missing newline after newline escape <\\>" - -* Actually: %\> is the escape to avoid end of string - -* Several STViz updates: - * Highlight template subexpressions and literal text responsible for output - * Gray out hidden (inherited+aliased) attributes - * Highlight user-instanced templates in bold - -December 31, 2012 - -* Reversing decision to use >\> and %\> as the escapes now for >> and %>. - Simply allowing >>> is the best, such as <>>. - It will strip off the >> and leave > as the appropriate end of expression. - Added testTripleAngleOnEnds. Even <<>> works now. There is no escape - for %>. - -December 26, 2012 - -* Allow [] as a dictionary value, resolves antlr/stringtemplate4#33 - -December 25, 2012 - -* Fix issues with bytecode to source mapping -* Fix several STViz bugs -* Improved error location reporting -* Fix several unit tests -* Explicit InstanceScope tracking in the interpreter - -December 15, 2012 - -* throw exceptionWhen the attribute name is no to be consistent with the - other check for '.' in the name. - -December 13, 2012 - -* Allow [] as a default value for formal arguments (fixes antlr/stringtemplate4#20) -* Add method STViz.waitForClose() -* Specify -Dtest.interactive to have STViz tests leave the window open for the user -* Code cleanup - -December 11, 2012 - -* Don't cache the STNoSuchPropertyException and STNoSuchAttributeException - instances. -* 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. -* Improved message when reporting ErrorType.NO_SUCH_PROPERTY. - -December 10, 2012 - -* DateRenderer and StringRenderer now use the provided locale (fixes - antlr/stringtemplate4#11) -* Fixes for handling of arrays (fixes antlr/stringtemplate4#12 and other - unreported issues) -* Try to load template file (.st) if group file (.stg) failed with IOException - (fixes antlr/stringtemplate4#14) -* Add STGroup.GROUP_FILE_EXTENSION and STGroup.TEMPLATE_FILE_EXTENSION -* Updated documentation, code cleanup - -December 9, 2012 - -* >\> and %\> are the escapes now for >> and %> Fixes antlr/stringtemplate4#17 - -December 3, 2012 -- Release 4.0.7-rc-1 - -December 1, 2012 - -* Missing ANT target for STParser.g in build - -September 26, 2012 -- Release 4.0.6 - -* 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$". - -August 13, 2012 - -* Fixed https://github.com/antlr/stringtemplate4/issues/5 - -May 21, 2012 - -* Made fields in the error messages public - -February 8, 2012 -- 4.0.5 release - -December 25, 2011 - -* STLexer.tokens missing from src build - -* Added STRawGroupDir that expects pure templates in .st files not template defs - with headers. So use $name$ not - - foo(name) ::= "$name" - -December 4, 2011 - -* synchronized object model adaptor -* import illegal in group files embedded in STGroupDirs - -July 19, 2011 (Udo) - -* Fixed Misc.newline issue in test code (Udo) - -July 18, 2011 -- Release 4.0.4 - -* Added delimiters "<", ">" notation to group file. - -July 5, 2011 - -* added "get import list" method. -* added methods to allow deep vs shallow setting of renderers; interp always - asks native group defining template for the renderer. -* STGroup.getInstanceOf was not auto-adding "/" to front if none was present - -June 30, 2011 - -* Updated javadoc on getAttributeRenderer() -* Updated javadoc on unload/importTemplates in STGroup() (ub) -* Added test case for unload of groups specified in group file imports. (ub) - -June 24, 2011 - -* STGroup.unload() now removes imports that were specified in the group - file, but only calls unload() on templates that were explicitly added - in the program. Resolves both Sam's and Udo's concerns. :) - -June 22, 2011 - -* subtemplates {...} in subdirectories didn't work. - -June 21, 2011 -- Release 4.0.3 - -* {} wasn't allowed as a template - -June 16, 2011 - -* Major overhaul of template names: -** '/' allowed as starting ID letter like -** getInstanceOf names must be fully qualified. If you don't put / on - front, one is added for you. -** template refs in expr are relative to location of surrounding template - unless prefixed with /. In that case they are relative to root of group. -** import statement no longer allows fully qualified file name. -** Changed all unit tests to use fully qualified names and see results that way. - -June 15, 2011 - -* STGroup.unload() calls unload() on each group in the imports list - instead of clearing the list. (Thanks to Sam...wait, did Udo already - try this?) - -June 14, 2011 - -* STRuntimeMessage got NPE upon ST.impl == null -* ctor ST() is protected; not for users. bad users! - -June 11, 2011 (Udo) - -* Removed warning (access static member through instance) - -June 4, 2011 (Udo) - -* Fixed and added tests - -May 29, 2011 (Udo) - -* Fixed test case for <\n> to handle different line.separator sizes - -May 28, 2011 (Udo) - -* BUG: On Windows wrapped lines are separated with \r\r\n -* made tests run on Windows and non-US locales - -May 20, 2011 (Udo) - -* STGroupDir.load(String name) no longer checks for (parent) group file when name specifies no parent (no '/') - -May 18, 2011 (Udo) - -* unload in STGroup now also unloads the import relationships -* Fixed test testRendererWithPredefinedFormat2 to also work in non-PDT timezones -* Fixed tests testArg1, testArg2 in TestGroupSyntaxErrors -* Fixed "URI is not hierarchical" issue when STGroupFile is imported from jar file - -May 17, 2011 (Udo) - -* Added getTemplateNames to STGroup - -May 14, 2011 - -* passthru() didn't watch for empty formal args - -May 10-15, 2011 (Udo) - -* fixed bug raising a NullPointerException when a formalArg's default value has a syntax error. -Example: main(a={(<"")>}) ::= "" -* STGroupFile.getName() returns group name also for imported groups (was null before). - -4.0.2 -- May 3, 2011 - -* Backing out change from 4/17; don't want Serializable implementation. -* Improved error msg for out of order required parameters (after optional ones) - -April 26, 2011 - -* rest() stripped nulls, which it shouldn't. Was inconsistent with trunc(), etc... - -April 21, 2011 - -* Made STGroup.iterateAcrossValues an instance variable not static. - That needed a change to convertAnythingIteratableToIterator, etc.. - to non-static. -* Removed STDump as unneeded; Use STViz. - -April 17, 2011 - -* Added implements Serializable to ST, STGroup. - -April 16, 2011 - -* Made compatible with Java 1.5; removed Arrays.copyOf() ref. -* Updated ANT build to ref ant lib dir not /usr/local/lib/ - -April 11, 2011 - -* Dictionaries weren't inherited. Added unit test. - -4.0.1 -- April 10, 2011 - -* Added STNoSuchAttributeException to distinguish from no such property. -* Pass through didn't handle case properly of empty or nonexistent attributes. - We only pass through nonempty values. Further, it makes no sense to set - values for parameter x if x has no definition above. That is the same as - having no value. This is required to get default attributes to work - with passthru in all cases. Added unit tests. -* Oops. That is not quite correct. If no value exists or the attribute - itself does not exist, we must set the parameter to null ifthere is no - default parameter. otherwise the interpreter will complain about a - missing argument value. -* Was missing alreadyLoaded = true; in STGroupString. -* Bug fix for <@super.r()> exprs; it tried to doubly-define region. - Code generator didn't generate mangled name either; fixed and then updated - http://www.antlr.org/wiki/display/ST4/Template+to+Bytecode+mapping -* Improved error msg when referencing implicit attributes like 'i'. - -April 9, 2011 - -* Sam pointed out that regions didn't work with <% %> -* Cleaned up STViz. -* STViz expands template attribute view when you click in output -* STViz template and attribute tree views now grouped. -* default arguments were not evaluated in context of invoked template; - couldn't see other args. -* Added '...' pass through arg back in. Only allowed with named arg lists - or as sole arg. Not allowed in <(name)()> indirect includes. - Inserts new passthru bytecode to set any unset args. -* AST pane not updated upon new ST selection -* Scroll output pane when ST selected -* Added STGroup.iterateAcrossValues static boolean for v3 compatibility - v3 iterates across values not keys like v4. But to convert ANTLR templates, - it's too hard to find without static typing in templates. -* Cleaned up ST.locals[] creation; centralized in Interpreter. -* MapModelAdaptor made copy of STs unnecessarily and w/o copying locals[] - -April 8, 2011 - -* Added scope tree showing all inherited attributes (dynamic scoping) in lower - left "attributes" pane. -* Undid some bugs I introduced concerning selecting templates. Tried to - move the cursor in output window which triggered multiple / wrong update - events. - - April 6, 2011 - -* Ignore indentation in <% .. %> templates but keep white space between elements -* Added better error msg for internal errors during template evaluation. - context [outputFile parser genericParser rule ruleBlockSingleAlt alt element - ruleRefAndListLabel ruleRef] 1:1 internal error caused by: java.lang.NullPointerException - at org.stringtemplate.v4.ST.rawSetAttribute(ST.java:294) - at org.stringtemplate.v4.Interpreter.storeArgs(Interpreter.java:576) - at org.stringtemplate.v4.Interpreter.super_new(Interpreter.java:495) - ... - -April 4, 2011 - -* in TestSubtemplates.java there was an extra (bad) import -* fixed a couple of unit tests that failed. -* removed .class files from depot -* added t() ::= <% ... %> template that ignores all newlines inside template. - This allows arbitrary formatting within a template that does not result - in new lines in the output. This is useful when you have a really complicated - template with IFs and such that needs to generate output all on the same line. - Currently, this can be quite challenging. There's no way to read a huge - template on one line. - -April 3, 2011 - -* ST.getAttribute() only looks in that template now. Can't look up - since it doesn't know what interp is executing. It's just to get - an attr out of a template now. Moved dynamically scope getAttribute() - to Interpreter. -* STRuntimeMessage takes an Interpreter interp arg now. -* ST dropped some weight. No need for enclosingInstance ptr now. That is - properly done in interpreter as a stack of scopes. Now, there is no - side-effect whatsoever in ST instances for execution. THREAD SAFE eval now. -* Added <<<...>>> template that ignores all \n inside; use <\n> to get one. -* Interpreter interp added to ModelAdaptor. BREAKING CHANGE IF YOU'VE BUILT - a model adaptor (rare) -* Internal clean up so stack of template evaluation scopes has debug info. - Required changes across lots of files. Started referring to scopes - so entire path to root is available and with debugging info if debug on - for that interpreter. Extracted InstanceScope from inner class. - -March 30 - April 2, 2011 - -* ST.inspect() now returns an STViz, which has all the goodies and gives - you access to the GUI stuff. -* added aggr.{prop1, prop2} for ST.add(). Too useful. (Was in v3). - Use ST.addAggr("aggr.{p1,p2}", a1, a2); -* refactored to fold DebugST into ST; adds one object ptr to every ST - instance but worth reduction in complexity. "new ST(...)" calls didn't - work (not DebugST objects) in inspector. ST.inspect() for any ST now. -* Fixed bug in STViz. Didn't highlight entire output when you click - topmost template. -* STGroup.debug no longer there nor static. It's an instance var of - Interpreter. ST.inspect() tells interp to debug. STGroup.trackCreationEvents - says to record where in code an ST was created and where code added attributes. -* Gutted tree model for STViz, refactored debugging/event tracking code. -* creation events had wrong location (launch of interp location); only tracks - now for externally/injected created templates. - -March 29, 2011 - -* Fixed bug where escaped quotes in template defs were not unescaped for use - by compiler. - -4.0 -- March 27, 2011 - -* ST.add() returns self now so we can chain. t.add("x", 1).add("y", "hi"); -* import from files in jar didn't work. -* removed field tokens from STGroupString -* improved imports lookup -* made fields of events public final. -* augmented debug event toString and fixed start/stop issue with eval - events. renamed fields to be more clear. -* Added IndentEvent for dbg -* ^(INDENT expr-sub-tree) is now ^(INDENTED_EXPR INDENT expr-sub-tree) - with changes to grammars. More consistent with subtree root being operator. - STViz now highlights indentation properly in template pane. -* Altered CodeGenerator.g to pass AST node for indentation not just string. - This way we get INDENT operations into the sourceMap for indent debug events. - -4.0b5 -- March 6, 2011 - -BIG THANKS to Sam Harwell and, again, to Udo Borkowski for debugging help and -suggestions. Sam is doing the C# implementation. Benjamin Niemann is doing -the Python port. Alan Condit is doing Objective-C. - -* true/false were only allowed as default args; now allowed as template - arg expressions in templates. Works as dictionary value too. -* couldn't have anonymous templates inside a region. -* parentheses were a bit weird in conditions. Now, conditions cannot - use parentheses to mean "early evaluation" except as obj.(propName) -* nativeGroup of all implicit templates was STGroup.defaultGroup. -* removed all writes of the enclosingInstance at evaluation time; fixed - issue for STViz. -* comments on line by themselves don't emit \n to output -* STViz tried to highlight AST pane even when we switched ASTs -* combined load_str, write into write_str single op. minor optimizations too. - Seems a tiny bit faster per benchmarks. -* Added ST.VERSION auto-updated by ANT. -* added STGroupString -* Added support for this in group.g: - oldStyleHeader // ignore but lets us use this parser in AW for both v3 and v4 - : 'group' ID ( ':' ID )? - ( 'implements' ID (',' ID)* )? - ';' - ; -* IndexOutOfBounds Exception when using "cap" format on empty string -* @t.() ::= "" caused NPE -* Region redefinition caused NPE. "<@r>a<@end><@r()>" -* STViz couldn't see first subtemplate when computing template range in output. -* Was incorrectly computing filename to load template .st files from group dir. -* Listener was not notified upon "no such template" in group dir. -* Redid how ST found imported files, dir, etc.. Can now import a template - file even. Can be absolute path or relative path. If relative, it - looks in dir of .stg file with import then CLASSPATH. -* The listener of import groups is now set to that of group that imports - them. -* Regions behave like tags now. Indent respected if <@r>...<@end> on - indented single line. Indent/newlines ignored after those tags if - on separate lines. - -4.0b4 -- February 5, 2011 - -BIG THANKS to Udo Borkowski for his help debugging these betas and his -suggestions. - -* added write to file methods -* had infinite loop for expr: " using new STWriter derived from type of current STWriter. - e.g., AutoIndentWriter. -* didn't detect nonterminated comment. -* added two literals "true" and "false" to the template argument syntax; e.g., - stat(name,x=true,y=false) ::= "..." -* it was treating "..." default arg as a template not string. -* throws STException now upon not finding group file or group dir instead - of sending err to listener. -* default args couldn't have subtemplates - t(x,y={}>}) ::= "..." -* Added a new benchmark from Oliver Zeigermann. - -4.0b3 -- January 28, 2011 - -* exception in lexer blew out of parsing -* missing '}' in {...} caused infinite loop -* NPE in storeArgs if empty arg list -* removed debugging prints. -* x={<(...)>} default arg was hardcoded to <...> not $..$ or whatever. -* The grammar needed to match and ignore an optional INDENT before region @end -* when redefining a region (template) the newline before the >> was kept. -* WS not ignored in front of STRING token in expressions. -* closing STViz doesn't exit vm now. -* throws exception if registering renderer or model adaptor for primitive - -4.0b2 -- January 22, 2011 - -* Order of static init issue; an error mgr was null. -* Fixed some unit testing the Windows friendly -* Fix bug in triple if-elseif-elseif-elseif; added unit tests -* bug where I did not say current_ip when calling exec() from writeObject -* Updated README to include install information - -4.0b1 -- January 14, 2011 diff --git a/License-MIT.txt b/License-MIT.txt new file mode 100644 index 0000000..380bff5 --- /dev/null +++ b/License-MIT.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 - present Mike Lischke + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index cdd8078..f37dddc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ [![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/mike-lischke/stringtemplate4-ts/nodejs.yml?style=for-the-badge&logo=github)](https://github.com/mike-lischke/stringtemplate4-ts/actions/workflows/nodejs.yml) +[![Weekly Downloads](https://img.shields.io/npm/dw/stringtemplate4ts?style=for-the-badge&color=blue)](https://www.npmjs.com/package/stringtemplate4ts) +[![npm version](https://img.shields.io/npm/v/stringtemplate4ts?style=for-the-badge&color=yellow)](https://www.npmjs.com/package/stringtemplate4ts) # Introduction @@ -21,6 +23,13 @@ The documentation is [here](./doc/index.md) Per the BSD license in [LICENSE.txt](LICENSE.txt), this software is not guaranteed to work and might even destroy all life on this planet. +## Known Differences + +The port closely resembles the original. Luckily, Java and TypeScript share many similarities, allowing for the implementation of even esoteric language features such as runtime method access and invocation using string names (also known as reflection). However, there are a few differences, which are listed below: + +- Importing modules is different in both languages and can be challenging when dealing with circular dependencies. To avoid these dependencies, interfaces and factory methods have been defined for certain classes that refer to each other. This should not impose any restrictions for normal usage. +- Formatting numbers with arbitrary format strings and locale support is not available. We can either have locale aware formatting using the standard `toLocaleString` method or we can have a custom format string pattern, not both. I decided for the latter (which uses the `fast-printf` library). Once I have found a library which supports both (such as `luxon` for date and time), this can be improved. + ## Installation Run @@ -43,10 +52,14 @@ Check the repository out and run npm run build ``` +in the project root. + ## Running Unit Tests Running the tests is equally simple. Just do: ```bash npm run test -``` \ No newline at end of file +``` + +in the project root. diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 0ea81cb..83fdc8b 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -48,18 +48,18 @@ See [Templates conditionals](templates.md#conditionals) If `attribute` has a value or is a boolean object that evaluates to true, include `subtemplate `else include `subtemplate2`. These conditionals may be nested. ``` -subtemplate -subtemplate2 +subtemplate +subtemplate2 ``` First attribute that has a value or is a boolean object that evaluates to true, include that subtemplate. These conditionals may be nested. ``` -subtemplate -subtemplate2 -subtemplate3 -subtemplate4 +subtemplate +subtemplate2 +subtemplate3 +subtemplate4 ``` @@ -82,7 +82,7 @@ See [Group file syntax](groups.md) ``` t1(arg1,arg2,...,argN) ::= "template1" // single-line template // multi line template -t2(args) ::= << +t2(args) ::= << template2 >> // multi line template that ignores indentation and newlines @@ -99,7 +99,7 @@ import "template file.st" import "group file.stg" ``` -The paths can be absolute, but should probably be relative to the class path or the directory of the template that imports them. +The paths can be absolute, but should probably be relative to the directory of the template that imports them. ## Reserved words diff --git a/doc/groups.md b/doc/groups.md index ea2dee1..189d24e 100644 --- a/doc/groups.md +++ b/doc/groups.md @@ -41,13 +41,11 @@ import "test.stg" // import a group of templates from a file import "test" // import a directory of templates ``` -**In the Java-reference implementation**, StringTemplate also looks for files and directories in the CLASSPATH. Using relative paths is particularly important if we want to load templates from jar files. Java cannot find files specified with absolute path names within jar files. Please refer to [Using StringTemplate with Java](java.md). - Templates with the same name override templates from imported groups just like method overriding and class inheritance. See [Group inheritance](inheritance.md). ## Dictionaries -There are situations where you need to translate a string in one language to a string in another language. For example, you might want to translate integer to int when translating Pascal to C. You could pass a Map or IDictionary (e.g. hashtable) from the model into the templates, but then you have output literals in your model:-1:. The StringTemplate solution is to support a dictionary feature. For example, here is a dictionary that maps Java type names to their default initialization values: +There are situations where you need to translate a string in one language to a string in another language. For example, you might want to translate integer to int when translating Pascal to C. You could pass a Map or Dictionary (e.g. Map) from the model into the templates, but then you have output literals in your model. The StringTemplate solution is to support a dictionary feature. For example, here is a dictionary that maps Java type names to their default initialization values: ``` typeInitMap ::= [ diff --git a/doc/indent.md b/doc/indent.md index 55d122e..af047c2 100644 --- a/doc/indent.md +++ b/doc/indent.md @@ -1,6 +1,6 @@ # Auto-indentation -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. +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. ``` slist(statements) ::= << @@ -16,9 +16,9 @@ StringTemplate performs auto indentation as the text gets emitted during renderi To turn off auto indentation, tell StringTemplate to use NoIndentWriter by invoking the write(writer) method instead of the usual render method: -```java -StringWriter sw = new StringWriter(); -NoIndentWriter w = new NoIndentWriter(sw); +```typescript +const sw = new StringWriter(); +const w = new NoIndentWriter(sw); st.write(w); // same as render() except with a different writer -String result = sw.toString(); +const result = sw.toString(); ``` diff --git a/doc/index.md b/doc/index.md index 668105f..8635c3b 100644 --- a/doc/index.md +++ b/doc/index.md @@ -1,16 +1,18 @@ # StringTemplate 4 Documentation -Please check [Frequently asked questions (FAQ)](faq/index.md) before asking questions on stackoverflow or StringTemplate-discussion list. - -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. +Please ask questions about StringTemplate in general on StackOverflow or in the StringTemplate-discussion list. For specific question about the TypeScript implementation of the ST library use the issue tracker or the discussions of the repository on Github. ## Installation -* [Java](java.md) -* [C#](https://github.com/antlr/antlrcs) -* [JavaScript--not stable](https://github.com/jsnyders/StringTemplate-js) -* Python -* [Objective-C](https://github.com/muggins/ST4-ObjC2.0-Runtime) +Get the Node.js package with the usual command: + +```bash +npm i stringtemplate4ts +``` + +in your project folder. + +> Note: This TypeScript port uses semantic versioning, independent of the original Code, and hence starts with version `1.0.0` instead of `4.3.3` (the version of Java ST4, at the time of writing this). ## Introductory material @@ -48,25 +50,6 @@ Notes: To add to or improve this documentation, { } Group Java1\_5 the inherited template class will write template constants. The following sample code creates group objects referring to both template group files, creates and filled in instances of template class, and finally prints out the rendered text. -```java -public void test(String[] args) { - STGroup java1_4 = new STGroupFile("/tmp/Java1_4.stg"); - STGroup java1_5 = new STGroupFile("/tmp/Java1_5.stg"); - System.out.println( getCode(java1_4) ); - System.out.println( getCode(java1_5) ); +```typescript +export const test = (args: unknown[]): void => { + const java1_4 = new STGroupFile("/tmp/Java1_4.stg"); + const java1_5 = new STGroupFile("/tmp/Java1_5.stg"); + console.log(getCode(java1_4)); + console.log(getCode(java1_5)); } -public String getCode(STGroup java) { - ST cl = java.getInstanceOf("class"); // create class - cl.add("name", "T"); - ST consts = java.getInstanceOf("constants"); - consts.add("typename", "MyEnum"); - consts.add("names", new String[] {"A","B"}); - cl.add("members", consts); // add constants as a member - return cl.render(); + +export const getCode = (java: STGroup): string => { + const cl = java.getInstanceOf("class"); // create class + cl?.add("name", "T"); + const consts = java.getInstanceOf("constants"); + consts?.add("typename", "MyEnum"); + consts?.add("names", ["A", "B"]); + cl?.add("members", consts); // add constants as a member + return cl?.render() ?? ""; } ``` @@ -84,7 +85,7 @@ In object-oriented programming languages, the type of the receiving object dicta Imagine we're generating an HTML page using templates from group file site.stg (using `$...$` delimiters) that invokes a searchbox template defined within the same group file: -``` +```stringtemplate // site.stg page(content) ::= << @@ -100,11 +101,11 @@ searchbox() ::= "
...
" To create an instance of page, inject some test content, and print it out, we can use the following controller code. -```java -STGroup g = new STGroupFile("site.stg", '$', '$'); -ST page = g.getInstanceOf("page"); -page.add("content", "a test page"); -System.out.println(page.render()); +```typescript +const g = new STGroupFile("site.stg", "$", "$"); +const page = g.getInstanceOf("page"); +page?.add("content", "a test page"); +console.log(page?.render()); ``` We get the following output. @@ -121,7 +122,7 @@ a test page Now, let's define a subgroup that overrides searchbox so that it generates nothing. -``` +```stringtemplate // bland.stg import "site.stg" searchbox() ::= "" @@ -129,8 +130,8 @@ searchbox() ::= "" We can use identical code except for changing the source of the templates: -```java -STGroup g = new STGroupFile("bland.stg", '$', '$'); +```typescript +const g = new STGroupFile("bland.stg", "$", "$"); ... ``` @@ -153,12 +154,12 @@ When dealing with lots of output language variations, a proper separation of con Obviously the number of variations can explode. To deal with this problem, StringTemplate allows you to dynamically import/inherit templates using the controller instead of an import statement in the group file (and is the only way to do it when using directories of templates instead of group files). Here's some code that assumes there are no imports in the group files. To create group dbg\_java1\_5, it imports java1\_5 group, which itself imports java1\_4. -```java -STGroup java1_4 = new STGroupFile("/tmp/Java1_4.stg"); -STGroup java1_5 = new STGroupFile("/tmp/Java1_5.stg"); +```typescript +const java1_4 = new STGroupFile("/tmp/Java1_4.stg"); +const java1_5 = new STGroupFile("/tmp/Java1_5.stg"); java1_5.imporTemplates(java1_4); // import "Java1_5.stg" -STGroup dbg_java1_4 = new STGroupFile("/tmp/Dbg.stg"); -STGroup dbg_java1_5 = new STGroupFile("/tmp/Dbg.stg"); +const dbg_java1_4 = new STGroupFile("/tmp/Dbg.stg"); +const dbg_java1_5 = new STGroupFile("/tmp/Dbg.stg"); dbg_java1_4.importTemplates(java1_4); // import "Java1_4.stg" dbg_java1_5.importTemplates(java1_5); // import "Java1_5.stg" ``` @@ -169,23 +170,23 @@ There are 2 kinds of people using StringTemplate: web type folks and code genera Remember, for each group there should only be one STGroup object. So, imagine we have group file foo.stg and template a.st in a directory called /tmp and we create a group object to handle that stuff: -```java -STGroup dir = STGroupDir("/tmp"); +```typescript +const dir = STGroupDir("/tmp"); dir.getInstanceOf("a"); // no problem; looks in "/tmp/a.st" dir.getInstanceOf("/foo/b"); // no problem if foo.stg has b() template ``` So far so good. Now, what you cannot do is have foo.stg import something because it is nested within dir: -``` +```stringtemplate import "bar.stg" // causes unsupported operation exception b() ::= "..." ``` If I did, -```java -STGroup g = new STGroupFile("/tmp/foo.stg"); +```typescript +const g = new STGroupFile("/tmp/foo.stg"); ``` then there is no problem. Difference is that you don't want to mix inheritance with subdirectories and a group file within a STGroupDir acts like a subdirectory. diff --git a/doc/inspector.md b/doc/inspector.md deleted file mode 100644 index 7e37b81..0000000 --- a/doc/inspector.md +++ /dev/null @@ -1,86 +0,0 @@ -# StringTemplate Inspector GUI - -One of the frustrations with ST v3 was that it was sometimes hard to debug the templates. For v4, everything is a lot cleaner and I can present for you a nice GUI that tells you everything about a template and any nested templates. There are some key bits of information you need when debugging a template: - -* What template fragment emitted this output? -* What did this template fragment emit? -* What are the attributes associated with this template instance? -* What attributes are visible to a particular template? -* Where in the source code did I set an attribute? -* Where in the source code did I create this template? -* How is ST interpreting the syntax of my template? - -The GUI frame answers these questions and provides extra information including the generated bytecodes compiled from the original template as well as an execution trace through the interpreter. - -## How to launch the inspector - -To use the GUI inspector, you don't need to do anything except call ST.inspect() on the root of your template hierarchy. If you also want to track template creation events and attribute injection events, turn on the static STGroup.trackCreationEvents flag. The interpretation of templates is totally side effect free so you can render and inspect templates as you wish and in any order. - -```java -STGroup.trackCreationEvents = true; -STGroup group = new STGroupFile("t.stg"); -ST st = group.getInstanceOf("test"); -st.add("attrname", value); -... -st.inspect(); -``` - -## Inspector window components - -Here's basic view when you start up: - - -* tree of templates is the upper left pane -* attributes of the templates stack (path from selected template to the root of the total anarchy) are in the lower left pane -* error messages from the compiler or interpreter go in the bottommost pane -* the output is in the upper right pane -* one of three things is in the lower right pane: - 1. the template source code and the AST built by the ST compiler - 1. the byte codes compiled from that source - 1. the execution trace of the byte code interpreter. - -![](images/startup.gif) - -### Clicking template in hierarchy shows related output - -Clicking on one of the templates in the upper left quadrant resets the display so that the output from that template instance is highlighted in the output pane. The stack of templates in the lower left pane also changes. Opening up the template names in that pane shows the attributes injected into that template. - -### Corresponding Java source code locations - -Also notice that the location in the source code where the template was created to show and also the place in the source where the attribute was added is shown. The main outputFile template was created at location CodeGenerator.java line 296. In the attributes pane you can see that rewriteMode was injected at line 343, and so on. If there is no location, that means that the template was automatically created by StringTemplate internally or the attribute was not set. - -### Clicking in output window shows which template emitted that text - -![](images/outputclick.gif) - -### AST window shows how ST compiler interpreted template source - -Sometimes it's helpful to figure out how ST interprets the syntax of your source code. When looking at the template source, the right subpane next to it shows the AST. If you click on an element in the AST, it highlights the place in the source code for which it was created. - -![](images/AST.png) - -### Displaying compiled ST bytecodes - -If you'd like to see what the bytecode looks like, you can click on that pane. - -![](images/bytecode.png) - -### Displaying bytecode interpreter trace - -Finally, you can also see the interpreter in action (mostly of educational value). The trace shows the stack of the byte code interpreter, the call stack, and the number of output characters. - -![](images/trace.png) - -### Dynamic scoping of attributes - -When you reference an attribute, say, x within your template, ST tries to resolve x within the injected attributes of that template. If you can't find it, ST looks up the enclosing template change towards the root of the overall template hierarchy. This dynamic scoping allows deeply nested templates to refer to attributes injected into the root template. You might, for example, want to know the overall file name in some deeply nested template. Or, you might want to know the surrounding method name when you're generating code in nested template for the various statements. - -Sometimes, though, it can be hard figuring out why an attribute as the wrong value. You can look at the lower left pane for the stack of templates to see the scope context. Simply start at the bottom and look upwards until you find the first definition of your attribute. Here's an example where the output shows "CommonTree" because the ruleLabelPropertyRef_start references attribute labelType: - -``` -(!=null?(().start):null) -``` - -`labelType` happens to be a default attribute of a template above in the hierarchy that references `ASTLabelType`. The `ASTLabelType` value is set as an argument of `genericParser` template way up the hierarchy, almost at the root. - -![](images/attrstack.gif) diff --git a/doc/java.md b/doc/java.md deleted file mode 100644 index 64771ee..0000000 --- a/doc/java.md +++ /dev/null @@ -1,112 +0,0 @@ -# Using StringTemplate with Java - -## Installation - -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 - -```bash -$ export CLASSPATH="/usr/local/lib/ST-4.3.4.jar:$CLASSPATH" -``` - -Java will now see all the libraries necessary to execute ST stuff. Also, check out the [StringTemplate repo](https://github.com/antlr/stringtemplate4). - -## Hello world - -Here's a simple, complete program to test your installation. - -```java -import org.stringtemplate.v4.*; - -public class Hello { - public static void main(String[] args) { - ST hello = new ST("Hello, "); - hello.add("name", "World"); - System.out.println(hello.render()); - } -} -``` - -Here's how to compile and run it from the command line: - -```bash -/tmp $ javac Hello.java -/tmp $ java Hello -Hello, World -``` - -## Loading template groups - -### Group files - -To load a group file, use the STGroupFile subclass of STGroup: - -```java -//load file name -STGroup g = new STGroupFile("test.stg"); -``` - -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. - -```java -// load relative file name -STGroup g = new STGroupFile("templates/test.stg"); -``` - -You can also use a fully qualified name: - -``` -// load fully qualified file name -STGroup g = new STGroupFile("/usr/local/share/templates/test.stg"); -``` - -### Group directories - -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: - -```java -// load relative directory of templates -STGroup g = new STGroupDir("templates"); -``` - -If templates is not found in the current directory, StringTemplate looks in the CLASSPATH. Or, you can specify the exact fully qualified name: - -``` -// load fully qualified directory of templates -STGroup g = new STGroupDir("/usr/local/share/templates"); -``` - -### Group strings - -For small groups, it sometimes makes sense to use a string within Java code: - -```java -String g = - "a(x) ::= <>\n"+ - "b() ::= <>\n"; -STGroup group = new STGroupString(g); -ST st = group.getInstanceOf("a"); -String expected = "foo"; -String result = st.render(); -assertEquals(expected, result); -``` - -### URL/URI/Path quagmire - -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: - -``` -// BAD -STGroup modelSTG = new STGroupFile(url.getPath()); -``` - -because it yields a file path to a jar and then inside: - -``` -file:/somedirectory/AJARFILE.jar!/foo/main.stg -``` - -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. - -## API documentation - -[Java API](https://www.stringtemplate.org/api/index.html) diff --git a/doc/listeners.md b/doc/listeners.md index ca431e9..af72386 100644 --- a/doc/listeners.md +++ b/doc/listeners.md @@ -1,13 +1,13 @@ # Error listeners -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: +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 the console, which is generally not what you want in a larger application. Here is the listener definition: -```java -public interface STErrorListener { - public void compileTimeError(STMessage msg); - public void runTimeError(STMessage msg); - public void IOError(STMessage msg); - public void internalError(STMessage msg); +```typescript +export interface STErrorListener { + compileTimeError(msg: STMessage): void; + runTimeError(msg: STMessage): void; + iOError(msg: STMessage): void; + internalError(msg: STMessage): void; } ``` @@ -15,9 +15,9 @@ The STMessage instances include information such as the ErrorType and any argume 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: -```java +```typescript // listener per group -STGroup g = ...; +const g = new STGroup(...); g.setListener(myListener); g.getInstance("foo"); ... @@ -25,11 +25,11 @@ g.getInstance("foo"); If you want to track interpretation errors with a particular listener, use the appropriate ST.write() method: -```java +```typescript // listener per rendering -STGroup g = ...; -ST st = g.getInstance("foo"); -st.write(myWriter, myListener); +const g = new STGroup(...); +const st = g.getInstance("foo"); +st?.write(myWriter, myListener); ``` Imported groups automatically use the listener of the importing group. diff --git a/doc/motivation.md b/doc/motivation.md index 108e226..65810a8 100644 --- a/doc/motivation.md +++ b/doc/motivation.md @@ -1,6 +1,10 @@ -# Motivation and philosophy +# Motivation and Philosophy -## Why should I use StringTemplate? +## Why a TypeScript Port? + +The TypeScript port of the Java StringTemplate library was created as part of porting ANTLR4 to TypeScript. Of course it can serve as standalone library, like the Java version does, but it's main purpose is the ANTLR4 TypeScript port. + +## Why Should I Use StringTemplate? StringTemplate ensures the separation of the specification of business logic and computation required to generate structured text from the specification of how that text is presented (i.e. its formatting). diff --git a/doc/null-vs-empty-previous.md b/doc/null-vs-empty-previous.md deleted file mode 100644 index a5db0a6..0000000 --- a/doc/null-vs-empty-previous.md +++ /dev/null @@ -1,84 +0,0 @@ -# null vs missing vs empty vs nonexistent in ST 4 - -*October 15, 2009* - -## Part 1: Null-valued attributes - -Let's consider values inside arrays. If names=`{"Tom", null, null, "Ter"}`, what should we get here: - -``` - -``` - -or here - -``` - -``` - -My preference would be: TomTer and Tom, Ter. That is what v3 does now. We recently introduced the null option so we can say: - -``` - -``` - -to get `foo` instead of an missing element when `names[i]` is null. - -HOWEVER, you cannot set an attribute to null. So, if instead of passing the list, we set them individually, we get a different answer. - -```java -st.add(names, "Tom"); -st.add(names, null); // do nothing -st.add(names, null); // do-nothing -st.add(names, "Ter"); -``` - -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. - -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. - -## Part 2. Missing versus null versus non-null - -In v4, I want to clearly identify the exact meetings of: missing versus null versus non-null means. Consider what this means: - -``` - -``` - -There are three situations: - -1. name doesn't exist as an attribute -1. name exists but has no value (it's null) -1. name exists and has a value - -Similarly, what about properties (using getProp or isProp or the actual field name): - -``` - -``` - -again, there are three situations: - -1. name doesn't exist as a property of the user object -1. name exists but has no value (it's null) -1. name exists and has a value - -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). - -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? - -``` - -``` - -Personally, I think it should be: - -1. EMPTY if name doesn't exist as an attribute -1. foo if name exists but has no value (it's null) -1. name's value if name exists and has a value - -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. - -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. - -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. diff --git a/doc/null-vs-empty.md b/doc/null-vs-empty.md index d621f63..9c017fe 100644 --- a/doc/null-vs-empty.md +++ b/doc/null-vs-empty.md @@ -2,7 +2,7 @@ *December 27, 2012* -In [null vs missing vs empty vs nonexistent in ST 4](null-vs-empty-previous.md) a few years ago, I tried to resolve in my head the difference between a missing attribute, a null value, an array with no elements, and a string with no characters. I don't think I got it completely thought through and ST v4 might have some weird inconsistencies. This page is an attempt to finally write down all the cases and resolve exactly how things should work. +A few years ago, I tried to resolve in my head the difference between a missing attribute, a null value, an array with no elements, and a string with no characters. I don't think I got it completely thought through and ST v4 might have some weird inconsistencies. This page is an attempt to finally write down all the cases and resolve exactly how things should work. I think the general rule should be: *no complete <...> expression evaluation ever equals null*. A lone x can have value null, but the resulting evaluates to the empty string. A missing entry in a list like [a,,b] is the only way to create a null value in ST and I think this might have been a mistake on my part to allow missing elements. diff --git a/doc/releasing-st4.md b/doc/releasing-st4.md deleted file mode 100644 index 6b3784d..0000000 --- a/doc/releasing-st4.md +++ /dev/null @@ -1,173 +0,0 @@ -# Cutting an ST Release - -## Github - -Create a pre-release or full release at github. - -### Delete existing release tag - -Wack any existing tag as mvn will create one and it fails if already there. - -``` -$ git tag -d 4.3.4 -$ git push origin :refs/tags/4.3.4 -$ git push upstream :refs/tags/4.3.4 -``` - -## Bump version - -Here is a simple script to display any line from the critical files with, say, `4.3.4` in it: - -```bash -find . -type f -exec grep -l '4\.3\.4' {} \; -``` - -For sure change `ST.java`: - -```java -public final static String VERSION = "4.3.4"; -``` - -Commit to repository. - -## Maven Repository Settings - -First, make sure you have maven set up to communicate with staging servers etc... Create file `~/.m2/settings.xml` with appropriate username/password for staging server and gpg.keyname/passphrase for signing. Make sure it has strict visibility privileges to just you. On unix, it looks like: - -```bash -beast:~/.m2 $ ls -l settings.xml --rw------- 1 parrt staff 914 Jul 15 14:42 settings.xml -``` - -Here is the file template - -```xml - - - - - - sonatype-nexus-staging - sonatype-username - XXX - - - sonatype-nexus-snapshots - sonatype-username - XXX - - - - - - false - - - UUU - XXX - - - - -``` - -## Maven deploy snapshot - -Do this: - -```bash -$ mvn deploy -DskipTests -... -[INFO] BUILD SUCCESS -[INFO] ------------------------------------------------------------------------ -[INFO] Total time: 8.672 s -[INFO] Finished at: 2018-11-10T11:01:28-08:00 -[INFO] ------------------------------------------------------------------------ -``` - -## Maven release - -The maven deploy lifecycle phased deploys the artifacts and the poms for the ST4 project to the [sonatype remote staging server](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/ST4/4.3.4-SNAPSHOT). - -```bash -mvn deploy -DskipTests -``` - -Make sure `gpg` is installed (`brew install gpg` on mac). Also must [create a key and publish it](https://blog.sonatype.com/2010/01/how-to-generate-pgp-signatures-with-maven/) then update `.m2/settings` to use that public key. - -Now, do this: - -```bash -mvn release:prepare -Darguments="-DskipTests" -``` - -Hm...per https://github.com/keybase/keybase-issues/issues/1712 we need this to make gpg work (needed for releasing not build): - -```bash -export GPG_TTY=$(tty) -``` - -It will start out by asking you the version number: - -``` -... -What is the release version for "StringTemplate 4"? (org.antlr:ST4) 4.3.4: : -What is SCM release tag or label for "StringTemplate 4"? (org.antlr:ST4) ST4-4.3.4: : 4.3.4 -What is the new development version for "StringTemplate 4"? (org.antlr:ST4) 4.3.5-SNAPSHOT: : 4.3.5-SNAPSHOT -... -``` - -Now release - -```bash -mvn release:perform -Darguments="-DskipTests" -``` - -Maven will use git to push pom.xml changes. - -Now, go here: - -    [https://oss.sonatype.org/#welcome](https://oss.sonatype.org/#welcome) - -and on the left click "Staging Repositories". You click the staging repo and close it, then you refresh, click it and release it. It's done when you see it here: - -    [https://oss.sonatype.org/service/local/repositories/releases/content/org/antlr/ST4/4.3.4](https://oss.sonatype.org/service/local/repositories/releases/content/org/antlr/ST4/4.3.4) - -All releases should be here: [https://repo1.maven.org/maven2/org/antlr/ST4/](https://repo1.maven.org/maven2/org/antlr/ST4/). - -Seems to take a while to propagate. - -## Javadoc - -```bash -mvn javadoc:javadoc -``` - -```bash -cp -r ~/antlr/code/stringtemplate4/target/apidocs/* ~/antlr/sites/website-st4/api -``` - -# Update website - -Copy the jars to stringtemplate.org site and update download/index.html - -```bash -cp ~/.m2/repository/org/antlr/ST4/4.3.4/ST4-4.3.4.jar ~/antlr/sites/website-st4/download/ST-4.3.4.jar -cd ~/antlr/sites/website-st4/download -git add ST-4.3.4.jar -``` - -## Update site - -Find stuff: - -``` -cd ~/antlr/sites/website-st4 -find . -type f -exec grep -l '4\.3' {} \;|grep -v api -vi index.html scripts/topnav.js download.html -``` - diff --git a/doc/renderers.md b/doc/renderers.md index 40e1be1..623d853 100644 --- a/doc/renderers.md +++ b/doc/renderers.md @@ -1,79 +1,55 @@ # Attribute Renderers -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_`, ...). -For example, an integer object is converted to text as a sequence of characters representing the numeric value. -What if we want commas to separate the 1000's places like 1,000,000? -What if we want commas and sometimes periods depending on the locale? -For more, see [The Internationalization and Localization of Web Applications](https://www.cs.usfca.edu/~parrt/papers/i18n.pdf). +The atomic element of a template is a simple attribute (any value) that is rendered to text. For example, an number object is converted to text as a sequence of characters representing the numeric value. + +What if we want commas to separate the 1000's places like 1,000,000? What if we want commas and sometimes periods depending on the locale? For more, see [The Internationalization and Localization of Web Applications](https://www.cs.usfca.edu/~parrt/papers/i18n.pdf). StringTemplate lets you register objects that know how to format or otherwise render attributes to text appropriately. -There is one registered renderer per type per group. -In the statically type port languages like Java and C#, we use an interface to describe these renderers: +There is one registered renderer per type per group. The interface to describe these renderers: -``` -public interface AttributeRenderer { - public String toString(T value, String formatString, Locale locale); +```typescript +export interface IAttributeRendererOptions { + format?: string; + locale?: Intl.Locale; + timeZone?: string; +} + +export interface AttributeRenderer { + toString(value: T, options: IAttributeRendererOptions): string; } + ``` + +This implemenation differs somewhat from the Java variant. Because all of the options are optional we better use an interface that can specify any of the options in any order (or not). In Java these options are individual parameters. + +This approach allows us also to add parameters that are not useful for all renderers, like the `timeZone` field, which is relevant only for the `DateRender`. To render expression ``, StringTemplate looks for a renderer associated with the object type of `e`, say, *t*. If *t* is associated with a registered renderer, *r*, it is suitable and StringTemplate invokes the renderer method: | Expression syntax | How interpreter invokes renderer r | |-------------------|------------------------------------| -| `` | `r.toString(e, null, locale)` | -| `` | `r.toString(e, "f", locale)` | +| `` | `r.toString(e, { locale })` | +| `` | `r.toString(e, { format: "f", locale })` | -StringTemplate supplies either the default locale, or whatever locale was set by the programmer. -If the format string passed to the renderer is not recognized then the renderer should simply call the usual string evaluation method. +StringTemplate supplies either the default locale and time zone, or whatever locale/time zone was set by the programmer. If the format string passed to the renderer is not recognized then the renderer should simply call the usual string evaluation method. -To register a renderer, we tell the group to associate an object type with a renderer object. -Here's an example that tells StringTemplate to render numbers with an instance of NumberRenderer using the Polish locale: +To register a renderer, we tell the group to associate an object type with a renderer object. Here's an example that tells StringTemplate to render Date with an instance of DateRenderer using the Portuguese locale (taken from the unit tests): -```java -String template = - "foo(x,y) ::= << >>\n"; -STGroup g = new STGroupString(template); -g.registerRenderer(Number.class, new NumberRenderer()); -ST st = group.getInstanceOf("foo"); -st.add("x", -2100); -st.add("y", 3.14159); -String result = st.render(new Locale("pl")); -// resulted is " -2 100 3,142 " since Polish uses ' ' for ',' and ',' for '.' -``` - -**StringTemplate matches the types of expressions with the renderers using the "is instance of" relationship.** -As in this example, we registered a renderer for numbers and StringTemplate used it for subclasses such as integers and floating-point numbers. -Here's the renderer definition: - -```java -/** Works with Byte, Short, Integer, Long, and BigInteger as well as - * Float, Double, and BigDecimal. You pass in a format string suitable - * for Formatter object: - * - * https://docs.oracle.com/javase/1.5.0/docs/api/java/util/Formatter.html - * - * For example, "%10d" emits a number as a decimal int padding to 10 char. - * This can even do long to date conversions using the format string. - */ -public class NumberRenderer implements AttributeRenderer { - public String toString(Number o, String formatString, Locale locale) { - if ( formatString==null ) return o.toString(); - Formatter f = new Formatter(locale); - f.format(formatString, o); - return f.toString(); - } -} -``` +```typescript +const input = ""; +const group = new STGroup(); +group.registerRenderer(Date, new DateRenderer()); +const st = new ST(group, input); -You can register this renderer for `Number` or any subtype of it, but not unrelated types: +const date = new Date(2012, 5, 12); // Months are 0-based. +st?.add("date", date); -```java -STGroup g = ...; -g.registerRenderer(Number.class, new NumberRenderer()); // ok -g.registerRenderer(Integer.class, new NumberRenderer()); // ok -g.registerRenderer(Double.class, new NumberRenderer()); // ok -g.registerRenderer(String.class, new NumberRenderer()); // error +const expected = "12 de junho de 2012"; +assertEquals(expected, st?.render(new Intl.Locale("pt"))); ``` +**StringTemplate4TypeScript matches the types of expressions with the renderers using a manual prototype chain walk.** +As in this example, we registered a renderer for dates and StringTemplate used it for any subclass derived from a Date. + StringTemplate comes with three predefined renderers: `DateRenderer`, `StringRenderer`, and `NumberRenderer`. diff --git a/doc/scala-model-adaptor.md b/doc/scala-model-adaptor.md deleted file mode 100644 index 0b225b0..0000000 --- a/doc/scala-model-adaptor.md +++ /dev/null @@ -1,167 +0,0 @@ -# A Model Adaptor for Scala Case Classes - -One issue with the original adaptors is that they fail to access Scala case classes. In Scala, case classes of the following form are extremely convenient to use: - -```scala - case class Point(x: Int, y: Int) - case class Triangle(p1: Point, p2: Point, p3: Point) -``` - -Below, we have included one implementation of an adaptor that works with the aforementioned Scala case classes. The adaptor uses Scala reflection to fetch the desired property, and then converts it back to Java before passing it along to the interpreter. Of note, there is also a handy `register()` method in the companion object that allows for quicker and less verbose registering of a new adaptor to an `STGroup `. - -Note also that an adaptor for each case class (and each sub-class) must be registered for the template to render correctly. For example, to use the `Triangle` case class from above, you would have to register an adaptor for both the `Point` and `Triangle` classes. -```scala -import org.stringtemplate.v4._ -import org.stringtemplate.v4.misc._ - -import scala.collection.mutable -import scala.reflect.ClassTag -import scala.reflect.runtime.universe._ - -trait ToJava { - import scala.collection.JavaConverters._ - - /** - * Recursively converts to java object that is usable by ST4 - * Note: For Options, None is converted to empty string ("") - */ - def toObject(o: Any): Object = { - o match { - case opt: Option[_] => opt.fold[Object]("")(toObject) - case map: Map[_, _] => map.map { - case (k, v) => toObject(k) -> toObject(v) - }.asJava - case it: Iterable[_] => it.map(toObject).asJava - case obj: AnyRef => obj - case primitive => primitive.asInstanceOf[Object] - } - } -} - -// A Scala-friendly adaptor for use with ST4 -class ScalaModelAdaptor[T: TypeTag: ClassTag] extends ObjectModelAdaptor[T] with ToJava { - import ScalaModelAdaptor._ - - // stores seen fields/methods in mirrors for future reference - private val mirrorCache = mutable.Map.empty[String, MethodMirror] - - // tells ST4 how to get the fields from an object of type T - override def getProperty(interp: Interpreter, self: ST, model: T, property: Any, propertyName: String): Object = { - mirrorCache.get(propertyName) match { - case Some(mirror) => toObject(mirror.bind(model).apply()) - case _ => - typeOf[T].member(TermName(propertyName)) match { - case NoSymbol => "" // skip over mismatched properties - case refl => - val mirror = getMirror(refl, model) - mirrorCache.put(propertyName, mirror) - toObject(mirror.apply()) - } - } - } -} - -object ScalaModelAdaptor { - import scala.reflect.classTag - - // Registers a new ScalaModelAdaptor to a given STGroup - def register[T: TypeTag: ClassTag](st: STGroup): STGroup = { - val adaptor = new ScalaModelAdaptor[T] - st.registerModelAdaptor(classTag[T].runtimeClass.asInstanceOf[Class[T]], adaptor) - st - } - - private def getMirror[T: TypeTag: ClassTag](refl: Symbol, model: T): MethodMirror = { - scala.reflect.runtime.universe - .runtimeMirror(getClass.getClassLoader) - .reflect(model) - .reflectMethod(refl.asMethod) - } -} - -// and a representative test: -object STest { - case class Point(x: Int, y: Int) - case class PointClss(name: String, pointList: List[Point], pointMap: Map[Int, Point], pointSet: Set[Point], pointLL: List[List[Point]]) - - val p = Point(4, 5) - val q = Point(1, 6) - val r = Point(3, 2) - val pl = PointClss("Point Test", List(p, q ,r), Map(1 -> p, 2 -> q, 3 -> r), Set(p, q, r), List(List(p, q), List(q, r))) - - val group = { - val template = - """ - |pointPrinter(p) ::= "(, )" - | - |mapKeyVal(m) ::= << - |{ -> }; separator = ", ">} - |>> - | - |ll(p) ::= << - |[] - |>> - | - |test(t) ::= << - |: - |List: []; - |Map: ; - |Set: {}; - |List of list: [] - |>> - |""".stripMargin - val g = new STGroupString(template) - - ScalaModelAdaptor.register[PointClss](g) - ScalaModelAdaptor.register[Point](g) - } - - group.getInstanceOf("test").add("t", pl).render() - - /* should print: - Point Test: - List: [(4, 5), (1, 6), (3, 2)]; - Map: {1 -> Point(4,5), 2 -> Point(1,6), 3 -> Point(3,2)}; - Set: {(4, 5), (1, 6), (3, 2)}; - List of list: [[(4, 5), (1, 6)], [(1, 6), (3, 2)]] - */ -} -``` - -## Advanced Customization for More Specific Adaptors - -You can also extend this adaptor and override the `getProperty()` function to encode functionality that is specific to a certain case class. If the `toObject()` method is needed in the `getProperty()` override (for example, special casing with iterables, maps, or options), the new class can be extended with the `toJava` trait. For example, if you wanted to modify how the `x` and `y` values of the `Point` class outputted, you could write it like this: - -```scala -class PointAdaptor extends ScalaModelAdaptor[Point] with ToJava { - override def getProperty(interp: Interpreter, self: ST, model: Point, property: Any, propertyName: String): Object = { - propertyName match { - case "x" => s"x: ${super.getProperty(interp, self, model, property, propertyName)}" - case "y" => s"y: ${super.getProperty(interp, self, model, property, propertyName)}" - case "x_times" => - val x = super.getProperty(interp, self, model, property, "x").asInstanceOf[Int] - toObject(Seq.tabulate(x)(_ => model)) - case _ => super.getProperty(interp, self, model, property, propertyName) - } - } -} - -object PointTest extends App { - val p = Point(2, 5) - - val group = { - val template = - """ - |id(x) ::= "" - |point(p) ::= << - |(, ); - |>>""".stripMargin - val g = new STGroupString(template) - g.registerModelAdaptor(classTag[Point].runtimeClass.asInstanceOf[Class[Point]], new PointAdaptor) - g - } - - group.getInstanceOf("point").add("p", p).render() - // should render as: (x: 2, y: 5); Point(2,5), Point(2,5) -} -``` diff --git a/doc/templates.md b/doc/templates.md index 0f69b0d..2155450 100644 --- a/doc/templates.md +++ b/doc/templates.md @@ -230,3 +230,5 @@ In practice, delayed evaluation means that templates may be created and assemble ## Formal template syntax Please see [StringTemplate template parser](https://github.com/antlr/grammars-v4/blob/master/stringtemplate/STParser.g4). + +> Note: the Java implementation of StringTemplate uses a handwritten ST lexer and an own version of the ST parser grammar, not what is linked above. The TS port does the same, but might later be changed to use the grammars from the grammar directory. diff --git a/doc/wrapping.md b/doc/wrapping.md index 6c7036b..1be9af0 100644 --- a/doc/wrapping.md +++ b/doc/wrapping.md @@ -1,6 +1,6 @@ # Automatic line wrapping -StringTemplate never automatically wraps lines--you must explicitly use the wrap option on an expression to indicate that StringTemplate should wrap lines in between expression elements. StringTemplate never breaks literals, but it can break in between a literal and an expression. the line wrapping is soft in the sense that an expression that emits text starting before the right edge will spit out that element even if it goes past the right edge. In other words, StringTemplate does not break elements to enforce a hard right edge. It will not break line between element and separator to avoid having for example a comma appear at the left edge. You may specify the line width as an argument to `render()` such as `st.render(72`). By default, `render()` does not wrap lines. +StringTemplate never automatically wraps lines - you must explicitly use the wrap option on an expression to indicate that StringTemplate should wrap lines in between expression elements. StringTemplate never breaks literals, but it can break in between a literal and an expression. the line wrapping is soft in the sense that an expression that emits text starting before the right edge will spit out that element even if it goes past the right edge. In other words, StringTemplate does not break elements to enforce a hard right edge. It will not break line between element and separator to avoid having for example a comma appear at the left edge. You may specify the line width as an argument to `render()` such as `st.render(72`). By default, `render()` does not wrap lines. That said, if there's a newline in the literal to emit, it will wrap at the newline. diff --git a/package.json b/package.json index a3058d4..4c7b0f2 100644 --- a/package.json +++ b/package.json @@ -16,12 +16,12 @@ "license": "MIT", "scripts": { "prepublishOnly": "npm run build && npm run test", - "build": "npm run generate-parsers && tsc && esbuild ./src/index.js --main-fields=module,main --bundle --outfile=dist/stringtemplate4-ts.mjs --format=esm --platform=node --sourcemap", + "build": "npm run generate-parsers && tsc && esbuild ./src/index.js --main-fields=module,main --bundle --outfile=dist/stringtemplate4ts.mjs --format=esm --platform=node", "build-minified": "npm run build -- --minify", "test": "node --experimental-vm-modules --no-warnings --loader ts-node/esm ./node_modules/jest/bin/jest.js --no-coverage --silent", "test-ci": "npm run test -- --no-coverage --watchAll=false --silent", "test-coverage": "npm run test -- --coverage --silent", - "generate-parsers": "antlr4ng -no-visitor -no-listener -Dlanguage=TypeScript -o src/org/stringtemplate/v4/compiler/generated -package parser -encoding utf8 -Xexact-output-dir src/org/stringtemplate/v4/compiler/*.g4" + "generate-parsers": "antlr4ng -no-visitor -no-listener -Dlanguage=TypeScript -o src/compiler/generated -package parser -encoding utf8 -Xexact-output-dir src/compiler/*.g4" }, "devDependencies": { "@types/he": "1.2.3", diff --git a/src/org/stringtemplate/v4/AttributeRenderer.ts b/src/AttributeRenderer.ts similarity index 100% rename from src/org/stringtemplate/v4/AttributeRenderer.ts rename to src/AttributeRenderer.ts diff --git a/src/org/stringtemplate/v4/AutoIndentWriter.ts b/src/AutoIndentWriter.ts similarity index 100% rename from src/org/stringtemplate/v4/AutoIndentWriter.ts rename to src/AutoIndentWriter.ts diff --git a/src/org/stringtemplate/v4/DateRenderer.ts b/src/DateRenderer.ts similarity index 100% rename from src/org/stringtemplate/v4/DateRenderer.ts rename to src/DateRenderer.ts diff --git a/src/org/stringtemplate/v4/InstanceScope.ts b/src/InstanceScope.ts similarity index 100% rename from src/org/stringtemplate/v4/InstanceScope.ts rename to src/InstanceScope.ts diff --git a/src/org/stringtemplate/v4/Interpreter.ts b/src/Interpreter.ts similarity index 100% rename from src/org/stringtemplate/v4/Interpreter.ts rename to src/Interpreter.ts diff --git a/src/org/stringtemplate/v4/ModelAdaptor.ts b/src/ModelAdaptor.ts similarity index 100% rename from src/org/stringtemplate/v4/ModelAdaptor.ts rename to src/ModelAdaptor.ts diff --git a/src/org/stringtemplate/v4/NoIndentWriter.ts b/src/NoIndentWriter.ts similarity index 100% rename from src/org/stringtemplate/v4/NoIndentWriter.ts rename to src/NoIndentWriter.ts diff --git a/src/org/stringtemplate/v4/NumberRenderer.ts b/src/NumberRenderer.ts similarity index 100% rename from src/org/stringtemplate/v4/NumberRenderer.ts rename to src/NumberRenderer.ts diff --git a/src/org/stringtemplate/v4/ST.ts b/src/ST.ts similarity index 100% rename from src/org/stringtemplate/v4/ST.ts rename to src/ST.ts diff --git a/src/org/stringtemplate/v4/STErrorListener.ts b/src/STErrorListener.ts similarity index 100% rename from src/org/stringtemplate/v4/STErrorListener.ts rename to src/STErrorListener.ts diff --git a/src/org/stringtemplate/v4/STGroup.ts b/src/STGroup.ts similarity index 100% rename from src/org/stringtemplate/v4/STGroup.ts rename to src/STGroup.ts diff --git a/src/org/stringtemplate/v4/STGroupBase.ts b/src/STGroupBase.ts similarity index 100% rename from src/org/stringtemplate/v4/STGroupBase.ts rename to src/STGroupBase.ts diff --git a/src/org/stringtemplate/v4/STGroupDir.ts b/src/STGroupDir.ts similarity index 100% rename from src/org/stringtemplate/v4/STGroupDir.ts rename to src/STGroupDir.ts diff --git a/src/org/stringtemplate/v4/STGroupFile.ts b/src/STGroupFile.ts similarity index 100% rename from src/org/stringtemplate/v4/STGroupFile.ts rename to src/STGroupFile.ts diff --git a/src/org/stringtemplate/v4/STGroupString.ts b/src/STGroupString.ts similarity index 100% rename from src/org/stringtemplate/v4/STGroupString.ts rename to src/STGroupString.ts diff --git a/src/org/stringtemplate/v4/STRawGroupDir.ts b/src/STRawGroupDir.ts similarity index 100% rename from src/org/stringtemplate/v4/STRawGroupDir.ts rename to src/STRawGroupDir.ts diff --git a/src/org/stringtemplate/v4/STWriter.ts b/src/STWriter.ts similarity index 100% rename from src/org/stringtemplate/v4/STWriter.ts rename to src/STWriter.ts diff --git a/src/org/stringtemplate/v4/StringRenderer.ts b/src/StringRenderer.ts similarity index 100% rename from src/org/stringtemplate/v4/StringRenderer.ts rename to src/StringRenderer.ts diff --git a/src/org/stringtemplate/v4/compiler/Bytecode.ts b/src/compiler/Bytecode.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/Bytecode.ts rename to src/compiler/Bytecode.ts diff --git a/src/org/stringtemplate/v4/compiler/BytecodeDisassembler.ts b/src/compiler/BytecodeDisassembler.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/BytecodeDisassembler.ts rename to src/compiler/BytecodeDisassembler.ts diff --git a/src/org/stringtemplate/v4/compiler/CodeGenerator.ts b/src/compiler/CodeGenerator.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/CodeGenerator.ts rename to src/compiler/CodeGenerator.ts diff --git a/src/org/stringtemplate/v4/compiler/CompilationState.ts b/src/compiler/CompilationState.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/CompilationState.ts rename to src/compiler/CompilationState.ts diff --git a/src/org/stringtemplate/v4/compiler/CompiledST.ts b/src/compiler/CompiledST.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/CompiledST.ts rename to src/compiler/CompiledST.ts diff --git a/src/org/stringtemplate/v4/compiler/Compiler.ts b/src/compiler/Compiler.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/Compiler.ts rename to src/compiler/Compiler.ts diff --git a/src/org/stringtemplate/v4/compiler/FormalArgument.ts b/src/compiler/FormalArgument.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/FormalArgument.ts rename to src/compiler/FormalArgument.ts diff --git a/src/org/stringtemplate/v4/compiler/Group.g4 b/src/compiler/Group.g4 similarity index 100% rename from src/org/stringtemplate/v4/compiler/Group.g4 rename to src/compiler/Group.g4 diff --git a/src/org/stringtemplate/v4/compiler/STException.ts b/src/compiler/STException.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/STException.ts rename to src/compiler/STException.ts diff --git a/src/org/stringtemplate/v4/compiler/STLexer.tokens b/src/compiler/STLexer.tokens similarity index 100% rename from src/org/stringtemplate/v4/compiler/STLexer.tokens rename to src/compiler/STLexer.tokens diff --git a/src/org/stringtemplate/v4/compiler/STLexer.ts b/src/compiler/STLexer.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/STLexer.ts rename to src/compiler/STLexer.ts diff --git a/src/org/stringtemplate/v4/compiler/STParser.g4 b/src/compiler/STParser.g4 similarity index 100% rename from src/org/stringtemplate/v4/compiler/STParser.g4 rename to src/compiler/STParser.g4 diff --git a/src/org/stringtemplate/v4/compiler/StringTable.ts b/src/compiler/StringTable.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/StringTable.ts rename to src/compiler/StringTable.ts diff --git a/src/org/stringtemplate/v4/compiler/common.ts b/src/compiler/common.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/common.ts rename to src/compiler/common.ts diff --git a/src/org/stringtemplate/v4/compiler/factories.ts b/src/compiler/factories.ts similarity index 100% rename from src/org/stringtemplate/v4/compiler/factories.ts rename to src/compiler/factories.ts diff --git a/src/index.ts b/src/index.ts index 3b80d27..57c261e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,63 +5,63 @@ // Import and export all files in this directory. -export * from "./org/stringtemplate/v4/misc/ErrorType.js"; -export * from "./org/stringtemplate/v4/misc/STModelAdaptor.js"; -export * from "./org/stringtemplate/v4/misc/MapModelAdaptor.js"; -export * from "./org/stringtemplate/v4/misc/AggregateModelAdaptor.js"; -export * from "./org/stringtemplate/v4/misc/STLexerMessage.js"; -export * from "./org/stringtemplate/v4/misc/STNoSuchPropertyException.js"; -export * from "./org/stringtemplate/v4/misc/MultiMap.js"; -export * from "./org/stringtemplate/v4/misc/STCompiletimeMessage.js"; -export * from "./org/stringtemplate/v4/misc/TypeRegistry.js"; -export * from "./org/stringtemplate/v4/misc/Coordinate.js"; -export * from "./org/stringtemplate/v4/misc/ErrorBuffer.js"; -export * from "./org/stringtemplate/v4/misc/AmbiguousMatchException.js"; -export * from "./org/stringtemplate/v4/misc/STMessage.js"; -export * from "./org/stringtemplate/v4/misc/STRuntimeMessage.js"; -export * from "./org/stringtemplate/v4/misc/ObjectModelAdaptor.js"; -export * from "./org/stringtemplate/v4/misc/ErrorManager.js"; -export * from "./org/stringtemplate/v4/misc/Aggregate.js"; -export * from "./org/stringtemplate/v4/misc/Misc.js"; -export * from "./org/stringtemplate/v4/misc/STGroupCompiletimeMessage.js"; -export * from "./org/stringtemplate/v4/misc/STNoSuchAttributeException.js"; -export * from "./org/stringtemplate/v4/STGroupString.js"; -export * from "./org/stringtemplate/v4/DateRenderer.js"; -export * from "./org/stringtemplate/v4/STGroupFile.js"; -export * from "./org/stringtemplate/v4/InstanceScope.js"; -export * from "./org/stringtemplate/v4/StringRenderer.js"; -export * from "./org/stringtemplate/v4/AttributeRenderer.js"; -export * from "./org/stringtemplate/v4/STGroup.js"; -export * from "./org/stringtemplate/v4/Interpreter.js"; -export * from "./org/stringtemplate/v4/STGroupDir.js"; -export * from "./org/stringtemplate/v4/STRawGroupDir.js"; -export * from "./org/stringtemplate/v4/NumberRenderer.js"; -export * from "./org/stringtemplate/v4/STWriter.js"; -export * from "./org/stringtemplate/v4/ModelAdaptor.js"; -export * from "./org/stringtemplate/v4/support/helpers.js"; -export * from "./org/stringtemplate/v4/support/StringWriter.js"; -export * from "./org/stringtemplate/v4/support/Writer.js"; -export * from "./org/stringtemplate/v4/support/Stack.js"; -export * from "./org/stringtemplate/v4/AutoIndentWriter.js"; -export * from "./org/stringtemplate/v4/ST.js"; -export * from "./org/stringtemplate/v4/compiler/generated/STParser.js"; -export * from "./org/stringtemplate/v4/compiler/generated/GroupParser.js"; -export * from "./org/stringtemplate/v4/compiler/generated/GroupLexer.js"; -export * from "./org/stringtemplate/v4/compiler/CompiledST.js"; -export * from "./org/stringtemplate/v4/compiler/Bytecode.js"; -export * from "./org/stringtemplate/v4/compiler/STException.js"; -export * from "./org/stringtemplate/v4/compiler/STLexer.js"; -export * from "./org/stringtemplate/v4/compiler/BytecodeDisassembler.js"; -export * from "./org/stringtemplate/v4/compiler/CompilationState.js"; -export * from "./org/stringtemplate/v4/compiler/FormalArgument.js"; -export * from "./org/stringtemplate/v4/compiler/CodeGenerator.js"; -export * from "./org/stringtemplate/v4/compiler/Compiler.js"; -export * from "./org/stringtemplate/v4/compiler/StringTable.js"; -export * from "./org/stringtemplate/v4/STErrorListener.js"; -export * from "./org/stringtemplate/v4/NoIndentWriter.js"; -export * from "./org/stringtemplate/v4/reflection/Method.js"; -export * from "./org/stringtemplate/v4/reflection/IMember.js"; -export * from "./org/stringtemplate/v4/reflection/Field.js"; +export * from "./misc/ErrorType.js"; +export * from "./misc/STModelAdaptor.js"; +export * from "./misc/MapModelAdaptor.js"; +export * from "./misc/AggregateModelAdaptor.js"; +export * from "./misc/STLexerMessage.js"; +export * from "./misc/STNoSuchPropertyException.js"; +export * from "./misc/MultiMap.js"; +export * from "./misc/STCompiletimeMessage.js"; +export * from "./misc/TypeRegistry.js"; +export * from "./misc/Coordinate.js"; +export * from "./misc/ErrorBuffer.js"; +export * from "./misc/AmbiguousMatchException.js"; +export * from "./misc/STMessage.js"; +export * from "./misc/STRuntimeMessage.js"; +export * from "./misc/ObjectModelAdaptor.js"; +export * from "./misc/ErrorManager.js"; +export * from "./misc/Aggregate.js"; +export * from "./misc/Misc.js"; +export * from "./misc/STGroupCompiletimeMessage.js"; +export * from "./misc/STNoSuchAttributeException.js"; +export * from "./STGroupString.js"; +export * from "./DateRenderer.js"; +export * from "./STGroupFile.js"; +export * from "./InstanceScope.js"; +export * from "./StringRenderer.js"; +export * from "./AttributeRenderer.js"; +export * from "./STGroup.js"; +export * from "./Interpreter.js"; +export * from "./STGroupDir.js"; +export * from "./STRawGroupDir.js"; +export * from "./NumberRenderer.js"; +export * from "./STWriter.js"; +export * from "./ModelAdaptor.js"; +export * from "./support/helpers.js"; +export * from "./support/StringWriter.js"; +export * from "./support/Writer.js"; +export * from "./support/Stack.js"; +export * from "./AutoIndentWriter.js"; +export * from "./ST.js"; +export * from "./compiler/generated/STParser.js"; +export * from "./compiler/generated/GroupParser.js"; +export * from "./compiler/generated/GroupLexer.js"; +export * from "./compiler/CompiledST.js"; +export * from "./compiler/Bytecode.js"; +export * from "./compiler/STException.js"; +export * from "./compiler/STLexer.js"; +export * from "./compiler/BytecodeDisassembler.js"; +export * from "./compiler/CompilationState.js"; +export * from "./compiler/FormalArgument.js"; +export * from "./compiler/CodeGenerator.js"; +export * from "./compiler/Compiler.js"; +export * from "./compiler/StringTable.js"; +export * from "./STErrorListener.js"; +export * from "./NoIndentWriter.js"; +export * from "./reflection/Method.js"; +export * from "./reflection/IMember.js"; +export * from "./reflection/Field.js"; -export * from "./org/stringtemplate/v4/support/HashMap.js"; -export * from "./org/stringtemplate/v4/support/TimeZone.js"; +export * from "./support/HashMap.js"; +export * from "./support/TimeZone.js"; diff --git a/src/org/stringtemplate/v4/misc/Aggregate.ts b/src/misc/Aggregate.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/Aggregate.ts rename to src/misc/Aggregate.ts diff --git a/src/org/stringtemplate/v4/misc/AggregateModelAdaptor.ts b/src/misc/AggregateModelAdaptor.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/AggregateModelAdaptor.ts rename to src/misc/AggregateModelAdaptor.ts diff --git a/src/org/stringtemplate/v4/misc/AmbiguousMatchException.ts b/src/misc/AmbiguousMatchException.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/AmbiguousMatchException.ts rename to src/misc/AmbiguousMatchException.ts diff --git a/src/org/stringtemplate/v4/misc/Coordinate.ts b/src/misc/Coordinate.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/Coordinate.ts rename to src/misc/Coordinate.ts diff --git a/src/org/stringtemplate/v4/misc/ErrorBuffer.ts b/src/misc/ErrorBuffer.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/ErrorBuffer.ts rename to src/misc/ErrorBuffer.ts diff --git a/src/org/stringtemplate/v4/misc/ErrorManager.ts b/src/misc/ErrorManager.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/ErrorManager.ts rename to src/misc/ErrorManager.ts diff --git a/src/org/stringtemplate/v4/misc/ErrorType.ts b/src/misc/ErrorType.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/ErrorType.ts rename to src/misc/ErrorType.ts diff --git a/src/org/stringtemplate/v4/misc/MapModelAdaptor.ts b/src/misc/MapModelAdaptor.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/MapModelAdaptor.ts rename to src/misc/MapModelAdaptor.ts diff --git a/src/org/stringtemplate/v4/misc/Misc.ts b/src/misc/Misc.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/Misc.ts rename to src/misc/Misc.ts diff --git a/src/org/stringtemplate/v4/misc/MultiMap.ts b/src/misc/MultiMap.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/MultiMap.ts rename to src/misc/MultiMap.ts diff --git a/src/org/stringtemplate/v4/misc/ObjectModelAdaptor.ts b/src/misc/ObjectModelAdaptor.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/ObjectModelAdaptor.ts rename to src/misc/ObjectModelAdaptor.ts diff --git a/src/org/stringtemplate/v4/misc/STCompiletimeMessage.ts b/src/misc/STCompiletimeMessage.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STCompiletimeMessage.ts rename to src/misc/STCompiletimeMessage.ts diff --git a/src/org/stringtemplate/v4/misc/STGroupCompiletimeMessage.ts b/src/misc/STGroupCompiletimeMessage.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STGroupCompiletimeMessage.ts rename to src/misc/STGroupCompiletimeMessage.ts diff --git a/src/org/stringtemplate/v4/misc/STLexerMessage.ts b/src/misc/STLexerMessage.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STLexerMessage.ts rename to src/misc/STLexerMessage.ts diff --git a/src/org/stringtemplate/v4/misc/STMessage.ts b/src/misc/STMessage.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STMessage.ts rename to src/misc/STMessage.ts diff --git a/src/org/stringtemplate/v4/misc/STModelAdaptor.ts b/src/misc/STModelAdaptor.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STModelAdaptor.ts rename to src/misc/STModelAdaptor.ts diff --git a/src/org/stringtemplate/v4/misc/STNoSuchAttributeException.ts b/src/misc/STNoSuchAttributeException.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STNoSuchAttributeException.ts rename to src/misc/STNoSuchAttributeException.ts diff --git a/src/org/stringtemplate/v4/misc/STNoSuchPropertyException.ts b/src/misc/STNoSuchPropertyException.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STNoSuchPropertyException.ts rename to src/misc/STNoSuchPropertyException.ts diff --git a/src/org/stringtemplate/v4/misc/STRuntimeMessage.ts b/src/misc/STRuntimeMessage.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/STRuntimeMessage.ts rename to src/misc/STRuntimeMessage.ts diff --git a/src/org/stringtemplate/v4/misc/TypeRegistry.ts b/src/misc/TypeRegistry.ts similarity index 100% rename from src/org/stringtemplate/v4/misc/TypeRegistry.ts rename to src/misc/TypeRegistry.ts diff --git a/src/org/stringtemplate/v4/reflection/Field.ts b/src/reflection/Field.ts similarity index 100% rename from src/org/stringtemplate/v4/reflection/Field.ts rename to src/reflection/Field.ts diff --git a/src/org/stringtemplate/v4/reflection/IMember.ts b/src/reflection/IMember.ts similarity index 100% rename from src/org/stringtemplate/v4/reflection/IMember.ts rename to src/reflection/IMember.ts diff --git a/src/org/stringtemplate/v4/reflection/Method.ts b/src/reflection/Method.ts similarity index 100% rename from src/org/stringtemplate/v4/reflection/Method.ts rename to src/reflection/Method.ts diff --git a/src/org/stringtemplate/v4/support/HashMap.ts b/src/support/HashMap.ts similarity index 100% rename from src/org/stringtemplate/v4/support/HashMap.ts rename to src/support/HashMap.ts diff --git a/src/org/stringtemplate/v4/support/HashMapIterator.ts b/src/support/HashMapIterator.ts similarity index 100% rename from src/org/stringtemplate/v4/support/HashMapIterator.ts rename to src/support/HashMapIterator.ts diff --git a/src/org/stringtemplate/v4/support/MurmurHash.ts b/src/support/MurmurHash.ts similarity index 100% rename from src/org/stringtemplate/v4/support/MurmurHash.ts rename to src/support/MurmurHash.ts diff --git a/src/org/stringtemplate/v4/support/Stack.ts b/src/support/Stack.ts similarity index 100% rename from src/org/stringtemplate/v4/support/Stack.ts rename to src/support/Stack.ts diff --git a/src/org/stringtemplate/v4/support/StringWriter.ts b/src/support/StringWriter.ts similarity index 100% rename from src/org/stringtemplate/v4/support/StringWriter.ts rename to src/support/StringWriter.ts diff --git a/src/org/stringtemplate/v4/support/TimeZone.ts b/src/support/TimeZone.ts similarity index 100% rename from src/org/stringtemplate/v4/support/TimeZone.ts rename to src/support/TimeZone.ts diff --git a/src/org/stringtemplate/v4/support/Writer.ts b/src/support/Writer.ts similarity index 100% rename from src/org/stringtemplate/v4/support/Writer.ts rename to src/support/Writer.ts diff --git a/src/org/stringtemplate/v4/support/helpers.ts b/src/support/helpers.ts similarity index 100% rename from src/org/stringtemplate/v4/support/helpers.ts rename to src/support/helpers.ts diff --git a/tests/org/stringtemplate/v4/test/BaseTest.ts b/tests/BaseTest.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/BaseTest.ts rename to tests/BaseTest.ts index 78e2c7a..9d8917e 100644 --- a/tests/org/stringtemplate/v4/test/BaseTest.ts +++ b/tests/BaseTest.ts @@ -11,8 +11,8 @@ import { existsSync, mkdirSync, rmSync, statSync, unlinkSync, writeFileSync } fr import { CharStreams, CommonToken, CommonTokenStream, Token } from "antlr4ng"; -import { Compiler, ST, STGroup, STLexer } from "../../../../../src/index.js"; -import { AfterEach, BeforeEach } from "../../../../decorators.js"; +import { Compiler, ST, STGroup, STLexer } from "../src/index.js"; +import { AfterEach, BeforeEach } from "./decorators.js"; export abstract class BaseTest { public static readonly pathSep = path.delimiter; diff --git a/tests/org/stringtemplate/v4/test/ErrorBufferAllErrors.ts b/tests/ErrorBufferAllErrors.ts similarity index 73% rename from tests/org/stringtemplate/v4/test/ErrorBufferAllErrors.ts rename to tests/ErrorBufferAllErrors.ts index 9b0f548..193bccc 100644 --- a/tests/org/stringtemplate/v4/test/ErrorBufferAllErrors.ts +++ b/tests/ErrorBufferAllErrors.ts @@ -5,9 +5,9 @@ // cspell: disable -import { ErrorBuffer, STMessage } from "../../../../../src/index.js"; +import { ErrorBuffer, STMessage } from "../src/index.js"; -import { Override } from "../../../../decorators.js"; +import { Override } from "./decorators.js"; export class ErrorBufferAllErrors extends ErrorBuffer { @Override diff --git a/tests/Test.spec.ts b/tests/Test.spec.ts index 655b664..32c6fea 100644 --- a/tests/Test.spec.ts +++ b/tests/Test.spec.ts @@ -1,42 +1,42 @@ /* * Copyright (c) Mike Lischke. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. See License-MIT.txt in the project root for license information. */ import { TestNG } from "./TestNG.js"; -import { TestAggregates } from "./org/stringtemplate/v4/test/TestAggregates.js"; -import { TestAttributes } from "./org/stringtemplate/v4/test/TestAttributes.js"; -import { TestBuggyDefaultValueRaisesNPETest } from "./org/stringtemplate/v4/test/TestBuggyDefaultValueRaisesNPETest.js"; -import { TestCompiler } from "./org/stringtemplate/v4/test/TestCompiler.js"; -import { TestCoreBasics } from "./org/stringtemplate/v4/test/TestCoreBasics.js"; -import { TestDictionaries } from "./org/stringtemplate/v4/test/TestDictionaries.js"; -import { TestDollarDelimiters } from "./org/stringtemplate/v4/test/TestDollarDelimiters.js"; -import { TestEarlyEvaluation } from "./org/stringtemplate/v4/test/TestEarlyEvaluation.js"; -import { TestFunctions } from "./org/stringtemplate/v4/test/TestFunctions.js"; -import { TestGroupSyntax } from "./org/stringtemplate/v4/test/TestGroupSyntax.js"; -import { TestGroupSyntaxErrors } from "./org/stringtemplate/v4/test/TestGroupSyntaxErrors.js"; -import { TestGroups } from "./org/stringtemplate/v4/test/TestGroups.js"; -import { TestImports } from "./org/stringtemplate/v4/test/TestImports.js"; -import { TestIndentation } from "./org/stringtemplate/v4/test/TestIndentation.js"; -import { TestIndirectionAndEarlyEval } from "./org/stringtemplate/v4/test/TestIndirectionAndEarlyEval.js"; -import { TestInterptimeErrors } from "./org/stringtemplate/v4/test/TestInterptimeErrors.js"; -import { TestLexer } from "./org/stringtemplate/v4/test/TestLexer.js"; -import { TestLineWrap } from "./org/stringtemplate/v4/test/TestLineWrap.js"; -import { TestLists } from "./org/stringtemplate/v4/test/TestLists.js"; -import { TestModelAdaptors } from "./org/stringtemplate/v4/test/TestModelAdaptors.js"; -import { TestNoNewlineTemplates } from "./org/stringtemplate/v4/test/TestNoNewlineTemplates.js"; -import { TestNullAndEmptyValues } from "./org/stringtemplate/v4/test/TestNullAndEmptyValues.js"; -import { TestOptions } from "./org/stringtemplate/v4/test/TestOptions.js"; -import { TestRegions } from "./org/stringtemplate/v4/test/TestRegions.js"; -import { TestRenderers } from "./org/stringtemplate/v4/test/TestRenderers.js"; -import { TestSTRawGroupDir } from "./org/stringtemplate/v4/test/TestSTRawGroupDir.js"; -import { TestScopes } from "./org/stringtemplate/v4/test/TestScopes.js"; -import { TestSubtemplates } from "./org/stringtemplate/v4/test/TestSubtemplates.js"; -import { TestSyntaxErrors } from "./org/stringtemplate/v4/test/TestSyntaxErrors.js"; -import { TestTemplateNames } from "./org/stringtemplate/v4/test/TestTemplateNames.js"; -import { TestTokensForDollarDelimiters } from "./org/stringtemplate/v4/test/TestTokensForDollarDelimiters.js"; -import { TestTypeRegistry } from "./org/stringtemplate/v4/test/TestTypeRegistry.js"; -import { TestWhitespace } from "./org/stringtemplate/v4/test/TestWhitespace.js"; +import { TestAggregates } from "./TestAggregates.js"; +import { TestAttributes } from "./TestAttributes.js"; +import { TestBuggyDefaultValueRaisesNPETest } from "./TestBuggyDefaultValueRaisesNPETest.js"; +import { TestCompiler } from "./TestCompiler.js"; +import { TestCoreBasics } from "./TestCoreBasics.js"; +import { TestDictionaries } from "./TestDictionaries.js"; +import { TestDollarDelimiters } from "./TestDollarDelimiters.js"; +import { TestEarlyEvaluation } from "./TestEarlyEvaluation.js"; +import { TestFunctions } from "./TestFunctions.js"; +import { TestGroupSyntax } from "./TestGroupSyntax.js"; +import { TestGroupSyntaxErrors } from "./TestGroupSyntaxErrors.js"; +import { TestGroups } from "./TestGroups.js"; +import { TestImports } from "./TestImports.js"; +import { TestIndentation } from "./TestIndentation.js"; +import { TestIndirectionAndEarlyEval } from "./TestIndirectionAndEarlyEval.js"; +import { TestInterptimeErrors } from "./TestInterptimeErrors.js"; +import { TestLexer } from "./TestLexer.js"; +import { TestLineWrap } from "./TestLineWrap.js"; +import { TestLists } from "./TestLists.js"; +import { TestModelAdaptors } from "./TestModelAdaptors.js"; +import { TestNoNewlineTemplates } from "./TestNoNewlineTemplates.js"; +import { TestNullAndEmptyValues } from "./TestNullAndEmptyValues.js"; +import { TestOptions } from "./TestOptions.js"; +import { TestRegions } from "./TestRegions.js"; +import { TestRenderers } from "./TestRenderers.js"; +import { TestSTRawGroupDir } from "./TestSTRawGroupDir.js"; +import { TestScopes } from "./TestScopes.js"; +import { TestSubtemplates } from "./TestSubtemplates.js"; +import { TestSyntaxErrors } from "./TestSyntaxErrors.js"; +import { TestTemplateNames } from "./TestTemplateNames.js"; +import { TestTokensForDollarDelimiters } from "./TestTokensForDollarDelimiters.js"; +import { TestTypeRegistry } from "./TestTypeRegistry.js"; +import { TestWhitespace } from "./TestWhitespace.js"; describe("TestAggregates", () => { const testNG = new TestNG(); diff --git a/tests/org/stringtemplate/v4/test/TestAggregates.ts b/tests/TestAggregates.ts similarity index 92% rename from tests/org/stringtemplate/v4/test/TestAggregates.ts rename to tests/TestAggregates.ts index a487854..8b732a2 100644 --- a/tests/org/stringtemplate/v4/test/TestAggregates.ts +++ b/tests/TestAggregates.ts @@ -5,11 +5,11 @@ // cspell: disable -import { Misc, ST, STGroupString } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { Misc, ST, STGroupString } from "../src/index.js"; +import { assertEquals } from "./junit.js"; import { BaseTest } from "./BaseTest.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; /** */ export class TestAggregates extends BaseTest { diff --git a/tests/org/stringtemplate/v4/test/TestAttributes.ts b/tests/TestAttributes.ts similarity index 87% rename from tests/org/stringtemplate/v4/test/TestAttributes.ts rename to tests/TestAttributes.ts index efb5369..d2590b6 100644 --- a/tests/org/stringtemplate/v4/test/TestAttributes.ts +++ b/tests/TestAttributes.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { assertTrue } from "../../../../junit.js"; -import { ST } from "../../../../../src/index.js"; +import { assertTrue } from "./junit.js"; +import { ST } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestAttributes extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestBuggyDefaultValueRaisesNPETest.ts b/tests/TestBuggyDefaultValueRaisesNPETest.ts similarity index 86% rename from tests/org/stringtemplate/v4/test/TestBuggyDefaultValueRaisesNPETest.ts rename to tests/TestBuggyDefaultValueRaisesNPETest.ts index 682da89..2867c68 100644 --- a/tests/org/stringtemplate/v4/test/TestBuggyDefaultValueRaisesNPETest.ts +++ b/tests/TestBuggyDefaultValueRaisesNPETest.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { ErrorBuffer, STGroupFile } from "../../../../../src/index.js"; +import { ErrorBuffer, STGroupFile } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; -import { assertEquals } from "../../../../junit.js"; +import { Test } from "./decorators.js"; +import { assertEquals } from "./junit.js"; export class TestBuggyDefaultValueRaisesNPETest extends BaseTest { /** diff --git a/tests/org/stringtemplate/v4/test/TestCompiler.ts b/tests/TestCompiler.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestCompiler.ts rename to tests/TestCompiler.ts index 04f15ea..105b1f8 100644 --- a/tests/org/stringtemplate/v4/test/TestCompiler.ts +++ b/tests/TestCompiler.ts @@ -60,10 +60,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { ErrorBuffer, STGroup, Compiler, ErrorManager } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { ErrorBuffer, STGroup, Compiler, ErrorManager } from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestCompiler extends BaseTest { diff --git a/tests/org/stringtemplate/v4/test/TestCoreBasics.ts b/tests/TestCoreBasics.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestCoreBasics.ts rename to tests/TestCoreBasics.ts index 5904bdf..68217e3 100644 --- a/tests/org/stringtemplate/v4/test/TestCoreBasics.ts +++ b/tests/TestCoreBasics.ts @@ -7,13 +7,13 @@ import { ErrorBufferAllErrors } from "./ErrorBufferAllErrors.js"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; +import { assertEquals } from "./junit.js"; import { ST, ErrorBuffer, STGroup, STGroupFile, STRuntimeMessage, STNoSuchPropertyException, STGroupString, AutoIndentWriter, NoIndentWriter, Misc, StringWriter, ErrorManager, -} from "../../../../../src/index.js"; +} from "../src/index.js"; -import { AfterAll, BeforeAll, Test } from "../../../../decorators.js"; +import { AfterAll, BeforeAll, Test } from "./decorators.js"; export class TestCoreBasics extends BaseTest { @BeforeAll diff --git a/tests/org/stringtemplate/v4/test/TestDictionaries.ts b/tests/TestDictionaries.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestDictionaries.ts rename to tests/TestDictionaries.ts index 5af41fa..7ea4c55 100644 --- a/tests/org/stringtemplate/v4/test/TestDictionaries.ts +++ b/tests/TestDictionaries.ts @@ -35,10 +35,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { Assert, assertEquals } from "../../../../junit.js"; -import { STGroupFile, ST, ErrorBuffer, STGroupString, Misc, HashMap, ErrorManager } from "../../../../../src/index.js"; +import { assertEquals, assertNotNull } from "./junit.js"; +import { STGroupFile, ST, ErrorBuffer, STGroupString, Misc, HashMap, ErrorManager } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestDictionaries extends BaseTest { @Test @@ -385,13 +385,13 @@ export class TestDictionaries extends BaseTest { TestDictionaries.writeFile(this.tmpdir, "t.stg", templates); const group = new STGroupFile(path.join(this.tmpdir, "t.stg")); const st = group.getInstanceOf("top"); - Assert.assertNotNull(st); + assertNotNull(st); const expecting = " electric " + Misc.newLine + " force" + Misc.newLine + " in between"; - Assert.assertEquals(expecting, st?.render()); + assertEquals(expecting, st?.render()); } @Test @@ -416,13 +416,13 @@ export class TestDictionaries extends BaseTest { TestDictionaries.writeFile(this.tmpdir, "t.stg", templates); const group = new STGroupFile(path.join(this.tmpdir, "t.stg")); const st = group.getInstanceOf("top"); - Assert.assertNotNull(st); + assertNotNull(st); const expecting = " electric foo" + Misc.newLine + " foo force" + Misc.newLine + " in foo between"; - Assert.assertEquals(expecting, st?.render()); + assertEquals(expecting, st?.render()); } @Test diff --git a/tests/org/stringtemplate/v4/test/TestDollarDelimiters.ts b/tests/TestDollarDelimiters.ts similarity index 95% rename from tests/org/stringtemplate/v4/test/TestDollarDelimiters.ts rename to tests/TestDollarDelimiters.ts index f2fc05e..e0a851e 100644 --- a/tests/org/stringtemplate/v4/test/TestDollarDelimiters.ts +++ b/tests/TestDollarDelimiters.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { Assert, assertEquals } from "../../../../junit.js"; -import { Misc, ST, STGroup, STGroupDir, STGroupFile, STGroupString } from "../../../../../src/index.js"; +import { assertEquals, assertNotNull } from "./junit.js"; +import { Misc, ST, STGroup, STGroupDir, STGroupFile, STGroupString } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestDollarDelimiters extends BaseTest { @Test @@ -137,14 +137,14 @@ export class TestDollarDelimiters extends BaseTest { // test html template directly let st = group.getInstanceOf("html"); - Assert.assertNotNull(st); + assertNotNull(st); let expected = ""; let result = st?.render(); assertEquals(expected, result); // test from entry template st = group.getInstanceOf("entry"); - Assert.assertNotNull(st); + assertNotNull(st); expected = "
"; result = st?.render(); assertEquals(expected, result); @@ -175,14 +175,14 @@ export class TestDollarDelimiters extends BaseTest { // test html template directly let st = group.getInstanceOf("html"); - Assert.assertNotNull(st); + assertNotNull(st); let expected = "
"; let result = st?.render(); assertEquals(expected, result); // test from entry template st = group.getInstanceOf("entry"); - Assert.assertNotNull(st); + assertNotNull(st); expected = "
"; result = st?.render(); assertEquals(expected, result); @@ -214,14 +214,14 @@ export class TestDollarDelimiters extends BaseTest { // test html template directly let st = group.getInstanceOf("html"); - Assert.assertNotNull(st); + assertNotNull(st); let expected = "
"; let result = st?.render(); assertEquals(expected, result); // test from entry template st = group.getInstanceOf("entry"); - Assert.assertNotNull(st); + assertNotNull(st); expected = "
"; result = st?.render(); assertEquals(expected, result); @@ -254,14 +254,14 @@ export class TestDollarDelimiters extends BaseTest { // test html template directly let st = group.getInstanceOf("html"); - Assert.assertNotNull(st); + assertNotNull(st); let expected = "
"; let result = st?.render(); assertEquals(expected, result); // test from entry template st = group.getInstanceOf("entry"); - Assert.assertNotNull(st); + assertNotNull(st); expected = "
"; result = st?.render(); assertEquals(expected, result); diff --git a/tests/org/stringtemplate/v4/test/TestEarlyEvaluation.ts b/tests/TestEarlyEvaluation.ts similarity index 85% rename from tests/org/stringtemplate/v4/test/TestEarlyEvaluation.ts rename to tests/TestEarlyEvaluation.ts index c857421..b5c44e5 100644 --- a/tests/org/stringtemplate/v4/test/TestEarlyEvaluation.ts +++ b/tests/TestEarlyEvaluation.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { ErrorManager, STGroupFile } from "../../../../../src/index.js"; +import { ErrorManager, STGroupFile } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; -import { Assert } from "../../../../junit.js"; +import { Test } from "./decorators.js"; +import { assertEquals } from "./junit.js"; export class TestEarlyEvaluation extends BaseTest { /** @@ -27,7 +27,7 @@ export class TestEarlyEvaluation extends BaseTest { const group = new STGroupFile(this.tmpdir + "/t.stg"); const st = group.getInstanceOf("main"); const s = st?.render(); - Assert.assertEquals("-ax-*-ay-", s); + assertEquals("-ax-*-ay-", s); } /** @@ -45,7 +45,7 @@ export class TestEarlyEvaluation extends BaseTest { const group = new STGroupFile(this.tmpdir + "/t.stg"); const st = group.getInstanceOf("main"); const s = st?.render(); - Assert.assertEquals("-ax-*", s); + assertEquals("-ax-*", s); } /** @@ -69,7 +69,7 @@ export class TestEarlyEvaluation extends BaseTest { ErrorManager.DEFAULT_ERROR_LISTENER.silent = false; - Assert.assertEquals("Hello", s); + assertEquals("Hello", s); } @Test @@ -80,11 +80,11 @@ export class TestEarlyEvaluation extends BaseTest { const group = new STGroupFile(this.tmpdir + "/t.stg"); const st = group.getInstanceOf("main"); let s = st?.render(); - Assert.assertEquals(" bar ", s); + assertEquals(" bar ", s); st?.add("x", "true"); s = st?.render(); - Assert.assertEquals(" foo ", s); + assertEquals(" foo ", s); } @Test @@ -95,7 +95,7 @@ export class TestEarlyEvaluation extends BaseTest { const group = new STGroupFile(this.tmpdir + "/t.stg"); const st = group.getInstanceOf("main"); const s = st?.render(); - Assert.assertEquals(" foo ", s); + assertEquals(" foo ", s); } @Test @@ -113,11 +113,11 @@ export class TestEarlyEvaluation extends BaseTest { st?.add("x", null); let s = st?.render(); - Assert.assertEquals(" pt: other, if ", s); + assertEquals(" pt: other, if ", s); st?.add("x", "arr"); s = st?.render(); - Assert.assertEquals(" parrt: value, if ", s); + assertEquals(" parrt: value, if ", s); } @Test @@ -132,11 +132,11 @@ export class TestEarlyEvaluation extends BaseTest { st?.add("x", null); let s = st?.render(); - Assert.assertEquals(" pt: , else ", s); // m[null] has no default value so else clause + assertEquals(" pt: , else ", s); // m[null] has no default value so else clause st?.add("x", "arr"); s = st?.render(); - Assert.assertEquals(" parrt: value, if ", s); + assertEquals(" parrt: value, if ", s); } } diff --git a/tests/org/stringtemplate/v4/test/TestFunctions.ts b/tests/TestFunctions.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestFunctions.ts rename to tests/TestFunctions.ts index 702027f..81e9443 100644 --- a/tests/org/stringtemplate/v4/test/TestFunctions.ts +++ b/tests/TestFunctions.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { ErrorManager, Misc, ST, STGroupFile } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { ErrorManager, Misc, ST, STGroupFile } from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestFunctions extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestGroupSyntax.ts b/tests/TestGroupSyntax.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestGroupSyntax.ts rename to tests/TestGroupSyntax.ts index 7699856..a5b02f3 100644 --- a/tests/org/stringtemplate/v4/test/TestGroupSyntax.ts +++ b/tests/TestGroupSyntax.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals, assertNotNull } from "../../../../junit.js"; -import { Misc, STGroupFile, ErrorBuffer, STGroupString } from "../../../../../src/index.js"; +import { assertEquals, assertNotNull } from "./junit.js"; +import { Misc, STGroupFile, ErrorBuffer, STGroupString } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestGroupSyntax extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestGroupSyntaxErrors.ts b/tests/TestGroupSyntaxErrors.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestGroupSyntaxErrors.ts rename to tests/TestGroupSyntaxErrors.ts index cb0ed64..76c91a2 100644 --- a/tests/org/stringtemplate/v4/test/TestGroupSyntaxErrors.ts +++ b/tests/TestGroupSyntaxErrors.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; -import { ErrorBuffer, Misc, STGroupFile } from "../../../../../src/index.js"; +import { assertEquals } from "./junit.js"; +import { ErrorBuffer, Misc, STGroupFile } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestGroupSyntaxErrors extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestGroups.ts b/tests/TestGroups.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestGroups.ts rename to tests/TestGroups.ts index 5bf84c2..23abf22 100644 --- a/tests/org/stringtemplate/v4/test/TestGroups.ts +++ b/tests/TestGroups.ts @@ -10,10 +10,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { Assert, assertEquals, assertNull, assertTrue } from "../../../../junit.js"; -import { STGroupDir, STGroupString, ErrorBuffer, STGroupFile, Misc } from "../../../../../src/index.js"; +import { assertEquals, assertNotNull, assertNull, assertTrue } from "./junit.js"; +import { STGroupDir, STGroupString, ErrorBuffer, STGroupFile, Misc } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; class Field { public name = "parrt"; @@ -695,14 +695,14 @@ export class TestGroups extends BaseTest { TestGroups.writeFile(this.tmpdir, "g2.stg", "f() ::= \"g2\"\nf2() ::= \"f2\"\n"); const group = new STGroupFile(this.tmpdir + "/t.stg"); let st = group.getInstanceOf("main"); - Assert.assertEquals("v1-g1", st?.render()); + assertEquals("v1-g1", st?.render()); // Change the text of group t, including the imports. TestGroups.writeFile(this.tmpdir, "t.stg", "import \"g2.stg\"\n\nmain() ::= <<\nv2-;\n>>"); group.unload(); st = group.getInstanceOf("main"); - Assert.assertEquals("v2-g2;f2", st?.render()); + assertEquals("v2-g2;f2", st?.render()); } @Test @@ -715,9 +715,9 @@ export class TestGroups extends BaseTest { TestGroups.writeFile(this.tmpdir, "t.stg", templates); const group = new STGroupFile(path.join(this.tmpdir, "t.stg")); const st = group.getInstanceOf("t"); - Assert.assertNotNull(st); + assertNotNull(st); const expecting = "Foo bar"; - Assert.assertEquals(expecting, st?.render()); + assertEquals(expecting, st?.render()); } @Test @@ -730,9 +730,9 @@ export class TestGroups extends BaseTest { TestGroups.writeFile(this.tmpdir, "t.stg", templates); const group = new STGroupFile(path.join(this.tmpdir, "t.stg")); const st = group.getInstanceOf("t"); - Assert.assertNotNull(st); + assertNotNull(st); const expecting = "Foo bar"; - Assert.assertEquals(expecting, st?.render()); + assertEquals(expecting, st?.render()); } @Test diff --git a/tests/org/stringtemplate/v4/test/TestImports.ts b/tests/TestImports.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestImports.ts rename to tests/TestImports.ts index 858d579..4cc859d 100644 --- a/tests/org/stringtemplate/v4/test/TestImports.ts +++ b/tests/TestImports.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { assertEquals, assertTrue } from "../../../../junit.js"; -import { STGroupFile, STGroupDir, ErrorBuffer } from "../../../../../src/index.js"; +import { assertEquals, assertTrue } from "./junit.js"; +import { STGroupFile, STGroupDir, ErrorBuffer } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestImports extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestIndentation.ts b/tests/TestIndentation.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestIndentation.ts rename to tests/TestIndentation.ts index f2aef06..45c05b1 100644 --- a/tests/org/stringtemplate/v4/test/TestIndentation.ts +++ b/tests/TestIndentation.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { STGroup, STGroupFile, ST, Misc, ErrorManager } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { STGroup, STGroupFile, ST, Misc, ErrorManager } from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestIndentation extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestIndirectionAndEarlyEval.ts b/tests/TestIndirectionAndEarlyEval.ts similarity index 95% rename from tests/org/stringtemplate/v4/test/TestIndirectionAndEarlyEval.ts rename to tests/TestIndirectionAndEarlyEval.ts index 52702b5..a3149e6 100644 --- a/tests/org/stringtemplate/v4/test/TestIndirectionAndEarlyEval.ts +++ b/tests/TestIndirectionAndEarlyEval.ts @@ -7,10 +7,10 @@ import { TestCoreBasics } from "./TestCoreBasics.js"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals, assertNull } from "../../../../junit.js"; -import { ST, STGroup, STGroupFile, ErrorBuffer } from "../../../../../src/index.js"; +import { assertEquals, assertNull } from "./junit.js"; +import { ST, STGroup, STGroupFile, ErrorBuffer } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestIndirectionAndEarlyEval extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestInterptimeErrors.ts b/tests/TestInterptimeErrors.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestInterptimeErrors.ts rename to tests/TestInterptimeErrors.ts index 135931d..badd709 100644 --- a/tests/org/stringtemplate/v4/test/TestInterptimeErrors.ts +++ b/tests/TestInterptimeErrors.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; -import { ErrorBuffer, Misc, ST, STGroup, STGroupFile } from "../../../../../src/index.js"; +import { Test } from "./decorators.js"; +import { ErrorBuffer, Misc, ST, STGroup, STGroupFile } from "../src/index.js"; export class TestInterptimeErrors extends BaseTest { private static UserHiddenName = class UserHiddenName { diff --git a/tests/org/stringtemplate/v4/test/TestLexer.ts b/tests/TestLexer.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestLexer.ts rename to tests/TestLexer.ts index c2626d6..b4160ea 100644 --- a/tests/org/stringtemplate/v4/test/TestLexer.ts +++ b/tests/TestLexer.ts @@ -7,7 +7,7 @@ import { BaseTest } from "./BaseTest.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestLexer extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestLineWrap.ts b/tests/TestLineWrap.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestLineWrap.ts rename to tests/TestLineWrap.ts index d604271..31d17d8 100644 --- a/tests/org/stringtemplate/v4/test/TestLineWrap.ts +++ b/tests/TestLineWrap.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; -import { AutoIndentWriter, Misc, ST, STGroupFile, StringWriter } from "../../../../../src/index.js"; +import { Test } from "./decorators.js"; +import { AutoIndentWriter, Misc, ST, STGroupFile, StringWriter } from "../src/index.js"; export class TestLineWrap extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestLists.ts b/tests/TestLists.ts similarity index 96% rename from tests/org/stringtemplate/v4/test/TestLists.ts rename to tests/TestLists.ts index 6a36bdb..7f6f498 100644 --- a/tests/org/stringtemplate/v4/test/TestLists.ts +++ b/tests/TestLists.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; -import { ErrorManager, Misc, ST, STGroupFile } from "../../../../../src/index.js"; +import { assertEquals } from "./junit.js"; +import { ErrorManager, Misc, ST, STGroupFile } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestLists extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestModelAdaptors.ts b/tests/TestModelAdaptors.ts similarity index 97% rename from tests/org/stringtemplate/v4/test/TestModelAdaptors.ts rename to tests/TestModelAdaptors.ts index 0bc5661..3249072 100644 --- a/tests/org/stringtemplate/v4/test/TestModelAdaptors.ts +++ b/tests/TestModelAdaptors.ts @@ -9,10 +9,10 @@ import { ErrorBufferAllErrors } from "./ErrorBufferAllErrors.js"; import { BaseTest } from "./BaseTest.js"; import { ModelAdaptor, Interpreter, ST, STNoSuchPropertyException, STGroupFile, STRuntimeMessage, HashMap, -} from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +} from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Test, Override } from "../../../../decorators.js"; +import { Test, Override } from "./decorators.js"; export class TestModelAdaptors extends BaseTest { private static UserAdaptor = class UserAdaptor implements ModelAdaptor { diff --git a/tests/org/stringtemplate/v4/test/TestNoNewlineTemplates.ts b/tests/TestNoNewlineTemplates.ts similarity index 95% rename from tests/org/stringtemplate/v4/test/TestNoNewlineTemplates.ts rename to tests/TestNoNewlineTemplates.ts index 0bb2e89..5fd592e 100644 --- a/tests/org/stringtemplate/v4/test/TestNoNewlineTemplates.ts +++ b/tests/TestNoNewlineTemplates.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; -import { STGroupString, STGroupFile } from "../../../../../src/index.js"; +import { assertEquals } from "./junit.js"; +import { STGroupString, STGroupFile } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestNoNewlineTemplates extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestNullAndEmptyValues.ts b/tests/TestNullAndEmptyValues.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestNullAndEmptyValues.ts rename to tests/TestNullAndEmptyValues.ts index 629b96d..5ef3987 100644 --- a/tests/org/stringtemplate/v4/test/TestNullAndEmptyValues.ts +++ b/tests/TestNullAndEmptyValues.ts @@ -6,12 +6,12 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { assertArrayEquals, assertEquals } from "../../../../junit.js"; +import { assertArrayEquals, assertEquals } from "./junit.js"; import { STGroup, ST, AutoIndentWriter, STGroupFile, Misc, StringWriter, ErrorManager, -} from "../../../../../src/index.js"; +} from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestNullAndEmptyValues extends BaseTest { public static T = class T { diff --git a/tests/org/stringtemplate/v4/test/TestOptions.ts b/tests/TestOptions.ts similarity index 97% rename from tests/org/stringtemplate/v4/test/TestOptions.ts rename to tests/TestOptions.ts index e227ffb..ef32634 100644 --- a/tests/org/stringtemplate/v4/test/TestOptions.ts +++ b/tests/TestOptions.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { STGroup, ErrorBuffer } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { STGroup, ErrorBuffer } from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestOptions extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestRegions.ts b/tests/TestRegions.ts similarity index 99% rename from tests/org/stringtemplate/v4/test/TestRegions.ts rename to tests/TestRegions.ts index e884655..5e301a6 100644 --- a/tests/org/stringtemplate/v4/test/TestRegions.ts +++ b/tests/TestRegions.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { STGroupFile, STGroupDir, ErrorBuffer, STGroupString, Misc } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { STGroupFile, STGroupDir, ErrorBuffer, STGroupString, Misc } from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Ignore, Test } from "../../../../decorators.js"; +import { Ignore, Test } from "./decorators.js"; export class TestRegions extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestRenderers.ts b/tests/TestRenderers.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestRenderers.ts rename to tests/TestRenderers.ts index abdc809..b6ebc53 100644 --- a/tests/org/stringtemplate/v4/test/TestRenderers.ts +++ b/tests/TestRenderers.ts @@ -6,12 +6,12 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; +import { assertEquals } from "./junit.js"; import { STGroup, STGroupFile, DateRenderer, ST, StringRenderer, NumberRenderer, TimeZone, -} from "../../../../../src/index.js"; +} from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestRenderers extends BaseTest { diff --git a/tests/org/stringtemplate/v4/test/TestSTRawGroupDir.ts b/tests/TestSTRawGroupDir.ts similarity index 96% rename from tests/org/stringtemplate/v4/test/TestSTRawGroupDir.ts rename to tests/TestSTRawGroupDir.ts index f349260..9411f56 100644 --- a/tests/org/stringtemplate/v4/test/TestSTRawGroupDir.ts +++ b/tests/TestSTRawGroupDir.ts @@ -6,10 +6,10 @@ // cspell: disable import { BaseTest } from "./BaseTest.js"; -import { assertEquals, assertNotNull } from "../../../../junit.js"; +import { assertEquals, assertNotNull } from "./junit.js"; -import { Test } from "../../../../decorators.js"; -import { Misc, STRawGroupDir } from "../../../../../src/index.js"; +import { Test } from "./decorators.js"; +import { Misc, STRawGroupDir } from "../src/index.js"; export class TestSTRawGroupDir extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestScopes.ts b/tests/TestScopes.ts similarity index 94% rename from tests/org/stringtemplate/v4/test/TestScopes.ts rename to tests/TestScopes.ts index 062e484..79ae317 100644 --- a/tests/org/stringtemplate/v4/test/TestScopes.ts +++ b/tests/TestScopes.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; -import { ErrorBuffer, ErrorManager, STGroupFile } from "../../../../../src/index.js"; +import { Test } from "./decorators.js"; +import { ErrorBuffer, ErrorManager, STGroupFile } from "../src/index.js"; export class TestScopes extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestSubtemplates.ts b/tests/TestSubtemplates.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestSubtemplates.ts rename to tests/TestSubtemplates.ts index 30eb542..f35886c 100644 --- a/tests/org/stringtemplate/v4/test/TestSubtemplates.ts +++ b/tests/TestSubtemplates.ts @@ -7,10 +7,10 @@ import { TestCoreBasics } from "./TestCoreBasics.js"; import { BaseTest } from "./BaseTest.js"; -import { STGroup, ST, STGroupFile, ErrorBuffer, Misc } from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +import { STGroup, ST, STGroupFile, ErrorBuffer, Misc } from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestSubtemplates extends BaseTest { diff --git a/tests/org/stringtemplate/v4/test/TestSyntaxErrors.ts b/tests/TestSyntaxErrors.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestSyntaxErrors.ts rename to tests/TestSyntaxErrors.ts index 949baed..4a5d530 100644 --- a/tests/org/stringtemplate/v4/test/TestSyntaxErrors.ts +++ b/tests/TestSyntaxErrors.ts @@ -8,10 +8,10 @@ import path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; -import { STGroup, ErrorBuffer, STException, STGroupFile, Misc } from "../../../../../src/index.js"; +import { assertEquals } from "./junit.js"; +import { STGroup, ErrorBuffer, STException, STGroupFile, Misc } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestSyntaxErrors extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestTemplateNames.ts b/tests/TestTemplateNames.ts similarity index 96% rename from tests/org/stringtemplate/v4/test/TestTemplateNames.ts rename to tests/TestTemplateNames.ts index 7472492..f018021 100644 --- a/tests/org/stringtemplate/v4/test/TestTemplateNames.ts +++ b/tests/TestTemplateNames.ts @@ -8,10 +8,10 @@ import * as path from "path"; import { BaseTest } from "./BaseTest.js"; -import { assertEquals } from "../../../../junit.js"; -import { STGroupDir, Misc, ErrorBuffer, STGroupFile } from "../../../../../src/index.js"; +import { assertEquals } from "./junit.js"; +import { STGroupDir, Misc, ErrorBuffer, STGroupFile } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestTemplateNames extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestTokensForDollarDelimiters.ts b/tests/TestTokensForDollarDelimiters.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestTokensForDollarDelimiters.ts rename to tests/TestTokensForDollarDelimiters.ts index 4d1cdee..98f96a6 100644 --- a/tests/org/stringtemplate/v4/test/TestTokensForDollarDelimiters.ts +++ b/tests/TestTokensForDollarDelimiters.ts @@ -7,7 +7,7 @@ import { BaseTest } from "./BaseTest.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestTokensForDollarDelimiters extends BaseTest { @Test diff --git a/tests/org/stringtemplate/v4/test/TestTypeRegistry.ts b/tests/TestTypeRegistry.ts similarity index 94% rename from tests/org/stringtemplate/v4/test/TestTypeRegistry.ts rename to tests/TestTypeRegistry.ts index 29f7e65..6dc4d1b 100644 --- a/tests/org/stringtemplate/v4/test/TestTypeRegistry.ts +++ b/tests/TestTypeRegistry.ts @@ -5,10 +5,10 @@ // cspell: disable -import { assertEquals, assertNull } from "../../../../junit.js"; -import { TypeRegistry } from "../../../../../src/index.js"; +import { assertEquals, assertNull } from "./junit.js"; +import { TypeRegistry } from "../src/index.js"; -import { Test } from "../../../../decorators.js"; +import { Test } from "./decorators.js"; export class TestTypeRegistry { // https://github.com/antlr/stringtemplate4/issues/122 diff --git a/tests/org/stringtemplate/v4/test/TestWhitespace.ts b/tests/TestWhitespace.ts similarity index 98% rename from tests/org/stringtemplate/v4/test/TestWhitespace.ts rename to tests/TestWhitespace.ts index d0e8b29..be45093 100644 --- a/tests/org/stringtemplate/v4/test/TestWhitespace.ts +++ b/tests/TestWhitespace.ts @@ -8,10 +8,10 @@ import { BaseTest } from "./BaseTest.js"; import { STGroup, ST, STGroupString, AutoIndentWriter, Misc, StringWriter, ErrorManager, -} from "../../../../../src/index.js"; -import { assertEquals } from "../../../../junit.js"; +} from "../src/index.js"; +import { assertEquals } from "./junit.js"; -import { AfterAll, BeforeAll, Ignore, Test } from "../../../../decorators.js"; +import { AfterAll, BeforeAll, Ignore, Test } from "./decorators.js"; export class TestWhitespace extends BaseTest { @BeforeAll diff --git a/tests/decorators.ts b/tests/decorators.ts index d74cd8b..4eb0691 100644 --- a/tests/decorators.ts +++ b/tests/decorators.ts @@ -1,15 +1,9 @@ /* * Copyright (c) Mike Lischke. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. See License-MIT.txt in the project root for license information. */ -/* - eslint-disable - @typescript-eslint/naming-convention, - prefer-arrow/prefer-arrow-functions, - jsdoc/require-param, - jsdoc/require-returns -*/ +/* eslint-disable @typescript-eslint/naming-convention */ /** * This file contains the decorators for the test framework. @@ -49,13 +43,19 @@ export interface IDataProviderParameters { /** A definition of the target function for a function decorator. */ export type DecoratorTargetFunction = (this: This, ...args: Args) => Return; -/** Marks a method as overriding an inherited method. */ -export function Override( +/** + * Marks a method as overriding an inherited method. + * @param target The decorated target function. + * @param _context The context of the decorator. + * + * @returns The original method. + */ +export const Override = ( target: DecoratorTargetFunction, _context: ClassMethodDecoratorContext>, -): DecoratorTargetFunction { +): DecoratorTargetFunction => { return target; -} +}; /** * Executes the given target method and handles expected exceptions. @@ -86,6 +86,8 @@ function executeTarget(this: unknown, target: Function, expectedExceptions?: Arr * instance. * The list is ordered from the top of the prototype chain to the current instance and contains the original * methods (not the decorator methods). + * @param target The target method. + * @param args The arguments for the target method. */ function executeTargetWithInheritance(this: This, target: Function, ...args: unknown[]) { // Call the original method and all overridden methods in the prototype chain (in reverse order). @@ -126,6 +128,7 @@ export function DataProvider(param: IDataProviderParameters): Function; * * @returns The original method. */ +// eslint-disable-next-line prefer-arrow/prefer-arrow-functions export function DataProvider( ...args: unknown[]): Function | DecoratorTargetFunction { if (args.length === 1) { @@ -177,6 +180,7 @@ export function Test(param: T): Function; * * @returns A decorator factory method. */ +// eslint-disable-next-line prefer-arrow/prefer-arrow-functions export function Test( ...args: unknown[]): Function | DecoratorTargetFunction { @@ -302,10 +306,10 @@ export function Test( +export const BeforeEach = ( target: DecoratorTargetFunction, context: ClassMethodDecoratorContext>, -): DecoratorTargetFunction { +): DecoratorTargetFunction => { const result = function (this: This, ...args: Args): Return { beforeEach(() => { @@ -319,7 +323,7 @@ export function BeforeEach( Object.defineProperty(result, "isBeforeEach", { value: true }); return result; -} +}; /** * Decorator function for the BeforeAll annotation. @@ -329,10 +333,10 @@ export function BeforeEach( * * @returns a method decorator. */ -export function BeforeAll( +export const BeforeAll = ( target: DecoratorTargetFunction, context: ClassMethodDecoratorContext>, -): DecoratorTargetFunction { +): DecoratorTargetFunction => { const result = function (this: This, ...args: Args): Return { beforeAll(() => { @@ -346,7 +350,7 @@ export function BeforeAll( Object.defineProperty(result, "isBeforeAll", { value: true }); return result; -} +}; /** * Decorator function for the AfterEach annotation. @@ -356,10 +360,10 @@ export function BeforeAll( * * @returns a method decorator. */ -export function AfterEach( +export const AfterEach = ( target: DecoratorTargetFunction, context: ClassMethodDecoratorContext>, -): DecoratorTargetFunction { +): DecoratorTargetFunction => { const result = function (this: This, ...args: Args): Return { afterEach(() => { @@ -373,7 +377,7 @@ export function AfterEach( Object.defineProperty(result, "isAfterEach", { value: true }); return result; -} +}; /** * Decorator function for the AfterAll annotation. * @@ -382,10 +386,10 @@ export function AfterEach( * * @returns a method decorator. */ -export function AfterAll( +export const AfterAll = ( target: DecoratorTargetFunction, context: ClassMethodDecoratorContext>, -): DecoratorTargetFunction { +): DecoratorTargetFunction => { const result = function (this: This, ...args: Args): Return { afterAll(() => { @@ -399,7 +403,7 @@ export function AfterAll( Object.defineProperty(result, "isAfterAll", { value: true }); return result; -} +}; /** * Decorator function for the Ignore annotation. @@ -408,7 +412,7 @@ export function AfterAll( * * @returns the original method. */ -export function Ignore(param: string): Function { +export const Ignore = (param: string): Function => { return (target: DecoratorTargetFunction, context: ClassMethodDecoratorContext>) => { @@ -417,4 +421,4 @@ export function Ignore(param: string): Function { return target; }; -} +}; diff --git a/tests/junit.ts b/tests/junit.ts index 6af0516..88e3ea3 100644 --- a/tests/junit.ts +++ b/tests/junit.ts @@ -1,6 +1,6 @@ /* * Copyright (c) Mike Lischke. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. See License-MIT.txt in the project root for license information. */ type Throwable = Error; @@ -36,13 +36,3 @@ export const assertNotNull = (value: T | null): void => { export const assertArrayEquals = (expected: T[], actual: T[]): void => { expect(actual).toEqual(expected); }; - -export class Assert { - public static assertNotNull(value: T | null): void { - expect(value).not.toBeNull(); - } - - public static assertEquals(expected: T | null, actual: T | null): void { - expect(actual).toEqual(expected); - } -}