1 /*******************************************************************************
2 * Copyright (c) 2000, 2011 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.jdt.internal.ui.text;
14 import java.io.IOException;
16 import org.eclipse.jface.internal.text.html.SingleCharReader;
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.IDocument;
23 * Reads from a document either forwards or backwards. May be configured to
24 * skip comments and strings.
26 public class JavaCodeReader extends SingleCharReader {
28 /** The EOF character */
29 public static final int EOF= -1;
31 private boolean fSkipComments= false;
32 private boolean fSkipStrings= false;
33 private boolean fForward= false;
35 private IDocument fDocument;
39 private int fCachedLineNumber= -1;
40 private int fCachedLineOffset= -1;
43 public JavaCodeReader() {
47 * Returns the offset of the last read character. Should only be called after read has been called.
49 public int getOffset() {
50 return fForward ? fOffset -1 : fOffset;
53 public void configureForwardReader(IDocument document, int offset, int length, boolean skipComments, boolean skipStrings) throws IOException {
56 fSkipComments= skipComments;
57 fSkipStrings= skipStrings;
60 fEnd= Math.min(fDocument.getLength(), fOffset + length);
63 public void configureBackwardReader(IDocument document, int offset, boolean skipComments, boolean skipStrings) throws IOException {
66 fSkipComments= skipComments;
67 fSkipStrings= skipStrings;
71 fCachedLineNumber= fDocument.getLineOfOffset(fOffset);
72 } catch (BadLocationException x) {
73 throw new IOException(x.getMessage());
81 public void close() throws IOException {
86 * @see SingleCharReader#read()
89 public int read() throws IOException {
91 return fForward ? readForwards() : readBackwards();
92 } catch (BadLocationException x) {
93 throw new IOException(x.getMessage());
97 private void gotoCommentEnd() throws BadLocationException {
98 while (fOffset < fEnd) {
99 char current= fDocument.getChar(fOffset++);
100 if (current == '*') {
101 if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') {
109 private void gotoStringEnd(char delimiter) throws BadLocationException {
110 while (fOffset < fEnd) {
111 char current= fDocument.getChar(fOffset++);
112 if (current == '\\') {
113 // ignore escaped characters
115 } else if (current == delimiter) {
121 private void gotoLineEnd() throws BadLocationException {
122 int line= fDocument.getLineOfOffset(fOffset);
123 fOffset= fDocument.getLineOffset(line + 1);
126 private int readForwards() throws BadLocationException {
127 while (fOffset < fEnd) {
128 char current= fDocument.getChar(fOffset++);
133 if (fSkipComments && fOffset < fEnd) {
134 char next= fDocument.getChar(fOffset);
136 // a comment starts, advance to the comment end
140 } else if (next == '/') {
141 // '//'-comment starts, advance to the line end
153 gotoStringEnd(current);
166 private void handleSingleLineComment() throws BadLocationException {
167 int line= fDocument.getLineOfOffset(fOffset);
168 if (line < fCachedLineNumber) {
169 fCachedLineNumber= line;
170 fCachedLineOffset= fDocument.getLineOffset(line);
172 while (fCachedLineOffset < offset) {
173 char current= fDocument.getChar(offset--);
174 if (current == '/' && fCachedLineOffset <= offset && fDocument.getChar(offset) == '/') {
182 private void gotoCommentStart() throws BadLocationException {
183 while (0 < fOffset) {
184 char current= fDocument.getChar(fOffset--);
185 if (current == '*' && 0 <= fOffset && fDocument.getChar(fOffset) == '/')
190 private void gotoStringStart(char delimiter) throws BadLocationException {
191 while (0 < fOffset) {
192 char current= fDocument.getChar(fOffset);
193 if (current == delimiter) {
194 if ( !(0 <= fOffset && fDocument.getChar(fOffset -1) == '\\'))
201 private int readBackwards() throws BadLocationException {
203 while (0 < fOffset) {
206 handleSingleLineComment();
208 char current= fDocument.getChar(fOffset);
212 if (fSkipComments && fOffset > 1) {
213 char next= fDocument.getChar(fOffset - 1);
215 // a comment ends, advance to the comment start
229 gotoStringStart(current);