private setLabelsUsingCurrentToken()

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
    }
  }