1 package net.sourceforge.phpdt.internal.ui.text;
 
   4  * (c) Copyright IBM Corp. 2000, 2001.
 
   8 import java.io.IOException;
 
  10 import net.sourceforge.phpdt.internal.corext.phpdoc.SingleCharReader;
 
  12 import org.eclipse.jface.text.BadLocationException;
 
  13 import org.eclipse.jface.text.IDocument;
 
  16  * Reads from a document either forwards or backwards. May be configured to skip
 
  17  * 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;
 
  26         private boolean fSkipStrings = false;
 
  28         private boolean fForward = false;
 
  30         private IDocument fDocument;
 
  34         private int fEnd = -1;
 
  36         private int fCachedLineNumber = -1;
 
  38         private int fCachedLineOffset = -1;
 
  40         public PHPCodeReader() {
 
  44          * Returns the offset of the last read character. Should only be called
 
  45          * after read has been called.
 
  47         public int getOffset() {
 
  48                 return fForward ? fOffset - 1 : fOffset;
 
  51         public void configureForwardReader(IDocument document, int offset,
 
  52                         int length, boolean skipComments, boolean skipStrings)
 
  56                 fSkipComments = skipComments;
 
  57                 fSkipStrings = skipStrings;
 
  60                 fEnd = Math.min(fDocument.getLength(), fOffset + length);
 
  63         public void configureBackwardReader(IDocument document, int offset,
 
  64                         boolean skipComments, boolean skipStrings) throws IOException {
 
  67                 fSkipComments = skipComments;
 
  68                 fSkipStrings = skipStrings;
 
  72                         fCachedLineNumber = fDocument.getLineOfOffset(fOffset);
 
  73                 } catch (BadLocationException x) {
 
  74                         throw new IOException(x.getMessage());
 
  81         public void close() throws IOException {
 
  86          * @see SingleCharReader#read()
 
  88         public int read() throws IOException {
 
  90                         return fForward ? readForwards() : readBackwards();
 
  91                 } catch (BadLocationException x) {
 
  92                         throw new IOException(x.getMessage());
 
  96         private void gotoCommentEnd() throws BadLocationException {
 
  97                 while (fOffset < fEnd) {
 
  98                         char current = fDocument.getChar(fOffset++);
 
 100                                 if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') {
 
 108         private void gotoStringEnd(char delimiter) throws BadLocationException {
 
 109                 while (fOffset < fEnd) {
 
 110                         char current = fDocument.getChar(fOffset++);
 
 111                         if (current == '\\') {
 
 112                                 // ignore escaped characters
 
 114                         } else if (current == delimiter) {
 
 120         private void gotoLineEnd() throws BadLocationException {
 
 121                 int line = fDocument.getLineOfOffset(fOffset);
 
 122                 fOffset = fDocument.getLineOffset(line + 1);
 
 125         private int readForwards() throws BadLocationException {
 
 126                 while (fOffset < fEnd) {
 
 127                         char current = fDocument.getChar(fOffset++);
 
 134                                         gotoStringEnd(current);
 
 141                                 if (fSkipComments && fOffset < fEnd) {
 
 150                                 if (fSkipComments && fOffset < fEnd) {
 
 151                                         char next = fDocument.getChar(fOffset);
 
 153                                                 // a comment starts, advance to the comment end
 
 157                                         } else if (next == '/') {
 
 158                                                 // '//'-comment starts, advance to the line end
 
 174         private void handleSingleLineComment() throws BadLocationException {
 
 175                 int line = fDocument.getLineOfOffset(fOffset);
 
 176                 if (line < fCachedLineNumber) {
 
 177                         fCachedLineNumber = line;
 
 178                         fCachedLineOffset = fDocument.getLineOffset(line);
 
 179                         int offset = fOffset;
 
 180                         while (fCachedLineOffset < offset) {
 
 181                                 char current = fDocument.getChar(offset--);
 
 183                                 if (current == '/' && fCachedLineOffset <= offset
 
 184                                                 && fDocument.getChar(offset) == '/') {
 
 189                                 if (current == '#' && fCachedLineOffset <= offset) {
 
 197         private void gotoCommentStart() throws BadLocationException {
 
 198                 while (0 < fOffset) {
 
 199                         char current = fDocument.getChar(fOffset--);
 
 200                         if (current == '*' && 0 <= fOffset
 
 201                                         && fDocument.getChar(fOffset) == '/')
 
 206         private void gotoStringStart(char delimiter) throws BadLocationException {
 
 207                 while (0 < fOffset) {
 
 208                         char current = fDocument.getChar(fOffset);
 
 209                         if (current == delimiter) {
 
 210                                 if (!(0 <= fOffset && fDocument.getChar(fOffset - 1) == '\\'))
 
 217         private int readBackwards() throws BadLocationException {
 
 219                 while (0 < fOffset) {
 
 222                         handleSingleLineComment();
 
 224                         char current = fDocument.getChar(fOffset);
 
 228                                 if (fSkipComments && fOffset > 1) {
 
 229                                         char next = fDocument.getChar(fOffset - 1);
 
 231                                                 // a comment ends, advance to the comment start
 
 244                                         gotoStringStart(current);