scan()

in lib/lexer.js [92:252]


  scan() {
    if(this.peek === ' ' || this.peek === '\t' ||
      this.peek === '\n' || this.peek === '\r') {
      this.inTypeName = false;
    }
    
    this.skipWhitespaces();
    if (this.inParam) {
      if (isLetter(this.peek) || this.peek === '_') {
        this.inParam = false;
        return this.scanID();
      }

      throw new SyntaxError(`Unexpect token: '${this.peek}'`);
    }

    if (this.inError) {
      if (isLetter(this.peek) || this.peek === '_') {
        this.inError = false;
        return this.scanID();
      }

      throw new SyntaxError(`Unexpect token: '${this.peek}'`);
    }

    if (this.inPropertyMode) {
      if (this.peek === ']') {
        this.inPropertyMode = false;
        this.getch();
        return new Token(']');
      }

      if (this.peek === '=') {
        this.getch();
        return new Token('=');
      }

      if (this.peek === ',') {
        this.getch();
        return new Token(',');
      }

      if (isLetter(this.peek) || this.peek === '_') {
        return this.scanID();
      }

      throw new SyntaxError(`Unexpect token: '${this.peek}'`);
    }

    if (this.peek === '/') {
      this.getch();
      var next0 = this.peek;
      this.getch();
      var next1 = this.peek;
      if (next0 === '*' && next1 === '*') {
        this.getch();
        return new AnnotationStart();
      }
      this.ungetch();
      this.ungetch();
    }

    if (this.peek === '*') {
      this.getch();
      if (this.peek === '/') {
        this.getch();
        return new AnnotationEnd();
      }

      if (this.peek === ' ') {
        this.getch();
      }
    }

    if (this.inTypeName && this.peek === '[') {
      this.inPropertyMode = true;
      this.getch();
      return new Token('[');
    }

    if (!this.peek) {
      var tok = new Token(this.peek);
      this.peek = ' ';
      return tok;
    }

    if (this.peek === '@') {
      let typeName = '';
      this.getch();
      while (this.peek !== ' ' && this.peek !== '\n'
        && this.peek !== '[') {
        typeName += this.peek;
        this.getch();
      }

      if (typeName === 'param') {
        this.inParam = true;
      }

      if (typeName === 'error') {
        this.inError = true;
      }

      if(this.peek === '[') {
        this.inTypeName = true;
      }

      return new Type(typeName);
    }

    let str = `${this.peek}`;

    var lineEnd = false;
    for ( ; ; ) {
      this.getch();
      if (lineEnd) {
        while (this.peek === ' ') {
          this.getch();
        }

        if (this.peek === '*') {
          this.getch();
          if (this.peek === ' ') {
            this.getch();
            lineEnd = false;
          } else if (this.peek === '/') {
            this.ungetch();
            this.ungetch();
            break;
          }
        }

        if (this.peek === '@') {
          this.ungetch();
          break;
        }
      }

      if (this.peek === '\n') {
        lineEnd = true;
      }

      if (this.peek === '*') {
        this.getch();
        if (this.peek === '/') {
          this.ungetch();
          break;
        }

        this.ungetch();
      }

      if (this.peek) {
        str += this.peek;
      } else {
        throw new SyntaxError('Unexpect end of file');
      }
    }

    return new Text(str);
  }