1 package net.sourceforge.phpdt.internal.ui.text;
4 * (c) Copyright IBM Corp. 2000, 2001.
8 import java.io.IOException;
10 import org.eclipse.jface.text.BadLocationException;
11 import org.eclipse.jface.text.IDocument;
13 import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
16 * Reads from a document either forwards or backwards. May be configured to
17 * skip comments and strings.
19 public class PHPCodeReader extends SingleCharReader {
21 /** The EOF character */
22 public static final int EOF= -1;
24 private boolean fSkipComments= false;
25 private boolean fSkipStrings= false;
26 private boolean fForward= false;
28 private IDocument fDocument;
32 private int fCachedLineNumber= -1;
33 private int fCachedLineOffset= -1;
36 public PHPCodeReader() {
40 * Returns the offset of the last read character. Should only be called after read has been called.
42 public int getOffset() {
43 return fForward ? fOffset -1 : fOffset;
46 public void configureForwardReader(IDocument document, int offset, int length, boolean skipComments, boolean skipStrings) throws IOException {
49 fSkipComments= skipComments;
50 fSkipStrings= skipStrings;
53 fEnd= Math.min(fDocument.getLength(), fOffset + length);
56 public void configureBackwardReader(IDocument document, int offset, boolean skipComments, boolean skipStrings) throws IOException {
59 fSkipComments= skipComments;
60 fSkipStrings= skipStrings;
64 fCachedLineNumber= fDocument.getLineOfOffset(fOffset);
65 } catch (BadLocationException x) {
66 throw new IOException(x.getMessage());
73 public void close() throws IOException {
78 * @see SingleCharReader#read()
80 public int read() throws IOException {
82 return fForward ? readForwards() : readBackwards();
83 } catch (BadLocationException x) {
84 throw new IOException(x.getMessage());
88 private void gotoCommentEnd() throws BadLocationException {
89 while (fOffset < fEnd) {
90 char current= fDocument.getChar(fOffset++);
92 if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') {
100 private void gotoStringEnd(char delimiter) throws BadLocationException {
101 while (fOffset < fEnd) {
102 char current= fDocument.getChar(fOffset++);
103 if (current == '\\') {
104 // ignore escaped characters
106 } else if (current == delimiter) {
112 private void gotoLineEnd() throws BadLocationException {
113 int line= fDocument.getLineOfOffset(fOffset);
114 fOffset= fDocument.getLineOffset(line + 1);
117 private int readForwards() throws BadLocationException {
118 while (fOffset < fEnd) {
119 char current= fDocument.getChar(fOffset++);
124 if (fSkipComments && fOffset < fEnd) {
125 char next= fDocument.getChar(fOffset);
127 // a comment starts, advance to the comment end
131 } else if (next == '/') {
132 // '//'-comment starts, advance to the line end
144 gotoStringEnd(current);
157 private void handleSingleLineComment() throws BadLocationException {
158 int line= fDocument.getLineOfOffset(fOffset);
159 if (line < fCachedLineNumber) {
160 fCachedLineNumber= line;
161 fCachedLineOffset= fDocument.getLineOffset(line);
163 while (fCachedLineOffset < offset) {
164 char current= fDocument.getChar(offset--);
165 if (current == '/' && fCachedLineOffset <= offset && fDocument.getChar(offset) == '/') {
173 private void gotoCommentStart() throws BadLocationException {
174 while (0 < fOffset) {
175 char current= fDocument.getChar(fOffset--);
176 if (current == '*' && 0 <= fOffset && fDocument.getChar(fOffset) == '/')
181 private void gotoStringStart(char delimiter) throws BadLocationException {
182 while (0 < fOffset) {
183 char current= fDocument.getChar(fOffset);
184 if (current == delimiter) {
185 if ( !(0 <= fOffset && fDocument.getChar(fOffset -1) == '\\'))
192 private int readBackwards() throws BadLocationException {
194 while (0 < fOffset) {
197 handleSingleLineComment();
199 char current= fDocument.getChar(fOffset);
203 if (fSkipComments && fOffset > 1) {
204 char next= fDocument.getChar(fOffset - 1);
206 // a comment ends, advance to the comment start
220 gotoStringStart(current);