in src/language/semantics/xpLexer.ts [1226:1402]
private setLabelsUsingCurrentToken(
poppedContext: Token | null | undefined,
prevToken: Token | null,
currentToken: Token
) {
if (!prevToken) {
prevToken = new BasicToken(',', CharLevelState.sep)
prevToken.tokenType = TokenLevelState.operator
}
let currentValue = currentToken.value
switch (currentToken.charType) {
case CharLevelState.lName:
// token is a 'name' that needs resolving:
// a Name cannot follow a Name -- unless it's like 'instance of'
switch (prevToken.charType) {
case CharLevelState.lName:
// previous token was lName and current token is lName
if (
Data.secondParts.indexOf(currentValue) > -1 &&
XPathLexer.isPartOperator(prevToken.value, currentValue)
) {
// castable as etc.
prevToken.tokenType = TokenLevelState.operator
currentToken.tokenType = TokenLevelState.operator
} else if (
XPathLexer.isTokenTypeEqual(prevToken, TokenLevelState.operator)
) {
// don't set to name because it may be a function etc.
//currentToken.tokenType = TokenLevelState.Name;
if (prevToken.value === 'as' || prevToken.value === 'of') {
// e.g. castable as xs:integer
// TODO: check if value equals xs:integer or element?
currentToken.tokenType = TokenLevelState.simpleType
} else if (
prevToken.value === '>' &&
currentToken.value === '>'
) {
currentToken.tokenType = TokenLevelState.operator
} else if (
prevToken.value === '<' &&
(currentToken.value === '<' || currentToken.value === '>')
) {
currentToken.tokenType = TokenLevelState.operator
}
} else if (
prevToken.tokenType === TokenLevelState.nodeNameTest ||
prevToken.tokenType === TokenLevelState.functionNameTest ||
XPathLexer.isTokenTypeAType(prevToken)
) {
Data.setAsOperatorIfKeyword(currentToken)
}
break
case CharLevelState.rB:
case CharLevelState.rBr:
case CharLevelState.rPr:
case CharLevelState.lAttr:
case CharLevelState.lNl:
case CharLevelState.lVar:
case CharLevelState.lSq:
case CharLevelState.lDq:
case CharLevelState.rLiteralSqEnt:
case CharLevelState.rLiteralDqEnt:
case CharLevelState.rDqEnt:
case CharLevelState.rSqEnt:
case CharLevelState.dot:
Data.setAsOperatorIfKeyword(currentToken)
break
case CharLevelState.dSep:
if (
prevToken.value === '()' ||
prevToken.value === '..' ||
prevToken.value === '[]' ||
prevToken.value === '{}'
) {
Data.setAsOperatorIfKeyword(currentToken)
}
break
default:
// current token is an lName but previous token was not
if (
XPathLexer.isTokenTypeUnset(prevToken) &&
Data.keywords.indexOf(currentValue) > -1
) {
currentToken.tokenType = TokenLevelState.operator
} else if (
XPathLexer.isCharTypeEqual(prevToken, CharLevelState.dSep) &&
prevToken.value === '()' &&
Data.keywords.indexOf(currentValue) > -1
) {
currentToken.tokenType = TokenLevelState.operator
} else if (
XPathLexer.isTokenTypeEqual(
prevToken,
TokenLevelState.operator
) &&
(prevToken.value === 'as' || prevToken.value === 'of')
) {
currentToken.tokenType = TokenLevelState.simpleType
}
break
}
break
case CharLevelState.sep:
let prevTokenT = prevToken.tokenType
let isStar = currentToken.value === '*'
if (
isStar &&
(prevTokenT === TokenLevelState.attributeNameTest ||
prevTokenT === TokenLevelState.uriLiteral ||
(prevTokenT === TokenLevelState.operator &&
prevToken.value === '?') ||
(prevTokenT === TokenLevelState.nodeType &&
prevToken.value === '()'))
) {
// @* or {example.com}*
currentToken.charType = CharLevelState.lName
currentToken.tokenType = TokenLevelState.nodeType
} else {
let possOccurrentIndicator =
currentToken.value === '?' || currentToken.value === '+' || isStar
if (possOccurrentIndicator) {
if (
prevTokenT === TokenLevelState.simpleType &&
prevToken.length > 1
) {
// xs:integer? etc
currentToken.charType = CharLevelState.lName
currentToken.tokenType = TokenLevelState.simpleType
} else if (
(prevTokenT === TokenLevelState.operator &&
prevToken.value === ')') ||
prevToken.value === ']'
) {
// ($a) * 9 or count($a) * 8 or abc as map(*)* or $item as node()+
if (
poppedContext &&
poppedContext.tokenType === TokenLevelState.simpleType
) {
currentToken.charType = CharLevelState.lName
currentToken.tokenType = TokenLevelState.nodeType
}
} else if (
isStar &&
(prevTokenT === TokenLevelState.operator ||
prevTokenT === TokenLevelState.complexExpression)
) {
// $a and * or if ($a) then * else book
if (
prevTokenT === TokenLevelState.operator &&
prevToken.charType === CharLevelState.dSep &&
prevToken.value === '()'
) {
// keep the same
} else {
currentToken.charType = CharLevelState.lName
currentToken.tokenType = TokenLevelState.nodeType
}
}
}
}
break
case CharLevelState.dSep:
if (currentToken.value === ':*' || currentToken.value === '..') {
currentToken.charType = CharLevelState.lName
currentToken.tokenType = TokenLevelState.nodeType
} else if (
currentToken.value === '()' &&
prevToken.tokenType === TokenLevelState.nodeType
) {
currentToken.charType = CharLevelState.lName
currentToken.tokenType = TokenLevelState.nodeType
}
break
}
}