Implements #2383 Add syntax modes for FreeMarker template language#2847
Merged
alexdima merged 1 commit intomicrosoft:mainfrom Jan 14, 2022
Merged
Implements #2383 Add syntax modes for FreeMarker template language#2847alexdima merged 1 commit intomicrosoft:mainfrom
alexdima merged 1 commit intomicrosoft:mainfrom
Conversation
melloware
approved these changes
Dec 21, 2021
|
This is fantastic. I have been testing it with my real world FreeMarker templates and its working exactly the way I would expect it to! |
FlipWarthog
approved these changes
Dec 21, 2021
|
Holy cow, this is amazing. Well done, @blutorange ! |
Member
|
Thank you for this PR! It seems like you put a lot of effort into this. Generally, it looks really good. However, I did not review every single line of those added ~25k lines of code, especially not the tests. At ten lines per second, a "proper" review would take more than 40 minutes. @alexdima what do you think how we should proceed here? |
Member
|
This looks very good and thorough, thank you very much! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Woah, test cases got really large, much larger than the implementation...
Adds syntax highlighting support for Apache FreeMarker, resolves #2383. Includes tests and samples for the website.
freemarker2since FreeMarker 3 will most likely change the syntaxfreemarker2.tag-*.interpolation-*. It also adds the modefreemarker2, which is an alias forfreemarker2.tag-angle.interpolation-dollar, the default mode when using FreeMarker via the Java API.(from the source code comment)
The grammar for FreeMarker 2.x. This tokenizer is intentionally limited to FreeMarker 2 as the next release FreeMarker 3 is a breaking change that will change the syntax, see:
https://cwiki.apache.org/confluence/display/FREEMARKER/FreeMarker+3
FreeMarker does not just have one grammar, it has 6 (!) different syntaxes.
These can be combined, resulting in 3*2=6 syntaxes. There's another tag syntax, but that one is legacy and therefore ignored by this tokenizer.
<#if true>...</#if>[#if true]...[/#if]Dollar interpolation syntax is like
${1+2}, bracket syntax like[=1+2].To prevent duplicate code, there are factory functions that take a syntax mode and dynamically create the tokenizer for that mode. This does not affect performance since the tokenizer is created only once.
Auto mode is implemented via parser states. Each parser state exists three times, one for each tag syntax mode (e.g.
default.auto,default.angle,default.bracket). Auto mode starts indefault.autoand switches todefault.angleordefault.bracketwhen it encounters the first directive.FreeMarker allows expressions within strings (
a${1+2}b), but these are impossible to tokenize. String interpolation is not implemented via a mode change when encountering${. Rather, FreeMarker tokenizes the string as a literal string first. Then, during the AST build phase, it creates a new parses and parses the unescaped string content.This is adapted from the official JavaCC grammar for FreeMarker: https://github.com/apache/freemarker/blob/2.3-gae/src/main/javacc/FTL.jj
Taken from the above file, a short rundown of the basic parser states:
It should be noted that there are another parser state not mentioned in the above excerpt: NO_DIRECTIVE is used as the initial starting state when parsing the contents of a string literal, which is allowed to contain interpolations, but no directives. However, note that FreeMarker first tokenizes a string literal as-is, then during the parsing stage, it takes the (unescaped) content of the string literal, and tokenizes + parses that content with a new child parser.