diff --git a/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java b/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java index 5f783eb89411..4b68ad95e1d1 100644 --- a/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java +++ b/xml/impl/src/com/intellij/ide/highlighter/XmlFileHighlighter.java @@ -15,7 +15,7 @@ */ package com.intellij.ide.highlighter; -import com.intellij.lexer.DtdHighlightingLexer; +import com.intellij.lexer.DtdLexer; import com.intellij.lexer.Lexer; import com.intellij.lexer.XHtmlHighlightingLexer; import com.intellij.lexer.XmlHighlightingLexer; @@ -137,7 +137,7 @@ public class XmlFileHighlighter extends SyntaxHighlighterBase { @NotNull public Lexer getHighlightingLexer() { if (myIsDtd) { - return new DtdHighlightingLexer(); + return new DtdLexer(true); } else if (myIsXHtml) { return new XHtmlHighlightingLexer(); } else { diff --git a/xml/impl/src/com/intellij/lang/dtd/DTDParserDefinition.java b/xml/impl/src/com/intellij/lang/dtd/DTDParserDefinition.java index a69fc5d60891..541aa16a72f7 100644 --- a/xml/impl/src/com/intellij/lang/dtd/DTDParserDefinition.java +++ b/xml/impl/src/com/intellij/lang/dtd/DTDParserDefinition.java @@ -17,24 +17,54 @@ package com.intellij.lang.dtd; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageUtil; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiParser; import com.intellij.lang.xml.XMLParserDefinition; -import com.intellij.lexer.OldXmlLexer; +import com.intellij.lexer.DtdLexer; +import com.intellij.lexer.Lexer; +import com.intellij.openapi.project.Project; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.parsing.xml.DtdParsing; import com.intellij.psi.impl.source.xml.XmlFileImpl; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlEntityDecl; +import org.jetbrains.annotations.NotNull; /** * @author max */ public class DTDParserDefinition extends XMLParserDefinition { public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) { - final OldXmlLexer xmlLexer = new OldXmlLexer(); - return LanguageUtil.canStickTokensTogetherByLexer(left, right, xmlLexer); + return LanguageUtil.canStickTokensTogetherByLexer(left, right, new DtdLexer(false)); } public PsiFile createFile(FileViewProvider viewProvider) { return new XmlFileImpl(viewProvider, XmlElementType.DTD_FILE); } + @NotNull + @Override + public PsiParser createParser(Project project) { + return new PsiParser() { + @NotNull + @Override + public ASTNode parse(IElementType root, PsiBuilder builder) { + return new DtdParsing(root, XmlEntityDecl.EntityContextType.GENERIC_XML, builder).parse(); + } + }; + } + + @Override + public IFileElementType getFileNodeType() { + return XmlElementType.DTD_FILE; + } + + @NotNull + @Override + public Lexer createLexer(Project project) { + return new DtdLexer(false); + } } diff --git a/xml/impl/src/com/intellij/lexer/DtdHighlightingLexer.java b/xml/impl/src/com/intellij/lexer/DtdHighlightingLexer.java deleted file mode 100644 index 9d20d761c5ba..000000000000 --- a/xml/impl/src/com/intellij/lexer/DtdHighlightingLexer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.lexer; - -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.xml.XmlTokenType; - -/** - * @author mike - */ -public class DtdHighlightingLexer extends DelegateLexer { - public DtdHighlightingLexer() { - super(new OldXmlLexer()); - } - - public IElementType getTokenType() { - IElementType tokenType = super.getTokenType(); - - if (tokenType == null) return tokenType; - - if (tokenType != XmlTokenType.XML_COMMENT_CHARACTERS && - tokenType != XmlTokenType.XML_COMMENT_END && - tokenType != XmlTokenType.XML_COMMENT_START && - tokenType != XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER) { - - // TODO: do not know when this happens! - switch (getState()) { - case __XmlLexer.DOCTYPE: - tokenType = XmlTokenType.XML_DECL_START; - break; - } - } - - return tokenType; - } -} diff --git a/xml/impl/src/com/intellij/lexer/OldXmlLexer.java b/xml/impl/src/com/intellij/lexer/DtdLexer.java similarity index 83% rename from xml/impl/src/com/intellij/lexer/OldXmlLexer.java rename to xml/impl/src/com/intellij/lexer/DtdLexer.java index ba2c2113d9ba..e7f14f0ef929 100644 --- a/xml/impl/src/com/intellij/lexer/OldXmlLexer.java +++ b/xml/impl/src/com/intellij/lexer/DtdLexer.java @@ -21,11 +21,11 @@ import com.intellij.psi.xml.XmlTokenType; /** * @author ik */ -public class OldXmlLexer extends MergingLexerAdapter { +public class DtdLexer extends MergingLexerAdapter { private final static TokenSet TOKENS_TO_MERGE = TokenSet.create(XmlTokenType.XML_DATA_CHARACTERS, XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN, XmlTokenType.XML_PI_TARGET); - public OldXmlLexer() { - super(new FlexAdapter(new _OldXmlLexer()), TOKENS_TO_MERGE); + public DtdLexer(boolean highlightingMode) { + super(new FlexAdapter(new _DtdLexer(highlightingMode)), TOKENS_TO_MERGE); } } diff --git a/xml/impl/src/com/intellij/lexer/_OldXmlLexer.flex b/xml/impl/src/com/intellij/lexer/_DtdLexer.flex similarity index 96% rename from xml/impl/src/com/intellij/lexer/_OldXmlLexer.flex rename to xml/impl/src/com/intellij/lexer/_DtdLexer.flex index 965b0d654cab..0869996e5e6e 100644 --- a/xml/impl/src/com/intellij/lexer/_OldXmlLexer.flex +++ b/xml/impl/src/com/intellij/lexer/_DtdLexer.flex @@ -8,13 +8,16 @@ import com.intellij.psi.xml.*; %% %{ - public _OldXmlLexer() { + private boolean isHighlightModeOn = false; + + public _DtdLexer(boolean highlightModeOn) { this((java.io.Reader)null); + isHighlightModeOn = highlightModeOn; } %} %unicode -%class _OldXmlLexer +%class _DtdLexer %public %implements FlexLexer %function advance @@ -136,7 +139,7 @@ NMTOKEN=({ALPHA}|{DIGIT}|"_"|":"|"."|"-")+ " {TAG_NAME} { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_TAG_NAME; } + {TAG_NAME} { yybegin(TAG_ATTRIBUTES); return isHighlightModeOn ? XmlTokenType.XML_TAG_NAME:XmlTokenType.XML_NAME; } ">" { yybegin(YYINITIAL); return XmlTokenType.XML_TAG_END; } "/>" { yybegin(YYINITIAL); return XmlTokenType.XML_EMPTY_ELEMENT_END; } diff --git a/xml/impl/src/com/intellij/lexer/_OldXmlLexer.java b/xml/impl/src/com/intellij/lexer/_DtdLexer.java similarity index 85% rename from xml/impl/src/com/intellij/lexer/_OldXmlLexer.java rename to xml/impl/src/com/intellij/lexer/_DtdLexer.java index 673aac6edc4e..a9308edbafdb 100644 --- a/xml/impl/src/com/intellij/lexer/_OldXmlLexer.java +++ b/xml/impl/src/com/intellij/lexer/_DtdLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.1 on 10.12.09 20:28 */ +/* The following code was generated by JFlex 1.4.3 on 7/31/12 2:32 PM */ /* It's an automatically generated code. Do not modify it. */ package com.intellij.lexer; @@ -10,36 +10,48 @@ import com.intellij.psi.xml.*; /** * This class is a scanner generated by - * JFlex 1.4.1 - * on 10.12.09 20:28 from the specification file - * C:/IDEA/tools/lexer/../../community/xml/impl/src/com/intellij/lexer/_OldXmlLexer.flex + * JFlex 1.4.3 + * on 7/31/12 2:32 PM from the specification file + * C:/Idea.Sources/Trunk/tools/lexer/../../community/xml/impl/src/com/intellij/lexer/_DtdLexer.flex */ -public class _OldXmlLexer implements FlexLexer { +public class _DtdLexer implements FlexLexer { /** initial size of the lookahead buffer */ private static final int ZZ_BUFFERSIZE = 16384; /** lexical states */ - public static final int PROCESSING_INSTRUCTION = 11; - public static final int DECL_ATTR_VALUE_DQ = 3; - public static final int DECL_ATTR = 2; - public static final int ATTRIBUTE_VALUE_START = 8; - public static final int DECL_ATTR_VALUE_SQ = 4; - public static final int ATTRIBUTE_VALUE_DQ = 9; - public static final int CONDITIONAL = 19; - public static final int DECL = 1; - public static final int DOCTYPE_MARKUP_STARTED = 12; - public static final int ATTRIBUTE_VALUE_SQ = 10; - public static final int DOCTYPE_EXTERNAL_ID = 14; - public static final int CDATA = 18; - public static final int COMMENT = 7; - public static final int TAG_NAME = 5; - public static final int DOCTYPE_MARKUP = 15; - public static final int DOCTYPE_COMMENT = 20; - public static final int DOCTYPE_MARKUP_DQ = 16; + public static final int PROCESSING_INSTRUCTION = 22; + public static final int DECL_ATTR_VALUE_DQ = 6; + public static final int DECL_ATTR = 4; + public static final int ATTRIBUTE_VALUE_START = 16; + public static final int DECL_ATTR_VALUE_SQ = 8; + public static final int ATTRIBUTE_VALUE_DQ = 18; + public static final int CONDITIONAL = 38; + public static final int DECL = 2; + public static final int DOCTYPE_MARKUP_STARTED = 24; + public static final int ATTRIBUTE_VALUE_SQ = 20; + public static final int DOCTYPE_EXTERNAL_ID = 28; + public static final int CDATA = 36; + public static final int COMMENT = 14; + public static final int TAG_NAME = 10; + public static final int DOCTYPE_MARKUP = 30; + public static final int DOCTYPE_COMMENT = 40; + public static final int DOCTYPE_MARKUP_DQ = 32; public static final int YYINITIAL = 0; - public static final int TAG_ATTRIBUTES = 6; - public static final int DOCTYPE_MARKUP_SQ = 17; - public static final int DOCTYPE = 13; + public static final int TAG_ATTRIBUTES = 12; + public static final int DOCTYPE_MARKUP_SQ = 34; + public static final int DOCTYPE = 26; + + /** + * 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, + 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, + 16, 16, 17, 17, 18, 18, 19, 19, 20, 20 + }; /** * Translates characters to character classes @@ -52,61 +64,78 @@ public class _OldXmlLexer implements FlexLexer { "\1\47\1\20\1\25\1\45\1\57\1\26\1\46\1\14\1\22\2\1"+ "\1\61\1\44\1\1\1\10\1\0\1\15\1\0\1\1\1\0\6\34"+ "\5\1\1\37\1\36\12\1\1\33\2\1\1\0\1\55\55\0\1\1"+ - "\12\0\1\1\4\0\1\1\5\0\27\1\1\0\37\1\1\0\u013f\1"+ - "\31\0\162\1\4\0\14\1\16\0\5\1\11\0\1\1\213\0\1\1"+ - "\13\0\1\1\1\0\3\1\1\0\1\1\1\0\24\1\1\0\54\1"+ - "\1\0\46\1\1\0\5\1\4\0\202\1\10\0\105\1\1\0\46\1"+ - "\2\0\2\1\6\0\20\1\41\0\46\1\2\0\1\1\7\0\47\1"+ - "\110\0\33\1\5\0\3\1\56\0\32\1\5\0\13\1\43\0\2\1"+ - "\1\0\143\1\1\0\1\1\17\0\2\1\7\0\2\1\12\0\3\1"+ - "\2\0\1\1\20\0\1\1\1\0\36\1\35\0\3\1\60\0\46\1"+ - "\13\0\1\1\u0152\0\66\1\3\0\1\1\22\0\1\1\7\0\12\1"+ - "\43\0\10\1\2\0\2\1\2\0\26\1\1\0\7\1\1\0\1\1"+ - "\3\0\4\1\3\0\1\1\36\0\2\1\1\0\3\1\16\0\2\1"+ - "\23\0\6\1\4\0\2\1\2\0\26\1\1\0\7\1\1\0\2\1"+ - "\1\0\2\1\1\0\2\1\37\0\4\1\1\0\1\1\23\0\3\1"+ - "\20\0\11\1\1\0\3\1\1\0\26\1\1\0\7\1\1\0\2\1"+ - "\1\0\5\1\3\0\1\1\22\0\1\1\17\0\2\1\43\0\10\1"+ - "\2\0\2\1\2\0\26\1\1\0\7\1\1\0\2\1\1\0\5\1"+ - "\3\0\1\1\36\0\2\1\1\0\3\1\17\0\1\1\21\0\1\1"+ - "\1\0\6\1\3\0\3\1\1\0\4\1\3\0\2\1\1\0\1\1"+ - "\1\0\2\1\3\0\2\1\3\0\3\1\3\0\10\1\1\0\3\1"+ - "\113\0\10\1\1\0\3\1\1\0\27\1\1\0\12\1\1\0\5\1"+ - "\46\0\2\1\43\0\10\1\1\0\3\1\1\0\27\1\1\0\12\1"+ - "\1\0\5\1\3\0\1\1\40\0\1\1\1\0\2\1\43\0\10\1"+ - "\1\0\3\1\1\0\27\1\1\0\20\1\46\0\2\1\43\0\22\1"+ - "\3\0\30\1\1\0\11\1\1\0\1\1\2\0\7\1\72\0\60\1"+ - "\1\0\2\1\14\0\7\1\72\0\2\1\1\0\1\1\2\0\2\1"+ - "\1\0\1\1\2\0\1\1\6\0\4\1\1\0\7\1\1\0\3\1"+ - "\1\0\1\1\1\0\1\1\2\0\2\1\1\0\4\1\1\0\2\1"+ - "\11\0\1\1\2\0\5\1\1\0\1\1\25\0\2\1\42\0\1\1"+ - "\77\0\10\1\1\0\42\1\35\0\4\1\164\0\42\1\1\0\5\1"+ - "\1\0\2\1\45\0\6\1\112\0\46\1\12\0\51\1\7\0\132\1"+ - "\5\0\104\1\5\0\122\1\6\0\7\1\1\0\77\1\1\0\1\1"+ - "\1\0\4\1\2\0\7\1\1\0\1\1\1\0\4\1\2\0\47\1"+ - "\1\0\1\1\1\0\4\1\2\0\37\1\1\0\1\1\1\0\4\1"+ - "\2\0\7\1\1\0\1\1\1\0\4\1\2\0\7\1\1\0\7\1"+ - "\1\0\27\1\1\0\37\1\1\0\1\1\1\0\4\1\2\0\7\1"+ - "\1\0\47\1\1\0\23\1\105\0\125\1\14\0\u026c\1\2\0\10\1"+ - "\12\0\32\1\5\0\113\1\25\0\15\1\1\0\4\1\16\0\22\1"+ - "\16\0\22\1\16\0\15\1\1\0\3\1\17\0\64\1\43\0\1\1"+ - "\4\0\1\1\103\0\130\1\10\0\51\1\127\0\35\1\63\0\36\1"+ - "\2\0\5\1\u038b\0\154\1\224\0\234\1\4\0\132\1\6\0\26\1"+ - "\2\0\6\1\2\0\46\1\2\0\6\1\2\0\10\1\1\0\1\1"+ - "\1\0\1\1\1\0\1\1\1\0\37\1\2\0\65\1\1\0\7\1"+ - "\1\0\1\1\3\0\3\1\1\0\7\1\3\0\4\1\2\0\6\1"+ - "\4\0\15\1\5\0\3\1\1\0\7\1\164\0\1\1\15\0\1\1"+ - "\202\0\1\1\4\0\1\1\2\0\12\1\1\0\1\1\3\0\5\1"+ - "\6\0\1\1\1\0\1\1\1\0\1\1\1\0\4\1\1\0\3\1"+ - "\1\0\7\1\3\0\3\1\5\0\5\1\u0ebb\0\2\1\52\0\5\1"+ + "\12\0\1\1\4\0\1\1\5\0\27\1\1\0\37\1\1\0\u01ca\1"+ + "\4\0\14\1\16\0\5\1\7\0\1\1\1\0\1\1\201\0\5\1"+ + "\1\0\2\1\2\0\4\1\10\0\1\1\1\0\3\1\1\0\1\1"+ + "\1\0\24\1\1\0\123\1\1\0\213\1\10\0\236\1\11\0\46\1"+ + "\2\0\1\1\7\0\47\1\110\0\33\1\5\0\3\1\55\0\53\1"+ + "\43\0\2\1\1\0\143\1\1\0\1\1\17\0\2\1\7\0\2\1"+ + "\12\0\3\1\2\0\1\1\20\0\1\1\1\0\36\1\35\0\131\1"+ + "\13\0\1\1\30\0\41\1\11\0\2\1\4\0\1\1\5\0\26\1"+ + "\4\0\1\1\11\0\1\1\3\0\1\1\27\0\31\1\253\0\66\1"+ + "\3\0\1\1\22\0\1\1\7\0\12\1\17\0\7\1\1\0\7\1"+ + "\5\0\10\1\2\0\2\1\2\0\26\1\1\0\7\1\1\0\1\1"+ + "\3\0\4\1\3\0\1\1\20\0\1\1\15\0\2\1\1\0\3\1"+ + "\16\0\2\1\23\0\6\1\4\0\2\1\2\0\26\1\1\0\7\1"+ + "\1\0\2\1\1\0\2\1\1\0\2\1\37\0\4\1\1\0\1\1"+ + "\23\0\3\1\20\0\11\1\1\0\3\1\1\0\26\1\1\0\7\1"+ + "\1\0\2\1\1\0\5\1\3\0\1\1\22\0\1\1\17\0\2\1"+ + "\43\0\10\1\2\0\2\1\2\0\26\1\1\0\7\1\1\0\2\1"+ + "\1\0\5\1\3\0\1\1\36\0\2\1\1\0\3\1\17\0\1\1"+ + "\21\0\1\1\1\0\6\1\3\0\3\1\1\0\4\1\3\0\2\1"+ + "\1\0\1\1\1\0\2\1\3\0\2\1\3\0\3\1\3\0\14\1"+ + "\26\0\1\1\64\0\10\1\1\0\3\1\1\0\27\1\1\0\12\1"+ + "\1\0\5\1\3\0\1\1\32\0\2\1\6\0\2\1\43\0\10\1"+ + "\1\0\3\1\1\0\27\1\1\0\12\1\1\0\5\1\3\0\1\1"+ + "\40\0\1\1\1\0\2\1\17\0\2\1\22\0\10\1\1\0\3\1"+ + "\1\0\51\1\2\0\1\1\20\0\1\1\21\0\2\1\30\0\6\1"+ + "\5\0\22\1\3\0\30\1\1\0\11\1\1\0\1\1\2\0\7\1"+ + "\72\0\60\1\1\0\2\1\14\0\7\1\72\0\2\1\1\0\1\1"+ + "\2\0\2\1\1\0\1\1\2\0\1\1\6\0\4\1\1\0\7\1"+ + "\1\0\3\1\1\0\1\1\1\0\1\1\2\0\2\1\1\0\4\1"+ + "\1\0\2\1\11\0\1\1\2\0\5\1\1\0\1\1\25\0\2\1"+ + "\42\0\1\1\77\0\10\1\1\0\44\1\33\0\5\1\163\0\53\1"+ + "\24\0\1\1\20\0\6\1\4\0\4\1\3\0\1\1\3\0\2\1"+ + "\7\0\3\1\4\0\15\1\14\0\1\1\21\0\46\1\12\0\53\1"+ + "\1\0\1\1\3\0\u0149\1\1\0\4\1\2\0\7\1\1\0\1\1"+ + "\1\0\4\1\2\0\51\1\1\0\4\1\2\0\41\1\1\0\4\1"+ + "\2\0\7\1\1\0\1\1\1\0\4\1\2\0\17\1\1\0\71\1"+ + "\1\0\4\1\2\0\103\1\45\0\20\1\20\0\125\1\14\0\u026c\1"+ + "\2\0\21\1\1\0\32\1\5\0\113\1\25\0\15\1\1\0\4\1"+ + "\16\0\22\1\16\0\22\1\16\0\15\1\1\0\3\1\17\0\64\1"+ + "\43\0\1\1\4\0\1\1\103\0\130\1\10\0\51\1\1\0\1\1"+ + "\5\0\106\1\12\0\35\1\63\0\36\1\2\0\5\1\13\0\54\1"+ + "\25\0\7\1\70\0\27\1\11\0\65\1\122\0\1\1\135\0\57\1"+ + "\21\0\7\1\67\0\36\1\15\0\2\1\20\0\46\1\32\0\44\1"+ + "\51\0\3\1\12\0\44\1\153\0\4\1\1\0\4\1\16\0\300\1"+ + "\100\0\u0116\1\2\0\6\1\2\0\46\1\2\0\6\1\2\0\10\1"+ + "\1\0\1\1\1\0\1\1\1\0\1\1\1\0\37\1\2\0\65\1"+ + "\1\0\7\1\1\0\1\1\3\0\3\1\1\0\7\1\3\0\4\1"+ + "\2\0\6\1\4\0\15\1\5\0\3\1\1\0\7\1\164\0\1\1"+ + "\15\0\1\1\20\0\15\1\145\0\1\1\4\0\1\1\2\0\12\1"+ + "\1\0\1\1\3\0\5\1\6\0\1\1\1\0\1\1\1\0\1\1"+ + "\1\0\4\1\1\0\13\1\2\0\4\1\5\0\5\1\4\0\1\1"+ + "\64\0\2\1\u0a7b\0\57\1\1\0\57\1\1\0\205\1\6\0\4\1"+ + "\21\0\46\1\12\0\66\1\11\0\1\1\20\0\27\1\11\0\7\1"+ + "\1\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1\1\0\7\1"+ + "\1\0\7\1\1\0\7\1\120\0\1\1\u01d5\0\2\1\52\0\5\1"+ "\5\0\2\1\4\0\126\1\6\0\3\1\1\0\132\1\1\0\4\1"+ - "\5\0\50\1\4\0\136\1\21\0\30\1\70\0\20\1\u0200\0\u19b6\1"+ - "\112\0\u51a6\1\132\0\u048d\1\u0773\0\u2ba4\1\u215c\0\u012e\1\2\0\73\1"+ - "\225\0\7\1\14\0\5\1\5\0\1\1\1\0\12\1\1\0\15\1"+ - "\1\0\5\1\1\0\1\1\1\0\2\1\1\0\2\1\1\0\154\1"+ - "\41\0\u016b\1\22\0\100\1\2\0\66\1\50\0\14\1\164\0\5\1"+ - "\1\0\207\1\44\0\32\1\6\0\32\1\13\0\131\1\3\0\6\1"+ - "\2\0\6\1\2\0\6\1\2\0\3\1\43\0"; + "\5\0\51\1\3\0\136\1\21\0\33\1\65\0\20\1\u0200\0\u19b6\1"+ + "\112\0\u51cc\1\64\0\u048d\1\103\0\56\1\2\0\u010d\1\3\0\20\1"+ + "\12\0\2\1\24\0\57\1\20\0\31\1\10\0\106\1\61\0\11\1"+ + "\2\0\147\1\2\0\4\1\1\0\2\1\16\0\12\1\120\0\10\1"+ + "\1\0\3\1\1\0\4\1\1\0\27\1\35\0\64\1\16\0\62\1"+ + "\76\0\6\1\3\0\1\1\16\0\34\1\12\0\27\1\31\0\35\1"+ + "\7\0\57\1\34\0\1\1\60\0\51\1\27\0\3\1\1\0\10\1"+ + "\24\0\27\1\3\0\1\1\5\0\60\1\1\0\1\1\3\0\2\1"+ + "\2\0\5\1\2\0\1\1\1\0\1\1\30\0\3\1\43\0\6\1"+ + "\2\0\6\1\2\0\6\1\11\0\7\1\1\0\7\1\221\0\43\1"+ + "\35\0\u2ba4\1\14\0\27\1\4\0\61\1\u2104\0\u012e\1\2\0\76\1"+ + "\2\0\152\1\46\0\7\1\14\0\5\1\5\0\1\1\1\0\12\1"+ + "\1\0\15\1\1\0\5\1\1\0\1\1\1\0\2\1\1\0\2\1"+ + "\1\0\154\1\41\0\u016b\1\22\0\100\1\2\0\66\1\50\0\14\1"+ + "\164\0\5\1\1\0\207\1\44\0\32\1\6\0\32\1\13\0\131\1"+ + "\3\0\6\1\2\0\6\1\2\0\6\1\2\0\3\1\43\0"; /** * Translates characters to character classes @@ -559,12 +588,15 @@ public class _OldXmlLexer implements FlexLexer { private boolean zzEOFDone; /* user code: */ - public _OldXmlLexer() { + private boolean isHighlightModeOn = false; + + public _DtdLexer(boolean highlightModeOn) { this((java.io.Reader)null); + isHighlightModeOn = highlightModeOn; } - public _OldXmlLexer(java.io.Reader in) { + public _DtdLexer(java.io.Reader in) { this.zzReader = in; } @@ -574,7 +606,7 @@ public class _OldXmlLexer implements FlexLexer { * * @param in the java.io.Inputstream to read input from. */ - public _OldXmlLexer(java.io.InputStream in) { + public _DtdLexer(java.io.InputStream in) { this(new java.io.InputStreamReader(in)); } @@ -588,7 +620,7 @@ public class _OldXmlLexer implements FlexLexer { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 1234) { + while (i < 1578) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -762,7 +794,7 @@ public class _OldXmlLexer implements FlexLexer { zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; - zzState = zzLexicalState; + zzState = ZZ_LEXSTATE[zzLexicalState]; zzForAction: { @@ -911,7 +943,7 @@ public class _OldXmlLexer implements FlexLexer { } case 96: break; case 13: - { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_TAG_NAME; + { yybegin(TAG_ATTRIBUTES); return isHighlightModeOn ? XmlTokenType.XML_TAG_NAME:XmlTokenType.XML_NAME; } case 97: break; case 48: diff --git a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java b/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java new file mode 100644 index 000000000000..68b7b928b31d --- /dev/null +++ b/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/DtdParsing.java @@ -0,0 +1,869 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.impl.source.parsing.xml; + +import com.intellij.codeInsight.daemon.XmlErrorMessages; +import com.intellij.lang.ASTNode; +import com.intellij.lang.LanguageParserDefinitions; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilderFactory; +import com.intellij.lang.dtd.DTDLanguage; +import com.intellij.lexer.DtdLexer; +import com.intellij.lexer._DtdLexer; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.psi.PsiFile; +import com.intellij.psi.impl.source.DummyHolder; +import com.intellij.psi.impl.source.DummyHolderFactory; +import com.intellij.psi.impl.source.resolve.FileContextUtil; +import com.intellij.psi.impl.source.tree.FileElement; +import com.intellij.psi.impl.source.tree.TreeElement; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import com.intellij.psi.xml.XmlElementType; +import com.intellij.psi.xml.XmlEntityDecl; +import com.intellij.xml.XmlBundle; + +/** + * @author Mike + */ +public class DtdParsing extends XmlParsing implements XmlElementType { + private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.xml.XmlParser"); + + private final IElementType myRootType; + public static final XmlEntityDecl.EntityContextType TYPE_FOR_MARKUP_DECL = XmlEntityDecl.EntityContextType.ELEMENT_CONTENT_SPEC; + private final XmlEntityDecl.EntityContextType myContextType; + + public DtdParsing(IElementType root, XmlEntityDecl.EntityContextType contextType, PsiBuilder builder) { + super(builder); + myRootType = root; + myContextType = contextType; + myBuilder.enforceCommentTokens(TokenSet.EMPTY); + } + + public DtdParsing(CharSequence chars, + final IElementType type, + final XmlEntityDecl.EntityContextType contextType, + PsiFile contextFile + ) { + this( + type, + contextType, + PsiBuilderFactory.getInstance().createBuilder( + LanguageParserDefinitions.INSTANCE.forLanguage(DTDLanguage.INSTANCE), + new DtdLexer(false) { + final int myInitialState = getLexerInitialState(type, contextType); + @Override + public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) { + super.start(buffer, startOffset, endOffset, myInitialState); + } + }, chars + ) + ); + if (contextFile != null) myBuilder.putUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY, contextFile); + } + + public ASTNode parse() { + final PsiBuilder.Marker root = myBuilder.mark(); + + if (myRootType == XML_MARKUP_DECL) { + parseTopLevelMarkupDecl(); + root.done(myRootType); + return myBuilder.getTreeBuilt(); + } + + PsiBuilder.Marker document = null; + if (myRootType == DTD_FILE) { + document = myBuilder.mark(); + parseProlog(); + } + + switch (myContextType) { + case GENERIC_XML: + parseGenericXml(); + break; + case ELEMENT_CONTENT_SPEC: + parseElementContentSpec(); + break; + case ATTLIST_SPEC: + parseAttlistContent(); + break; + case ATTR_VALUE: + parseAttrValue(); + case ATTRIBUTE_SPEC: + parseAttributeContentSpec(); + break; + case ENTITY_DECL_CONTENT: + parseEntityDeclContent(); + break; + case ENUMERATED_TYPE: + parseEnumeratedTypeContent(); + break; + } + + while(!myBuilder.eof()) myBuilder.advanceLexer(); + if (document != null) document.done(XML_DOCUMENT); + root.done(myRootType); + ASTNode astNode = myBuilder.getTreeBuilt(); + + if (myRootType != DTD_FILE) { + PsiFile file = myBuilder.getUserDataUnprotected(FileContextUtil.CONTAINING_FILE_KEY); + if (file != null) { + final DummyHolder result = DummyHolderFactory.createHolder(file.getManager(), DTDLanguage.INSTANCE, file); + final FileElement holder = result.getTreeElement(); + holder.rawAddChildren((TreeElement)astNode); + } + } + + return astNode; + } + + private static int getLexerInitialState(IElementType rootNodeType, XmlEntityDecl.EntityContextType context) { + short state = 0; + + switch (context) { + case ELEMENT_CONTENT_SPEC: + case ATTRIBUTE_SPEC: + case ATTLIST_SPEC: + case ENUMERATED_TYPE: + case ENTITY_DECL_CONTENT: + { + state = _DtdLexer.DOCTYPE_MARKUP; + break; + } + + case ATTR_VALUE: + case GENERIC_XML: { + break; + } + + + default: LOG.error("context: " + context); + } + + if (rootNodeType == XML_MARKUP_DECL && context == TYPE_FOR_MARKUP_DECL) { + state = _DtdLexer.DOCTYPE; + } + return state; + } + + private void parseGenericXml() { + IElementType tokenType; + + while ((tokenType = myBuilder.getTokenType()) != null) { + if (tokenType == XML_ATTLIST_DECL_START) { + parseAttlistDecl(); + } + else if (tokenType == XML_ELEMENT_DECL_START) { + parseElementDecl(); + } + else if (tokenType == XML_ENTITY_DECL_START) { + parseEntityDecl(); + } + else if (tokenType == XML_NOTATION_DECL_START) { + parseNotationDecl(); + } + else if (tokenType == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } + else if (parseProcessingInstruction()) { + } + else if (tokenType == XML_START_TAG_START) { + parseTag(false); + } else if (isCommentToken(tokenType)) { + parseComment(); + } + else if (parseConditionalSection()) { + } + else if (tokenType != null) { + addToken(); + } + } + } + + private void parseNotationDecl() { + if (myBuilder.getTokenType() != XML_NOTATION_DECL_START) { + return; + } + + PsiBuilder.Marker decl = myBuilder.mark(); + addToken(); + + if (!parseName()) { + decl.done(XML_NOTATION_DECL); + return; + } + + parseEntityDeclContent(); + + if (myBuilder.getTokenType() != null) { + addToken(); + } + + decl.done(XML_NOTATION_DECL); + } + + private void parseEntityDecl() { + if (myBuilder.getTokenType() != XML_ENTITY_DECL_START) { + return; + } + + PsiBuilder.Marker decl = myBuilder.mark(); + addToken(); + + if (myBuilder.getTokenType() == XML_PERCENT) { + addToken(); + } + + if (parseCompositeName()) { + decl.done(XML_ENTITY_DECL); + return; + } + + parseEntityDeclContent(); + + if (myBuilder.getTokenType() != null) { + addToken(); + } + + decl.done(XML_ENTITY_DECL); + } + + private boolean parseCompositeName() { + if (!parseName()) { + if (myBuilder.getTokenType() == XML_LEFT_PAREN) { + parseGroup(); + } else { + myBuilder.error(XmlBundle.message("dtd.parser.message.name.expected")); + return true; + } + } + return false; + } + + private void parseEntityDeclContent() { + IElementType tokenType = myBuilder.getTokenType(); + if (tokenType != XML_ATTRIBUTE_VALUE_START_DELIMITER && + tokenType != XML_DOCTYPE_PUBLIC && + tokenType != XML_DOCTYPE_SYSTEM) { + myBuilder.error(XmlBundle.message("dtd.parser.message.literal.public.system.expected")); + return; + } + + while (tokenType != XML_TAG_END && tokenType != null) { + if (tokenType == XML_ATTRIBUTE_VALUE_START_DELIMITER) { + parseAttributeValue(); + } + else { + addToken(); + } + + tokenType = myBuilder.getTokenType(); + } + } + + private boolean parseConditionalSection() { + if (myBuilder.getTokenType() != XML_CONDITIONAL_SECTION_START) { + return false; + } + + PsiBuilder.Marker conditionalSection = myBuilder.mark(); + + addToken(); + IElementType tokenType = myBuilder.getTokenType(); + if (tokenType != XML_CONDITIONAL_IGNORE && + tokenType != XML_CONDITIONAL_INCLUDE && + tokenType != XML_ENTITY_REF_TOKEN) { + conditionalSection.done(XML_CONDITIONAL_SECTION); + return true; + } + + if (tokenType == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } else { + addToken(); + } + + if (myBuilder.getTokenType() != XML_MARKUP_START) { + conditionalSection.done(XML_CONDITIONAL_SECTION); + return true; + } + + parseMarkupContent(); + + if (myBuilder.getTokenType() != XML_CONDITIONAL_SECTION_END) { + conditionalSection.done(XML_CONDITIONAL_SECTION); + return true; + } + addToken(); + conditionalSection.done(XML_CONDITIONAL_SECTION); + return true; + } + + private boolean parseProcessingInstruction() { + if (myBuilder.getTokenType() != XML_PI_START) { + return false; + } + PsiBuilder.Marker tag = myBuilder.mark(); + + addToken(); + if (myBuilder.getTokenType() != XML_PI_TARGET) { + tag.done(XML_PROCESSING_INSTRUCTION); + return true; + } + addToken(); + if (myBuilder.getTokenType() != XML_PI_END) { + tag.done(XML_PROCESSING_INSTRUCTION); + return true; + } + addToken(); + tag.done(XML_PROCESSING_INSTRUCTION); + return true; + } + + private void parseEntityRef() { + PsiBuilder.Marker ref = myBuilder.mark(); + + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + addToken(); + } + + ref.done(XML_ENTITY_REF); + } + + private void parseProlog() { + PsiBuilder.Marker prolog = myBuilder.mark(); + + while (parseProcessingInstruction()) {} + + if (myBuilder.getTokenType() == XML_DECL_START) { + parseDecl(); + } + + while (parseProcessingInstruction()) {} + + if (myBuilder.getTokenType() == XML_DOCTYPE_START) { + parseDocType(); + } + + while (parseProcessingInstruction()) {} + + prolog.done(XML_PROLOG); + } + + private void parseDocType() { + if (myBuilder.getTokenType() != XML_DOCTYPE_START) { + return; + } + + PsiBuilder.Marker docType = myBuilder.mark(); + addToken(); + + if (myBuilder.getTokenType() != XML_NAME) { + docType.done(XML_DOCTYPE); + return; + } + + addToken(); + + if (myBuilder.getTokenType() == XML_DOCTYPE_SYSTEM) { + addToken(); + + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(); + } + } + else if (myBuilder.getTokenType() == XML_DOCTYPE_PUBLIC) { + addToken(); + + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(); + } + + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(); + } + } + + if (myBuilder.getTokenType() == XML_MARKUP_START) { + parseMarkupDecl(); + } + + if (myBuilder.getTokenType() != XML_DOCTYPE_END) { + docType.done(XML_DOCTYPE); + return; + } + + addToken(); + + docType.done(XML_DOCTYPE); + } + + private void parseMarkupDecl() { + PsiBuilder.Marker decl = myBuilder.mark(); + parseMarkupContent(); + + decl.done(XML_MARKUP_DECL); + } + + private void parseMarkupContent() { + IElementType tokenType = myBuilder.getTokenType(); + if (tokenType == XML_MARKUP_START) { + addToken(); + } + + while (true) { + tokenType = myBuilder.getTokenType(); + + if (tokenType == XML_ELEMENT_DECL_START) { + parseElementDecl(); + } + else if (tokenType == XML_ATTLIST_DECL_START) { + parseAttlistDecl(); + } + else if (tokenType == XML_ENTITY_DECL_START) { + parseEntityDecl(); + } + else if (tokenType == XML_NOTATION_DECL_START) { + parseNotationDecl(); + } else if (tokenType == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } else if (tokenType == XML_COMMENT_START) { + parseComment(); + } + else if (parseConditionalSection()) { + } + else { + break; + } + } + + if (tokenType == XML_MARKUP_END) { + addToken(); + } + } + + private void parseElementDecl() { + if (myBuilder.getTokenType() != XML_ELEMENT_DECL_START) { + return; + } + + PsiBuilder.Marker decl = myBuilder.mark(); + + addToken(); + + if (parseCompositeName()) { + decl.done(XML_ELEMENT_DECL); + return; + } + + doParseContentSpec(false); + + skipTillEndOfBlock(); + + decl.done(XML_ELEMENT_DECL); + } + + private void skipTillEndOfBlock() { + while (!myBuilder.eof() && + myBuilder.getTokenType() != XML_TAG_END && + !isAnotherDeclStart(myBuilder.getTokenType()) + ) { + if (myBuilder.getTokenType() == XML_COMMENT_START) parseComment(); + else addToken(); + } + + if(myBuilder.getTokenType() == XML_TAG_END) addToken(); + } + + private boolean isAnotherDeclStart(IElementType type) { + return type == XML_ATTLIST_DECL_START || type == XML_ELEMENT_DECL_START; + } + + private boolean parseName() { + if (myBuilder.getTokenType() == XML_NAME) { + addToken(); + + return true; + } + + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + return true; + } + + return false; + } + + private void parseElementContentSpec() { + doParseContentSpec(true); + } + + private void doParseContentSpec(boolean topLevel) { + if (!topLevel && myBuilder.rawLookup(0) != XML_WHITE_SPACE) { + myBuilder.error(XmlBundle.message("dtd.parser.message.whitespace.expected")); + } else if (!topLevel) { + final IElementType tokenType = myBuilder.getTokenType(); + String tokenText; + + if (tokenType != XML_LEFT_PAREN && + tokenType != XML_ENTITY_REF_TOKEN && + tokenType != XML_CONTENT_ANY && + tokenType != XML_CONTENT_EMPTY && + (tokenType != XML_NAME || ( !("-".equals(tokenText = myBuilder.getTokenText())) && !"O".equals(tokenText))) // sgml compatibility + ) { + PsiBuilder.Marker spec = myBuilder.mark(); + spec.done(XML_ELEMENT_CONTENT_SPEC); + myBuilder.error(XmlBundle.message("dtd.parser.message.left.paren.or.entityref.or.empty.or.any.expected")); + return; + } + } + + PsiBuilder.Marker spec = myBuilder.mark(); + + parseElementContentSpecInner(topLevel); + + spec.done(XML_ELEMENT_CONTENT_SPEC); + } + + private boolean parseElementContentSpecInner(boolean topLevel) { + IElementType tokenType = myBuilder.getTokenType(); + boolean endedWithDelimiter = false; + + while ( + tokenType != null && + tokenType != XML_TAG_END && + tokenType != XML_START_TAG_START && + tokenType != XML_ELEMENT_DECL_START && + tokenType != XML_RIGHT_PAREN && + tokenType != XML_COMMENT_START + ) { + if (tokenType == XML_BAR && topLevel) { + addToken(); + tokenType = myBuilder.getTokenType(); + continue; + } else + if (tokenType == XML_LEFT_PAREN) { + if (!parseGroup()) return false; + endedWithDelimiter = false; + } else + if (tokenType == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + endedWithDelimiter = false; + } else if (tokenType == XML_NAME || + tokenType == XML_CONTENT_EMPTY || + tokenType == XML_CONTENT_ANY || + tokenType == XML_PCDATA + ) { + addToken(); + endedWithDelimiter = false; + } + else { + myBuilder.error(XmlBundle.message("dtd.parser.message.name.or.entity.ref.expected")); + return false; + } + + tokenType = myBuilder.getTokenType(); + + if (tokenType == XML_STAR || + tokenType == XML_PLUS || + tokenType == XML_QUESTION + ) { + addToken(); + tokenType = myBuilder.getTokenType(); + + if (tokenType == XML_PLUS) { + addToken(); + tokenType = myBuilder.getTokenType(); + } + } + if (tokenType == XML_BAR || tokenType == XML_COMMA) { + addToken(); + tokenType = myBuilder.getTokenType(); + endedWithDelimiter = true; + } + } + + if (endedWithDelimiter && tokenType == XML_RIGHT_PAREN) { + myBuilder.error(XmlBundle.message("dtd.parser.message.name.or.entity.ref.expected")); + } + return true; + } + + private boolean parseGroup() { + PsiBuilder.Marker group = myBuilder.mark(); + addToken(); + boolean b = parseElementContentSpecInner(false); + if (b && myBuilder.getTokenType() == XML_RIGHT_PAREN) { + addToken(); + group.done(XML_ELEMENT_CONTENT_GROUP); + return true; + } else if (b) { + myBuilder.error(XmlBundle.message("dtd.parser.message.rbrace.expected")); + group.done(XML_ELEMENT_CONTENT_GROUP); + return false; + } + group.done(XML_ELEMENT_CONTENT_GROUP); + return b; + } + + private void parseAttlistDecl() { + if (myBuilder.getTokenType() != XML_ATTLIST_DECL_START) { + return; + } + + PsiBuilder.Marker decl = myBuilder.mark(); + addToken(); + + if (!parseName()) { + final IElementType tokenType = myBuilder.getTokenType(); + if (tokenType == XML_LEFT_PAREN) { + parseGroup(); + } else { + myBuilder.error(XmlBundle.message("dtd.parser.message.name.expected")); + decl.done(XML_ATTLIST_DECL); + return; + } + } + + parseAttlistContent(); + + skipTillEndOfBlock(); + + decl.done(XML_ATTLIST_DECL); + } + + private void parseAttlistContent() { + while (true) { + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } + else if (parseAttributeDecl()) { + } + else { + break; + } + } + } + + private boolean parseAttributeDecl() { + if (myBuilder.getTokenType() != XML_NAME) { + return false; + } + + PsiBuilder.Marker decl = myBuilder.mark(); + + addToken(); + + final boolean b = parseAttributeContentSpec(); + //if (myBuilder.getTokenType() == XML_COMMENT_START) parseComment(); + decl.done(XML_ATTRIBUTE_DECL); + return b; + } + + private boolean parseAttributeContentSpec() { + if (parseName()) { + } + else if (myBuilder.getTokenType() == XML_LEFT_PAREN) { + parseEnumeratedType(); + } + else { + return true; + } + + if (myBuilder.getTokenType() == XML_ATT_IMPLIED) { + addToken(); + } + else if (myBuilder.getTokenType() == XML_ATT_REQUIRED) { + addToken(); + } + else if (myBuilder.getTokenType() == XML_ATT_FIXED) { + addToken(); + + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { + parseAttributeValue(); + } + } + else if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { + parseAttributeValue(); + } + + return true; + } + + private void parseEnumeratedType() { + PsiBuilder.Marker enumeratedType = myBuilder.mark(); + addToken(); + + parseEnumeratedTypeContent(); + + if (myBuilder.getTokenType() == XML_RIGHT_PAREN) { + addToken(); + } + + enumeratedType.done(XML_ENUMERATED_TYPE); + } + + private void parseEnumeratedTypeContent() { + while (true) { + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + continue; + } + + if (myBuilder.getTokenType() != XML_NAME && myBuilder.getTokenType() != XML_BAR) break; + addToken(); + } + } + + private void parseDecl() { + if (myBuilder.getTokenType() != XML_DECL_START) { + return; + } + + PsiBuilder.Marker decl = myBuilder.mark(); + addToken(); + + parseAttributeList(); + + if (myBuilder.getTokenType() == XML_DECL_END) { + addToken(); + } + else { + myBuilder.error(XmlErrorMessages.message("expected.prologue.tag.termination.expected")); + } + + decl.done(XML_DECL); + } + + private void parseAttributeList() { + int lastPosition = -1; + while (true) { + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + continue; + } + + if (myBuilder.getTokenType() != XML_NAME) { + return; + } + + if (lastPosition != -1) { + if (lastPosition == myBuilder.getCurrentOffset()) { + myBuilder.error(XmlErrorMessages.message("expected.whitespace")); + lastPosition = -1; + } + } + + addToken(); + + if (myBuilder.getTokenType() != XML_EQ) { + myBuilder.error(XmlErrorMessages.message("expected.attribute.eq.sign")); + continue; + } + + addToken(); + + if (myBuilder.getTokenType() != XML_ATTRIBUTE_VALUE_START_DELIMITER) { + return; + } + + addToken(); + + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(); + + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_END_DELIMITER) { + lastPosition = myBuilder.getCurrentOffset(); + addToken(); + } + else { + lastPosition = -1; + } + } + else if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_END_DELIMITER) { + lastPosition = myBuilder.getCurrentOffset(); + addToken(); + } + else { + lastPosition = -1; + } + } + } + + private int parseAttributeValue() { + if (myBuilder.getTokenType() != XML_ATTRIBUTE_VALUE_START_DELIMITER) { + return -1; + } + + PsiBuilder.Marker value = myBuilder.mark(); + + addToken(); + + while (true) { + if (myBuilder.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { + addToken(); + } + else if (myBuilder.getTokenType() == XML_CHAR_ENTITY_REF) { + addToken(); + } + else if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } + else { + break; + } + } + + if (myBuilder.getTokenType() != XML_ATTRIBUTE_VALUE_END_DELIMITER) { + value.done(XML_ATTRIBUTE_VALUE); + return -1; + } + + int tokenEnd = myBuilder.getCurrentOffset(); + addToken(); + value.done(XML_ATTRIBUTE_VALUE); + return tokenEnd; + } + + private void addToken() { + myBuilder.advanceLexer(); + } + + private void parseTopLevelMarkupDecl() { + parseMarkupContent(); + while (myBuilder.getTokenType() != null) { + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } + else if (myBuilder.getTokenType() == XML_ENTITY_DECL_START) { + parseEntityDecl(); + } + else { + myBuilder.advanceLexer(); + } + } + } + + private void parseAttrValue() { + while(myBuilder.getTokenType() != null) { + if (myBuilder.getTokenType() == XML_ENTITY_REF_TOKEN) { + parseEntityRef(); + } else { + addToken(); + } + } + } +} diff --git a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/OldXmlParser.java b/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/OldXmlParser.java deleted file mode 100644 index 57a94c156c82..000000000000 --- a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/OldXmlParser.java +++ /dev/null @@ -1,1160 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.psi.impl.source.parsing.xml; - -import com.intellij.codeInsight.daemon.XmlErrorMessages; -import com.intellij.lang.ASTFactory; -import com.intellij.lang.ASTNode; -import com.intellij.lexer.FilterLexer; -import com.intellij.lexer.Lexer; -import com.intellij.lexer.LexerUtil; -import com.intellij.lexer._OldXmlLexer; -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiManager; -import com.intellij.psi.impl.source.DummyHolderFactory; -import com.intellij.psi.impl.source.tree.*; -import com.intellij.psi.templateLanguages.OuterLanguageElement; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; -import com.intellij.psi.xml.XmlElementType; -import com.intellij.psi.xml.XmlEntityDecl; -import com.intellij.psi.xml.XmlTag; -import com.intellij.util.CharTable; -import com.intellij.xml.XmlBundle; -import gnu.trove.THashSet; -import org.jetbrains.annotations.Nullable; - -import java.util.Set; - -/** - * @author Mike - */ -public class OldXmlParser implements XmlElementType { - private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.parsing.xml.XmlParser"); - - private static final TokenSet XML_WHITE_SPACE_OR_COMMENT_BIT_SET = - TokenSet.create(new IElementType[]{XML_WHITE_SPACE, XML_COMMENT_START, XML_COMMENT_CHARACTERS, - XML_COMMENT_END, XML_BAD_CHARACTER}); - - private static final TokenSet XML_COMMENT_BIT_SET = - TokenSet.create(new IElementType[]{XML_COMMENT_START, XML_COMMENT_CHARACTERS, XML_COMMENT_END}); - - private int myLastTokenEnd = -1; - private final IElementType myRootType; - private final CharTable myCharTable; - private final PsiManager myManager; - private final CharSequence myBuffer; - private final Set myNames; - private final XmlEntityDecl.EntityContextType myContextType; - private PsiElement myContext; - public static final XmlEntityDecl.EntityContextType TYPE_FOR_MARKUP_DECL = XmlEntityDecl.EntityContextType.ELEMENT_CONTENT_SPEC; - - public OldXmlParser(CharSequence chars, - IElementType type, - XmlEntityDecl.EntityContextType contextType, - CharTable charTable, - @Nullable PsiManager manager) { - this(chars, type, contextType, charTable, manager, null, null); - } - - public OldXmlParser(CharSequence chars, - IElementType type, - XmlEntityDecl.EntityContextType contextType, - CharTable charTable, - @Nullable PsiManager manager, - @Nullable Set names, - @Nullable PsiElement context) { - myCharTable = charTable; - myRootType = type; - myManager = manager; - myContextType = contextType; - myNames = names; - myBuffer = chars; - myContext = context; - } - - public ASTNode parse() { - final FileElement holderElement = myManager != null ? DummyHolderFactory.createHolder(myManager, myContext).getTreeElement():null; - - Lexer lexer = getLexer(myContextType, myBuffer); - int state = lexer.getState(); - final CompositeElement root = ASTFactory.composite(myRootType); - if (holderElement != null) holderElement.rawAddChildren(root); - - XmlEntityDecl.EntityContextType contextType = myContextType; - - if (myRootType == XML_DOCUMENT) { - root.rawAddChildren(parseProlog(lexer)); - } else if (myRootType == XML_MARKUP_DECL) { - parseMarkupDecl(lexer, root); - contextType = null; - } - - if (contextType != null) { - switch (contextType) { - case GENERIC_XML: - parseGenericXml(lexer, root, myNames != null ? myNames : new THashSet()); - break; - case ELEMENT_CONTENT_SPEC: - parseElementContentSpec(root, lexer); - break; - case ATTLIST_SPEC: - parseAttlistContent(root, lexer); - break; - case ATTR_VALUE: - parseAttrValue(root, lexer); - case ATTRIBUTE_SPEC: - parseAttributeContentSpec(root, lexer); - break; - case ENTITY_DECL_CONTENT: - parseEntityDeclContent(root, lexer); - break; - case ENUMERATED_TYPE: - parseEnumeratedTypeContent(root, lexer); - break; - } - } - - if ((myContext == null || contextType == XmlEntityDecl.EntityContextType.GENERIC_XML) && - contextType != XmlEntityDecl.EntityContextType.ELEMENT_CONTENT_SPEC) { // TODO: FIXME code for tests compatibility - insertMissingTokens(root, ((FilterLexer)lexer).getOriginal(), 0, myBuffer.length(), state, new WhiteSpaceAndCommentsProcessor()); - } - return root; - } - - private Lexer getLexer(XmlEntityDecl.EntityContextType context, CharSequence buffer) { - Lexer lexer = new XmlPsiLexer(); - FilterLexer filterLexer = new FilterLexer(lexer, new FilterLexer.SetFilter(OldXmlParser.XML_WHITE_SPACE_OR_COMMENT_BIT_SET)); - short state = 0; - - switch (context) { - case ELEMENT_CONTENT_SPEC: - case ATTRIBUTE_SPEC: - case ATTLIST_SPEC: - case ENUMERATED_TYPE: - case ENTITY_DECL_CONTENT: - { - state = _OldXmlLexer.DOCTYPE_MARKUP; - break; - } - - case ATTR_VALUE: - case GENERIC_XML: { - break; - } - - - default: LOG.error("context: " + context); - } - - if (myRootType == XML_MARKUP_DECL && context == TYPE_FOR_MARKUP_DECL) { - state = _OldXmlLexer.DOCTYPE; - } - - filterLexer.start(buffer, 0, buffer.length(), state); - return filterLexer; - } - - - private void parseGenericXml(Lexer lexer, CompositeElement root, Set names) { - IElementType tokenType; - - while ((tokenType = lexer.getTokenType()) != null) { - if (tokenType == XML_ATTLIST_DECL_START) { - root.rawAddChildren(parseAttlistDecl(lexer)); - } - else if (tokenType == XML_ELEMENT_DECL_START) { - root.rawAddChildren(parseElementDecl(lexer)); - } - else if (tokenType == XML_ENTITY_DECL_START) { - root.rawAddChildren(parseEntityDecl(lexer)); - } - else if (tokenType == XML_NOTATION_DECL_START) { - root.rawAddChildren(parseNotationDecl(lexer)); - } - else if (tokenType == XML_ENTITY_REF_TOKEN) { - root.rawAddChildren(parseEntityRef(lexer)); - } - else if (parseProcessingInstruction(root, lexer)) { - } - else if (_parseTag(root, lexer, names)) { - } - else if (parseConditionalSection(root, lexer)) { - } - else if (tokenType != null) { - addToken(root, lexer); - } - } - } - - private TreeElement parseNotationDecl(Lexer lexer) { - CompositeElement decl = ASTFactory.composite(XML_NOTATION_DECL); - - if (lexer.getTokenType() != XML_NOTATION_DECL_START) { - return decl; - } - - addToken(decl, lexer); - - if (!parseName(decl, lexer)) { - return decl; - } - - parseEntityDeclContent(decl, lexer); - - if (lexer.getTokenType() != null) { - addToken(decl, lexer); - } - - return decl; - } - - private TreeElement parseEntityDecl(Lexer lexer) { - CompositeElement decl = ASTFactory.composite(XML_ENTITY_DECL); - - if (lexer.getTokenType() != XML_ENTITY_DECL_START) { - return decl; - } - - addToken(decl, lexer); - - if (lexer.getTokenType() == XML_PERCENT) { - addToken(decl, lexer); - } - - if (parseCompositeName(lexer, decl)) return decl; - - parseEntityDeclContent(decl, lexer); - - if (lexer.getTokenType() != null) { - addToken(decl, lexer); - } - - return decl; - } - - private boolean parseCompositeName(final Lexer lexer, final CompositeElement decl) { - if (!parseName(decl, lexer)) { - if (lexer.getTokenType() == XML_LEFT_PAREN) { - parseGroup(decl, lexer); - } else { - decl.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.name.expected"))); - return true; - } - } - return false; - } - - private void parseEntityDeclContent(CompositeElement decl, Lexer lexer) { - IElementType tokenType = lexer.getTokenType(); - if (tokenType != XML_ATTRIBUTE_VALUE_START_DELIMITER && - tokenType != XML_DOCTYPE_PUBLIC && - tokenType != XML_DOCTYPE_SYSTEM) { - decl.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.literal.public.system.expected"))); - return; - } - - while (tokenType != XML_TAG_END && tokenType != null) { - if (tokenType == XML_ATTRIBUTE_VALUE_START_DELIMITER) { - parseAttributeValue(decl, lexer); - } - else { - addToken(decl, lexer); - } - - tokenType = lexer.getTokenType(); - } - } - - private boolean parseConditionalSection(CompositeElement parent, Lexer lexer) { - if (lexer.getTokenType() != XML_CONDITIONAL_SECTION_START) { - return false; - } - CompositeElement conditionalSection = ASTFactory.composite(XML_CONDITIONAL_SECTION); - parent.rawAddChildren(conditionalSection); - - addToken(conditionalSection, lexer); - IElementType tokenType = lexer.getTokenType(); - if (tokenType != XML_CONDITIONAL_IGNORE && - tokenType != XML_CONDITIONAL_INCLUDE && - tokenType != XML_ENTITY_REF_TOKEN) { - return true; - } - - if (tokenType == XML_ENTITY_REF_TOKEN) { - conditionalSection.rawAddChildren(parseEntityRef(lexer) ); - } else { - addToken(conditionalSection, lexer); - } - - if (lexer.getTokenType() != XML_MARKUP_START) { - return true; - } - - parseMarkupContent(lexer, conditionalSection); - - if (lexer.getTokenType() != XML_CONDITIONAL_SECTION_END) { - return true; - } - addToken(conditionalSection, lexer); - return true; - } - - private boolean parseProcessingInstruction(CompositeElement parent, Lexer lexer) { - if (lexer.getTokenType() != XML_PI_START) { - return false; - } - CompositeElement tag = ASTFactory.composite(XML_PROCESSING_INSTRUCTION); - parent.rawAddChildren(tag); - - addToken(tag, lexer); - if (lexer.getTokenType() != XML_PI_TARGET) { - return true; - } - addToken(tag, lexer); - if (lexer.getTokenType() != XML_PI_END) { - return true; - } - addToken(tag, lexer); - return true; - } - - private boolean _parseTag(CompositeElement parent, Lexer lexer, Set names) { - if (lexer.getTokenType() != XML_START_TAG_START) { - return false; - } - - CompositeElement tag = ASTFactory.composite(XML_TAG); - parent.rawAddChildren(tag); - - addToken(tag, lexer); - - if (lexer.getTokenType() != XML_TAG_NAME) { - return true; - } - - final String openedName = lexer.getTokenText(); - addToken(tag, lexer); - - parseAttributeList(tag, lexer); - - while (lexer.getTokenType() == XML_BAD_CHARACTER || lexer.getTokenType() == XML_NAME) { - addToken(tag, lexer); - parseAttributeList(tag, lexer); - } - TreeElement tagEnd; - if (lexer.getTokenType() == XML_TAG_END) { - tagEnd = addToken(tag, lexer); - boolean setFlag = false; - if (!names.contains(openedName)) { - names.add(openedName); - setFlag = true; - } - - CompositeElement text = null; - while (true) { - if (parseProcessingInstruction(tag, lexer)) { - } - else if (_parseTag(tag, lexer, names)) { - } - else if (lexer.getTokenType() == XML_DATA_CHARACTERS) { - if (text == null) { - text = ASTFactory.composite(XML_TEXT); - tag.rawAddChildren(text); - } - addToken(text, lexer); - } - else if (lexer.getTokenType() == XML_CDATA_START) { - addToken(tag, lexer); - } - else if (lexer.getTokenType() == XML_CDATA_END) { - addToken(tag, lexer); - } - else if (lexer.getTokenType() == XML_CHAR_ENTITY_REF) { - addToken(tag, lexer); - } - else if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - tag.rawAddChildren(parseEntityRef(lexer)); - } - else { - break; - } - } - if (setFlag) { - names.remove(openedName); - } - - final int pos = lexer.getTokenStart(); - - if (lexer.getTokenType() != XML_END_TAG_START) { - tagEnd.rawInsertAfterMe(Factory.createErrorElement(XmlErrorMessages.message("element.is.not.closed"))); - - return false; - } - TreeElement endTagStart = createTokenElement(lexer, myCharTable); - lexer.advance(); - - if (lexer.getTokenType() != XML_TAG_NAME) { - tag.rawAddChildren(endTagStart); - return true; - } - - final String closingName = lexer.getBufferSequence().subSequence(lexer.getTokenStart(), - lexer.getTokenEnd()).toString(); - - if (!closingName.equals(openedName) && names.contains(closingName)) { - lexer.start(lexer.getBufferSequence(), pos, lexer.getBufferEnd()); - if (tagEnd != null) { - final TreeElement start = tagEnd.getTreeNext(); - if (start != null) { - start.rawRemoveUpToLast(); - parent.rawAddChildren(start); - } - } - tagEnd.rawInsertAfterMe(Factory.createErrorElement(XmlErrorMessages.message("element.is.not.closed"))); - return true; - } - - tag.rawAddChildren(endTagStart); - addToken(tag, lexer); - - if (lexer.getTokenType() != XML_TAG_END) { - return true; - } - - addToken(tag, lexer); - } - else if (lexer.getTokenType() == XML_EMPTY_ELEMENT_END) { - addToken(tag, lexer); - } - else { - tag.getLastChildNode().rawInsertAfterMe(Factory.createErrorElement(XmlErrorMessages.message("element.is.not.closed"))); - } - - return true; - } - - private static TreeElement createTokenElement(Lexer lexer, CharTable table) { - IElementType tokenType = lexer.getTokenType(); - if (tokenType == null) return null; - return ASTFactory.leaf(tokenType, LexerUtil.internToken(lexer, table)); - } - - - private TreeElement parseEntityRef(Lexer lexer) { - CompositeElement ref = ASTFactory.composite(XML_ENTITY_REF); - - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - addToken(ref, lexer); - } - - return ref; - } - - private TreeElement parseProlog(Lexer lexer) { - CompositeElement prolog = ASTFactory.composite(XML_PROLOG); - - while (parseProcessingInstruction(prolog, lexer)) { - } - - if (lexer.getTokenType() == XML_DECL_START) { - prolog.rawAddChildren(parseDecl(lexer)); - } - - while (parseProcessingInstruction(prolog, lexer)) { - } - - if (lexer.getTokenType() == XML_DOCTYPE_START) { - prolog.rawAddChildren(parseDocType(lexer)); - } - - while (parseProcessingInstruction(prolog, lexer)) { - } - - return prolog; - } - - private TreeElement parseDocType(Lexer lexer) { - CompositeElement docType = ASTFactory.composite(XML_DOCTYPE); - - if (lexer.getTokenType() != XML_DOCTYPE_START) { - return docType; - } - - addToken(docType, lexer); - - if (lexer.getTokenType() != XML_NAME) { - return docType; - } - - addToken(docType, lexer); - - if (lexer.getTokenType() == XML_DOCTYPE_SYSTEM) { - addToken(docType, lexer); - - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { - addToken(docType, lexer); - } - } - else if (lexer.getTokenType() == XML_DOCTYPE_PUBLIC) { - addToken(docType, lexer); - - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { - addToken(docType, lexer); - } - - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { - addToken(docType, lexer); - } - } - - if (lexer.getTokenType() == XML_MARKUP_START) { - docType.rawAddChildren(parseMarkupDecl(lexer)); - } - - if (lexer.getTokenType() != XML_DOCTYPE_END) { - return docType; - } - - addToken(docType, lexer); - - return docType; - } - - private TreeElement parseMarkupDecl(Lexer lexer) { - CompositeElement decl = ASTFactory.composite(XML_MARKUP_DECL); - - parseMarkupContent(lexer, decl); - - return decl; - } - - private void parseMarkupContent(Lexer lexer, CompositeElement decl) { - IElementType tokenType = lexer.getTokenType(); - if (tokenType == XML_MARKUP_START) { - addToken(decl, lexer); - } - - while (true) { - tokenType = lexer.getTokenType(); - - if (tokenType == XML_ELEMENT_DECL_START) { - decl.rawAddChildren(parseElementDecl(lexer)); - } - else if (tokenType == XML_ATTLIST_DECL_START) { - decl.rawAddChildren(parseAttlistDecl(lexer)); - } - else if (tokenType == XML_ENTITY_DECL_START) { - decl.rawAddChildren(parseEntityDecl(lexer)); - } - else if (tokenType == XML_NOTATION_DECL_START) { - decl.rawAddChildren(parseNotationDecl(lexer)); - } else if (tokenType == XML_ENTITY_REF_TOKEN) { - decl.rawAddChildren(parseEntityRef(lexer)); - } - else if (parseConditionalSection(decl, lexer)) { - } - else { - break; - } - } - - if (tokenType == XML_MARKUP_END) { - addToken(decl, lexer); - } - } - - private TreeElement parseElementDecl(Lexer lexer) { - CompositeElement decl = ASTFactory.composite(XML_ELEMENT_DECL); - - if (lexer.getTokenType() != XML_ELEMENT_DECL_START) { - return decl; - } - - addToken(decl, lexer); - - if (parseCompositeName(lexer, decl)) return decl; - - doParseContentSpec(decl, lexer, false); - - if (lexer.getTokenType() == XML_TAG_END) { - addToken(decl, lexer); - } - - return decl; - } - - private boolean parseName(CompositeElement decl, Lexer lexer) { - if (lexer.getTokenType() == XML_NAME) { - addToken(decl, lexer); - - return true; - } - - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - decl.rawAddChildren(parseEntityRef(lexer)); - return true; - } - - return false; - } - - private ASTNode parseElementContentSpec(CompositeElement parent, Lexer lexer) { - return doParseContentSpec(parent, lexer, true); - } - - private ASTNode doParseContentSpec(final CompositeElement parent, final Lexer lexer, boolean topLevel) { - if (myLastTokenEnd == lexer.getTokenStart()) { - parent.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.whitespace.expected"))); - } else if (!topLevel) { - final IElementType tokenType = lexer.getTokenType(); - String tokenText; - - if (tokenType != XML_LEFT_PAREN && - tokenType != XML_ENTITY_REF_TOKEN && - tokenType != XML_CONTENT_ANY && - tokenType != XML_CONTENT_EMPTY && - (tokenType != XML_NAME || ( !(tokenText = TreeUtil.getTokenText(lexer)).equals("-") && !tokenText.equals("O"))) // sgml compatibility - ) { - parent.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.left.paren.or.entityref.or.empty.or.any.expected"))); - } - } - - CompositeElement spec = ASTFactory.composite(XML_ELEMENT_CONTENT_SPEC); - parent.rawAddChildren(spec); - - parseElementContentSpecInner(lexer, spec, topLevel); - - return spec; - } - - private boolean parseElementContentSpecInner(final Lexer lexer, final CompositeElement spec, boolean topLevel) { - IElementType tokenType = lexer.getTokenType(); - boolean endedWithDelimiter = false; - - while ( - tokenType != null && - tokenType != XML_TAG_END && - tokenType != XML_START_TAG_START && - tokenType != XML_ELEMENT_DECL_START && - tokenType != XML_RIGHT_PAREN - ) { - if (tokenType == XML_BAR && topLevel) { - addToken(spec, lexer); - tokenType = lexer.getTokenType(); - continue; - } else - if (tokenType == XML_LEFT_PAREN) { - if (!parseGroup(spec, lexer)) return false; - endedWithDelimiter = false; - } else - if (tokenType == XML_ENTITY_REF_TOKEN) { - spec.rawAddChildren(parseEntityRef(lexer)); - endedWithDelimiter = false; - } else if (tokenType == XML_NAME || - tokenType == XML_CONTENT_EMPTY || - tokenType == XML_CONTENT_ANY || - tokenType == XML_PCDATA - ) { - addToken(spec, lexer); - endedWithDelimiter = false; - } - else { - spec.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.name.or.entity.ref.expected"))); - return false; - } - - tokenType = lexer.getTokenType(); - - if (tokenType == XML_STAR || - tokenType == XML_PLUS || - tokenType == XML_QUESTION - ) { - addToken(spec, lexer); - tokenType = lexer.getTokenType(); - - if (tokenType == XML_PLUS) { - addToken(spec, lexer); - tokenType = lexer.getTokenType(); - } - } - if (tokenType == XML_BAR || tokenType == XML_COMMA) { - addToken(spec, lexer); - tokenType = lexer.getTokenType(); - endedWithDelimiter = true; - } - } - - if (endedWithDelimiter && tokenType == XML_RIGHT_PAREN) { - spec.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.name.or.entity.ref.expected"))); - } - return true; - } - - private boolean parseGroup(final CompositeElement spec, final Lexer lexer) { - CompositeElement group = ASTFactory.composite(XML_ELEMENT_CONTENT_GROUP); - spec.rawAddChildren(group); - addToken(group, lexer); - boolean b = parseElementContentSpecInner(lexer, group, false); - if (b && lexer.getTokenType() == XML_RIGHT_PAREN) { - addToken(group, lexer); - return true; - } else if (b) { - group.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.rbrace.expected"))); - return false; - } - return b; - } - - private TreeElement parseAttlistDecl(Lexer lexer) { - CompositeElement decl = ASTFactory.composite(XML_ATTLIST_DECL); - - if (lexer.getTokenType() != XML_ATTLIST_DECL_START) { - return decl; - } - - addToken(decl, lexer); - - if (!parseName(decl, lexer)) { - final IElementType tokenType = lexer.getTokenType(); - if (tokenType == XML_LEFT_PAREN) { - parseGroup(decl, lexer); - } else { - decl.rawAddChildren(Factory.createErrorElement(XmlBundle.message("dtd.parser.message.name.expected"))); - return decl; - } - } - - parseAttlistContent(decl, lexer); - - if (lexer.getTokenType() == XML_TAG_END) { - addToken(decl, lexer); - } - - return decl; - } - - private void parseAttlistContent(CompositeElement parent, Lexer lexer) { - while (true) { - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - parent.rawAddChildren(parseEntityRef(lexer)); - } - else if (parseAttributeDecl(parent, lexer)) { - } - else { - break; - } - } - } - - private boolean parseAttributeDecl(CompositeElement parent, Lexer lexer) { - if (lexer.getTokenType() != XML_NAME) { - return false; - } - - CompositeElement decl = ASTFactory.composite(XML_ATTRIBUTE_DECL); - parent.rawAddChildren(decl); - - addToken(decl, lexer); - - return parseAttributeContentSpec(decl, lexer); - } - - private boolean parseAttributeContentSpec(CompositeElement parent, Lexer lexer) { - if (parseName(parent, lexer)) { - } - else if (lexer.getTokenType() == XML_LEFT_PAREN) { - parent.rawAddChildren(parseEnumeratedType(lexer)); - } - else { - return true; - } - - if (lexer.getTokenType() == XML_ATT_IMPLIED) { - addToken(parent, lexer); - } - else if (lexer.getTokenType() == XML_ATT_REQUIRED) { - addToken(parent, lexer); - } - else if (lexer.getTokenType() == XML_ATT_FIXED) { - addToken(parent, lexer); - - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { - parseAttributeValue(parent, lexer); - } - } - else if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_START_DELIMITER) { - parseAttributeValue(parent, lexer); - } - - return true; - } - - private CompositeElement parseEnumeratedType(Lexer lexer) { - CompositeElement enumeratedType = ASTFactory.composite(XML_ENUMERATED_TYPE); - addToken(enumeratedType, lexer); - - parseEnumeratedTypeContent(enumeratedType, lexer); - - if (lexer.getTokenType() == XML_RIGHT_PAREN) { - addToken(enumeratedType, lexer); - } - - return enumeratedType; - } - - private void parseEnumeratedTypeContent(CompositeElement enumeratedType, Lexer lexer) { - while (true) { - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - enumeratedType.rawAddChildren(parseEntityRef(lexer)); - continue; - } - - if (lexer.getTokenType() != XML_NAME && lexer.getTokenType() != XML_BAR) break; - addToken(enumeratedType, lexer); - } - } - - private TreeElement parseDecl(Lexer lexer) { - CompositeElement decl = ASTFactory.composite(XML_DECL); - - if (lexer.getTokenType() != XML_DECL_START) { - return decl; - } - addToken(decl, lexer); - - parseAttributeList(decl, lexer); - - if (lexer.getTokenType() == XML_DECL_END) { - addToken(decl, lexer); - } - else { - decl.rawAddChildren(Factory.createErrorElement(XmlErrorMessages.message("expected.prologue.tag.termination.expected"))); - } - - return decl; - } - - private void parseAttributeList(CompositeElement tag, Lexer lexer) { - CompositeElement parent = tag; - int lastPosition = -1; - while (true) { - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - tag.rawAddChildren(parseEntityRef(lexer)); - continue; - } - - if (lexer.getTokenType() != XML_NAME) { - return; - } - - if (lastPosition != -1) { - if (lastPosition == lexer.getTokenStart()) { - tag.rawAddChildren(Factory.createErrorElement(XmlErrorMessages.message("expected.whitespace"))); - lastPosition = -1; - } - } - - if (tag instanceof XmlTag) { - CompositeElement attribute = ASTFactory.composite(XML_ATTRIBUTE); - tag.rawAddChildren(attribute); - parent = attribute; - } - - addToken(parent, lexer); - - if (lexer.getTokenType() != XML_EQ) { - parent.rawAddChildren(Factory.createErrorElement(XmlErrorMessages.message("expected.attribute.eq.sign"))); - continue; - } - - addToken(parent, lexer); - - if (tag instanceof XmlTag) { - CompositeElement attributeValue = ASTFactory.composite(XML_ATTRIBUTE_VALUE); - parent.rawAddChildren(attributeValue); - parent = attributeValue; - } - - if (lexer.getTokenType() != XML_ATTRIBUTE_VALUE_START_DELIMITER) { - return; - } - - addToken(parent, lexer); - - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { - addToken(parent, lexer); - - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_END_DELIMITER) { - lastPosition = lexer.getTokenEnd(); - addToken(parent, lexer); - } - else { - lastPosition = -1; - } - } - else if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_END_DELIMITER) { - lastPosition = lexer.getTokenEnd(); - addToken(parent, lexer); - } - else { - lastPosition = -1; - } - - if (tag instanceof XmlTag) { - parent = tag; - } - } - } - - private int parseAttributeValue(CompositeElement parent, Lexer lexer) { - if (lexer.getTokenType() != XML_ATTRIBUTE_VALUE_START_DELIMITER) { - return -1; - } - - CompositeElement value = ASTFactory.composite(XML_ATTRIBUTE_VALUE); - - parent.rawAddChildren(value); - - addToken(value, lexer); - - while (true) { - if (lexer.getTokenType() == XML_ATTRIBUTE_VALUE_TOKEN) { - addToken(value, lexer); - } - else if (lexer.getTokenType() == XML_CHAR_ENTITY_REF) { - addToken(value, lexer); - } - else if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - value.rawAddChildren(parseEntityRef(lexer)); - } - else { - break; - } - } - - if (lexer.getTokenType() != XML_ATTRIBUTE_VALUE_END_DELIMITER) { - return -1; - } - - int tokenEnd = lexer.getTokenEnd(); - addToken(value, lexer); - return tokenEnd; - } - - private TreeElement addToken(CompositeElement decl, Lexer lexer) { - final TreeElement element = createTokenElement(lexer, myCharTable); - if (element != null) { - decl.rawAddChildren(element); - myLastTokenEnd = lexer.getTokenEnd(); - lexer.advance(); - } - return element; - } - - private TreeElement parseMarkupDecl(Lexer lexer, CompositeElement root) { - parseMarkupContent(lexer, root); - while (lexer.getTokenType() != null) { - final TreeElement children; - - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - children = parseEntityRef(lexer); - } - else if (lexer.getTokenType() == XML_ENTITY_DECL_START) { - children = parseEntityDecl(lexer); - } - else { - children = createTokenElement(lexer, myCharTable); - lexer.advance(); - } - - root.rawAddChildren(children); - } - - return root; - } - - private void parseAttrValue(CompositeElement element, Lexer lexer) { - while(lexer.getTokenType() != null) { - if (lexer.getTokenType() == XML_ENTITY_REF_TOKEN) { - final TreeElement children = parseEntityRef(lexer); - element.rawAddChildren(children); - } else { - addToken(element, lexer); - } - } - } - - private class WhiteSpaceAndCommentsProcessor { - - private TreeElement process(Lexer lexer) { - TreeElement first = null; - TreeElement last = null; - while (isTokenValid(lexer.getTokenType())) { - TreeElement tokenElement; - - IElementType type = lexer.getTokenType(); - if (!XML_WHITE_SPACE_OR_COMMENT_BIT_SET.contains(type)) { - LOG.error("Missed token should be white space or comment:" + type); - throw new RuntimeException(); - } - - if (lexer.getTokenType() == XML_COMMENT_START) { - tokenElement = parseComment(lexer); - } - else { - tokenElement = createTokenElement(lexer, myCharTable); - lexer.advance(); - } - - if (last != null) { - last.rawInsertAfterMe(tokenElement); - last = tokenElement; - } - else { - first = last = tokenElement; - } - } - return first; - } - - private boolean isTokenValid(IElementType tokenType) { - return tokenType != null && XML_WHITE_SPACE_OR_COMMENT_BIT_SET.contains(tokenType); - } - - private TreeElement parseComment(Lexer lexer) { - final CompositeElement comment = ASTFactory.composite(XML_COMMENT); - - while (lexer.getTokenType() != null && XML_COMMENT_BIT_SET.contains(lexer.getTokenType())) { - final TreeElement tokenElement = createTokenElement(lexer, myCharTable); - lexer.advance(); - comment.rawAddChildren(tokenElement); - } - - return comment; - } - } - - private void insertMissingTokens(CompositeElement root, - Lexer lexer, - int startOffset, - int endOffset, - int state, - WhiteSpaceAndCommentsProcessor processor) { - if (state < 0) { - lexer.start(lexer.getBufferSequence(), startOffset, endOffset); - } - else { - lexer.start(lexer.getBufferSequence(), startOffset, endOffset, state); - } - - LeafElement leaf = TreeUtil.findFirstLeaf(root); - if (leaf == null) { - final TreeElement firstMissing = processor.process(lexer); - if (firstMissing != null) { - root.rawAddChildren(firstMissing); - } - return; - } - { - // Missing in the begining - final IElementType tokenType = lexer.getTokenType(); - if (tokenType != leaf.getElementType() && processor.isTokenValid(tokenType)) { - final TreeElement firstMissing = processor.process(lexer); - if (firstMissing != null) { - root.getFirstChildNode().rawInsertBeforeMe(firstMissing); - } - } - passTokenOrChameleon(leaf, lexer); - } - // Missing in tree body - insertMissingTokensInTreeBody(leaf, lexer, processor, null); - if (lexer.getTokenType() != null) { - // whitespaces at the end of the file - final TreeElement firstMissing = processor.process(lexer); - if (firstMissing != null) { - ASTNode current = root; - while (current instanceof CompositeElement) { - if (current.getUserData(TreeUtil.UNCLOSED_ELEMENT_PROPERTY) != null) break; - current = current.getLastChildNode(); - } - if (current instanceof CompositeElement) { - ((CompositeElement)current).rawAddChildren(firstMissing); - } - else { - root.getLastChildNode().rawInsertAfterMe(firstMissing); - } - } - } - } - - private static void insertMissingTokensInTreeBody(TreeElement leaf, Lexer lexer, - WhiteSpaceAndCommentsProcessor processor, - ASTNode endToken) { - final TreeUtil.CommonParentState commonParents = new TreeUtil.CommonParentState(); - while (leaf != null) { - commonParents.strongWhiteSpaceHolder = null; - final IElementType tokenType = lexer.getTokenType(); - final TreeElement next = TreeUtil.nextLeaf(leaf, commonParents, null, false); - - if (next == null || tokenType == null || next == endToken) break; - if (tokenType != next.getElementType() && processor.isTokenValid(tokenType)) { - final TreeElement firstMissing = processor.process(lexer); - final CompositeElement unclosedElement = commonParents.strongWhiteSpaceHolder; - if (unclosedElement != null) { - if (commonParents.isStrongElementOnRisingSlope || unclosedElement.getFirstChildNode() == null) { - unclosedElement.rawAddChildren(firstMissing); - } - else { - unclosedElement.getFirstChildNode().rawInsertBeforeMe(firstMissing); - } - } - else { - final ASTNode insertBefore = commonParents.nextLeafBranchStart; - TreeElement insertAfter = commonParents.startLeafBranchStart; - TreeElement current = commonParents.startLeafBranchStart; - while (current != insertBefore) { - final TreeElement treeNext = current.getTreeNext(); - if (treeNext == insertBefore) { - insertAfter = current; - break; - } - if (treeNext.getUserData(TreeUtil.UNCLOSED_ELEMENT_PROPERTY) != null) { - insertAfter = null; - ((CompositeElement)treeNext).rawAddChildren(firstMissing); - break; - } - current = treeNext; - } - if (insertAfter != null && firstMissing != null) insertAfter.rawInsertAfterMe(firstMissing); - } - } - passTokenOrChameleon(next, lexer); - leaf = next; - } - } - - private static void passTokenOrChameleon(final ASTNode next, Lexer lexer) { - if (next instanceof LeafElement && next instanceof OuterLanguageElement) { - final int endOfChameleon = next.getTextLength() + lexer.getTokenStart(); - while (lexer.getTokenType() != null && lexer.getTokenEnd() < endOfChameleon) { - lexer.advance(); - } - } - lexer.advance(); - } -} diff --git a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java b/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java index 5b449f1fa4d3..a98e5dbc5c53 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java +++ b/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlParsing.java @@ -34,7 +34,7 @@ import static com.intellij.psi.xml.XmlElementType.*; public class XmlParsing { private static final int BALANCING_DEPTH_THRESHOLD = 1000; - private final PsiBuilder myBuilder; + protected final PsiBuilder myBuilder; private final Stack myTagNamesStack = new Stack(); public XmlParsing(final PsiBuilder builder) { @@ -116,7 +116,7 @@ public class XmlParsing { doctype.done(XML_DOCTYPE); } - private void parseTag(boolean multipleRootTagError) { + protected void parseTag(boolean multipleRootTagError) { assert token() == XML_START_TAG_START : "Tag start expected"; final PsiBuilder.Marker tag = mark(); diff --git a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java b/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java deleted file mode 100644 index 78402417bbbb..000000000000 --- a/xml/impl/src/com/intellij/psi/impl/source/parsing/xml/XmlPsiLexer.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.psi.impl.source.parsing.xml; - -import com.intellij.lexer.OldXmlLexer; -import com.intellij.psi.TokenType; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.xml.XmlTokenType; - -/** - * @author Mike - */ -public class XmlPsiLexer extends OldXmlLexer{ - public XmlPsiLexer() { - } - - public IElementType getTokenType() { - IElementType type = super.getTokenType(); - - if (type == XmlTokenType.XML_WHITE_SPACE) { - return TokenType.WHITE_SPACE; - } - - return type; - } -} diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java index be9dc8b88b49..59afb95c34d9 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityDeclImpl.java @@ -23,9 +23,8 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.impl.source.SourceTreeToPsiMap; -import com.intellij.psi.impl.source.parsing.xml.OldXmlParser; +import com.intellij.psi.impl.source.parsing.xml.DtdParsing; import com.intellij.psi.impl.source.resolve.reference.impl.providers.URIReferenceProvider; -import com.intellij.psi.impl.source.tree.SharedImplUtil; import com.intellij.psi.tree.xml.IXmlLeafElementType; import com.intellij.psi.xml.*; import com.intellij.util.IncorrectOperationException; @@ -33,9 +32,6 @@ import com.intellij.xml.util.XmlUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashSet; -import java.util.Set; - /** * @author mike */ @@ -93,7 +89,7 @@ public class XmlEntityDeclImpl extends XmlElementImpl implements XmlEntityDecl, return null; } - public PsiElement parse(PsiFile baseFile, EntityContextType context, final XmlEntityRef originalElement) { + public PsiElement parse(PsiFile baseFile, EntityContextType contextType, final XmlEntityRef originalElement) { PsiElement dep = XmlElement.DEPENDING_ELEMENT.get(getParent()); PsiElement dependsOnElement = getValueElement(dep instanceof PsiFile ? (PsiFile)dep : baseFile); String value = null; @@ -108,25 +104,9 @@ public class XmlEntityDeclImpl extends XmlElementImpl implements XmlEntityDecl, if (value == null) return null; - - Set names = null; - - if (context == EntityContextType.GENERIC_XML) { - names = new HashSet(); - // calculating parent names - PsiElement parent = originalElement; - while(parent != null){ - if(parent instanceof XmlTag){ - names.add(((XmlTag)parent).getName()); - } - parent = parent.getParent(); - } - } - - OldXmlParser oldXmlParser = new OldXmlParser(value, XML_ELEMENT_DECL, context, SharedImplUtil.findCharTableByTree(this), getManager(), names, - originalElement); - PsiElement generated = oldXmlParser.parse().getPsi().getFirstChild(); - if (context == EntityContextType.ELEMENT_CONTENT_SPEC) { + DtdParsing dtdParsing = new DtdParsing(value, XML_ELEMENT_DECL, contextType, baseFile); + PsiElement generated = dtdParsing.parse().getPsi().getFirstChild(); + if (contextType == EntityContextType.ELEMENT_CONTENT_SPEC && generated instanceof XmlElementContentSpec) { generated = generated.getFirstChild(); } setDependsOnElement(generated, dependsOnElement); @@ -178,7 +158,8 @@ public class XmlEntityDeclImpl extends XmlElementImpl implements XmlEntityDecl, for (ASTNode e = getFirstChildNode(); e != null; e = e.getTreeNext()) { if (e.getElementType() instanceof IXmlLeafElementType) { XmlToken token = (XmlToken)SourceTreeToPsiMap.treeElementToPsi(e); - if (token.getTokenType() == XmlTokenType.XML_DOCTYPE_PUBLIC || token.getTokenType() == XmlTokenType.XML_DOCTYPE_SYSTEM) { + if (token.getTokenType() == XmlTokenType.XML_DOCTYPE_PUBLIC || + token.getTokenType() == XmlTokenType.XML_DOCTYPE_SYSTEM) { return false; } } diff --git a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java index e05f8ae509fd..6b0bd810c682 100644 --- a/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java +++ b/xml/impl/src/com/intellij/psi/impl/source/xml/XmlEntityRefImpl.java @@ -173,7 +173,8 @@ public class XmlEntityRefImpl extends XmlElementImpl implements XmlEntityRef { return true; } }; - deps.add(targetElement); + FileViewProvider provider = targetElement.getContainingFile().getViewProvider(); + deps.add(provider.getPsi(provider.getBaseLanguage())); boolean notfound = PsiTreeUtil.processElements(targetElement, processor); if (notfound) { diff --git a/xml/impl/src/com/intellij/psi/xml/XmlElementType.java b/xml/impl/src/com/intellij/psi/xml/XmlElementType.java index 0db40f5eada0..4b33722b7876 100644 --- a/xml/impl/src/com/intellij/psi/xml/XmlElementType.java +++ b/xml/impl/src/com/intellij/psi/xml/XmlElementType.java @@ -16,18 +16,14 @@ package com.intellij.psi.xml; import com.intellij.lang.ASTNode; -import com.intellij.lang.Language; import com.intellij.lang.dtd.DTDLanguage; import com.intellij.lang.html.HTMLLanguage; import com.intellij.lang.xhtml.XHTMLLanguage; import com.intellij.lang.xml.XMLLanguage; -import com.intellij.openapi.project.Project; -import com.intellij.psi.impl.source.parsing.xml.OldXmlParser; -import com.intellij.psi.impl.source.tree.SharedImplUtil; +import com.intellij.psi.impl.source.parsing.xml.DtdParsing; import com.intellij.psi.tree.CustomParsingType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; -import com.intellij.psi.tree.IReparseableElementType; import com.intellij.psi.tree.xml.IXmlElementType; import com.intellij.util.CharTable; @@ -66,22 +62,11 @@ public interface XmlElementType extends XmlTokenType { IElementType XHTML_FILE = new IFileElementType(XHTMLLanguage.INSTANCE); - IElementType DTD_FILE = new IReparseableElementType("DTD_FILE", DTDLanguage.INSTANCE){ - public ASTNode parseContents(ASTNode chameleon) { - return new OldXmlParser(chameleon.getChars(), - XML_DOCUMENT, - XmlEntityDecl.EntityContextType.GENERIC_XML, - SharedImplUtil.findCharTableByTree(chameleon), - SharedImplUtil.getManagerByTree(chameleon) - ).parse(); - } - public boolean isParsable(CharSequence buffer, Language fileLanguage, final Project project) {return true;} - }; + IFileElementType DTD_FILE = new IFileElementType("DTD_FILE", DTDLanguage.INSTANCE); IElementType XML_MARKUP_DECL = new CustomParsingType("XML_MARKUP_DECL", XMLLanguage.INSTANCE){ public ASTNode parse(CharSequence text, CharTable table) { - // TODO - return new OldXmlParser(text, XML_MARKUP_DECL, OldXmlParser.TYPE_FOR_MARKUP_DECL, table, null).parse(); + return new DtdParsing(text, XML_MARKUP_DECL, DtdParsing.TYPE_FOR_MARKUP_DECL, null).parse(); } }; } diff --git a/xml/impl/src/com/intellij/xml/util/XmlUtil.java b/xml/impl/src/com/intellij/xml/util/XmlUtil.java index 0c36beb61375..da1dc8b5fd32 100644 --- a/xml/impl/src/com/intellij/xml/util/XmlUtil.java +++ b/xml/impl/src/com/intellij/xml/util/XmlUtil.java @@ -613,7 +613,7 @@ public class XmlUtil { if (element instanceof XmlEntityRef) { XmlEntityRef ref = (XmlEntityRef)element; - PsiElement newElement = parseEntityRef(targetFile, ref, true); + PsiElement newElement = parseEntityRef(targetFile, ref); while (newElement != null) { if (!processElement(newElement, deepFlag, wideFlag, processIncludes)) return false; @@ -666,12 +666,12 @@ public class XmlUtil { } } - private static PsiElement parseEntityRef(PsiFile targetFile, XmlEntityRef ref, boolean cacheValue) { + private static PsiElement parseEntityRef(PsiFile targetFile, XmlEntityRef ref) { XmlEntityDecl.EntityContextType type = getContextType(ref); { final XmlEntityDecl entityDecl = ref.resolve(targetFile); - if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, ref); } PsiElement e = ref; @@ -681,7 +681,7 @@ public class XmlUtil { final PsiFile f = e.getContainingFile(); if (f != null) { final XmlEntityDecl entityDecl = ref.resolve(targetFile); - if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, ref); } continue; @@ -689,7 +689,7 @@ public class XmlUtil { if (e instanceof PsiFile) { PsiFile refFile = (PsiFile)e; final XmlEntityDecl entityDecl = ref.resolve(refFile); - if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, ref); break; } @@ -699,7 +699,7 @@ public class XmlUtil { final PsiElement element = ref.getUserData(XmlElement.DEPENDING_ELEMENT); if (element instanceof XmlFile) { final XmlEntityDecl entityDecl = ref.resolve((PsiFile)element); - if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, cacheValue, ref); + if (entityDecl != null) return parseEntityDecl(entityDecl, targetFile, type, ref); } return null; @@ -741,10 +741,7 @@ public class XmlUtil { private static PsiElement parseEntityDecl(final XmlEntityDecl entityDecl, final PsiFile targetFile, final XmlEntityDecl.EntityContextType type, - boolean cacheValue, final XmlEntityRef entityRef) { - if (!cacheValue) return entityDecl.parse(targetFile, type, entityRef); - synchronized (PsiLock.LOCK) { // we depend on targetFile and entityRef CachedValue value = entityRef.getUserData(PARSED_DECL_KEY); // return entityDecl.parse(targetFile, type); diff --git a/xml/tests/src/com/intellij/codeInsight/XmlParsingTest.java b/xml/tests/src/com/intellij/codeInsight/XmlParsingTest.java index b3fe52305eec..9c80b9ef90be 100644 --- a/xml/tests/src/com/intellij/codeInsight/XmlParsingTest.java +++ b/xml/tests/src/com/intellij/codeInsight/XmlParsingTest.java @@ -19,8 +19,7 @@ import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.DebugUtil; -import com.intellij.psi.impl.source.CharTableImpl; -import com.intellij.psi.impl.source.parsing.xml.OldXmlParser; +import com.intellij.psi.impl.source.parsing.xml.DtdParsing; import com.intellij.psi.impl.source.tree.CompositeElement; import com.intellij.psi.impl.source.tree.LeafElement; import com.intellij.psi.impl.source.tree.TreeUtil; @@ -405,7 +404,7 @@ public class XmlParsingTest extends ParsingTestCase { } private CompositeElement parseManually(final String value, final IElementType xmlElementDecl, XmlEntityDecl.EntityContextType parseType) { - return (CompositeElement)new OldXmlParser(value, xmlElementDecl, parseType, new CharTableImpl(), getPsiManager()).parse(); + return (CompositeElement)new DtdParsing(value, xmlElementDecl, parseType, null).parse(); } public void testCharacters1() throws Exception { diff --git a/xml/tests/testData/psi/testElementDeclaration.txt b/xml/tests/testData/psi/testElementDeclaration.txt index ed6b23544792..f1107388b00e 100644 --- a/xml/tests/testData/psi/testElementDeclaration.txt +++ b/xml/tests/testData/psi/testElementDeclaration.txt @@ -53,9 +53,9 @@ XmlFile:test.dtd XmlToken:XML_ELEMENT_DECL_START(' + PsiWhiteSpace(' ') PsiElement(XML_ELEMENT_CONTENT_SPEC) - PsiWhiteSpace(' ') + PsiErrorElement:( or entity ref or EMPTY or ANY expected + XmlToken:XML_TAG_END('>') \ No newline at end of file diff --git a/xml/tests/testData/psi/testEmptyElementsInDtd.txt b/xml/tests/testData/psi/testEmptyElementsInDtd.txt index b15b4a0d79b2..98de113e9b09 100644 --- a/xml/tests/testData/psi/testEmptyElementsInDtd.txt +++ b/xml/tests/testData/psi/testEmptyElementsInDtd.txt @@ -19,8 +19,8 @@ XmlFile:test.dtd XmlToken:XML_LEFT_PAREN('(') PsiErrorElement:Xml name or entity ref expected - XmlToken:XML_COMMA(',') - XmlToken:XML_RIGHT_PAREN(')') + XmlToken:XML_COMMA(',') + XmlToken:XML_RIGHT_PAREN(')') PsiWhiteSpace('\n') PsiElement(XML_ATTLIST_DECL) XmlToken:XML_ATTLIST_DECL_START('') XmlTag:b XmlToken:XML_START_TAG_START('<') - XmlToken:XML_TAG_NAME('b') + XmlToken:XML_NAME('b') PsiWhiteSpace(' ') PsiElement(XML_ATTRIBUTE) XmlToken:XML_NAME('c') @@ -17,10 +17,9 @@ PsiElement(XML_ELEMENT_DECL) XmlToken:XML_TAG_END('>') PsiWhiteSpace(' ') XmlToken:XML_END_TAG_START('') PsiWhiteSpace(' ') XmlToken:XML_END_TAG_START('') - \ No newline at end of file + XmlToken:XML_NAME('a') + XmlToken:XML_TAG_END('>') \ No newline at end of file diff --git a/xml/tests/testData/psi/testNewParsing19.txt b/xml/tests/testData/psi/testNewParsing19.txt index e16bf8b863fc..de7eda26d52c 100644 --- a/xml/tests/testData/psi/testNewParsing19.txt +++ b/xml/tests/testData/psi/testNewParsing19.txt @@ -13,9 +13,12 @@ XmlFile:test.xml PsiWhiteSpace(' ') XmlToken:XML_NAME('a') PsiWhiteSpace(' ') - XmlToken:XML_BAD_CHARACTER('#') PsiElement(XML_ELEMENT_CONTENT_SPEC) - XmlToken:XML_CONTENT_EMPTY('EMPTY') + + PsiErrorElement:( or entity ref or EMPTY or ANY expected + + XmlToken:XML_BAD_CHARACTER('#') + XmlToken:XML_CONTENT_EMPTY('EMPTY') XmlToken:XML_TAG_END('>') PsiElement(XML_ATTLIST_DECL) XmlToken:XML_ATTLIST_DECL_START('') + PsiWhiteSpace(' ') + XmlToken:XML_ATT_IMPLIED('#IMPLIED') + PsiWhiteSpace(' ') + XmlToken:XML_NAME('zz') + PsiWhiteSpace(' ') + XmlToken:XML_NAME('CDATA') + PsiWhiteSpace(' ') + XmlToken:XML_ATT_IMPLIED('#IMPLIED') + XmlToken:XML_TAG_END('>') XmlToken:XML_MARKUP_END(']') XmlToken:XML_DOCTYPE_END('>') PsiWhiteSpace('\n')