Skip to content

Commit 8678a90

Browse files
committed
Move whitespaceRequiredWithinTokens from LegacyOverrides to BuiltInFeatures
Removes the legacy override flag in favor of a feature flag, and migrates parseWhitespaceControlStrictly to pass a WhitespaceControlParser enum through the token pipeline rather than checking config at parse time.
1 parent d764558 commit 8678a90

11 files changed

Lines changed: 146 additions & 49 deletions

File tree

src/main/java/com/hubspot/jinjava/LegacyOverrides.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public interface LegacyOverrides extends WithLegacyOverrides {
2222
.withIterateOverMapKeys(true)
2323
.withUsePyishObjectMapper(true)
2424
.withUseSnakeCasePropertyNaming(true)
25-
.withWhitespaceRequiredWithinTokens(true)
2625
.withUseNaturalOperatorPrecedence(true)
2726
.withParseWhitespaceControlStrictly(true)
2827
.withAllowAdjacentTextNodes(true)
@@ -50,11 +49,6 @@ default boolean isUseSnakeCasePropertyNaming() {
5049
return false;
5150
}
5251

53-
@Value.Default
54-
default boolean isWhitespaceRequiredWithinTokens() {
55-
return false;
56-
}
57-
5852
@Value.Default
5953
default boolean isUseNaturalOperatorPrecedence() {
6054
return false;

src/main/java/com/hubspot/jinjava/features/BuiltInFeatures.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.hubspot.jinjava.features;
22

33
public interface BuiltInFeatures {
4+
String WHITESPACE_REQUIRED_WITHIN_TOKENS = "whitespace_required_within_tokens";
45
String FIXED_DATE_TIME_FILTER_NULL_ARG = "FIXED_DATE_TIME_FILTER_NULL_ARG";
56
String ECHO_UNDEFINED = "echoUndefined";
67
String PREVENT_ACCIDENTAL_EXPRESSIONS = "PREVENT_ACCIDENTAL_EXPRESSIONS";

src/main/java/com/hubspot/jinjava/tree/TreeParser.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,15 @@
3838
import com.hubspot.jinjava.tree.parse.TokenScanner;
3939
import com.hubspot.jinjava.tree.parse.TokenScannerSymbols;
4040
import com.hubspot.jinjava.tree.parse.UnclosedToken;
41+
import com.hubspot.jinjava.tree.parse.WhitespaceControlParser;
4142
import org.apache.commons.lang3.StringUtils;
4243

4344
public class TreeParser {
4445

4546
private final PeekingIterator<Token> scanner;
4647
private final JinjavaInterpreter interpreter;
4748
private final TokenScannerSymbols symbols;
49+
private final WhitespaceControlParser whitespaceControlParser;
4850

4951
private Node parent;
5052

@@ -53,6 +55,10 @@ public TreeParser(JinjavaInterpreter interpreter, String input) {
5355
Iterators.peekingIterator(new TokenScanner(input, interpreter.getConfig()));
5456
this.interpreter = interpreter;
5557
this.symbols = interpreter.getConfig().getTokenScannerSymbols();
58+
this.whitespaceControlParser =
59+
interpreter.getConfig().getLegacyOverrides().isParseWhitespaceControlStrictly()
60+
? WhitespaceControlParser.STRICT
61+
: WhitespaceControlParser.LENIENT;
5662
}
5763

5864
public Node buildTree() {
@@ -178,7 +184,8 @@ private Node text(TextToken textToken) {
178184
StringUtils.stripEnd(textToken.getImage(), "\t "),
179185
textToken.getLineNumber(),
180186
textToken.getStartPosition(),
181-
symbols
187+
symbols,
188+
whitespaceControlParser
182189
);
183190
}
184191
}

src/main/java/com/hubspot/jinjava/tree/parse/ExpressionToken.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,17 @@ public ExpressionToken(
2929
int startPosition,
3030
TokenScannerSymbols symbols
3131
) {
32-
super(image, lineNumber, startPosition, symbols);
32+
this(image, lineNumber, startPosition, symbols, WhitespaceControlParser.LENIENT);
33+
}
34+
35+
public ExpressionToken(
36+
String image,
37+
int lineNumber,
38+
int startPosition,
39+
TokenScannerSymbols symbols,
40+
WhitespaceControlParser whitespaceControlParser
41+
) {
42+
super(image, lineNumber, startPosition, symbols, whitespaceControlParser);
3343
}
3444

3545
@Override

src/main/java/com/hubspot/jinjava/tree/parse/NoteToken.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,17 @@ public NoteToken(
2525
int startPosition,
2626
TokenScannerSymbols symbols
2727
) {
28-
super(image, lineNumber, startPosition, symbols);
28+
this(image, lineNumber, startPosition, symbols, WhitespaceControlParser.LENIENT);
29+
}
30+
31+
public NoteToken(
32+
String image,
33+
int lineNumber,
34+
int startPosition,
35+
TokenScannerSymbols symbols,
36+
WhitespaceControlParser whitespaceControlParser
37+
) {
38+
super(image, lineNumber, startPosition, symbols, whitespaceControlParser);
2939
}
3040

3141
@Override

src/main/java/com/hubspot/jinjava/tree/parse/TagToken.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,17 @@ public TagToken(
3131
int startPosition,
3232
TokenScannerSymbols symbols
3333
) {
34-
super(image, lineNumber, startPosition, symbols);
34+
this(image, lineNumber, startPosition, symbols, WhitespaceControlParser.LENIENT);
35+
}
36+
37+
public TagToken(
38+
String image,
39+
int lineNumber,
40+
int startPosition,
41+
TokenScannerSymbols symbols,
42+
WhitespaceControlParser whitespaceControlParser
43+
) {
44+
super(image, lineNumber, startPosition, symbols, whitespaceControlParser);
3545
}
3646

3747
@Override

src/main/java/com/hubspot/jinjava/tree/parse/TextToken.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,17 @@ public TextToken(
2727
int startPosition,
2828
TokenScannerSymbols symbols
2929
) {
30-
super(image, lineNumber, startPosition, symbols);
30+
this(image, lineNumber, startPosition, symbols, WhitespaceControlParser.LENIENT);
31+
}
32+
33+
public TextToken(
34+
String image,
35+
int lineNumber,
36+
int startPosition,
37+
TokenScannerSymbols symbols,
38+
WhitespaceControlParser whitespaceControlParser
39+
) {
40+
super(image, lineNumber, startPosition, symbols, whitespaceControlParser);
3141
}
3242

3343
public void mergeImageAndContent(TextToken otherToken) {

src/main/java/com/hubspot/jinjava/tree/parse/Token.java

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
**********************************************************************/
1616
package com.hubspot.jinjava.tree.parse;
1717

18-
import com.hubspot.jinjava.JinjavaConfig;
19-
import com.hubspot.jinjava.LegacyOverrides;
20-
import com.hubspot.jinjava.interpret.JinjavaInterpreter;
2118
import com.hubspot.jinjava.interpret.UnexpectedTokenException;
2219
import java.io.Serializable;
2320

@@ -32,6 +29,7 @@ public abstract class Token implements Serializable {
3229
protected final int lineNumber;
3330
protected final int startPosition;
3431
private final TokenScannerSymbols symbols;
32+
private final WhitespaceControlParser whitespaceControlParser;
3533

3634
private boolean leftTrim;
3735
private boolean rightTrim;
@@ -41,12 +39,14 @@ public Token(
4139
String image,
4240
int lineNumber,
4341
int startPosition,
44-
TokenScannerSymbols symbols
42+
TokenScannerSymbols symbols,
43+
WhitespaceControlParser whitespaceControlParser
4544
) {
4645
this.image = image;
4746
this.lineNumber = lineNumber;
4847
this.startPosition = startPosition;
4948
this.symbols = symbols;
49+
this.whitespaceControlParser = whitespaceControlParser;
5050
parse();
5151
}
5252

@@ -89,25 +89,14 @@ public void setRightTrimAfterEnd(boolean rightTrimAfterEnd) {
8989
* @return the content stripped of any whitespace control characters.
9090
*/
9191
protected final String handleTrim(String unwrapped) {
92-
boolean parseWhitespaceControlStrictly = JinjavaInterpreter
93-
.getCurrentMaybe()
94-
.map(JinjavaInterpreter::getConfig)
95-
.map(JinjavaConfig::getLegacyOverrides)
96-
.map(LegacyOverrides::isParseWhitespaceControlStrictly)
97-
.orElse(false);
98-
99-
WhitespaceControlParser parser = parseWhitespaceControlStrictly
100-
? WhitespaceControlParser.STRICT
101-
: WhitespaceControlParser.LENIENT;
102-
10392
String result = unwrapped;
104-
if (parser.hasLeftTrim(result)) {
93+
if (whitespaceControlParser.hasLeftTrim(result)) {
10594
setLeftTrim(true);
106-
result = parser.stripLeft(result);
95+
result = whitespaceControlParser.stripLeft(result);
10796
}
108-
if (parser.hasRightTrim(result)) {
97+
if (whitespaceControlParser.hasRightTrim(result)) {
10998
setRightTrim(true);
110-
result = parser.stripRight(result);
99+
result = whitespaceControlParser.stripRight(result);
111100
}
112101
return result;
113102
}
@@ -132,18 +121,43 @@ public String toString() {
132121
static Token newToken(
133122
int tokenKind,
134123
TokenScannerSymbols symbols,
124+
WhitespaceControlParser whitespaceControlParser,
135125
String image,
136126
int lineNumber,
137127
int startPosition
138128
) {
139129
if (tokenKind == symbols.getFixed()) {
140-
return new TextToken(image, lineNumber, startPosition, symbols);
130+
return new TextToken(
131+
image,
132+
lineNumber,
133+
startPosition,
134+
symbols,
135+
whitespaceControlParser
136+
);
141137
} else if (tokenKind == symbols.getNote()) {
142-
return new NoteToken(image, lineNumber, startPosition, symbols);
138+
return new NoteToken(
139+
image,
140+
lineNumber,
141+
startPosition,
142+
symbols,
143+
whitespaceControlParser
144+
);
143145
} else if (tokenKind == symbols.getExprStart()) {
144-
return new ExpressionToken(image, lineNumber, startPosition, symbols);
146+
return new ExpressionToken(
147+
image,
148+
lineNumber,
149+
startPosition,
150+
symbols,
151+
whitespaceControlParser
152+
);
145153
} else if (tokenKind == symbols.getTag()) {
146-
return new TagToken(image, lineNumber, startPosition, symbols);
154+
return new TagToken(
155+
image,
156+
lineNumber,
157+
startPosition,
158+
symbols,
159+
whitespaceControlParser
160+
);
147161
} else {
148162
throw new UnexpectedTokenException(
149163
String.valueOf((char) tokenKind),

src/main/java/com/hubspot/jinjava/tree/parse/TokenScanner.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import com.google.common.collect.AbstractIterator;
2121
import com.hubspot.jinjava.JinjavaConfig;
22+
import com.hubspot.jinjava.features.BuiltInFeatures;
2223

2324
public class TokenScanner extends AbstractIterator<Token> {
2425

@@ -38,7 +39,8 @@ public class TokenScanner extends AbstractIterator<Token> {
3839
private char inQuote = 0;
3940
private int currLine = 1;
4041
private int lastNewlinePos = 0;
41-
private TokenScannerSymbols symbols;
42+
private final TokenScannerSymbols symbols;
43+
private final WhitespaceControlParser whitespaceControlParser;
4244

4345
public TokenScanner(String input, JinjavaConfig config) {
4446
this.config = config;
@@ -58,6 +60,10 @@ public TokenScanner(String input, JinjavaConfig config) {
5860
lastNewlinePos = 0;
5961

6062
symbols = config.getTokenScannerSymbols();
63+
whitespaceControlParser =
64+
config.getLegacyOverrides().isParseWhitespaceControlStrictly()
65+
? WhitespaceControlParser.STRICT
66+
: WhitespaceControlParser.LENIENT;
6167
}
6268

6369
private Token getNextToken() {
@@ -88,7 +94,11 @@ private Token getNextToken() {
8894
if (currPost < length) {
8995
c = is[currPost];
9096
boolean startTokenFound = true;
91-
if (config.getLegacyOverrides().isWhitespaceRequiredWithinTokens()) {
97+
if (
98+
config
99+
.getFeatures()
100+
.isActive(BuiltInFeatures.WHITESPACE_REQUIRED_WITHIN_TOKENS)
101+
) {
92102
boolean hasNextChar = (currPost + 1) < length;
93103
boolean nextCharIsWhitespace = hasNextChar && (' ' == is[currPost + 1]);
94104
startTokenFound = nextCharIsWhitespace;
@@ -232,12 +242,14 @@ private Token getEndToken() {
232242
String.valueOf(is, tokenStart, tokenLength),
233243
currLine,
234244
tokenStart - lastNewlinePos + 1,
235-
symbols
245+
symbols,
246+
whitespaceControlParser
236247
);
237248
}
238249
return Token.newToken(
239250
type,
240251
symbols,
252+
whitespaceControlParser,
241253
String.valueOf(is, tokenStart, tokenLength),
242254
currLine,
243255
tokenStart - lastNewlinePos + 1
@@ -248,6 +260,7 @@ private Token newToken(int kind) {
248260
Token t = Token.newToken(
249261
kind,
250262
symbols,
263+
whitespaceControlParser,
251264
String.valueOf(is, lastStart, tokenLength),
252265
currLine,
253266
lastStart - lastNewlinePos + 1
@@ -276,7 +289,14 @@ private Token newToken(int kind) {
276289
}
277290

278291
if (inRaw > 0 && t.getType() != symbols.getFixed()) {
279-
return Token.newToken(symbols.getFixed(), symbols, t.image, currLine, tokenStart);
292+
return Token.newToken(
293+
symbols.getFixed(),
294+
symbols,
295+
whitespaceControlParser,
296+
t.image,
297+
currLine,
298+
tokenStart
299+
);
280300
}
281301

282302
return t;

src/main/java/com/hubspot/jinjava/tree/parse/UnclosedToken.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ public UnclosedToken(
88
int startPosition,
99
TokenScannerSymbols symbols
1010
) {
11-
super(image, lineNumber, startPosition, symbols);
11+
this(image, lineNumber, startPosition, symbols, WhitespaceControlParser.LENIENT);
12+
}
13+
14+
public UnclosedToken(
15+
String image,
16+
int lineNumber,
17+
int startPosition,
18+
TokenScannerSymbols symbols,
19+
WhitespaceControlParser whitespaceControlParser
20+
) {
21+
super(image, lineNumber, startPosition, symbols, whitespaceControlParser);
1222
}
1323
}

0 commit comments

Comments
 (0)