From 0766fa4ed6a46277539e4c50bbe9e8215db749cd Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 25 Jul 2016 16:30:58 +0200 Subject: [PATCH] recognize escapes in file template text in absence of Velocity plugin (IDEA-158193) --- .../impl/FileTemplateLexerTest.java | 41 +++++++++++++++++++ .../impl/_FileTemplateTextLexer.java | 35 +++++++++------- .../impl/FileTemplateConfigurable.java | 9 +++- .../impl/FileTemplateTextLexer.flex | 2 + .../impl/FileTemplateTokenType.java | 1 + 5 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateLexerTest.java diff --git a/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateLexerTest.java b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateLexerTest.java new file mode 100644 index 000000000000..fa66f6b8fd84 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/ide/fileTemplates/impl/FileTemplateLexerTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.ide.fileTemplates.impl; + +import com.intellij.lexer.Lexer; +import com.intellij.testFramework.LexerTestCase; + +/** + * @author peter + */ +public class FileTemplateLexerTest extends LexerTestCase { + + public void testEscapes() { + doTest("\\#include foo $bar", "ESCAPE ('\\#')\n" + + "TEXT ('include foo ')\n" + + "MACRO ('$bar')"); + } + + @Override + protected Lexer createLexer() { + return FileTemplateConfigurable.createDefaultLexer(); + } + + @Override + protected String getDirPath() { + return null; + } +} \ No newline at end of file diff --git a/platform/lang-impl/gen/com/intellij/ide/fileTemplates/impl/_FileTemplateTextLexer.java b/platform/lang-impl/gen/com/intellij/ide/fileTemplates/impl/_FileTemplateTextLexer.java index 7fcda461cee1..03ed0b414fc3 100644 --- a/platform/lang-impl/gen/com/intellij/ide/fileTemplates/impl/_FileTemplateTextLexer.java +++ b/platform/lang-impl/gen/com/intellij/ide/fileTemplates/impl/_FileTemplateTextLexer.java @@ -52,7 +52,8 @@ class _FileTemplateTextLexer implements FlexLexer { /* The ZZ_CMAP_A table has 256 entries */ static final char ZZ_CMAP_A[] = zzUnpackCMap( - "\43\0\1\6\1\3\13\0\12\2\7\0\32\1\4\0\1\1\1\0\32\1\1\4\1\0\1\5\202\0"); + "\43\0\1\6\1\3\13\0\12\2\7\0\32\1\1\0\1\7\2\0\1\1\1\0\32\1\1\4\1\0\1\5\202"+ + "\0"); /** * Translates DFA states to action switch labels. @@ -60,10 +61,10 @@ class _FileTemplateTextLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\1\0\3\1\1\2\1\0\1\3\1\0\1\2"; + "\1\0\4\1\1\2\1\0\1\3\1\4\1\0\1\2"; private static int [] zzUnpackAction() { - int [] result = new int[9]; + int [] result = new int[11]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -88,11 +89,11 @@ class _FileTemplateTextLexer implements FlexLexer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\7\0\16\0\25\0\34\0\43\0\25\0\52"+ - "\0\7"; + "\0\0\0\10\0\20\0\30\0\40\0\50\0\60\0\30"+ + "\0\10\0\70\0\10"; private static int [] zzUnpackRowMap() { - int [] result = new int[9]; + int [] result = new int[11]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -115,12 +116,12 @@ class _FileTemplateTextLexer implements FlexLexer { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\3\2\1\3\2\2\1\4\10\0\2\5\1\0\1\6"+ - "\3\0\1\7\6\0\2\5\5\0\2\10\5\0\2\10"+ - "\2\0\1\11\1\0"; + "\3\2\1\3\2\2\1\4\1\5\11\0\2\6\1\0"+ + "\1\7\4\0\1\10\11\0\1\11\2\0\1\11\2\0"+ + "\2\6\6\0\2\12\6\0\2\12\2\0\1\13\2\0"; private static int [] zzUnpackTrans() { - int [] result = new int[49]; + int [] result = new int[64]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -158,10 +159,10 @@ class _FileTemplateTextLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\1\0\1\11\3\1\1\0\1\1\1\0\1\11"; + "\1\0\1\11\4\1\1\0\1\1\1\11\1\0\1\11"; private static int [] zzUnpackAttribute() { - int [] result = new int[9]; + int [] result = new int[11]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -469,15 +470,19 @@ class _FileTemplateTextLexer implements FlexLexer { case 1: { return FileTemplateTokenType.TEXT; } - case 4: break; + case 5: break; case 2: { return FileTemplateTokenType.MACRO; } - case 5: break; + case 6: break; case 3: { return FileTemplateTokenType.DIRECTIVE; } - case 6: break; + case 7: break; + case 4: + { return FileTemplateTokenType.ESCAPE; + } + case 8: break; default: zzScanError(ZZ_NO_MATCH); } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java index d6a4d77bb5ea..c6f4f75a3e01 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateConfigurable.java @@ -16,6 +16,7 @@ package com.intellij.ide.fileTemplates.impl; +import com.google.common.annotations.VisibleForTesting; import com.intellij.codeInsight.template.impl.TemplateColors; import com.intellij.ide.IdeBundle; import com.intellij.ide.fileTemplates.FileTemplate; @@ -419,7 +420,7 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc private final Lexer myLexer; public TemplateHighlighter() { - myLexer = new MergingLexerAdapter(new FlexAdapter(new _FileTemplateTextLexer()), TokenSet.create(FileTemplateTokenType.TEXT)); + myLexer = createDefaultLexer(); } @NotNull @@ -439,6 +440,12 @@ public class FileTemplateConfigurable implements Configurable, Configurable.NoSc } } + @NotNull + @VisibleForTesting + static Lexer createDefaultLexer() { + return new MergingLexerAdapter(new FlexAdapter(new _FileTemplateTextLexer()), TokenSet.create(FileTemplateTokenType.TEXT)); + } + public void focusToNameField() { myNameField.selectAll(); diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTextLexer.flex b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTextLexer.flex index 7c821dfda71b..93303df413af 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTextLexer.flex +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTextLexer.flex @@ -25,6 +25,8 @@ DIRECTIVE="#"{ALPHA}+ %% + "\\#" { return FileTemplateTokenType.ESCAPE; } + "\\$" { return FileTemplateTokenType.ESCAPE; } {MACRO} { return FileTemplateTokenType.MACRO; } {DIRECTIVE} { return FileTemplateTokenType.DIRECTIVE; } [^] { return FileTemplateTokenType.TEXT; } diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java index 977a14e56748..7bb5a8ff6f5b 100644 --- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java +++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FileTemplateTokenType.java @@ -20,6 +20,7 @@ import com.intellij.lang.Language; import com.intellij.psi.tree.IElementType; interface FileTemplateTokenType { + IElementType ESCAPE = new IElementType("ESCAPE", Language.ANY); IElementType TEXT = new IElementType("TEXT", Language.ANY); IElementType MACRO = new IElementType("MACRO", Language.ANY); IElementType DIRECTIVE = new IElementType("DIRECTIVE", Language.ANY);