in flex/src/com/intellij/lang/actionscript/parsing/ActionScriptXmlTokensParser.kt [25:168]
override fun parseTag(names: Stack<String>): Boolean {
val tokenType = builder.tokenType
assert(JSTokenTypes.XML_START_TAG_START === tokenType || JSTokenTypes.XML_START_TAG_LIST === tokenType)
val marker = builder.mark()
builder.advanceLexer()
val name: String?
if (builder.tokenType === JSTokenTypes.XML_LBRACE) {
val nameBuilder = StringBuilder()
parseXmlJsScript(nameBuilder)
name = nameBuilder.toString()
}
else {
name = builder.tokenText
}
var seenEnd = JSTokenTypes.XML_START_TAG_LIST === tokenType
names.push(name)
var hasErrors = false
try {
var currentTokenType = builder.tokenType
while (currentTokenType != null
) {
if (!JSElementTypes.XML_TOKENS.contains(currentTokenType)
&& currentTokenType !== JSTokenTypes.XML_LBRACE
) {
if (!seenEnd) {
builder.error(XmlParserBundle.message("xml.parsing.tag.start.is.not.closed"))
return false
}
val errorMarker = builder.mark()
builder.advanceLexer()
errorMarker.error(JavaScriptParserBundle.message("javascript.parser.message.expected.xml.element"))
currentTokenType = builder.tokenType
continue
}
if (currentTokenType === JSTokenTypes.XML_START_TAG_START ||
currentTokenType === JSTokenTypes.XML_START_TAG_LIST
) {
parseTag(names)
currentTokenType = builder.tokenType
continue
}
else if (currentTokenType === JSTokenTypes.XML_EMPTY_TAG_END ||
currentTokenType === JSTokenTypes.XML_END_TAG_LIST
) {
builder.advanceLexer()
return !hasErrors
}
else if (currentTokenType === JSTokenTypes.XML_END_TAG_START) {
if (!seenEnd) {
builder.error(XmlParserBundle.message("xml.parsing.tag.start.is.not.closed"))
return false
}
val endTagStart = builder.mark()
builder.advanceLexer()
val type = builder.tokenType
if (type === XmlTokenType.XML_TAG_NAME
|| type === JSTokenTypes.XML_LBRACE) {
val endName: String?
if (type === JSTokenTypes.XML_LBRACE) {
val nameBuilder = StringBuilder()
parseXmlJsScript(nameBuilder)
endName = nameBuilder.toString()
}
else {
endName = builder.tokenText
}
if (!StringUtil.equals(name, endName)
&& (endName == null || !endName.endsWith(CompletionUtilCore.DUMMY_IDENTIFIER_TRIMMED))
) {
if (names.contains(endName)) {
endTagStart.rollbackTo()
builder.error(XmlParserBundle.message("xml.parsing.named.element.is.not.closed", name))
return !hasErrors
}
else {
builder.error(XmlParserBundle.message("xml.parsing.closing.tag.matches.nothing"))
hasErrors = true
}
}
if (type !== JSTokenTypes.XML_LBRACE) {
builder.advanceLexer()
}
}
else if (JSTokenTypes.XML_START_TAG_LIST !== tokenType) {
builder.error(XmlParserBundle.message("xml.parsing.closing.tag.name.missing"))
hasErrors = true
}
if (builder.tokenType !== XmlTokenType.XML_TAG_END) {
builder.error(XmlParserBundle.message("xml.parsing.closing.tag.is.not.done"))
hasErrors = true
}
else {
builder.advanceLexer()
}
endTagStart.drop()
return !hasErrors
}
else if (currentTokenType === JSTokenTypes.XML_NAME) {
parseAttribute()
currentTokenType = builder.tokenType
continue
}
else if (currentTokenType === JSTokenTypes.XML_TAG_CONTENT) {
val xmlTextMarker = builder.mark()
builder.advanceLexer()
xmlTextMarker.done(JSElementTypes.XML_TEXT)
currentTokenType = builder.tokenType
continue
}
if (currentTokenType === JSTokenTypes.XML_TAG_END) {
seenEnd = true
}
if (currentTokenType === JSTokenTypes.XML_LBRACE) {
parseXmlJsScript(null)
}
else {
if (currentTokenType === JSTokenTypes.XML_RBRACE) {
builder.error(JavaScriptParserBundle.message("javascript.parser.message.unexpected.token", builder.tokenText))
}
builder.advanceLexer()
}
if (currentTokenType !== JSTokenTypes.XML_LBRACE
&& builder.tokenType === JSTokenTypes.XML_ATTR_EQUAL) {
builder.error(JavaScriptParserBundle.message("javascript.parser.message.missing.attribute.name"))
hasErrors = true
}
currentTokenType = builder.tokenType
}
return !hasErrors
}
finally {
names.pop()
marker.done(xmlLiteralExpression)
marker.setCustomEdgeTokenBinders(null, INCOMPLETE_TAG_WHITESPACE_BINDER)
}
}