From 17813350a484e11dae5138e56d57dfb93d393caa Mon Sep 17 00:00:00 2001 From: "Svetlana.Zemlyanskay" Date: Tue, 10 Jul 2012 17:12:03 +0400 Subject: [PATCH] Add GNU GetText plugin --- plugins/gettext/gettext.iml | 16 + plugins/gettext/src/META-INF/plugin.xml | 32 + .../src/com/jetbrains/gettext/GetText.flex | 161 ++++ .../gettext/GetTextCompositeElement.java | 30 + .../gettext/GetTextCompositeElementType.java | 27 + .../gettext/GetTextCompositeElementTypes.java | 17 + .../jetbrains/gettext/GetTextElementType.java | 14 + .../com/jetbrains/gettext/GetTextFile.java | 26 + .../jetbrains/gettext/GetTextFileType.java | 39 + .../gettext/GetTextFileTypeFactory.java | 14 + .../gettext/GetTextFileViewProvider.java | 21 + .../GetTextFileViewProviderFactory.java | 18 + .../com/jetbrains/gettext/GetTextIcons.java | 13 + .../jetbrains/gettext/GetTextLanguage.java | 15 + .../com/jetbrains/gettext/GetTextLexer.java | 14 + .../jetbrains/gettext/GetTextTokenTypes.java | 49 ++ .../com/jetbrains/gettext/_GetTextLexer.java | 703 ++++++++++++++++++ .../GetTextCompletitionContributor.java | 89 +++ .../highlighter/GetTextHighlighterData.java | 42 ++ .../highlighter/GetTextSyntaxHighlighter.java | 47 ++ .../gettext/lang/CommandFormatException.java | 11 + .../jetbrains/gettext/lang/MsgCommand.java | 68 ++ .../gettext/lang/MsgCommandContainer.java | 68 ++ .../gettext/lang/MsgctxtCommand.java | 22 + .../jetbrains/gettext/lang/MsgidCommand.java | 28 + .../gettext/lang/MsgidPluralCommand.java | 21 + .../jetbrains/gettext/lang/MsgstrCommand.java | 76 ++ .../gettext/lang/UnknownCommandException.java | 11 + .../gettext/parser/GetTextParser.java | 75 ++ .../parser/GetTextParserDefinition.java | 75 ++ .../jetbrains/gettext/GetTextLexerTest.java | 66 ++ .../jetbrains/gettext/GetTextParserTest.java | 47 ++ .../com/jetbrains/gettext/GetTextUtils.java | 32 + .../jetbrains/gettext/lexer/complex_flags.po | 6 + .../jetbrains/gettext/lexer/complex_flags.txt | 35 + .../gettext/lexer/complex_flags_parser.txt | 36 + .../test/com/jetbrains/gettext/lexer/flags.po | 6 + .../com/jetbrains/gettext/lexer/flags.txt | 30 + .../jetbrains/gettext/lexer/flags_parser.txt | 31 + .../com/jetbrains/gettext/lexer/msg_plural.po | 8 + .../jetbrains/gettext/lexer/msg_plural.txt | 44 ++ .../gettext/lexer/msg_plural_parser.txt | 45 ++ .../com/jetbrains/gettext/lexer/parser.po | 2 + .../jetbrains/gettext/lexer/parser_parser.txt | 0 .../com/jetbrains/gettext/lexer/range_flag.po | 6 + .../jetbrains/gettext/lexer/range_flag.txt | 37 + .../gettext/lexer/range_flag_parser.txt | 46 ++ .../com/jetbrains/gettext/lexer/simple.po | 13 + .../com/jetbrains/gettext/lexer/simple.txt | 62 ++ .../jetbrains/gettext/lexer/simple_parser.txt | 60 ++ .../com/jetbrains/gettext/lexer/string.po | 4 + .../com/jetbrains/gettext/lexer/string.txt | 10 + .../jetbrains/gettext/lexer/string_parser.txt | 15 + .../gettext/lexer/without_comments.po | 4 + .../gettext/lexer/without_comments.txt | 20 + .../gettext/lexer/without_comments_parser.txt | 29 + 56 files changed, 2536 insertions(+) create mode 100644 plugins/gettext/gettext.iml create mode 100644 plugins/gettext/src/META-INF/plugin.xml create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetText.flex create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElement.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementType.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementTypes.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextElementType.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextFile.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextFileType.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextFileTypeFactory.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextIcons.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextLanguage.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextLexer.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/MsgctxtCommand.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/MsgidCommand.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/MsgidPluralCommand.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/lang/UnknownCommandException.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java create mode 100644 plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParserDefinition.java create mode 100644 plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java create mode 100644 plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java create mode 100644 plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/flags.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/parser.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/parser_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/simple.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/string.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/string.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/string_parser.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.po create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.txt create mode 100644 plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments_parser.txt diff --git a/plugins/gettext/gettext.iml b/plugins/gettext/gettext.iml new file mode 100644 index 000000000000..53e9f256bae4 --- /dev/null +++ b/plugins/gettext/gettext.iml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/plugins/gettext/src/META-INF/plugin.xml b/plugins/gettext/src/META-INF/plugin.xml new file mode 100644 index 000000000000..3f91a8f5968a --- /dev/null +++ b/plugins/gettext/src/META-INF/plugin.xml @@ -0,0 +1,32 @@ + + GetText + com.jetbrains.gettext + + GNU GetText language support + + 1.0 + + + JetBrains + com.intellij.modules.lang + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetText.flex b/plugins/gettext/src/com/jetbrains/gettext/GetText.flex new file mode 100644 index 000000000000..d20b2d432ec2 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetText.flex @@ -0,0 +1,161 @@ +package com.jetbrains.gettext; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextTokenTypes; +import com.jetbrains.gettext.GetTextElementType; + +%% + +%{ + + public _GetTextLexer() { + this((java.io.Reader)null); + } + +%} + +%class _GetTextLexer +%implements FlexLexer +%unicode +%function advance +%type IElementType +%eof{ return; +%eof} +%caseless +%ignorecase + +EOL = (\r|\n|\r\n) +NO_EOL = !(\r|\n|\r\n) +SPACE = [ \t\f] +WHITE_SPACE = {EOL} | {SPACE} + +STRING_TAIL = [^\r\n]* +QUOTED_STRING = ("\"")~(\r|\n|\r\n|"\"") +TMP_QUOTED_STRING = ("\"")~("\"") + +DOUBLEQUOTE = \" +DOUBLEQUOTED_STRING = ([^\"] | \"\" | \\\")+ + +LBRACE = "[" +RBRACE = "]" +NUMBER = [0-9]* + +COMMENT_SYMBOL = "#" + +COMMENT_TYPE_SYMBOLS = ("#."|"#:"|"#,"|"#|") +COMMENT = (" "|\t|\f)~{EOL} +EXTRACTED_COMMENT = (".")~{EOL} +REFERENCE_COMMENT = (":")~{EOL} +PREVIOUS_COMMENT = ("|")~{EOL} +FLAG_GROUP = (",") + +DOT = "." +COLON = ":" +LINE = "|" +COMMA = "," + +MSGCTXT = "msgctxt" +MSGID = "msgid" +MSGID_PLURAL = "msgid_plural" +MSGSTR = "msgstr" + + +FUZZY_FLAG = "fuzzy" +NO = "no-" +FORMAT = "-format" +C = "c" +OBJC = "objc" +SH = "sh" +PYTHON = "python" +LISP = "lisp" +ELISP = "elisp" +LIBREP = "librep" +SCHEME = "scheme" +SMALLTALK = "smalltalk" +JAVA = "java" +CSHARP = "csharp" +AWK = "awk" +YCP = "ycp" +TCL = "tcl" +PERL = "perl-brace" +PHP = "php" +GCC = "gcc-internal" +GFC = "gfc-internal" +QT = "qt" +KDE = "kde" +BOOST = "boost" +OBJECT_PASCAL = "object-pascal" +QT_PLURAL = "qt-plural" + +PASCAL_FORMAT_FLAG = "object-pascal-format" +NO_PASCAL_FORMAT_FLAG = "no-object-pascal-format" +QT_FORMAT_FLAG = "qt-plural-format" +NO_QT_FORMAT_FLAG = "no-qt-plural-format" +FORMAT_FLAG = (C|OBJC|SH|PYTHON|LISP|EISP|LIBREP|SCHEME|SMALLTALK|JAVA|SCHARP|AWK|OBJECT_PASCAL|YCP|TCL|PERL|PHP|GCC|GFC|QT|QT_PLURAL|KDE|BOOST) {FORMAT} +NO_FORMAT_FLAG = {NO} {FORMAT_FLAG} + +RANGE_FLAG = "range" +DOTS = ".." + +FLAG_DELIVERY="," + +%state START_COMMENT +%state COMMENT +%state EXTR_COMMENT +%state REFERENCE_COMMENT +%state PREVIOUS_COMMENT +%state FLAG_COMMENT +%state FLAG_DEL + +%ignorecase + +%% + + {COMMENT_SYMBOL} { yybegin(START_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + {SPACE} { yybegin(COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + {DOT} { yybegin(EXTR_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + {COLON} { yybegin(REFERENCE_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + {LINE} { yybegin(PREVIOUS_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + {FLAG_GROUP} { yybegin(FLAG_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS;} + + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + {EOL} { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE;} + + {STRING_TAIL} { return GetTextTokenTypes.COMMENT;} + {STRING_TAIL} { return GetTextTokenTypes.EXTR_COMMENT;} + {STRING_TAIL} { return GetTextTokenTypes.REFERENCE;} + {STRING_TAIL} { return GetTextTokenTypes.PREVIOUS_COMMENT;} + + {PASCAL_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG;} + {NO_PASCAL_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG;} + {QT_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG;} + {NO_QT_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG;} + {FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG;} + {NO_FORMAT_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG;} + {FUZZY_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.FUZZY_FLAG;} + {RANGE_FLAG} { yybegin(FLAG_DEL); return GetTextTokenTypes.RANGE_FLAG;} + + {FLAG_DELIVERY} { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_DELIVERY;} + +{MSGCTXT} { return GetTextTokenTypes.MSGCTXT;} +{MSGID} { return GetTextTokenTypes.MSGID;} +{MSGID_PLURAL} { return GetTextTokenTypes.MSGID_PLURAL;} +{MSGSTR} { return GetTextTokenTypes.MSGSTR;} + + {WHITE_SPACE} { return GetTextTokenTypes.WHITE_SPACE;} + {SPACE} { return GetTextTokenTypes.WHITE_SPACE;} +{NUMBER} { return GetTextTokenTypes.NUMBER;} +{LBRACE} { return GetTextTokenTypes.LBRACE;} +{RBRACE} { return GetTextTokenTypes.RBRACE;} +{COLON} { return GetTextTokenTypes.COLON;} +{DOTS} { return GetTextTokenTypes.DOTS;} + +{QUOTED_STRING} { return GetTextTokenTypes.STRING;} + +[^] { return GetTextTokenTypes.BAD_CHARACTER; } \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElement.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElement.java new file mode 100644 index 000000000000..657daac4fbed --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElement.java @@ -0,0 +1,30 @@ +package com.jetbrains.gettext; + +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.intellij.lang.ASTNode; +import com.intellij.lang.Language; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextCompositeElement extends ASTWrapperPsiElement { + public GetTextCompositeElement(@NotNull ASTNode node) { + super(node); + } + + @NotNull + public Language getLanguage() { + return GetTextLanguage.INSTANCE; + } + + @NotNull + @SuppressWarnings({ "ConstantConditions", "EmptyMethod" }) + public ASTNode getNode() { + return super.getNode(); + } + + public String toString() { + return getNode().getElementType().toString(); + } +} \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementType.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementType.java new file mode 100644 index 000000000000..210089011018 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementType.java @@ -0,0 +1,27 @@ +package com.jetbrains.gettext; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.CompositeElement; +import com.intellij.psi.tree.ICompositeElementType; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextCompositeElementType extends IElementType implements ICompositeElementType { + public GetTextCompositeElementType(@NotNull @NonNls final String debugName) { + super(debugName, GetTextLanguage.INSTANCE); + } + + public static PsiElement createPsiElement(ASTNode node) { + return new GetTextCompositeElement(node); + } + + @NotNull + public ASTNode createCompositeNode() { + return new CompositeElement(this); + } +} \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementTypes.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementTypes.java new file mode 100644 index 000000000000..b92bf379c32b --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextCompositeElementTypes.java @@ -0,0 +1,17 @@ +package com.jetbrains.gettext; + +import com.intellij.psi.tree.IElementType; + +/** + * @author Svetlana.Zemlyanskaya + */ +public interface GetTextCompositeElementTypes { + IElementType HEADER = new GetTextCompositeElementType("HEADER"); + + IElementType MSG_BLOCK = new GetTextCompositeElementType("MSG_BLOCK"); + IElementType MSG_CONTENT = new GetTextCompositeElementType("MSG_CONTENT"); + IElementType MSGID = new GetTextCompositeElementType("MSGID"); + IElementType MSGSTR = new GetTextCompositeElementType("MSGSTR"); + IElementType MSGCTXT = new GetTextCompositeElementType("MSGCTXT"); + IElementType MSGID_PLURAL = new GetTextCompositeElementType("MSGID_PLURAL"); +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextElementType.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextElementType.java new file mode 100644 index 000000000000..8e14a67254a6 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextElementType.java @@ -0,0 +1,14 @@ +package com.jetbrains.gettext; + +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextElementType extends IElementType { + public GetTextElementType(@NotNull @NonNls String debugName) { + super(debugName, GetTextLanguage.INSTANCE); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFile.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFile.java new file mode 100644 index 000000000000..b1bfc500f2fa --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextFile.java @@ -0,0 +1,26 @@ +package com.jetbrains.gettext; + +import com.intellij.extapi.psi.PsiFileBase; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.FileViewProvider; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextFile extends PsiFileBase { + public GetTextFile (FileViewProvider viewProvider) { + super(viewProvider, GetTextLanguage.INSTANCE); + } + + @NotNull + public FileType getFileType() { + return GetTextFileType.INSTANCE; + } + + @Override + public String toString() { + return "GNU GetText File"; + } +} + diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileType.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileType.java new file mode 100644 index 000000000000..dae16e73914e --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileType.java @@ -0,0 +1,39 @@ +package com.jetbrains.gettext; + +import com.intellij.openapi.fileTypes.LanguageFileType; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextFileType extends LanguageFileType { + public static final GetTextFileType INSTANCE = new GetTextFileType(); + + private GetTextFileType() { + super(GetTextLanguage.INSTANCE); + } + + @NotNull + public String getName() { + return "GetText"; + } + + @NotNull + public String getDescription() { + return "GNU GetText"; + } + + @NotNull + public String getDefaultExtension() { + return "po"; + } + + @Override + public Icon getIcon() { + return GetTextIcons.FILETYPE_ICON; + } +} + + diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileTypeFactory.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileTypeFactory.java new file mode 100644 index 000000000000..f39b76ecdf2b --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileTypeFactory.java @@ -0,0 +1,14 @@ +package com.jetbrains.gettext; + +import com.intellij.openapi.fileTypes.FileTypeConsumer; +import com.intellij.openapi.fileTypes.FileTypeFactory; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextFileTypeFactory extends FileTypeFactory { + public void createFileTypes(@NotNull FileTypeConsumer consumer) { + consumer.consume(GetTextFileType.INSTANCE, GetTextFileType.INSTANCE.getDefaultExtension()); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java new file mode 100644 index 000000000000..2b806f7e9875 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProvider.java @@ -0,0 +1,21 @@ +package com.jetbrains.gettext; + +import com.intellij.lang.Language; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiManager; +import com.intellij.psi.SingleRootFileViewProvider; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextFileViewProvider extends SingleRootFileViewProvider { + + protected GetTextFileViewProvider(@NotNull PsiManager manager, @NotNull VirtualFile virtualFile, final boolean physical, @NotNull Language language) { + super(manager, virtualFile, physical, language); + } + + public boolean supportsIncrementalReparse(@NotNull final Language rootLanguage) { + return false; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java new file mode 100644 index 000000000000..07d5914c3166 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextFileViewProviderFactory.java @@ -0,0 +1,18 @@ +package com.jetbrains.gettext; + +import com.intellij.lang.Language; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.FileViewProvider; +import com.intellij.psi.FileViewProviderFactory; +import com.intellij.psi.PsiManager; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextFileViewProviderFactory implements FileViewProviderFactory { + + public FileViewProvider createFileViewProvider(@NotNull VirtualFile file, Language language, @NotNull PsiManager manager, boolean physical) { + return new GetTextFileViewProvider(manager, file, physical, language); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextIcons.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextIcons.java new file mode 100644 index 000000000000..6aa2a3da3660 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextIcons.java @@ -0,0 +1,13 @@ +package com.jetbrains.gettext; + +import com.intellij.icons.AllIcons; + +import javax.swing.*; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextIcons { + //public static Icon FILETYPE_ICON = IconLoader.getIcon("FileIcon.png", GetTextIcons.class); + public static Icon FILETYPE_ICON = AllIcons.FileTypes.Text; +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextLanguage.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextLanguage.java new file mode 100644 index 000000000000..acbf437d373a --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextLanguage.java @@ -0,0 +1,15 @@ +package com.jetbrains.gettext; + + +import com.intellij.lang.Language; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextLanguage extends Language { + public static GetTextLanguage INSTANCE = new GetTextLanguage(); + + private GetTextLanguage() { + super("GetText"); + } +} \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextLexer.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextLexer.java new file mode 100644 index 000000000000..d99e96f4311a --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextLexer.java @@ -0,0 +1,14 @@ +package com.jetbrains.gettext; + +import com.intellij.lexer.FlexAdapter; + +import java.io.Reader; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextLexer extends FlexAdapter { + public GetTextLexer() { + super(new _GetTextLexer((Reader)null)); + } +} \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java b/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java new file mode 100644 index 000000000000..fb32c5570c45 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/GetTextTokenTypes.java @@ -0,0 +1,49 @@ +package com.jetbrains.gettext; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; + +/** + * @author Svetlana.Zemlyanskaya + */ +public interface GetTextTokenTypes { + + IElementType COMMENT_SYMBOLS = new GetTextElementType("COMMENT_SYMBOLS"); + + IElementType BAD_CHARACTER = new GetTextElementType("BAD_CHARACTER"); + IElementType WHITE_SPACE = new GetTextElementType("WHITE_SPACE"); + + IElementType COMMENT = new GetTextElementType("COMMENT"); //# + IElementType EXTR_COMMENT = new GetTextElementType("EXTR_COMMENT"); //#. + IElementType REFERENCE = new GetTextElementType("REFERENCE"); //#: + IElementType FLAG_COMMENT = new GetTextElementType("FLAG_COMMENT"); //#, + IElementType PREVIOUS_COMMENT = new GetTextElementType("PREVIOUS_TRANSLATE_COMMENT"); //#| + + IElementType RANGE_FLAG = new GetTextElementType("RANGE_FLAG"); + IElementType FUZZY_FLAG = new GetTextElementType("FUZZY_FLAG"); + IElementType FORMAT_FLAG = new GetTextElementType("FORMAT_FLAG"); + IElementType NO_FORMAT_FLAG = new GetTextElementType("NO_FORMAT_FLAG"); + IElementType FLAG_DELIVERY = new GetTextElementType("DELIVERY"); + + IElementType MSG = new GetTextElementType("MSG_START"); + + IElementType MSGCTXT = new GetTextElementType("MSGCTXT"); + IElementType MSGID = new GetTextElementType("MSGID"); + IElementType MSGID_PLURAL = new GetTextElementType("MSGID_PLURAL"); + IElementType MSGSTR = new GetTextElementType("MSGSTR"); + + IElementType COLON = new GetTextElementType("COLON"); + IElementType DOTS = new GetTextElementType("DOTS"); + IElementType NUMBER = new GetTextElementType("NUMBER"); + IElementType LBRACE = new GetTextElementType("LBRACE"); + IElementType RBRACE = new GetTextElementType("RBRACE"); + + IElementType STRING = new GetTextElementType("STRING"); + + TokenSet SYSTEM_COMMENTS = TokenSet.create(EXTR_COMMENT, REFERENCE, FLAG_COMMENT, PREVIOUS_COMMENT, FLAG_DELIVERY, COMMENT_SYMBOLS); + TokenSet COMMENTS = TokenSet.orSet(TokenSet.create(COMMENT), SYSTEM_COMMENTS); + TokenSet STRING_LITERALS = TokenSet.create(STRING); + TokenSet KEYWORDS = TokenSet.create(MSG, MSGCTXT, MSGID, MSGID_PLURAL, MSGSTR); + TokenSet FLAGS = TokenSet.create(FUZZY_FLAG, FORMAT_FLAG, NO_FORMAT_FLAG, RANGE_FLAG); + TokenSet BRACES = TokenSet.create(LBRACE, RBRACE); +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java b/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java new file mode 100644 index 000000000000..9b20ffd1d9cf --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/_GetTextLexer.java @@ -0,0 +1,703 @@ +/* The following code was generated by JFlex 1.4.3 on 7/10/12 5:05 PM */ + +package com.jetbrains.gettext; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.tree.IElementType; + + +/** + * This class is a scanner generated by + * JFlex 1.4.3 + * on 7/10/12 5:05 PM from the specification file + * /home/svetlana/git/idea/IDEA/tools/lexer/../../community/plugins/gettext/src/com/jetbrains/gettext/GetText.flex + */ +class _GetTextLexer implements FlexLexer { + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int FLAG_DEL = 14; + public static final int YYINITIAL = 0; + public static final int REFERENCE_COMMENT = 8; + public static final int COMMENT = 4; + public static final int FLAG_COMMENT = 12; + public static final int PREVIOUS_COMMENT = 10; + public static final int EXTR_COMMENT = 6; + public static final int START_COMMENT = 2; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\3\1\2\1\0\1\3\1\1\22\0\1\3\1\0\1\4"+ + "\1\10\10\0\1\13\1\40\1\11\1\0\12\7\1\12\6\0\1\32"+ + "\1\41\1\20\1\24\1\44\1\33\1\17\1\43\1\23\1\42\1\45"+ + "\1\27\1\15\1\36\1\37\1\26\1\50\1\31\1\16\1\21\1\30"+ + "\1\46\1\47\1\22\1\35\1\34\1\5\1\0\1\6\1\0\1\25"+ + "\1\0\1\32\1\41\1\20\1\24\1\44\1\33\1\17\1\43\1\23"+ + "\1\42\1\45\1\27\1\15\1\36\1\37\1\26\1\50\1\31\1\16"+ + "\1\21\1\30\1\46\1\47\1\22\1\35\1\34\1\0\1\14\uff83\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\2\1\1\2\1\3\1\4\1\5\2\1\1\6\2\7"+ + "\1\6\1\10\1\11\1\1\1\12\1\6\1\13\1\6"+ + "\2\14\1\15\1\16\1\17\1\20\1\21\2\2\2\3"+ + "\2\4\2\5\21\6\1\22\1\0\2\23\1\24\101\0"+ + "\1\25\3\0\1\26\1\27\22\0\1\30\20\0\1\31"+ + "\17\0\1\32\23\0\1\33\1\0\1\34\2\0"; + + private static int [] zzUnpackAction() { + int [] result = new int[203]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\51\0\122\0\173\0\244\0\315\0\366\0\u011f"+ + "\0\u0148\0\u0171\0\u0148\0\u019a\0\u0148\0\u0148\0\u01c3\0\u0148"+ + "\0\u01ec\0\u0148\0\u0215\0\u023e\0\u0148\0\u0148\0\u01ec\0\u0148"+ + "\0\u0148\0\u0148\0\u0267\0\u0290\0\u02b9\0\u02e2\0\u030b\0\u0334"+ + "\0\u035d\0\u0386\0\u03af\0\u03d8\0\u0401\0\u042a\0\u0453\0\u047c"+ + "\0\u04a5\0\u04ce\0\u04f7\0\u0520\0\u0549\0\u0572\0\u059b\0\u05c4"+ + "\0\u05ed\0\u0616\0\u063f\0\u0148\0\u019a\0\u0668\0\u0148\0\u0148"+ + "\0\u0691\0\u06ba\0\u06e3\0\u0401\0\u070c\0\u0735\0\u075e\0\u0787"+ + "\0\u07b0\0\u07d9\0\u0802\0\u082b\0\u0854\0\u087d\0\u08a6\0\u08cf"+ + "\0\u08f8\0\u0921\0\u094a\0\u0973\0\u099c\0\u09c5\0\u09ee\0\u0a17"+ + "\0\u0a40\0\u0a69\0\u0a92\0\u0abb\0\u0ae4\0\u0b0d\0\u0b36\0\u0b5f"+ + "\0\u0b88\0\u0bb1\0\u0bda\0\u0c03\0\u0c2c\0\u0c55\0\u0c7e\0\u0ca7"+ + "\0\u0cd0\0\u0cf9\0\u0d22\0\u0d4b\0\u0d74\0\u0d9d\0\u0dc6\0\u0def"+ + "\0\u0e18\0\u0e41\0\u0e6a\0\u0e93\0\u0ebc\0\u0ee5\0\u0f0e\0\u0f37"+ + "\0\u0f60\0\u0f89\0\u0fb2\0\u0fdb\0\u1004\0\u102d\0\u1056\0\u107f"+ + "\0\u10a8\0\u10d1\0\u10fa\0\u1123\0\u114c\0\u0148\0\u0148\0\u1175"+ + "\0\u119e\0\u11c7\0\u11f0\0\u1219\0\u1242\0\u126b\0\u1294\0\u12bd"+ + "\0\u12e6\0\u130f\0\u1338\0\u1361\0\u138a\0\u13b3\0\u13dc\0\u1405"+ + "\0\u142e\0\u0148\0\u1457\0\u1480\0\u14a9\0\u14d2\0\u14fb\0\u1524"+ + "\0\u154d\0\u1576\0\u159f\0\u15c8\0\u15f1\0\u161a\0\u1643\0\u166c"+ + "\0\u1695\0\u16be\0\u0148\0\u16e7\0\u1710\0\u1739\0\u1762\0\u178b"+ + "\0\u17b4\0\u17dd\0\u1806\0\u182f\0\u1858\0\u1881\0\u18aa\0\u18d3"+ + "\0\u18fc\0\u1925\0\u0148\0\u194e\0\u1977\0\u19a0\0\u19c9\0\u19f2"+ + "\0\u1a1b\0\u1a44\0\u1a6d\0\u1a96\0\u1abf\0\u1ae8\0\u1b11\0\u1b3a"+ + "\0\u1b63\0\u1b8c\0\u1bb5\0\u1bde\0\u1c07\0\u1c30\0\u0148\0\u1c59"+ + "\0\u0148\0\u1c82\0\u1cab"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[203]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\11\1\12\2\13\1\14\1\15\1\16\1\17\1\20"+ + "\1\21\1\22\2\11\1\23\34\11\1\24\1\25\1\26"+ + "\1\14\1\15\1\16\1\17\1\11\1\27\1\30\1\31"+ + "\1\32\1\23\33\11\1\33\1\24\1\25\1\33\1\34"+ + "\44\33\1\35\1\24\1\25\1\35\1\36\44\35\1\37"+ + "\1\24\1\25\1\37\1\40\44\37\1\41\1\24\1\25"+ + "\1\41\1\42\44\41\1\11\1\24\1\25\1\13\1\14"+ + "\1\15\1\16\1\17\1\11\1\21\1\22\2\11\1\23"+ + "\1\43\1\44\1\45\1\46\4\11\1\47\1\50\1\11"+ + "\1\51\1\52\1\53\1\11\1\54\1\55\1\56\1\11"+ + "\1\57\1\60\1\11\1\61\1\62\2\11\1\63\1\11"+ + "\1\24\1\25\1\13\1\14\1\15\1\16\1\17\1\11"+ + "\1\21\1\22\1\64\1\11\1\23\33\11\53\0\1\13"+ + "\46\0\1\65\1\66\1\67\1\65\1\67\44\65\7\0"+ + "\1\17\52\0\1\70\55\0\1\71\34\0\1\25\46\0"+ + "\1\33\2\0\46\33\1\34\1\66\1\67\1\34\1\33"+ + "\44\34\1\35\2\0\46\35\1\36\1\66\1\67\1\36"+ + "\1\35\44\36\1\37\2\0\46\37\1\40\1\66\1\67"+ + "\1\40\1\37\44\40\1\41\2\0\46\41\1\42\1\66"+ + "\1\67\1\42\1\41\44\42\15\0\1\72\2\0\1\73"+ + "\22\0\1\74\25\0\1\75\12\0\1\75\55\0\1\76"+ + "\30\0\1\77\65\0\1\100\5\0\1\101\1\102\27\0"+ + "\1\103\57\0\1\104\65\0\1\105\31\0\1\106\40\0"+ + "\1\101\67\0\1\107\52\0\1\110\46\0\1\111\43\0"+ + "\1\112\41\0\1\113\51\0\1\114\45\0\1\115\31\0"+ + "\1\67\65\0\1\116\63\0\1\117\61\0\1\120\25\0"+ + "\1\74\63\0\1\121\44\0\1\74\42\0\1\122\55\0"+ + "\1\74\53\0\1\77\35\0\1\101\22\0\1\123\45\0"+ + "\1\124\57\0\1\74\37\0\1\125\54\0\1\126\52\0"+ + "\1\127\45\0\1\130\57\0\1\131\20\0\1\101\76\0"+ + "\1\74\31\0\1\132\12\0\1\133\26\0\1\134\1\0"+ + "\1\135\2\0\1\136\54\0\1\137\53\0\1\140\11\0"+ + "\1\141\43\0\1\142\54\0\1\143\36\0\1\144\36\0"+ + "\1\145\65\0\1\146\32\0\1\147\1\150\1\151\1\152"+ + "\4\0\1\153\1\154\2\0\1\155\2\0\1\156\1\0"+ + "\1\157\1\0\1\160\1\161\1\0\1\162\1\163\2\0"+ + "\1\164\20\0\1\74\23\0\1\165\22\0\1\166\64\0"+ + "\1\74\44\0\1\167\50\0\1\167\4\0\1\121\36\0"+ + "\1\170\50\0\1\171\53\0\1\172\53\0\1\173\52\0"+ + "\1\101\34\0\1\114\64\0\1\174\56\0\1\175\55\0"+ + "\1\101\50\0\1\176\41\0\1\177\30\0\1\200\2\0"+ + "\1\201\22\0\1\151\25\0\1\202\12\0\1\202\55\0"+ + "\1\203\30\0\1\204\65\0\1\205\5\0\1\206\1\207"+ + "\27\0\1\210\74\0\1\211\21\0\1\206\71\0\1\212"+ + "\46\0\1\213\43\0\1\214\41\0\1\215\51\0\1\216"+ + "\45\0\1\217\47\0\1\220\51\0\1\74\56\0\1\221"+ + "\52\0\1\222\41\0\1\223\53\0\1\224\44\0\1\225"+ + "\44\0\1\226\71\0\1\74\44\0\1\227\61\0\1\230"+ + "\25\0\1\151\63\0\1\231\44\0\1\151\42\0\1\232"+ + "\55\0\1\151\53\0\1\204\35\0\1\206\22\0\1\233"+ + "\54\0\1\151\45\0\1\234\45\0\1\235\57\0\1\236"+ + "\20\0\1\206\76\0\1\151\31\0\1\237\12\0\1\240"+ + "\31\0\1\241\57\0\1\242\41\0\1\243\55\0\1\244"+ + "\54\0\1\245\50\0\1\246\45\0\1\247\53\0\1\250"+ + "\11\0\1\251\43\0\1\252\54\0\1\253\36\0\1\254"+ + "\37\0\1\151\23\0\1\255\22\0\1\256\64\0\1\151"+ + "\44\0\1\257\50\0\1\257\4\0\1\231\42\0\1\260"+ + "\12\0\1\260\41\0\1\261\46\0\1\262\50\0\1\105"+ + "\42\0\1\263\56\0\1\264\52\0\1\206\34\0\1\216"+ + "\64\0\1\265\56\0\1\266\55\0\1\206\24\0\1\267"+ + "\51\0\1\151\56\0\1\270\47\0\1\271\54\0\1\77"+ + "\46\0\1\272\41\0\1\273\44\0\1\274\71\0\1\151"+ + "\33\0\1\275\57\0\1\276\52\0\1\277\47\0\1\300"+ + "\51\0\1\301\50\0\1\302\43\0\1\303\12\0\1\303"+ + "\41\0\1\304\35\0\1\305\64\0\1\306\45\0\1\211"+ + "\42\0\1\307\55\0\1\310\54\0\1\204\36\0\1\261"+ + "\57\0\1\311\53\0\1\312\34\0\1\313\52\0\1\304"+ + "\30\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[7380]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + private static final char[] EMPTY_BUFFER = new char[0]; + private static final int YYEOF = -1; + private static java.io.Reader zzReader = null; // Fake + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\10\1\1\11\1\1\1\11\1\1\2\11\1\1\1\11"+ + "\1\1\1\11\2\1\2\11\1\1\3\11\31\1\1\11"+ + "\1\0\1\1\2\11\101\0\1\1\3\0\2\11\22\0"+ + "\1\11\20\0\1\11\17\0\1\11\23\0\1\11\1\0"+ + "\1\11\2\0"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[203]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private CharSequence zzBuffer = ""; + + /** this buffer may contains the current text array to be matched when it is cheap to acquire it */ + private char[] zzBufferArray; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ + + public _GetTextLexer() { + this((java.io.Reader)null); + } + + + + _GetTextLexer(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + _GetTextLexer(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 160) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + public final int getTokenStart(){ + return zzStartRead; + } + + public final int getTokenEnd(){ + return getTokenStart() + yylength(); + } + + public void reset(CharSequence buffer, int start, int end,int initialState){ + zzBuffer = buffer; + zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer); + zzCurrentPos = zzMarkedPos = zzStartRead = start; + zzPushbackPos = 0; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = end; + yybegin(initialState); + } + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(zzStartRead+pos); + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() { + if (!zzEOFDone) { + zzEOFDone = true; + + } + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public IElementType advance() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + char[] zzBufferArrayL = zzBufferArray; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 2: + { return GetTextTokenTypes.COMMENT; + } + case 29: break; + case 27: + { yybegin(FLAG_DEL); return GetTextTokenTypes.NO_FORMAT_FLAG; + } + case 30: break; + case 25: + { return GetTextTokenTypes.MSGCTXT; + } + case 31: break; + case 14: + { yybegin(EXTR_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 32: break; + case 7: + { return GetTextTokenTypes.WHITE_SPACE; + } + case 33: break; + case 8: + { return GetTextTokenTypes.LBRACE; + } + case 34: break; + case 10: + { yybegin(START_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 35: break; + case 26: + { yybegin(FLAG_DEL); return GetTextTokenTypes.FORMAT_FLAG; + } + case 36: break; + case 6: + { return GetTextTokenTypes.BAD_CHARACTER; + } + case 37: break; + case 9: + { return GetTextTokenTypes.RBRACE; + } + case 38: break; + case 12: + { yybegin(YYINITIAL); return GetTextTokenTypes.WHITE_SPACE; + } + case 39: break; + case 16: + { yybegin(FLAG_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 40: break; + case 17: + { yybegin(PREVIOUS_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 41: break; + case 20: + { return GetTextTokenTypes.DOTS; + } + case 42: break; + case 4: + { return GetTextTokenTypes.REFERENCE; + } + case 43: break; + case 24: + { return GetTextTokenTypes.MSGSTR; + } + case 44: break; + case 19: + { return GetTextTokenTypes.STRING; + } + case 45: break; + case 15: + { yybegin(REFERENCE_COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 46: break; + case 22: + { yybegin(FLAG_DEL); return GetTextTokenTypes.RANGE_FLAG; + } + case 47: break; + case 11: + { return GetTextTokenTypes.COLON; + } + case 48: break; + case 1: + { return GetTextTokenTypes.NUMBER; + } + case 49: break; + case 18: + { yybegin(FLAG_COMMENT); return GetTextTokenTypes.FLAG_DELIVERY; + } + case 50: break; + case 3: + { return GetTextTokenTypes.EXTR_COMMENT; + } + case 51: break; + case 21: + { return GetTextTokenTypes.MSGID; + } + case 52: break; + case 5: + { return GetTextTokenTypes.PREVIOUS_COMMENT; + } + case 53: break; + case 28: + { return GetTextTokenTypes.MSGID_PLURAL; + } + case 54: break; + case 23: + { yybegin(FLAG_DEL); return GetTextTokenTypes.FUZZY_FLAG; + } + case 55: break; + case 13: + { yybegin(COMMENT); return GetTextTokenTypes.COMMENT_SYMBOLS; + } + case 56: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + return null; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java new file mode 100644 index 000000000000..de526dcbcb9b --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/completion/GetTextCompletitionContributor.java @@ -0,0 +1,89 @@ +package com.jetbrains.gettext.completion; + +import com.intellij.codeInsight.completion.*; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.psi.PsiElement; +import com.intellij.util.ProcessingContext; +import com.jetbrains.gettext.GetTextLanguage; +import com.jetbrains.gettext.GetTextTokenTypes; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.List; + +import static com.intellij.patterns.PlatformPatterns.psiElement; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextCompletitionContributor extends CompletionContributor { + + private final static String[] KEYWORDS = { + "msgid", + "msgstr", + "msgctxt", + "msgid_plural", + "fuzzy", + "c-format" + }; + + //private final static String[] BUILT_IN_FILTERS = { + // "date", + // "format", + // "replace", + // "url_encode", + // "json_encode", + // "title", + // "capitalize", + // "upper", + // "lower", + // "striptags", + // "join", + // "reverse", + // "length", + // "sort", + // "default", + // "keys", + // "escape", + // "raw", + // "merge" + //}; + + private final static List KEYWORD_LOOKUPS = new ArrayList(); + //private final static List BUILT_IN_FILTER_LOOKUPS = new ArrayList(); + + static { + for (String keyword : KEYWORDS) { + KEYWORD_LOOKUPS.add(LookupElementBuilder.create(keyword)); + } + //for (String filter : BUILT_IN_FILTERS) { + // BUILT_IN_FILTER_LOOKUPS.add(LookupElementBuilder.create(filter)); + //} + } + + public GetTextCompletitionContributor() { + extend(CompletionType.BASIC, psiElement().withParent(psiElement().withLanguage(GetTextLanguage.INSTANCE)), + new GetTextKeywordCompletionContributor()); + } + + private static class GetTextKeywordCompletionContributor extends CompletionProvider { + + @Override + protected void addCompletions(@NotNull CompletionParameters parameters, + ProcessingContext context, + @NotNull CompletionResultSet result) { + final PsiElement currElement = parameters.getPosition().getOriginalElement(); + if (currElement.getNode().getElementType() == GetTextTokenTypes.BAD_CHARACTER) { + for (LookupElementBuilder builder : KEYWORD_LOOKUPS) result.addElement(builder); + result.stopHere(); + //return; + } + //PsiElement prevElement = currElement.getPrevSibling(); + //if (prevElement != null && prevElement instanceof PsiWhiteSpace) prevElement = prevElement.getPrevSibling(); + //if (prevElement != null && prevElement.getNode().getElementType() == TwigTokenTypes.FILTER) { + // for (LookupElementBuilder builder : BUILT_IN_FILTER_LOOKUPS) result.addElement(builder); + // result.stopHere(); + //} + } + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java new file mode 100644 index 000000000000..1147e110535b --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextHighlighterData.java @@ -0,0 +1,42 @@ +package com.jetbrains.gettext.highlighter; + +import com.intellij.openapi.editor.HighlighterColors; +import com.intellij.openapi.editor.SyntaxHighlighterColors; +import com.intellij.openapi.editor.colors.TextAttributesKey; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextHighlighterData { + + public static final String COMMENT_ID = "GET_TEXT_COMMENT"; + public static final TextAttributesKey COMMENT = + TextAttributesKey.createTextAttributesKey(COMMENT_ID, SyntaxHighlighterColors.LINE_COMMENT.getDefaultAttributes().clone()); + + public static final String KEYWORD_ID = "GET_TEXT_KEYWORD"; + public static final TextAttributesKey KEYWORD = + TextAttributesKey.createTextAttributesKey(KEYWORD_ID, SyntaxHighlighterColors.KEYWORD.getDefaultAttributes().clone()); + + public static final String STRING_ID = "GET_TEXT_STRING"; + public static final TextAttributesKey STRING = + TextAttributesKey.createTextAttributesKey(STRING_ID, SyntaxHighlighterColors.STRING.getDefaultAttributes().clone()); + + public static final String FLAG_ID = "GET_TEXT_FLAG"; + public static final TextAttributesKey FLAG = + TextAttributesKey.createTextAttributesKey(FLAG_ID, SyntaxHighlighterColors.DOC_COMMENT_TAG.getDefaultAttributes().clone()); + + public static final String TRANSLATED_NUMBER_ID = "GET_TEXT_TRANSLATED_NUMBER"; + public static final TextAttributesKey TRANSLATED_NUMBER = + TextAttributesKey.createTextAttributesKey(TRANSLATED_NUMBER_ID, SyntaxHighlighterColors.NUMBER.getDefaultAttributes().clone()); + + public static final String BRACES_ID = "GET_TEXT_BRACES"; + public static final TextAttributesKey BRACES = + TextAttributesKey.createTextAttributesKey(BRACES_ID, SyntaxHighlighterColors.BRACES.getDefaultAttributes().clone()); + + public static final String DOTS_ID = "GET_TEXT_DOTS"; + public static final TextAttributesKey DOTS = + TextAttributesKey.createTextAttributesKey(DOTS_ID, SyntaxHighlighterColors.DOT.getDefaultAttributes().clone()); + + public static final TextAttributesKey BAD_CHARACTER = + TextAttributesKey.createTextAttributesKey("TS_BAD_CHARACTER", HighlighterColors.BAD_CHARACTER.getDefaultAttributes()); +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java new file mode 100644 index 000000000000..7719be7df13b --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/highlighter/GetTextSyntaxHighlighter.java @@ -0,0 +1,47 @@ +package com.jetbrains.gettext.highlighter; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextLexer; +import com.jetbrains.gettext.GetTextTokenTypes; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextSyntaxHighlighter extends SyntaxHighlighterBase { + private static final Map keys1; + + public GetTextSyntaxHighlighter() { + } + + @NotNull + public Lexer getHighlightingLexer() { + return new GetTextLexer(); + } + + static { + keys1 = new HashMap(); + + fillMap(keys1, GetTextTokenTypes.FLAGS, GetTextHighlighterData.FLAG); + fillMap(keys1, GetTextTokenTypes.COMMENTS, GetTextHighlighterData.COMMENT); + fillMap(keys1, GetTextTokenTypes.KEYWORDS, GetTextHighlighterData.KEYWORD); + fillMap(keys1, GetTextTokenTypes.STRING_LITERALS, GetTextHighlighterData.STRING); + fillMap(keys1, GetTextTokenTypes.BRACES, GetTextHighlighterData.BRACES); + keys1.put(GetTextTokenTypes.NUMBER, GetTextHighlighterData.TRANSLATED_NUMBER); + keys1.put(GetTextTokenTypes.DOTS, GetTextHighlighterData.DOTS); + keys1.put(TokenType.BAD_CHARACTER, GetTextHighlighterData.BAD_CHARACTER); + + } + + @NotNull + public TextAttributesKey[] getTokenHighlights(IElementType tokenType) { + return pack(keys1.get(tokenType)); + } +} \ No newline at end of file diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java b/plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java new file mode 100644 index 000000000000..212465d09c2e --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/CommandFormatException.java @@ -0,0 +1,11 @@ +package com.jetbrains.gettext.lang; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class CommandFormatException extends Exception { + + public CommandFormatException(String message) { + super(message); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java new file mode 100644 index 000000000000..b85fd9d6dcec --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommand.java @@ -0,0 +1,68 @@ +package com.jetbrains.gettext.lang; + +import com.intellij.lang.PsiBuilder; +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextTokenTypes; + +/** + * @author Svetlana.Zemlyanskaya + */ +public abstract class MsgCommand { + + protected boolean exists = false; + + public abstract IElementType getCompositeElement(); + + public void parse(PsiBuilder builder) throws CommandFormatException { + builder.advanceLexer(); + int count = 0; + while (builder.getTokenType() == GetTextTokenTypes.STRING) { + checkString(builder); + count++; + } + if (count == 0) { + throw new CommandFormatException("String for " + getName() + " is not specified"); + } + } + + private static void checkString(PsiBuilder builder) { + String text = builder.getTokenText(); + if (text != null && text.length() > 0 && + (text.charAt(0) != '\"' || text.charAt(text.length() - 1) != '\"')) { + PsiBuilder.Marker marker = builder.mark(); + builder.advanceLexer(); + marker.error("Unbounded string"); + } else { + builder.advanceLexer(); + } + } + + public boolean isNecessary() { + return false; + } + + public boolean isMultiple() { + return false; + } + + public boolean exists() { + return exists; + } + + public boolean register() { + if (!exists) { + exists = true; + return true; + } + else if (isMultiple()) { + return true; + } + return false; + } + + public abstract String getName(); + + public int getCount() { + return exists ? 1 : 0; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java new file mode 100644 index 000000000000..8305aa91bd90 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgCommandContainer.java @@ -0,0 +1,68 @@ +package com.jetbrains.gettext.lang; + +import com.intellij.lang.PsiBuilder; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.containers.hash.HashMap; +import com.jetbrains.gettext.GetTextTokenTypes; + +import java.util.Map; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class MsgCommandContainer { + + private Map commands; + + public MsgCommandContainer() { + this.commands = new HashMap(); + commands.put(GetTextTokenTypes.MSGID, new MsgidCommand()); + commands.put(GetTextTokenTypes.MSGSTR, new MsgstrCommand()); + commands.put(GetTextTokenTypes.MSGCTXT, new MsgctxtCommand()); + commands.put(GetTextTokenTypes.MSGID_PLURAL, new MsgidPluralCommand()); + } + + + public boolean isFull() { + for (MsgCommand command : commands.values()) { + boolean full = !command.isNecessary() || command.exists(); + if (!full) { + return false; + } + } + return true; + } + + private MsgCommand getCommand(IElementType token) throws UnknownCommandException { + MsgCommand command = commands.get(token); + if (command == null) { + throw new UnknownCommandException("Unexpected token"); + } + return command; + } + + public boolean parse(PsiBuilder builder) { + PsiBuilder.Marker marker = builder.mark(); + try { + MsgCommand command = getCommand(builder.getTokenType()); + command.parse(builder); + //if (result) { + marker.done(command.getCompositeElement()); + //} + //else { + // marker.error("String for " + command.getName() + " is not specified"); + //} + //return result; + return true; + } + catch (Exception e) { + marker.error(e.getMessage()); + builder.advanceLexer(); + return false; + } + } + + public boolean addCommand(IElementType token) throws UnknownCommandException { + return getCommand(token).register(); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgctxtCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgctxtCommand.java new file mode 100644 index 000000000000..3da7994ee968 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgctxtCommand.java @@ -0,0 +1,22 @@ +package com.jetbrains.gettext.lang; + +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextCompositeElementTypes; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class MsgctxtCommand extends MsgCommand { + public MsgctxtCommand() { + } + + @Override + public IElementType getCompositeElement() { + return GetTextCompositeElementTypes.MSGCTXT; + } + + @Override + public String getName() { + return "msgctxt"; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgidCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgidCommand.java new file mode 100644 index 000000000000..f4780d09f9e4 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgidCommand.java @@ -0,0 +1,28 @@ +package com.jetbrains.gettext.lang; + +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextCompositeElementTypes; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class MsgidCommand extends MsgCommand { + + public MsgidCommand() { + } + + @Override + public IElementType getCompositeElement() { + return GetTextCompositeElementTypes.MSGID; + } + + @Override + public boolean isNecessary() { + return true; + } + + @Override + public String getName() { + return "msgid"; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgidPluralCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgidPluralCommand.java new file mode 100644 index 000000000000..12c8664bdd52 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgidPluralCommand.java @@ -0,0 +1,21 @@ +package com.jetbrains.gettext.lang; + +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextCompositeElementTypes; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class MsgidPluralCommand extends MsgCommand { + public MsgidPluralCommand() { + } + @Override + public IElementType getCompositeElement() { + return GetTextCompositeElementTypes.MSGID_PLURAL; + } + + @Override + public String getName() { + return "msgid_plural"; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java new file mode 100644 index 000000000000..15afdcb08002 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/MsgstrCommand.java @@ -0,0 +1,76 @@ +package com.jetbrains.gettext.lang; + +import com.intellij.lang.PsiBuilder; +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextCompositeElementTypes; +import com.jetbrains.gettext.GetTextTokenTypes; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class MsgstrCommand extends MsgCommand { + + private int count; + + public MsgstrCommand() { + count = 0; + } + + @Override + public IElementType getCompositeElement() { + return GetTextCompositeElementTypes.MSGSTR; + } + + @Override + public void parse(PsiBuilder builder) throws CommandFormatException { + try { + super.parse(builder); + } + catch (CommandFormatException e) { + parseBraces(builder); + } + //return super.parse(builder) || parseBraces(builder); + } + + private boolean parseBraces(PsiBuilder builder) throws CommandFormatException { + if (builder.getTokenType() == GetTextTokenTypes.LBRACE) { + builder.advanceLexer(); + if (builder.getTokenType() == GetTextTokenTypes.NUMBER) { + builder.advanceLexer(); + if (builder.getTokenType() == GetTextTokenTypes.RBRACE) { + super.parse(builder); + } + } + } + return false; + } + + @Override + public boolean isNecessary() { + return true; + } + + @Override + public boolean isMultiple() { + return true; + } + + @Override + public String getName() { + return "msgstr"; + } + + @Override + public int getCount() { + return count; + } + + @Override + public boolean register() { + boolean result = super.register(); + if (result) { + count++; + } + return result; + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/lang/UnknownCommandException.java b/plugins/gettext/src/com/jetbrains/gettext/lang/UnknownCommandException.java new file mode 100644 index 000000000000..60d70f9b4e75 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/lang/UnknownCommandException.java @@ -0,0 +1,11 @@ +package com.jetbrains.gettext.lang; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class UnknownCommandException extends Exception { + + public UnknownCommandException(String message) { + super(message); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java b/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java new file mode 100644 index 000000000000..c0b9a0242118 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParser.java @@ -0,0 +1,75 @@ +package com.jetbrains.gettext.parser; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiParser; +import com.intellij.psi.tree.IElementType; +import com.jetbrains.gettext.GetTextCompositeElementTypes; +import com.jetbrains.gettext.GetTextTokenTypes; +import com.jetbrains.gettext.lang.MsgCommandContainer; +import com.jetbrains.gettext.lang.UnknownCommandException; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextParser implements PsiParser { + @NotNull + @Override + public ASTNode parse(IElementType root, PsiBuilder builder) { + builder.setDebugMode(true); + final PsiBuilder.Marker marker = builder.mark(); + while (!builder.eof()) { + parseMsgBock(builder); + } + marker.done(root); + return builder.getTreeBuilt(); + } + + private static void parseMsgBock(PsiBuilder builder) { + PsiBuilder.Marker msgidMarker = builder.mark(); + parseCommentHeader(builder); + parseMsgContent(builder); + msgidMarker.done(GetTextCompositeElementTypes.MSG_BLOCK); + } + + private static void parseCommentHeader(PsiBuilder builder) { + PsiBuilder.Marker marker = builder.mark(); + while (GetTextTokenTypes.COMMENTS.contains(builder.getTokenType()) || + GetTextTokenTypes.FLAGS.contains(builder.getTokenType())) { + builder.advanceLexer(); + } + marker.done(GetTextCompositeElementTypes.HEADER); + } + + private static boolean parseMsgContent(PsiBuilder builder) { + PsiBuilder.Marker marker = builder.mark(); + MsgCommandContainer container = new MsgCommandContainer(); + while (!canTerminate(builder, container)) { + try { + IElementType token = builder.getTokenType(); + if (container.parse(builder)) { + container.addCommand(token); + } + } + catch (UnknownCommandException e) { + //marker.precede().error(e.getMessage()); + //builder.advanceLexer(); + } + } + if (!container.isFull()) { + marker.error("Not enough commands"); + return false; + } + else { + marker.done(GetTextCompositeElementTypes.MSG_CONTENT); + return true; + } + } + + private static boolean canTerminate(PsiBuilder builder, MsgCommandContainer container) { + return builder.eof() || + GetTextTokenTypes.SYSTEM_COMMENTS.contains(builder.getTokenType()) || + builder.getTokenType() == GetTextTokenTypes.MSGID && container.isFull(); + } +} diff --git a/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParserDefinition.java b/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParserDefinition.java new file mode 100644 index 000000000000..193a5ecc46f7 --- /dev/null +++ b/plugins/gettext/src/com/jetbrains/gettext/parser/GetTextParserDefinition.java @@ -0,0 +1,75 @@ +package com.jetbrains.gettext.parser; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.ParserDefinition; +import com.intellij.lang.PsiParser; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.project.Project; +import com.intellij.psi.FileViewProvider; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.IFileElementType; +import com.intellij.psi.tree.IStubFileElementType; +import com.intellij.psi.tree.TokenSet; +import com.jetbrains.gettext.*; +import org.jetbrains.annotations.NotNull; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextParserDefinition implements ParserDefinition { + private static final TokenSet WHITE_SPACE = TokenSet.create(GetTextTokenTypes.WHITE_SPACE); + private static final TokenSet COMMENT = TokenSet.create(GetTextTokenTypes.COMMENT, GetTextTokenTypes.COMMENT_SYMBOLS); + + @NotNull + public Lexer createLexer(Project project) { + return new GetTextLexer(); + } + + public PsiParser createParser(Project project) { + return new GetTextParser(); + } + + public IFileElementType getFileNodeType() { + return new IStubFileElementType(GetTextLanguage.INSTANCE); + } + + @NotNull + public TokenSet getWhitespaceTokens() { + return WHITE_SPACE; + } + + @NotNull + public TokenSet getCommentTokens() { + return COMMENT; + } + + @NotNull + public TokenSet getStringLiteralElements() { + return GetTextTokenTypes.STRING_LITERALS; + } + + @NotNull + public PsiElement createElement(ASTNode node) { + final IElementType type = node.getElementType(); + if (type instanceof GetTextCompositeElementType) { + return GetTextCompositeElementType.createPsiElement(node); + } + throw new AssertionError("Unknown type: " + type); + } + + public PsiFile createFile(FileViewProvider viewProvider) { + return new GetTextFile(viewProvider); + } + + public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { + return SpaceRequirements.MAY; + } + + @Override + public String toString() { + return "GetTextParserDefinition"; + } +} + diff --git a/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java b/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java new file mode 100644 index 000000000000..666bbcd73d34 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/GetTextLexerTest.java @@ -0,0 +1,66 @@ +package com.jetbrains.gettext; + +import com.intellij.lexer.Lexer; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.tree.IElementType; +import com.intellij.testFramework.UsefulTestCase; + +import java.io.File; +import java.io.IOException; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextLexerTest extends UsefulTestCase { + + private static void doFileLexerTest(Lexer lexer, String testText, String expected) { + lexer.start(testText); + String result = ""; + while (true) { + IElementType tokenType = lexer.getTokenType(); + if (tokenType == null) { + break; + } + String tokenText = getTokenText(lexer); + String tokenTypeName = tokenType.toString(); + String line = tokenTypeName + " ('" + tokenText + "')\n"; + result += line; + lexer.advance(); + } + assertSameLinesWithFile(expected, result); + } + + private static String getTokenText(Lexer lexer) { + return lexer.getBufferSequence().subSequence(lexer.getTokenStart(), lexer.getTokenEnd()).toString(); + } + + private static void doTest(String fileName) throws IOException { + final String fullPath = GetTextUtils.getFullPath(fileName); + final Lexer lexer = new GetTextLexer(); + final String testText = getFileText(fullPath + ".po"); + final String expected = fullPath + ".txt"; + doFileLexerTest(lexer, testText, expected); + } + + public static String getFileText(final String filePath) { + try { + return FileUtil.loadFile(new File(filePath)); + } + catch (IOException e) { + System.out.println(filePath); + throw new RuntimeException(e); + } + } + + public void testLexer() throws Throwable { + doTest("string"); + } + + public void testAllFiles() throws Throwable { + for (final String file : GetTextUtils.getAllTestedFiles()) { + doTest(file); + } + } +} + + diff --git a/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java b/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java new file mode 100644 index 000000000000..6e574abfe2d7 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/GetTextParserTest.java @@ -0,0 +1,47 @@ +package com.jetbrains.gettext; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.DebugUtil; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NonNls; + +import java.io.File; +import java.io.IOException; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextParserTest extends LightCodeInsightFixtureTestCase { + + private void doTest(String fileName) throws IOException { + final String filePath = GetTextUtils.getFullPath(fileName) + ".po"; + + try { + final String fileText = FileUtil.loadFile(new File(filePath)); + doTest(StringUtil.convertLineSeparators(fileText), fileName); + } + catch (IOException e) { + fail("Can't load file: " + filePath); + } + } + + private void doTest(@NonNls final String code, final String fileName) { + final PsiFile psiFile = createLightFile(fileName, GetTextLanguage.INSTANCE, code); + final String tree = DebugUtil.psiTreeToString(psiFile, false); + final String path = GetTextUtils.getFullParserResultPath(fileName); + assertSameLinesWithFile(path, tree); + } + + public void testSimple() throws IOException { + doTest("string"); + } + + public void testAllFiles() throws Throwable { + for(final String file : GetTextUtils.getAllTestedFiles()) { + System.out.println("Start: " + file); + doTest(file); + } + } +} diff --git a/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java b/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java new file mode 100644 index 000000000000..d0099f4d0837 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/GetTextUtils.java @@ -0,0 +1,32 @@ +package com.jetbrains.gettext; + +import com.intellij.openapi.application.PathManager; + +/** + * @author Svetlana.Zemlyanskaya + */ +public class GetTextUtils { + + public static String[] getAllTestedFiles() { + return new String[]{ + "simple", + "without_comments", + "flags", + "complex_flags", + "msg_plural", + "range_flag", + "string"}; + } + + protected static String getDataSubpath() { + return "community/plugins/gettext/test/com/jetbrains/gettext/lexer"; + } + + public static String getFullPath(final String fileName) { + return PathManager.getHomePath() + "/" + getDataSubpath() + "/" + fileName; + } + + public static String getFullParserResultPath(final String fileName) { + return getFullPath(fileName) + "_parser.txt"; + } +} \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.po new file mode 100644 index 000000000000..cc96fa6374dd --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.po @@ -0,0 +1,6 @@ +# test +#. another +#: ref +#, fuzzy, c-format, no-objc-format +msgid "new string to translate" +msgstr "translated string" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt new file mode 100644 index 000000000000..6cb191ceaf80 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags.txt @@ -0,0 +1,35 @@ +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (' ') +COMMENT ('test') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('.') +EXTR_COMMENT (' another') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (':') +REFERENCE (' ref') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (',') +WHITE_SPACE (' ') +FUZZY_FLAG ('fuzzy') +DELIVERY (',') +WHITE_SPACE (' ') +FORMAT_FLAG ('c-format') +DELIVERY (',') +WHITE_SPACE (' ') +NO_FORMAT_FLAG ('no-objc-format') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"new string to translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt new file mode 100644 index 000000000000..84ee7f7463e1 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/complex_flags_parser.txt @@ -0,0 +1,36 @@ +GNU GetText File + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(' ') + PsiComment(COMMENT)('test') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('.') + MSG_BLOCK + HEADER + PsiElement(EXTR_COMMENT)(' another') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(':') + PsiElement(REFERENCE)(' ref') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(',') + PsiWhiteSpace(' ') + PsiElement(FUZZY_FLAG)('fuzzy') + PsiElement(DELIVERY)(',') + PsiWhiteSpace(' ') + PsiElement(FORMAT_FLAG)('c-format') + PsiElement(DELIVERY)(',') + PsiWhiteSpace(' ') + PsiElement(NO_FORMAT_FLAG)('no-objc-format') + PsiWhiteSpace('\n') + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"new string to translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.po new file mode 100644 index 000000000000..1c0785015626 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.po @@ -0,0 +1,6 @@ +# test +#. another +#: ref +#, fuzzy, +msgid "new string to translate" +msgstr "translated string" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt new file mode 100644 index 000000000000..33db8a1dae30 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags.txt @@ -0,0 +1,30 @@ +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (' ') +COMMENT ('test') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('.') +EXTR_COMMENT (' another') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (':') +REFERENCE (' ref') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (',') +WHITE_SPACE (' ') +FUZZY_FLAG ('fuzzy') +DELIVERY (',') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"new string to translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt new file mode 100644 index 000000000000..039070d56e50 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/flags_parser.txt @@ -0,0 +1,31 @@ +GNU GetText File + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(' ') + PsiComment(COMMENT)('test') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('.') + MSG_BLOCK + HEADER + PsiElement(EXTR_COMMENT)(' another') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(':') + PsiElement(REFERENCE)(' ref') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(',') + PsiWhiteSpace(' ') + PsiElement(FUZZY_FLAG)('fuzzy') + PsiElement(DELIVERY)(',') + PsiWhiteSpace('\n') + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"new string to translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.po new file mode 100644 index 000000000000..c198b49cfa84 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.po @@ -0,0 +1,8 @@ +# test +#. another +#: ref +#| msgid test +msgid_plural "" +msgid "new string to translate" +msgstr[0] "translated string" +msgstr[01] "translated string" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt new file mode 100644 index 000000000000..4cc17e19bbd6 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural.txt @@ -0,0 +1,44 @@ +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (' ') +COMMENT ('test') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('.') +EXTR_COMMENT (' another') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (':') +REFERENCE (' ref') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('|') +PREVIOUS_TRANSLATE_COMMENT (' msgid test') +WHITE_SPACE (' +') +MSGID_PLURAL ('msgid_plural') +WHITE_SPACE (' ') +STRING ('""') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"new string to translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +LBRACE ('[') +NUMBER ('0') +RBRACE (']') +WHITE_SPACE (' ') +STRING ('"translated string"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +LBRACE ('[') +NUMBER ('01') +RBRACE (']') +WHITE_SPACE (' ') +STRING ('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt new file mode 100644 index 000000000000..d9707ff13dc7 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/msg_plural_parser.txt @@ -0,0 +1,45 @@ +GNU GetText File + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(' ') + PsiComment(COMMENT)('test') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('.') + MSG_BLOCK + HEADER + PsiElement(EXTR_COMMENT)(' another') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(':') + PsiElement(REFERENCE)(' ref') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('|') + PsiElement(PREVIOUS_TRANSLATE_COMMENT)(' msgid test') + PsiWhiteSpace('\n') + MSG_CONTENT + MSGID_PLURAL + PsiElement(MSGID_PLURAL)('msgid_plural') + PsiWhiteSpace(' ') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"new string to translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiElement(LBRACE)('[') + PsiElement(NUMBER)('0') + PsiElement(RBRACE)(']') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiElement(LBRACE)('[') + PsiElement(NUMBER)('01') + PsiElement(RBRACE)(']') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/parser.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/parser.po new file mode 100644 index 000000000000..8fb1fac63830 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/parser.po @@ -0,0 +1,2 @@ +msgid "string" +msgstr "translated" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/parser_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/parser_parser.txt new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.po new file mode 100644 index 000000000000..80f9327d1fcd --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.po @@ -0,0 +1,6 @@ +# test +#. another +#: ref +#, fuzzy, range: 0..10 +msgid "new string to translate" +msgstr "translated string" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt new file mode 100644 index 000000000000..60d2ec2e176a --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag.txt @@ -0,0 +1,37 @@ +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (' ') +COMMENT ('test') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('.') +EXTR_COMMENT (' another') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (':') +REFERENCE (' ref') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (',') +WHITE_SPACE (' ') +FUZZY_FLAG ('fuzzy') +DELIVERY (',') +WHITE_SPACE (' ') +RANGE_FLAG ('range') +COLON (':') +WHITE_SPACE (' ') +NUMBER ('0') +DOTS ('..') +NUMBER ('10') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"new string to translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt new file mode 100644 index 000000000000..46048336c942 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/range_flag_parser.txt @@ -0,0 +1,46 @@ +GNU GetText File + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(' ') + PsiComment(COMMENT)('test') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('.') + MSG_BLOCK + HEADER + PsiElement(EXTR_COMMENT)(' another') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(':') + PsiElement(REFERENCE)(' ref') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(',') + PsiWhiteSpace(' ') + PsiElement(FUZZY_FLAG)('fuzzy') + PsiElement(DELIVERY)(',') + PsiWhiteSpace(' ') + PsiElement(RANGE_FLAG)('range') + MSG_CONTENT + PsiErrorElement:Unexpected token + + PsiElement(COLON)(':') + PsiErrorElement:Unexpected token + + PsiWhiteSpace(' ') + PsiElement(NUMBER)('0') + PsiErrorElement:Unexpected token + + PsiElement(DOTS)('..') + PsiErrorElement:Unexpected token + + PsiElement(NUMBER)('10') + PsiWhiteSpace('\n') + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"new string to translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.po new file mode 100644 index 000000000000..327fa0c9a109 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.po @@ -0,0 +1,13 @@ +# test +#. another +#: ref +#| msgid test +msgid "new string to translate" +msgstr "translated string" + +# t +#. another +#: ref +#| msgid test +msgid "new string to translate" +msgstr "translated string" diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt new file mode 100644 index 000000000000..ba45c1662815 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple.txt @@ -0,0 +1,62 @@ +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (' ') +COMMENT ('test') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('.') +EXTR_COMMENT (' another') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (':') +REFERENCE (' ref') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('|') +PREVIOUS_TRANSLATE_COMMENT (' msgid test') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"new string to translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"translated string"') +WHITE_SPACE (' +') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (' ') +COMMENT ('t') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('.') +EXTR_COMMENT (' another') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS (':') +REFERENCE (' ref') +WHITE_SPACE (' +') +COMMENT_SYMBOLS ('#') +COMMENT_SYMBOLS ('|') +PREVIOUS_TRANSLATE_COMMENT (' msgid test') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"new string to translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"translated string"') +WHITE_SPACE (' +') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt new file mode 100644 index 000000000000..5250fbc94eb3 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/simple_parser.txt @@ -0,0 +1,60 @@ +GNU GetText File + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(' ') + PsiComment(COMMENT)('test') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('.') + MSG_BLOCK + HEADER + PsiElement(EXTR_COMMENT)(' another') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(':') + PsiElement(REFERENCE)(' ref') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('|') + PsiElement(PREVIOUS_TRANSLATE_COMMENT)(' msgid test') + PsiWhiteSpace('\n') + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"new string to translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') + PsiWhiteSpace('\n') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(' ') + PsiComment(COMMENT)('t') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('.') + MSG_BLOCK + HEADER + PsiElement(EXTR_COMMENT)(' another') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)(':') + PsiElement(REFERENCE)(' ref') + PsiWhiteSpace('\n') + PsiComment(COMMENT_SYMBOLS)('#') + PsiComment(COMMENT_SYMBOLS)('|') + PsiElement(PREVIOUS_TRANSLATE_COMMENT)(' msgid test') + PsiWhiteSpace('\n') + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"new string to translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated string"') + PsiWhiteSpace('\n') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/string.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/string.po new file mode 100644 index 000000000000..3ef390f8e671 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/string.po @@ -0,0 +1,4 @@ +msgid " +"" +" +"\n" \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/string.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/string.txt new file mode 100644 index 000000000000..928ffa32eb1f --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/string.txt @@ -0,0 +1,10 @@ +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('" +') +STRING ('""') +WHITE_SPACE (' +') +STRING ('" +') +STRING ('"\n"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/string_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/string_parser.txt new file mode 100644 index 000000000000..7bab51b67de5 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/string_parser.txt @@ -0,0 +1,15 @@ +GNU GetText File + MSG_BLOCK + HEADER + + PsiErrorElement:Not enough commands + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiErrorElement:Unbounded string + PsiElement(STRING)('"\n') + PsiElement(STRING)('""') + PsiWhiteSpace('\n') + PsiErrorElement:Unbounded string + PsiElement(STRING)('"\n') + PsiElement(STRING)('"\n"') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.po b/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.po new file mode 100644 index 000000000000..57013dc8ca86 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.po @@ -0,0 +1,4 @@ +msgid "str-to-translate" +msgstr "translated str" +msgid "one more" +msgstr "one more translated str" diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.txt new file mode 100644 index 000000000000..1a7772639825 --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments.txt @@ -0,0 +1,20 @@ +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"str-to-translate"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"translated str"') +WHITE_SPACE (' +') +MSGID ('msgid') +WHITE_SPACE (' ') +STRING ('"one more"') +WHITE_SPACE (' +') +MSGSTR ('msgstr') +WHITE_SPACE (' ') +STRING ('"one more translated str"') +WHITE_SPACE (' +') \ No newline at end of file diff --git a/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments_parser.txt b/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments_parser.txt new file mode 100644 index 000000000000..36393b9f709c --- /dev/null +++ b/plugins/gettext/test/com/jetbrains/gettext/lexer/without_comments_parser.txt @@ -0,0 +1,29 @@ +GNU GetText File + MSG_BLOCK + HEADER + + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"str-to-translate"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"translated str"') + PsiWhiteSpace('\n') + MSG_BLOCK + HEADER + + MSG_CONTENT + MSGID + PsiElement(MSGID)('msgid') + PsiWhiteSpace(' ') + PsiElement(STRING)('"one more"') + PsiWhiteSpace('\n') + MSGSTR + PsiElement(MSGSTR)('msgstr') + PsiWhiteSpace(' ') + PsiElement(STRING)('"one more translated str"') + PsiWhiteSpace('\n') \ No newline at end of file