protected calcNewState()

in src/language/semantics/xslLexer.ts [207:509]


  protected calcNewState(
    isCurrentCharNewLine: boolean,
    char: string,
    nextChar: string,
    existing: XMLCharState
  ): XMLCharState {
    let rc: XMLCharState = existing
    let firstCharOfToken = true
    if (firstCharOfToken) {
    }

    switch (existing) {
      case XMLCharState.lCt:
        rc = XMLCharState.lCt2
        break
      case XMLCharState.lCt2:
        rc = XMLCharState.lCtName
        break
      case XMLCharState.lCtName:
        if (char === '>') {
          rc = XMLCharState.rCt
        }
        break
      case XMLCharState.lPi:
        rc = XMLCharState.lPi2
        break
      case XMLCharState.lPi2:
        rc = XMLCharState.lPiName
        break
      case XMLCharState.lPiName:
        if (this.isWhitespace(isCurrentCharNewLine, char)) {
          rc = XMLCharState.rPiName
        } else if (char === '?' && nextChar === '>') {
          rc = XMLCharState.rPiNameOnly
          this.skipTokenChar = true
        }
        break
      case XMLCharState.rPiName:
        if (this.isWhitespace(isCurrentCharNewLine, char)) {
          // no change
        } else if (char === '?' && nextChar === '>') {
          rc = XMLCharState.rPi
          this.skipTokenChar = true
        } else {
          rc = XMLCharState.lPiValue
        }
        break
      case XMLCharState.lPiValue:
        if (char === '?' && nextChar === '>') {
          rc = XMLCharState.rPi
          this.skipTokenChar = true
        }
        break
      case XMLCharState.rPi:
      case XMLCharState.rPiNameOnly:
      case XMLCharState.rSelfCt:
      case XMLCharState.rSelfCtNoAtt:
        if (this.skipTokenChar) {
          this.skipTokenChar = false
        } else {
          rc = this.testChar(char, nextChar, false)
        }
        break
      case XMLCharState.lComment:
        if (this.commentCharCount === 0) {
          // char === '-' we've already processed <!-
          this.commentCharCount++
        } else if (this.commentCharCount === 1) {
          // if commendCharCount === 1 then we're just in the comment value
          if (char === '-' && nextChar === '-') {
            this.commentCharCount++
          }
        } else if (this.commentCharCount === 2) {
          // we're on the second '-' at comment end
          this.commentCharCount++
        } else if (this.commentCharCount === 3) {
          // we're expecting the '>' at the comment end
          if (char === '>') {
            rc = XMLCharState.rComment
          }
          // stop checking as '--' already encountered without '>'
          this.commentCharCount = 4
        }
        break
      case XMLCharState.lExclam:
        // assume  <![CDATA[
        if (char === '[' && nextChar === 'C') {
          this.cdataCharCount = 0
          rc = XMLCharState.lCd
        } else if (char === '-' && nextChar === '-') {
          rc = XMLCharState.lComment
          this.commentCharCount = 0
        } else if (char === '>') {
          this.dtdNesting--
          if (this.dtdNesting < 0) {
            this.dtdNesting = 0
            rc = XMLCharState.rDtd
          }
        } else if (char === '<') {
          this.dtdNesting++
        }
        // TODO: Handle internal DTD subset
        break
      case XMLCharState.lCd:
        switch (this.cdataCharCount) {
          case 0:
          // [C  of <![CDATA[ already checked
          case 2:
          // DA already checked
          case 4:
            // TA already checked
            this.cdataCharCount++
            break
          case 1:
            if (char === 'D' && nextChar === 'A') {
              this.cdataCharCount++
            } else {
              rc = XMLCharState.init
            }
            break
          case 3:
            if (char === 'T' && nextChar === 'A') {
              this.cdataCharCount++
            } else {
              rc = XMLCharState.init
            }
            break
          case 5:
            if (char === '[') {
              this.cdataCharCount = 0
              rc = XMLCharState.lCdataEnd
            } else {
              rc = XMLCharState.init
            }
            break
        }
        break
      case XMLCharState.lCdataEnd:
      case XMLCharState.awaitingRcdata:
        if (char === ']' && nextChar === ']') {
          this.cdataCharCount = 0
          rc = XMLCharState.rCd
        } else if (char === '{') {
          if (nextChar === '{') {
            rc = XMLCharState.escTvtCdata
          } else {
            rc = XMLCharState.tvtCdata
          }
        }
        break
      // otherwise continue awaiting ]]>
      case XMLCharState.rCd:
        if (this.cdataCharCount === 0) {
          this.cdataCharCount++
        } else if (char === '>') {
          this.cdataCharCount = 0
          rc = XMLCharState.rCdataEnd
        } else {
          // TODO: ]] not permited on its own in CDATA, show error
          this.cdataCharCount = 0
          rc = XMLCharState.init
        }
        break
      case XMLCharState.lSt:
        if (char === '>') {
          // error for: '<>'
          rc = XMLCharState.rSt
        } else {
          // TODO: check first char of element name is oK
          rc = XMLCharState.lEn
        }
        break
      // element name started
      case XMLCharState.lEn:
        if (this.isWhitespace(isCurrentCharNewLine, char)) {
          rc = XMLCharState.lsElementNameWs
        } else if (char === '>') {
          rc = XMLCharState.rStNoAtt
        } else if (char === '/' && nextChar === '>') {
          rc = XMLCharState.rSelfCtNoAtt
          this.skipTokenChar = true
        }
        break
      // whitespace after element name (or after att-value)
      case XMLCharState.lsElementNameWs:
      case XMLCharState.rSq:
      case XMLCharState.rDq:
      case XMLCharState.wsBeforeAttname:
        if (this.isWhitespace(isCurrentCharNewLine, char)) {
          if (existing !== XMLCharState.lsElementNameWs) {
            rc = XMLCharState.wsBeforeAttname
          }
        } else if (char === '>') {
          rc = XMLCharState.rSt
        } else if (char === '/' && nextChar === '>') {
          rc = XMLCharState.rSelfCt
          this.skipTokenChar = true
        } else {
          rc = XMLCharState.lAn
        }
        break
      // attribute name started
      case XMLCharState.lAn:
        if (this.isWhitespace(isCurrentCharNewLine, char)) {
          rc = XMLCharState.wsAfterAttName
        } else if (char === '=') {
          rc = XMLCharState.lStEq
        } else {
          const charState = this.testAttNameChar(char, nextChar)
          if (charState !== XMLCharState.lText) {
            rc = charState
          }
        }
        break
      // whitespace after attribute name
      case XMLCharState.wsAfterAttName:
        if (char === '=') {
          rc = XMLCharState.lStEq
        } else if (!this.isWhitespace(isCurrentCharNewLine, char)) {
          // TODO: force error - guessing intended end of start tag
          rc = XMLCharState.syntaxError
        }
        break
      // '=' char after attribute name or
      // whitespace after attname and '=' char
      case XMLCharState.lStEq:
      case XMLCharState.lsEqWs:
        if (this.isWhitespace(isCurrentCharNewLine, char)) {
          rc = XMLCharState.lsEqWs
        } else if (char === '"') {
          rc = XMLCharState.lDq
        } else if (char === "'") {
          rc = XMLCharState.lSq
        } else {
          rc = XMLCharState.syntaxError
        }
        break
      case XMLCharState.lDq:
        if (char === '"') {
          rc = XMLCharState.rDq
        } else if (char === '{') {
          if (nextChar === '{') {
            rc = XMLCharState.escDqAvt
          } else {
            rc = XMLCharState.dqAvt
          }
        } else if (char === '&') {
          rc = XMLCharState.lEntity
          this.entityContext = EntityPosition.attrDq
        } else {
          const charState = this.testAttValueChar(char, nextChar)
          if (charState !== XMLCharState.lText) {
            rc = charState
          }
        }
        break
      case XMLCharState.lSq:
        if (char === "'") {
          rc = XMLCharState.rSq
        } else if (char === '{') {
          if (nextChar === '{') {
            rc = XMLCharState.escSqAvt
          } else {
            rc = XMLCharState.sqAvt
          }
        } else if (char === '&') {
          rc = XMLCharState.lEntity
          this.entityContext = EntityPosition.attrSq
        } else {
          const charState = this.testAttValueChar(char, nextChar)
          if (charState !== XMLCharState.lText) {
            rc = charState
          }
        }
        break
      case XMLCharState.escDqAvt:
        rc = XMLCharState.lDq
        break
      case XMLCharState.escSqAvt:
        rc = XMLCharState.lSq
        break
      case XMLCharState.escTvt:
        rc = XMLCharState.init
        break
      case XMLCharState.escTvtCdata:
        rc = XMLCharState.awaitingRcdata
        break
      case XMLCharState.lEntity:
        if (char === ';') {
          rc = XMLCharState.rEntity
        } else if (this.isWhitespace(isCurrentCharNewLine, char)) {
          rc = this.testChar(char, nextChar, false)
        }
        break
      case XMLCharState.lText:
        rc = this.testChar(char, nextChar, true)
        break
      default:
        // awaiting a new node
        rc = this.testChar(char, nextChar, false)
    }
    return rc
  }