/**
  * Returns a token.
  *
  * @param line The segment from which to get the token's text.
  * @param beg The starting offset of the token's text in the segment.
  * @param end The ending offset of the token's text in the segment.
  * @param startOffset The offset in the document of the token.
  * @param type The type of token.
  * @return The token.
  */
 public Token createToken(
     final char[] line, final int beg, final int end, final int startOffset, final int type) {
   Token token = tokenList[currentFreeToken];
   token.set(line, beg, end, startOffset, type);
   currentFreeToken++;
   if (currentFreeToken == size) augmentTokenList();
   return token;
 }
Exemple #2
0
  /**
   * Gets the next token from a tokenizer.
   *
   * @param wantWhitespace If true, leading whitespace will be returned as a token.
   * @param wantComment If true, comments are returned as tokens.
   * @return The next token in the stream.
   * @throws TextParseException The input was invalid.
   * @throws IOException An I/O error occurred.
   */
  public Token get(boolean wantWhitespace, boolean wantComment) throws IOException {
    int type;
    int c;

    if (ungottenToken) {
      ungottenToken = false;
      if (current.type == WHITESPACE) {
        if (wantWhitespace) {
          return current;
        }
      } else if (current.type == COMMENT) {
        if (wantComment) {
          return current;
        }
      } else {
        if (current.type == EOL) {
          line++;
        }
        return current;
      }
    }
    int skipped = skipWhitespace();
    if (skipped > 0 && wantWhitespace) {
      return current.set(WHITESPACE, null);
    }
    type = IDENTIFIER;
    sb.setLength(0);
    while (true) {
      c = getChar();
      if (c == -1 || delimiters.indexOf(c) != -1) {
        if (c == -1) {
          if (quoting) throw exception("EOF in " + "quoted string");
          else if (sb.length() == 0) {
            return current.set(EOF, null);
          } else {
            return current.set(type, sb);
          }
        }
        if (sb.length() == 0 && type != QUOTED_STRING) {
          if (c == '(') {
            multiline++;
            skipWhitespace();
            continue;
          } else if (c == ')') {
            if (multiline <= 0) throw exception("invalid " + "close " + "parenthesis");
            multiline--;
            skipWhitespace();
            continue;
          } else if (c == '"') {
            if (!quoting) {
              quoting = true;
              delimiters = quotes;
              type = QUOTED_STRING;
            } else {
              quoting = false;
              delimiters = delim;
              skipWhitespace();
            }
            continue;
          } else if (c == '\n') {
            return current.set(EOL, null);
          } else if (c == ';') {
            while (true) {
              c = getChar();
              if (c == '\n' || c == -1) {
                break;
              }
              sb.append((char) c);
            }
            if (wantComment) {
              ungetChar(c);
              return current.set(COMMENT, sb);
            } else if (c == -1 && type != QUOTED_STRING) {
              checkUnbalancedParens();
              return current.set(EOF, null);
            } else if (multiline > 0) {
              skipWhitespace();
              sb.setLength(0);
              continue;
            } else {
              return current.set(EOL, null);
            }
          } else {
            throw new IllegalStateException();
          }
        } else {
          ungetChar(c);
        }
        break;
      } else if (c == '\\') {
        c = getChar();
        if (c == -1) {
          throw exception("unterminated escape sequence");
        }
        sb.append('\\');
      } else if (quoting && c == '\n') {
        throw exception("newline in quoted string");
      }
      sb.append((char) c);
    }
    if (sb.length() == 0 && type != QUOTED_STRING) {
      checkUnbalancedParens();
      return current.set(EOF, null);
    }
    return current.set(type, sb);
  }
  /**
   * Draws a single view (i.e., a line of text for a wrapped view), wrapping the text onto multiple
   * lines if necessary.
   *
   * @param painter The painter to use to render tokens.
   * @param g The graphics context in which to paint.
   * @param r The rectangle in which to paint.
   * @param view The <code>View</code> to paint.
   * @param fontHeight The height of the font being used.
   * @param y The y-coordinate at which to begin painting.
   */
  protected void drawView(
      TokenPainter painter, Graphics2D g, Rectangle r, View view, int fontHeight, int y) {

    float x = r.x;

    LayeredHighlighter h = (LayeredHighlighter) host.getHighlighter();

    RSyntaxDocument document = (RSyntaxDocument) getDocument();
    Element map = getElement();

    int p0 = view.getStartOffset();
    int lineNumber = map.getElementIndex(p0);
    int p1 = view.getEndOffset(); // - 1;

    setSegment(p0, p1 - 1, document, drawSeg);
    // System.err.println("drawSeg=='" + drawSeg + "' (p0/p1==" + p0 + "/" + p1 + ")");
    int start = p0 - drawSeg.offset;
    Token token = document.getTokenListForLine(lineNumber);

    // If this line is an empty line, then the token list is simply a
    // null token.  In this case, the line highlight will be skipped in
    // the loop below, so unfortunately we must manually do it here.
    if (token != null && token.type == Token.NULL) {
      h.paintLayeredHighlights(g, p0, p1, r, host, this);
      return;
    }

    // Loop through all tokens in this view and paint them!
    while (token != null && token.isPaintable()) {

      int p = calculateBreakPosition(p0, token, x);
      x = r.x;

      h.paintLayeredHighlights(g, p0, p, r, host, this);

      while (token != null
          && token.isPaintable()
          && token.offset + token.textCount - 1 < p) { // <=p) {
        x = painter.paint(token, g, x, y, host, this);
        token = token.getNextToken();
      }

      if (token != null && token.isPaintable() && token.offset < p) {
        int tokenOffset = token.offset;
        tempToken.set(drawSeg.array, tokenOffset - start, p - 1 - start, tokenOffset, token.type);
        painter.paint(tempToken, g, x, y, host, this);
        token.makeStartAt(p);
      }

      p0 = (p == p0) ? p1 : p;
      y += fontHeight;
    } // End of while (token!=null && token.isPaintable()).

    // NOTE: We should re-use code from Token (paintBackground()) here,
    // but don't because I'm just too lazy.
    if (host.getEOLMarkersVisible()) {
      g.setColor(host.getForegroundForTokenType(Token.WHITESPACE));
      g.setFont(host.getFontForTokenType(Token.WHITESPACE));
      g.drawString("\u00B6", x, y - fontHeight);
    }
  }