in src/language/semantics/xpLexer.ts [392:641]
private calcNewState(
isFirstChar: boolean,
nesting: number,
char: string,
nextChar: string,
existing: CharLevelState
): [CharLevelState, number] {
let rv: CharLevelState
let firstCharOfToken = true
switch (existing) {
case CharLevelState.lNl:
let charCode = char.charCodeAt(0)
let nextCharCode = nextChar ? nextChar.charCodeAt(0) : -1
if (XPathLexer.isDigit(charCode) || char === '.') {
rv = existing
} else if (char === 'e' || char === 'E') {
if (
nextChar === '-' ||
nextChar === '+' ||
XPathLexer.isDigit(nextCharCode)
) {
rv = CharLevelState.exp
} else {
rv = existing
}
} else {
;({ rv, nesting } = this.testChar(
existing,
firstCharOfToken,
char,
nextChar,
nesting
))
}
break
case CharLevelState.exp:
rv = CharLevelState.lNl
break
case CharLevelState.rDqEnt:
rv = existing
switch (nesting) {
case 0:
case 2:
nesting++
break
case 1:
if (char === 'u' && nextChar === 'o') {
nesting++
} else {
nesting = 0
rv = CharLevelState.lDqEnt
}
break
case 3:
if (char === 't') {
nesting++
} else {
rv = CharLevelState.lDqEnt
nesting = 0
}
break
case 4:
if (char === ';') {
rv = CharLevelState.rDq
} else {
rv = CharLevelState.lDqEnt
}
nesting = 0
break
}
break
case CharLevelState.rSqEnt:
rv = existing
switch (nesting) {
case 0:
case 2:
nesting++
break
case 1:
if (char === 'p' && nextChar === 'o') {
nesting++
} else {
nesting = 0
rv = CharLevelState.lSqEnt
}
break
case 3:
if (char === 's') {
nesting++
} else {
rv = CharLevelState.lSqEnt
nesting = 0
}
break
case 4:
if (char === ';') {
rv = CharLevelState.rSq
} else {
rv = CharLevelState.lSqEnt
}
nesting = 0
break
}
break
case CharLevelState.lWs:
if (char === ' ' || char === '\t') {
rv = existing
this.wsCharNumber++
} else if (char === '\n') {
rv = existing
this.wsCharNumber = 0
this.wsNewLine = true
this.lineNumber++
} else {
// we must switch to the new state, depending on the char/nextChar
;({ rv, nesting } = this.testChar(
existing,
firstCharOfToken,
char,
nextChar,
nesting
))
}
break
case CharLevelState.lName:
case CharLevelState.lVar:
case CharLevelState.lAttr:
if (
char === '-' ||
char === '.' ||
(char === ':' &&
!(
nextChar === ':' ||
nextChar === '*' ||
nextChar === ' ' ||
nextChar === '\n' ||
nextChar === '\r' ||
nextChar === '\t'
))
) {
rv = existing
} else {
// we must switch to the new state, depending on the char/nextChar
;({ rv, nesting } = this.testChar(
existing,
isFirstChar,
char,
nextChar,
nesting
))
}
break
case CharLevelState.dSep:
rv = CharLevelState.dSep2
break
case CharLevelState.lUri:
rv = char === '}' ? CharLevelState.rUri : existing
break
case CharLevelState.lSqEnt:
rv = char === '&' && nextChar === 'a' ? CharLevelState.rSqEnt : existing
break
case CharLevelState.lDqEnt:
rv = char === '&' && nextChar === 'q' ? CharLevelState.rDqEnt : existing
break
case CharLevelState.lSq:
case CharLevelState.rLiteralSqEnt:
if (char === "'") {
if (nextChar === "'") {
rv = CharLevelState.escSq
} else {
rv = CharLevelState.rSq
}
} else if (char === '&') {
rv = CharLevelState.lLiteralSqEnt
} else {
rv = CharLevelState.lSq
}
break
case CharLevelState.lLiteralSqEnt:
if (char === "'") {
if (nextChar === "'") {
rv = CharLevelState.escSq
} else {
rv = CharLevelState.rSq
}
} else if (char === ';') {
rv = CharLevelState.rLiteralSqEnt
} else {
rv = existing
}
break
case CharLevelState.escSq:
rv = CharLevelState.lSq
break
case CharLevelState.escDq:
rv = CharLevelState.lDq
break
case CharLevelState.lDq:
case CharLevelState.rLiteralDqEnt:
if (char === '"') {
if (nextChar === '"') {
rv = CharLevelState.escDq
} else {
rv = CharLevelState.rDq
}
} else if (char === '&') {
rv = CharLevelState.lLiteralDqEnt
} else {
rv = CharLevelState.lDq
}
break
case CharLevelState.lLiteralDqEnt:
if (char === '"') {
if (nextChar === '"') {
rv = CharLevelState.escDq
} else {
rv = CharLevelState.rDq
}
} else if (char === ';') {
rv = CharLevelState.rLiteralDqEnt
} else {
rv = existing
}
break
case CharLevelState.lC:
if (char === ':' && nextChar === ')') {
rv = nesting === 1 ? CharLevelState.rC : existing
nesting--
} else if (char === '(' && nextChar === ':') {
rv = existing
nesting++
} else {
rv = existing
}
break
case CharLevelState.lEnt:
rv = char === ';' ? CharLevelState.rEnt : existing
break
default:
;({ rv, nesting } = this.testChar(
existing,
isFirstChar,
char,
nextChar,
nesting
))
}
return [rv, nesting]
}