From 2c018985a939017f71be6ee2763a3929162cb6e3 Mon Sep 17 00:00:00 2001 From: Andrey Starovoyt Date: Mon, 22 Sep 2014 19:11:40 +0400 Subject: [PATCH] handlebars: add decimal support instead of integer (see https://github.com/wycats/handlebars.js/issues/472) Conflicts: gen/com/dmarcotte/handlebars/parsing/_HbLexer.java handlebars/src/com/dmarcotte/handlebars/HbHighlighter.java --- .../handlebars/parsing/_HbLexer.java | 127 ++++++------ .../dmarcotte/handlebars/HbHighlighter.java | 188 +++++++++--------- .../handlebars/parsing/HbParsing.java | 16 +- .../handlebars/parsing/HbTokenTypes.java | 2 +- .../handlebars/parsing/handlebars.flex | 2 +- .../parser/MustachesWithHashArguments.txt | 8 +- .../parser/MustachesWithIntegerParameters.txt | 4 +- test/data/parser/ParamWithDecimal.hbs | 1 + test/data/parser/ParamWithDecimal.txt | 15 ++ .../parsing/HbLexerFreeFormTest.java | 18 ++ .../parsing/HbParserFreeFormTest.java | 5 + .../parsing/HbTokenizerSpecTest.java | 10 +- 12 files changed, 217 insertions(+), 179 deletions(-) create mode 100644 test/data/parser/ParamWithDecimal.hbs create mode 100644 test/data/parser/ParamWithDecimal.txt diff --git a/gen/com/dmarcotte/handlebars/parsing/_HbLexer.java b/gen/com/dmarcotte/handlebars/parsing/_HbLexer.java index e251f2d..e3717ec 100644 --- a/gen/com/dmarcotte/handlebars/parsing/_HbLexer.java +++ b/gen/com/dmarcotte/handlebars/parsing/_HbLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 10/12/14 4:32 PM */ +/* The following code was generated by JFlex 1.4.3 on 10/12/14 4:55 PM */ // We base our lexer directly on the official handlebars.l lexer definition, // making some modifications to account for Jison/JFlex syntax and functionality differences @@ -17,7 +17,7 @@ /** * This class is a scanner generated by * JFlex 1.4.3 - * on 10/12/14 4:32 PM from the specification file + * on 10/12/14 4:55 PM from the specification file * handlebars.flex */ final class _HbLexer implements FlexLexer { @@ -66,14 +66,14 @@ final class _HbLexer implements FlexLexer { "\1\1\1\2\3\0\1\1\1\3\1\2\3\3\1\4"+ "\1\5\1\4\3\3\1\6\6\3\1\2\1\3\1\7"+ "\1\3\1\10\1\0\1\11\1\12\1\0\1\13\1\14"+ - "\1\0\1\15\2\0\1\16\6\0\1\17\1\0\1\20"+ - "\1\0\1\10\1\21\1\12\1\22\1\23\1\24\1\25"+ - "\1\12\1\26\1\15\1\0\1\27\3\0\1\20\1\30"+ - "\3\0\1\31\3\30\1\32\1\33\1\0\1\31\2\30"+ - "\1\34\2\30\1\35\1\36\1\30\1\36\2\30"; + "\1\0\1\15\2\0\1\16\6\0\1\17\1\11\1\0"+ + "\1\20\1\0\1\10\1\21\1\12\1\22\1\23\1\24"+ + "\1\25\1\12\1\26\1\15\1\0\1\27\4\0\1\20"+ + "\1\30\3\0\1\31\3\30\1\32\1\33\1\0\1\31"+ + "\2\30\1\34\2\30\1\35\1\36\1\30\1\36\2\30"; private static int [] zzUnpackAction() { - int [] result = new int[89]; + int [] result = new int[91]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -103,16 +103,16 @@ private static int zzUnpackAction(String packed, int offset, int [] result) { "\0\u01c0\0\u0120\0\u01e0\0\u0200\0\u0220\0\u0240\0\u0260\0\u0280"+ "\0\u02a0\0\u02c0\0\u0120\0\u02e0\0\u0300\0\300\0\u0120\0\u0320"+ "\0\u0340\0\u0120\0\u0120\0\u0360\0\u0380\0\u01a0\0\u03a0\0\u0120"+ - "\0\u01c0\0\u03c0\0\u03e0\0\u0400\0\u0420\0\u0260\0\u0120\0\u0280"+ - "\0\u0440\0\u0460\0\u0120\0\u0120\0\u0480\0\u0120\0\u0120\0\u0120"+ - "\0\u0120\0\u0120\0\u0120\0\u0120\0\u0380\0\u0120\0\u04a0\0\u04c0"+ + "\0\u01c0\0\u03c0\0\u03e0\0\u0400\0\u0420\0\u0260\0\u0120\0\u0440"+ + "\0\u0280\0\u0460\0\u0480\0\u0120\0\u0120\0\u04a0\0\u0120\0\u0120"+ + "\0\u0120\0\u0120\0\u0120\0\u0120\0\u0120\0\u0380\0\u0120\0\u04c0"+ "\0\u04e0\0\u0500\0\u0520\0\u0540\0\u0560\0\u0580\0\u05a0\0\u05c0"+ - "\0\u05e0\0\u0600\0\u0120\0\u0120\0\u0620\0\u0120\0\u0640\0\u0660"+ - "\0\u0120\0\u0680\0\u06a0\0\u0120\0\u06c0\0\u06e0\0\u0120\0\u0700"+ - "\0\u0720"; + "\0\u05e0\0\u0600\0\u0620\0\u0640\0\u0120\0\u0120\0\u0660\0\u0120"+ + "\0\u0680\0\u06a0\0\u0120\0\u06c0\0\u06e0\0\u0120\0\u0700\0\u0720"+ + "\0\u0120\0\u0740\0\u0760"; private static int [] zzUnpackRowMap() { - int [] result = new int[89]; + int [] result = new int[91]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -152,38 +152,39 @@ private static int zzUnpackRowMap(String packed, int offset, int [] result) { "\1\37\3\0\4\37\3\0\7\36\1\55\2\36\3\0"+ "\1\36\2\37\2\0\1\37\2\0\1\37\3\0\4\37"+ "\3\0\11\36\1\56\3\0\1\36\2\57\2\0\1\37"+ - "\2\0\1\37\3\0\2\37\2\57\3\0\11\36\1\56"+ - "\3\0\37\60\1\43\1\0\2\31\40\0\1\61\37\0"+ - "\1\62\37\0\1\63\37\0\1\64\1\0\1\65\1\66"+ - "\1\67\1\70\1\71\1\72\1\73\42\0\1\74\37\0"+ - "\1\75\37\0\1\76\21\0\2\46\1\0\35\46\2\51"+ - "\1\0\35\51\1\36\2\37\2\0\1\37\2\0\1\37"+ - "\3\0\4\37\3\0\2\36\1\77\7\36\3\0\1\36"+ - "\2\37\2\0\1\37\2\0\1\37\3\0\4\37\3\0"+ - "\5\36\1\100\4\36\3\0\1\36\2\37\2\0\1\37"+ - "\2\0\1\37\3\0\4\37\3\0\1\36\1\101\10\36"+ - "\3\0\3\61\1\102\34\61\13\0\1\103\27\0\1\64"+ - "\2\0\1\66\1\67\1\70\1\71\1\72\25\0\1\36"+ - "\2\37\2\0\1\37\2\0\1\37\3\0\4\37\3\0"+ - "\1\104\11\36\3\0\1\36\2\37\2\0\1\37\2\0"+ - "\1\37\3\0\4\37\3\0\1\105\11\36\3\0\1\36"+ - "\2\37\2\0\1\37\2\0\1\37\3\0\4\37\3\0"+ - "\2\36\1\106\7\36\3\0\3\61\1\107\34\61\16\110"+ - "\1\111\14\110\1\112\4\110\1\36\2\113\2\0\1\37"+ - "\2\0\1\37\3\0\2\37\2\113\3\0\12\36\3\0"+ - "\1\36\2\114\2\0\1\37\2\0\1\37\3\0\2\37"+ - "\2\114\3\0\12\36\3\0\1\36\2\37\2\0\1\37"+ - "\2\0\1\37\3\0\4\37\3\0\1\115\11\36\6\0"+ - "\1\116\34\0\16\110\1\117\21\110\16\120\1\121\37\120"+ - "\1\122\14\120\1\123\4\120\1\36\2\124\2\0\1\37"+ - "\2\0\1\37\3\0\2\37\2\124\3\0\12\36\3\0"+ - "\16\110\1\125\21\110\16\120\1\122\37\120\1\0\21\120"+ - "\33\123\1\126\4\123\16\0\1\127\21\0\33\123\1\130"+ - "\22\123\1\131\14\123\1\130\22\123\1\121\14\123\1\126"+ - "\4\123"; + "\2\0\1\37\3\0\1\37\1\60\2\57\3\0\11\36"+ + "\1\56\3\0\37\61\1\43\1\0\2\31\40\0\1\62"+ + "\37\0\1\63\37\0\1\64\37\0\1\65\1\0\1\66"+ + "\1\67\1\70\1\71\1\72\1\73\1\74\42\0\1\75"+ + "\37\0\1\76\37\0\1\77\21\0\2\46\1\0\35\46"+ + "\2\51\1\0\35\51\1\36\2\37\2\0\1\37\2\0"+ + "\1\37\3\0\4\37\3\0\2\36\1\100\7\36\3\0"+ + "\1\36\2\37\2\0\1\37\2\0\1\37\3\0\4\37"+ + "\3\0\5\36\1\101\4\36\3\0\1\36\2\37\2\0"+ + "\1\37\2\0\1\37\3\0\4\37\3\0\1\36\1\102"+ + "\10\36\37\0\1\103\3\0\3\62\1\104\34\62\13\0"+ + "\1\105\27\0\1\65\2\0\1\67\1\70\1\71\1\72"+ + "\1\73\25\0\1\36\2\37\2\0\1\37\2\0\1\37"+ + "\3\0\4\37\3\0\1\106\11\36\3\0\1\36\2\37"+ + "\2\0\1\37\2\0\1\37\3\0\4\37\3\0\1\107"+ + "\11\36\3\0\1\36\2\37\2\0\1\37\2\0\1\37"+ + "\3\0\4\37\3\0\2\36\1\110\7\36\4\0\2\57"+ + "\13\0\2\57\14\0\1\103\3\0\3\62\1\111\34\62"+ + "\16\112\1\113\14\112\1\114\4\112\1\36\2\115\2\0"+ + "\1\37\2\0\1\37\3\0\2\37\2\115\3\0\12\36"+ + "\3\0\1\36\2\116\2\0\1\37\2\0\1\37\3\0"+ + "\2\37\2\116\3\0\12\36\3\0\1\36\2\37\2\0"+ + "\1\37\2\0\1\37\3\0\4\37\3\0\1\117\11\36"+ + "\6\0\1\120\34\0\16\112\1\121\21\112\16\122\1\123"+ + "\37\122\1\124\14\122\1\125\4\122\1\36\2\126\2\0"+ + "\1\37\2\0\1\37\3\0\2\37\2\126\3\0\12\36"+ + "\3\0\16\112\1\127\21\112\16\122\1\124\37\122\1\0"+ + "\21\122\33\125\1\130\4\125\16\0\1\131\21\0\33\125"+ + "\1\132\22\125\1\133\14\125\1\132\22\125\1\123\14\125"+ + "\1\130\4\125"; private static int [] zzUnpackTrans() { - int [] result = new int[1856]; + int [] result = new int[1920]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -226,13 +227,13 @@ private static int zzUnpackTrans(String packed, int offset, int [] result) { private static final String ZZ_ATTRIBUTE_PACKED_0 = "\2\1\3\0\4\1\1\11\1\1\2\11\4\1\1\11"+ "\10\1\1\11\2\1\1\0\1\11\1\1\1\0\2\11"+ - "\1\0\1\1\2\0\1\11\6\0\1\11\1\0\1\1"+ - "\1\0\2\11\1\1\7\11\1\0\1\11\3\0\2\1"+ - "\3\0\4\1\2\11\1\0\1\11\2\1\1\11\2\1"+ - "\1\11\2\1\1\11\2\1"; + "\1\0\1\1\2\0\1\11\6\0\1\11\1\1\1\0"+ + "\1\1\1\0\2\11\1\1\7\11\1\0\1\11\4\0"+ + "\2\1\3\0\4\1\2\11\1\0\1\11\2\1\1\11"+ + "\2\1\1\11\2\1\1\11\2\1"; private static int [] zzUnpackAttribute() { - int [] result = new int[89]; + int [] result = new int[91]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -676,22 +677,28 @@ else if (zzAtEOF) { { return HbTokenTypes.OPEN_BLOCK; } case 51: break; + case 15: + // lookahead expression with fixed lookahead length + yypushback(1); + { return HbTokenTypes.NUMBER; + } + case 52: break; case 6: { return HbTokenTypes.DATA_PREFIX; } - case 52: break; + case 53: break; case 1: { return HbTokenTypes.CONTENT; } - case 53: break; + case 54: break; case 5: { return HbTokenTypes.EQUALS; } - case 54: break; + case 55: break; case 17: { return HbTokenTypes.OPEN_UNESCAPED; } - case 55: break; + case 56: break; case 30: { // backtrack over any extra stache characters at the end of this string while (yylength() > 2 && yytext().subSequence(yylength() - 3, yylength()).toString().equals("}}}")) { @@ -700,24 +707,18 @@ else if (zzAtEOF) { yypopState(); return HbTokenTypes.COMMENT; } - case 56: break; + case 57: break; case 23: { yypopState(); return HbTokenTypes.CLOSE_UNESCAPED; } - case 57: break; + case 58: break; case 13: { yypopState(); return HbTokenTypes.CLOSE; } - case 58: break; + case 59: break; case 3: { return HbTokenTypes.INVALID; } - case 59: break; - case 15: - // lookahead expression with fixed lookahead length - yypushback(1); - { return HbTokenTypes.INTEGER; - } case 60: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { diff --git a/src/com/dmarcotte/handlebars/HbHighlighter.java b/src/com/dmarcotte/handlebars/HbHighlighter.java index e2d57b7..9fc1bdb 100644 --- a/src/com/dmarcotte/handlebars/HbHighlighter.java +++ b/src/com/dmarcotte/handlebars/HbHighlighter.java @@ -15,100 +15,98 @@ import java.util.LinkedHashMap; import java.util.Map; -/** - * @author max - */ public class HbHighlighter extends SyntaxHighlighterBase { - private static final Map keys1; - private static final Map keys2; - - @NotNull - public Lexer getHighlightingLexer() { - return new HbLexer(); - } - - private static final TextAttributesKey MUSTACHES = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.MUSTACHES", - DefaultLanguageHighlighterColors.BRACES - ); - - private static final TextAttributesKey IDENTIFIERS = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.IDENTIFIERS", - DefaultLanguageHighlighterColors.KEYWORD - ); - - private static final TextAttributesKey COMMENTS = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.COMMENTS", - DefaultLanguageHighlighterColors.BLOCK_COMMENT - ); - - private static final TextAttributesKey OPERATORS = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.OPERATORS", - DefaultLanguageHighlighterColors.OPERATION_SIGN - ); - - private static final TextAttributesKey VALUES = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.VALUES", - DefaultLanguageHighlighterColors.NUMBER - ); - - private static final TextAttributesKey STRINGS = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.STRINGS", - DefaultLanguageHighlighterColors.STRING - ); - - private static final TextAttributesKey DATA_PREFIX = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.DATA_PREFIX", - DefaultLanguageHighlighterColors.KEYWORD - ); - - private static final TextAttributesKey ESCAPE = TextAttributesKey.createTextAttributesKey( - "HANDLEBARS.ESCAPE", - DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE - ); - - static { - keys1 = new HashMap(); - keys2 = new HashMap(); - - keys1.put(HbTokenTypes.OPEN, MUSTACHES); - keys1.put(HbTokenTypes.OPEN_BLOCK, MUSTACHES); - keys1.put(HbTokenTypes.OPEN_PARTIAL, MUSTACHES); - keys1.put(HbTokenTypes.OPEN_ENDBLOCK, MUSTACHES); - keys1.put(HbTokenTypes.OPEN_INVERSE, MUSTACHES); - keys1.put(HbTokenTypes.OPEN_UNESCAPED, MUSTACHES); - keys1.put(HbTokenTypes.CLOSE, MUSTACHES); - keys1.put(HbTokenTypes.CLOSE_UNESCAPED, MUSTACHES); - keys1.put(HbTokenTypes.ID, IDENTIFIERS); - keys1.put(HbTokenTypes.PARTIAL_NAME, IDENTIFIERS); - keys1.put(HbTokenTypes.COMMENT, COMMENTS); - keys1.put(HbTokenTypes.UNCLOSED_COMMENT, COMMENTS); - keys1.put(HbTokenTypes.EQUALS, OPERATORS); - keys1.put(HbTokenTypes.SEP, OPERATORS); - keys1.put(HbTokenTypes.INTEGER, VALUES); - keys1.put(HbTokenTypes.ELSE, IDENTIFIERS); - keys1.put(HbTokenTypes.BOOLEAN, VALUES); - keys1.put(HbTokenTypes.STRING, STRINGS); - keys1.put(HbTokenTypes.DATA_PREFIX, DATA_PREFIX); - keys1.put(HbTokenTypes.ESCAPE_CHAR, ESCAPE); - - } - - @NotNull - public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { - return pack(keys1.get(tokenType), keys2.get(tokenType)); - } - - public static final Map> DISPLAY_NAMES - = new LinkedHashMap>(); - static { - DISPLAY_NAMES.put(MUSTACHES, new Pair(HbBundle.message("hb.page.colors.descriptor.mustaches.key"),null)); - DISPLAY_NAMES.put(IDENTIFIERS, new Pair(HbBundle.message("hb.page.colors.descriptor.identifiers.key"),null)); - DISPLAY_NAMES.put(COMMENTS, new Pair(HbBundle.message("hb.page.colors.descriptor.comments.key"),null)); - DISPLAY_NAMES.put(OPERATORS, new Pair(HbBundle.message("hb.page.colors.descriptor.operators.key"),null)); - DISPLAY_NAMES.put(VALUES, new Pair(HbBundle.message("hb.page.colors.descriptor.values.key"),null)); - DISPLAY_NAMES.put(STRINGS, new Pair(HbBundle.message("hb.page.colors.descriptor.strings.key"),null)); - DISPLAY_NAMES.put(DATA_PREFIX, new Pair(HbBundle.message("hb.page.colors.descriptor.data.prefix.key"),null)); - DISPLAY_NAMES.put(ESCAPE, new Pair(HbBundle.message("hb.page.colors.descriptor.escape.key"),null)); - } + private static final Map keys1; + private static final Map keys2; + + @NotNull + public Lexer getHighlightingLexer() { + return new HbLexer(); + } + + private static final TextAttributesKey MUSTACHES = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.MUSTACHES", + DefaultLanguageHighlighterColors.BRACES + ); + + private static final TextAttributesKey IDENTIFIERS = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.IDENTIFIERS", + DefaultLanguageHighlighterColors.KEYWORD + ); + + private static final TextAttributesKey COMMENTS = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.COMMENTS", + DefaultLanguageHighlighterColors.BLOCK_COMMENT + ); + + private static final TextAttributesKey OPERATORS = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.OPERATORS", + DefaultLanguageHighlighterColors.OPERATION_SIGN + ); + + private static final TextAttributesKey VALUES = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.VALUES", + DefaultLanguageHighlighterColors.NUMBER + ); + + private static final TextAttributesKey STRINGS = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.STRINGS", + DefaultLanguageHighlighterColors.STRING + ); + + private static final TextAttributesKey DATA_PREFIX = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.DATA_PREFIX", + DefaultLanguageHighlighterColors.KEYWORD + ); + + private static final TextAttributesKey ESCAPE = TextAttributesKey.createTextAttributesKey( + "HANDLEBARS.ESCAPE", + DefaultLanguageHighlighterColors.VALID_STRING_ESCAPE + ); + + static { + keys1 = new HashMap(); + keys2 = new HashMap(); + + keys1.put(HbTokenTypes.OPEN, MUSTACHES); + keys1.put(HbTokenTypes.OPEN_BLOCK, MUSTACHES); + keys1.put(HbTokenTypes.OPEN_PARTIAL, MUSTACHES); + keys1.put(HbTokenTypes.OPEN_ENDBLOCK, MUSTACHES); + keys1.put(HbTokenTypes.OPEN_INVERSE, MUSTACHES); + keys1.put(HbTokenTypes.OPEN_UNESCAPED, MUSTACHES); + keys1.put(HbTokenTypes.CLOSE, MUSTACHES); + keys1.put(HbTokenTypes.CLOSE_UNESCAPED, MUSTACHES); + keys1.put(HbTokenTypes.ID, IDENTIFIERS); + keys1.put(HbTokenTypes.COMMENT, COMMENTS); + keys1.put(HbTokenTypes.UNCLOSED_COMMENT, COMMENTS); + keys1.put(HbTokenTypes.EQUALS, OPERATORS); + keys1.put(HbTokenTypes.SEP, OPERATORS); + keys1.put(HbTokenTypes.NUMBER, VALUES); + keys1.put(HbTokenTypes.ELSE, IDENTIFIERS); + keys1.put(HbTokenTypes.BOOLEAN, VALUES); + keys1.put(HbTokenTypes.STRING, STRINGS); + keys1.put(HbTokenTypes.DATA_PREFIX, DATA_PREFIX); + keys1.put(HbTokenTypes.ESCAPE_CHAR, ESCAPE); + } + + @NotNull + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(keys1.get(tokenType), keys2.get(tokenType)); + } + + public static final Map> DISPLAY_NAMES + = new LinkedHashMap>(); + + static { + DISPLAY_NAMES.put(MUSTACHES, new Pair(HbBundle.message("hb.page.colors.descriptor.mustaches.key"), null)); + DISPLAY_NAMES + .put(IDENTIFIERS, new Pair(HbBundle.message("hb.page.colors.descriptor.identifiers.key"), null)); + DISPLAY_NAMES.put(COMMENTS, new Pair(HbBundle.message("hb.page.colors.descriptor.comments.key"), null)); + DISPLAY_NAMES.put(OPERATORS, new Pair(HbBundle.message("hb.page.colors.descriptor.operators.key"), null)); + DISPLAY_NAMES.put(VALUES, new Pair(HbBundle.message("hb.page.colors.descriptor.values.key"), null)); + DISPLAY_NAMES.put(STRINGS, new Pair(HbBundle.message("hb.page.colors.descriptor.strings.key"), null)); + DISPLAY_NAMES + .put(DATA_PREFIX, new Pair(HbBundle.message("hb.page.colors.descriptor.data.prefix.key"), null)); + DISPLAY_NAMES.put(ESCAPE, new Pair(HbBundle.message("hb.page.colors.descriptor.escape.key"), null)); + } } diff --git a/src/com/dmarcotte/handlebars/parsing/HbParsing.java b/src/com/dmarcotte/handlebars/parsing/HbParsing.java index 5557700..9489164 100644 --- a/src/com/dmarcotte/handlebars/parsing/HbParsing.java +++ b/src/com/dmarcotte/handlebars/parsing/HbParsing.java @@ -481,12 +481,12 @@ private boolean parseParams(PsiBuilder builder) { * param * : path * | STRING - * | INTEGER + * | NUMBER * | BOOLEAN * | dataName * ; */ - private boolean parseParam(PsiBuilder builder) { + protected boolean parseParam(PsiBuilder builder) { PsiBuilder.Marker paramMarker = builder.mark(); if (parsePath(builder)) { @@ -505,7 +505,7 @@ private boolean parseParam(PsiBuilder builder) { } PsiBuilder.Marker integerMarker = builder.mark(); - if (parseLeafToken(builder, INTEGER)) { + if (parseLeafToken(builder, NUMBER)) { integerMarker.drop(); paramMarker.done(PARAM); return true; @@ -590,7 +590,7 @@ private boolean parseHashSegments(PsiBuilder builder) { * hashSegment * : ID EQUALS path * | ID EQUALS STRING - * | ID EQUALS INTEGER + * | ID EQUALS NUMBER * | ID EQUALS BOOLEAN * | ID EQUALS dataName * ; @@ -609,7 +609,7 @@ && parseLeafToken(builder, EQUALS) * partialName * : path * | STRING - * | INTEGER + * | NUMBER * ; */ private boolean parsePartialName(PsiBuilder builder) { @@ -635,7 +635,7 @@ private boolean parsePartialName(PsiBuilder builder) { } PsiBuilder.Marker integerMarker = builder.mark(); - if (parseLeafToken(builder, INTEGER)) { + if (parseLeafToken(builder, NUMBER)) { integerMarker.drop(); partialNameMarker.done(PARTIAL_NAME); return true; @@ -702,7 +702,7 @@ private boolean parsePath(PsiBuilder builder) { * : * | SEP ID pathSegments' */ - private boolean parsePathSegments(PsiBuilder builder) { + protected boolean parsePathSegments(PsiBuilder builder) { PsiBuilder.Marker pathSegmentsMarker = builder.mark(); /* HB_CUSTOMIZATION: see isHashNextLookAhead docs for details */ @@ -725,7 +725,7 @@ private boolean parsePathSegments(PsiBuilder builder) { /** * See {@link #parsePathSegments(com.intellij.lang.PsiBuilder)} for more info on this method */ - private void parsePathSegmentsPrime(PsiBuilder builder) { + protected void parsePathSegmentsPrime(PsiBuilder builder) { PsiBuilder.Marker pathSegmentsPrimeMarker = builder.mark(); if (!parseLeafToken(builder, SEP)) { diff --git a/src/com/dmarcotte/handlebars/parsing/HbTokenTypes.java b/src/com/dmarcotte/handlebars/parsing/HbTokenTypes.java index 46176f4..3e7c1dd 100644 --- a/src/com/dmarcotte/handlebars/parsing/HbTokenTypes.java +++ b/src/com/dmarcotte/handlebars/parsing/HbTokenTypes.java @@ -49,7 +49,7 @@ private HbTokenTypes() { public static final IElementType CLOSE_UNESCAPED = new HbElementType("CLOSE_UNESCAPED", "hb.parsing.element.expected.close.unescaped"); public static final IElementType ELSE = new HbElementType("ELSE", ""); public static final IElementType BOOLEAN = new HbElementType("BOOLEAN", "hb.parsing.element.expected.boolean"); - public static final IElementType INTEGER = new HbElementType("INTEGER", "hb.parsing.element.expected.integer"); + public static final IElementType NUMBER = new HbElementType("NUMBER", "hb.parsing.element.expected.integer"); public static final IElementType STRING = new HbElementType("STRING", "hb.parsing.element.expected.string"); public static final IElementType ESCAPE_CHAR = new HbElementType("ESCAPE_CHAR", ""); public static final IElementType INVALID = new HbElementType("INVALID", "hb.parsing.element.expected.invalid"); diff --git a/src/com/dmarcotte/handlebars/parsing/handlebars.flex b/src/com/dmarcotte/handlebars/parsing/handlebars.flex index 4d03292..5a7db6f 100644 --- a/src/com/dmarcotte/handlebars/parsing/handlebars.flex +++ b/src/com/dmarcotte/handlebars/parsing/handlebars.flex @@ -126,7 +126,7 @@ WhiteSpace = {LineTerminator} | [ \t\f] "else"/["}"\t \n\x0B\f\r] { return HbTokenTypes.ELSE; } // create a custom token for "else" so that we can highlight it independently of the "{{" but still parse it as an inverse operator "true"/["}"\t \n\x0B\f\r] { return HbTokenTypes.BOOLEAN; } "false"/["}"\t \n\x0B\f\r] { return HbTokenTypes.BOOLEAN; } - \-?[0-9]+/[}\t \n\x0B\f\r] { return HbTokenTypes.INTEGER; } + \-?[0-9]+(\.[0-9]+)?/[}\t \n\x0B\f\r] { return HbTokenTypes.NUMBER; } /* ID is the inverse of control characters. Control characters ranges: diff --git a/test/data/parser/MustachesWithHashArguments.txt b/test/data/parser/MustachesWithHashArguments.txt index 510917f..b907958 100644 --- a/test/data/parser/MustachesWithHashArguments.txt +++ b/test/data/parser/MustachesWithHashArguments.txt @@ -32,8 +32,8 @@ HbFile:MustachesWithHashArguments.hbs HbPsiElementImpl([Hb] EQUALS) PsiElement([Hb] EQUALS)('=') HbParamImpl(PARAM) - HbPsiElementImpl([Hb] INTEGER) - PsiElement([Hb] INTEGER)('1') + HbPsiElementImpl([Hb] NUMBER) + PsiElement([Hb] NUMBER)('1') HbPsiElementImpl([Hb] CLOSE) PsiElement([Hb] CLOSE)('}}') PsiWhiteSpace('\n') @@ -203,8 +203,8 @@ HbFile:MustachesWithHashArguments.hbs HbPsiElementImpl([Hb] EQUALS) PsiElement([Hb] EQUALS)('=') HbParamImpl(PARAM) - HbPsiElementImpl([Hb] INTEGER) - PsiElement([Hb] INTEGER)('1') + HbPsiElementImpl([Hb] NUMBER) + PsiElement([Hb] NUMBER)('1') HbPsiElementImpl([Hb] CLOSE) PsiElement([Hb] CLOSE)('}}') PsiWhiteSpace('\n') diff --git a/test/data/parser/MustachesWithIntegerParameters.txt b/test/data/parser/MustachesWithIntegerParameters.txt index 2122dd0..f8347a6 100644 --- a/test/data/parser/MustachesWithIntegerParameters.txt +++ b/test/data/parser/MustachesWithIntegerParameters.txt @@ -9,7 +9,7 @@ HbFile:MustachesWithIntegerParameters.hbs PsiElement([Hb] ID)('foo') PsiWhiteSpace(' ') HbParamImpl(PARAM) - HbPsiElementImpl([Hb] INTEGER) - PsiElement([Hb] INTEGER)('1') + HbPsiElementImpl([Hb] NUMBER) + PsiElement([Hb] NUMBER)('1') HbPsiElementImpl([Hb] CLOSE) PsiElement([Hb] CLOSE)('}}') \ No newline at end of file diff --git a/test/data/parser/ParamWithDecimal.hbs b/test/data/parser/ParamWithDecimal.hbs new file mode 100644 index 0000000..feacc99 --- /dev/null +++ b/test/data/parser/ParamWithDecimal.hbs @@ -0,0 +1 @@ +{{name 10.1}} \ No newline at end of file diff --git a/test/data/parser/ParamWithDecimal.txt b/test/data/parser/ParamWithDecimal.txt new file mode 100644 index 0000000..d5ab96f --- /dev/null +++ b/test/data/parser/ParamWithDecimal.txt @@ -0,0 +1,15 @@ +HbFile:ParamWithDecimal.hbs + HbStatementsImpl(STATEMENTS) + HbSimpleMustacheImpl(MUSTACHE) + HbPsiElementImpl([Hb] OPEN) + PsiElement([Hb] OPEN)('{{') + HbMustacheNameImpl(MUSTACHE_NAME) + HbPathImpl(PATH) + HbPsiElementImpl([Hb] ID) + PsiElement([Hb] ID)('name') + PsiWhiteSpace(' ') + HbParamImpl(PARAM) + HbPsiElementImpl([Hb] NUMBER) + PsiElement([Hb] NUMBER)('10.1') + HbPsiElementImpl([Hb] CLOSE) + PsiElement([Hb] CLOSE)('}}') \ No newline at end of file diff --git a/test/src/com/dmarcotte/handlebars/parsing/HbLexerFreeFormTest.java b/test/src/com/dmarcotte/handlebars/parsing/HbLexerFreeFormTest.java index 051ab0a..d6a737f 100644 --- a/test/src/com/dmarcotte/handlebars/parsing/HbLexerFreeFormTest.java +++ b/test/src/com/dmarcotte/handlebars/parsing/HbLexerFreeFormTest.java @@ -238,4 +238,22 @@ public void testOpenCloseUnescapedWhitespaceStrip() { result = tokenize("{{~{ foo }~}}"); result.shouldMatchTokenTypes(OPEN_UNESCAPED, WHITE_SPACE, ID, WHITE_SPACE, CLOSE_UNESCAPED); } + + public void testDecimalNumberAsMustacheParam() { + TokenizerResult result = tokenize("{{name 10.123}}"); + result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, NUMBER, CLOSE); + result.shouldMatchTokenContent("{{", "name", " ", "10.123", "}}"); + } + + public void testThreeDecimalNumberAsMustacheParam() { + TokenizerResult result = tokenize("{{name 42 10.1 42}}"); + result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, NUMBER, WHITE_SPACE, NUMBER, WHITE_SPACE, NUMBER, CLOSE); + result.shouldMatchTokenContent("{{", "name", " ", "42", " ", "10.1", " ", "42", "}}"); + } + + public void testDecimalNumberAsMustacheHashParam() { + TokenizerResult result = tokenize("{{name paramValue=10.1}}"); + result.shouldMatchTokenTypes(OPEN, ID, WHITE_SPACE, ID, EQUALS, NUMBER, CLOSE); + result.shouldMatchTokenContent("{{", "name", " ", "paramValue", "=", "10.1", "}}"); + } } diff --git a/test/src/com/dmarcotte/handlebars/parsing/HbParserFreeFormTest.java b/test/src/com/dmarcotte/handlebars/parsing/HbParserFreeFormTest.java index abcf6fd..3177417 100644 --- a/test/src/com/dmarcotte/handlebars/parsing/HbParserFreeFormTest.java +++ b/test/src/com/dmarcotte/handlebars/parsing/HbParserFreeFormTest.java @@ -72,4 +72,9 @@ public void testUnclosedSimpleComment() { public void testUnclosedBlockComment() { doTest(true); } + + public void testParamWithDecimal() { + doTest(true); + } + } diff --git a/test/src/com/dmarcotte/handlebars/parsing/HbTokenizerSpecTest.java b/test/src/com/dmarcotte/handlebars/parsing/HbTokenizerSpecTest.java index 87953d1..3e6e54f 100644 --- a/test/src/com/dmarcotte/handlebars/parsing/HbTokenizerSpecTest.java +++ b/test/src/com/dmarcotte/handlebars/parsing/HbTokenizerSpecTest.java @@ -356,12 +356,12 @@ public void testTokenizeMustacheWithStringParamWithEscapeQuotes() { */ public void testTokenizesNumbers() { TokenizerResult result = tokenize("{{ foo 1 }}"); - result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, INTEGER, WHITE_SPACE, CLOSE); - result.shouldBeToken(4, INTEGER, "1"); + result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, NUMBER, WHITE_SPACE, CLOSE); + result.shouldBeToken(4, NUMBER, "1"); result = tokenize("{{ foo -1 }}"); - result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, INTEGER, WHITE_SPACE, CLOSE); - result.shouldBeToken(4, INTEGER, "-1"); + result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, NUMBER, WHITE_SPACE, CLOSE); + result.shouldBeToken(4, NUMBER, "-1"); } /** @@ -388,7 +388,7 @@ public void testTokenizeHashArguments() { result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, ID, WHITE_SPACE, CLOSE); result = tokenize("{{ foo bar baz=1 }}"); - result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, INTEGER, WHITE_SPACE, CLOSE); + result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, NUMBER, WHITE_SPACE, CLOSE); result = tokenize("{{ foo bar baz=true }}"); result.shouldMatchTokenTypes(OPEN, WHITE_SPACE, ID, WHITE_SPACE, ID, WHITE_SPACE, ID, EQUALS, BOOLEAN, WHITE_SPACE, CLOSE);