use PsiBuilder based parser for dtd markup parsing

This commit is contained in:
Maxim.Mossienko
2012-07-31 19:24:46 +04:00
parent ca2b2a37c1
commit ad2a14afc9
20 changed files with 1082 additions and 1427 deletions
@@ -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 {
@@ -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);
}
}
@@ -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;
}
}
@@ -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);
}
}
@@ -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}|"_"|":"|"."|"-")+
<YYINITIAL,TAG_NAME,TAG_ATTRIBUTES,ATTRIBUTE_VALUE_START,ATTRIBUTE_VALUE_DQ,ATTRIBUTE_VALUE_SQ>"</" { yybegin(TAG_NAME); return XmlTokenType.XML_END_TAG_START; }
<TAG_NAME> {TAG_NAME} { yybegin(TAG_ATTRIBUTES); return XmlTokenType.XML_TAG_NAME; }
<TAG_NAME> {TAG_NAME} { yybegin(TAG_ATTRIBUTES); return isHighlightModeOn ? XmlTokenType.XML_TAG_NAME:XmlTokenType.XML_NAME; }
<TAG_ATTRIBUTES> ">" { yybegin(YYINITIAL); return XmlTokenType.XML_TAG_END; }
<TAG_ATTRIBUTES> "/>" { yybegin(YYINITIAL); return XmlTokenType.XML_EMPTY_ELEMENT_END; }
@@ -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
* <a href="http://www.jflex.de/">JFlex</a> 1.4.1
* on 10.12.09 20:28 from the specification file
* <tt>C:/IDEA/tools/lexer/../../community/xml/impl/src/com/intellij/lexer/_OldXmlLexer.flex</tt>
* <a href="http://www.jflex.de/">JFlex</a> 1.4.3
* on 7/31/12 2:32 PM from the specification file
* <tt>C:/Idea.Sources/Trunk/tools/lexer/../../community/xml/impl/src/com/intellij/lexer/_DtdLexer.flex</tt>
*/
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:
@@ -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();
}
}
}
}
File diff suppressed because it is too large Load Diff
@@ -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<String> myTagNamesStack = new Stack<String>();
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();
@@ -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;
}
}
@@ -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<String> names = null;
if (context == EntityContextType.GENERIC_XML) {
names = new HashSet<String>();
// 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;
}
}
@@ -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) {
@@ -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();
}
};
}
@@ -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<PsiElement> value = entityRef.getUserData(PARSED_DECL_KEY);
// return entityDecl.parse(targetFile, type);
@@ -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 {
@@ -53,9 +53,9 @@ XmlFile:test.dtd
XmlToken:XML_ELEMENT_DECL_START('<!ELEMENT')
PsiWhiteSpace(' ')
XmlToken:XML_NAME('xxx4')
PsiErrorElement:( or entity ref or EMPTY or ANY expected
<empty list>
PsiWhiteSpace(' ')
PsiElement(XML_ELEMENT_CONTENT_SPEC)
<empty list>
PsiWhiteSpace(' ')
PsiErrorElement:( or entity ref or EMPTY or ANY expected
<empty list>
XmlToken:XML_TAG_END('>')
@@ -19,8 +19,8 @@ XmlFile:test.dtd
XmlToken:XML_LEFT_PAREN('(')
PsiErrorElement:Xml name or entity ref expected
<empty list>
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('<!ATTLIST')
@@ -1,12 +1,16 @@
PsiElement(XML_ELEMENT_CONTENT_SPEC)
PsiElement(XML_ELEMENT_CONTENT_SPEC)
XmlToken:XML_BAR('|')
PsiWhiteSpace(' ')
PsiElement(XML_ENTITY_REF)
XmlToken:XML_ENTITY_REF_TOKEN('%pre.qname;')
PsiWhiteSpace(' ')
XmlToken:XML_BAR('|')
PsiWhiteSpace(' ')
PsiElement(XML_ENTITY_REF)
XmlToken:XML_ENTITY_REF_TOKEN('%blockquote.qname;')
PsiWhiteSpace(' ')
XmlToken:XML_BAR('|')
PsiWhiteSpace(' ')
PsiElement(XML_ENTITY_REF)
XmlToken:XML_ENTITY_REF_TOKEN('%address.qname;')
XmlToken:XML_ENTITY_REF_TOKEN('%address.qname;')
@@ -1,11 +1,11 @@
PsiElement(XML_ELEMENT_DECL)
XmlTag:a
XmlToken:XML_START_TAG_START('<')
XmlToken:XML_TAG_NAME('a')
XmlToken:XML_NAME('a')
XmlToken:XML_TAG_END('>')
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('</')
XmlToken:XML_TAG_NAME('b')
XmlToken:XML_NAME('b')
XmlToken:XML_TAG_END('>')
PsiWhiteSpace(' ')
XmlToken:XML_END_TAG_START('</')
XmlToken:XML_TAG_NAME('a')
XmlToken:XML_TAG_END('>')
XmlToken:XML_NAME('a')
XmlToken:XML_TAG_END('>')
+14 -11
View File
@@ -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')
<empty list>
PsiErrorElement:( or entity ref or EMPTY or ANY expected
<empty list>
XmlToken:XML_BAD_CHARACTER('#')
XmlToken:XML_CONTENT_EMPTY('EMPTY')
XmlToken:XML_TAG_END('>')
PsiElement(XML_ATTLIST_DECL)
XmlToken:XML_ATTLIST_DECL_START('<!ATTLIST')
@@ -31,15 +34,15 @@ XmlFile:test.xml
PsiWhiteSpace(' ')
PsiElement(XML_ATTRIBUTE_DECL)
XmlToken:XML_NAME('yy')
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('>')
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')