KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > JavaCodeReader


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 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
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text;
12
13
14 import java.io.IOException JavaDoc;
15
16 import org.eclipse.jface.internal.text.html.SingleCharReader;
17
18 import org.eclipse.jface.text.BadLocationException;
19 import org.eclipse.jface.text.IDocument;
20
21
22 /**
23  * Reads from a document either forwards or backwards. May be configured to
24  * skip comments and strings.
25  */

26 public class JavaCodeReader extends SingleCharReader {
27
28     /** The EOF character */
29     public static final int EOF= -1;
30
31     private boolean fSkipComments= false;
32     private boolean fSkipStrings= false;
33     private boolean fForward= false;
34
35     private IDocument fDocument;
36     private int fOffset;
37
38     private int fEnd= -1;
39     private int fCachedLineNumber= -1;
40     private int fCachedLineOffset= -1;
41
42
43     public JavaCodeReader() {
44     }
45
46     /**
47      * Returns the offset of the last read character. Should only be called after read has been called.
48      */

49     public int getOffset() {
50         return fForward ? fOffset -1 : fOffset;
51     }
52
53     public void configureForwardReader(IDocument document, int offset, int length, boolean skipComments, boolean skipStrings) throws IOException JavaDoc {
54         fDocument= document;
55         fOffset= offset;
56         fSkipComments= skipComments;
57         fSkipStrings= skipStrings;
58
59         fForward= true;
60         fEnd= Math.min(fDocument.getLength(), fOffset + length);
61     }
62
63     public void configureBackwardReader(IDocument document, int offset, boolean skipComments, boolean skipStrings) throws IOException JavaDoc {
64         fDocument= document;
65         fOffset= offset;
66         fSkipComments= skipComments;
67         fSkipStrings= skipStrings;
68
69         fForward= false;
70         try {
71             fCachedLineNumber= fDocument.getLineOfOffset(fOffset);
72         } catch (BadLocationException x) {
73             throw new IOException JavaDoc(x.getMessage());
74         }
75     }
76
77     /*
78      * @see Reader#close()
79      */

80     public void close() throws IOException JavaDoc {
81         fDocument= null;
82     }
83
84     /*
85      * @see SingleCharReader#read()
86      */

87     public int read() throws IOException JavaDoc {
88         try {
89             return fForward ? readForwards() : readBackwards();
90         } catch (BadLocationException x) {
91             throw new IOException JavaDoc(x.getMessage());
92         }
93     }
94
95     private void gotoCommentEnd() throws BadLocationException {
96         while (fOffset < fEnd) {
97             char current= fDocument.getChar(fOffset++);
98             if (current == '*') {
99                 if (fOffset < fEnd && fDocument.getChar(fOffset) == '/') {
100                     ++ fOffset;
101                     return;
102                 }
103             }
104         }
105     }
106
107     private void gotoStringEnd(char delimiter) throws BadLocationException {
108         while (fOffset < fEnd) {
109             char current= fDocument.getChar(fOffset++);
110             if (current == '\\') {
111                 // ignore escaped characters
112
++ fOffset;
113             } else if (current == delimiter) {
114                 return;
115             }
116         }
117     }
118
119     private void gotoLineEnd() throws BadLocationException {
120         int line= fDocument.getLineOfOffset(fOffset);
121         fOffset= fDocument.getLineOffset(line + 1);
122     }
123
124     private int readForwards() throws BadLocationException {
125         while (fOffset < fEnd) {
126             char current= fDocument.getChar(fOffset++);
127
128             switch (current) {
129                 case '/':
130
131                     if (fSkipComments && fOffset < fEnd) {
132                         char next= fDocument.getChar(fOffset);
133                         if (next == '*') {
134                             // a comment starts, advance to the comment end
135
++ fOffset;
136                             gotoCommentEnd();
137                             continue;
138                         } else if (next == '/') {
139                             // '//'-comment starts, advance to the line end
140
gotoLineEnd();
141                             continue;
142                         }
143                     }
144
145                     return current;
146
147                 case '"':
148                 case '\'':
149
150                     if (fSkipStrings) {
151                         gotoStringEnd(current);
152                         continue;
153                     }
154
155                     return current;
156             }
157
158             return current;
159         }
160
161         return EOF;
162     }
163
164     private void handleSingleLineComment() throws BadLocationException {
165         int line= fDocument.getLineOfOffset(fOffset);
166         if (line < fCachedLineNumber) {
167             fCachedLineNumber= line;
168             fCachedLineOffset= fDocument.getLineOffset(line);
169             int offset= fOffset;
170             while (fCachedLineOffset < offset) {
171                 char current= fDocument.getChar(offset--);
172                 if (current == '/' && fCachedLineOffset <= offset && fDocument.getChar(offset) == '/') {
173                     fOffset= offset;
174                     return;
175                 }
176             }
177         }
178     }
179
180     private void gotoCommentStart() throws BadLocationException {
181         while (0 < fOffset) {
182             char current= fDocument.getChar(fOffset--);
183             if (current == '*' && 0 <= fOffset && fDocument.getChar(fOffset) == '/')
184                 return;
185         }
186     }
187
188     private void gotoStringStart(char delimiter) throws BadLocationException {
189         while (0 < fOffset) {
190             char current= fDocument.getChar(fOffset);
191             if (current == delimiter) {
192                 if ( !(0 <= fOffset && fDocument.getChar(fOffset -1) == '\\'))
193                     return;
194             }
195             -- fOffset;
196         }
197     }
198
199     private int readBackwards() throws BadLocationException {
200
201         while (0 < fOffset) {
202             -- fOffset;
203
204             handleSingleLineComment();
205
206             char current= fDocument.getChar(fOffset);
207             switch (current) {
208                 case '/':
209
210                     if (fSkipComments && fOffset > 1) {
211                         char next= fDocument.getChar(fOffset - 1);
212                         if (next == '*') {
213                             // a comment ends, advance to the comment start
214
fOffset -= 2;
215                             gotoCommentStart();
216                             continue;
217                         }
218                     }
219
220                     return current;
221
222                 case '"':
223                 case '\'':
224
225                     if (fSkipStrings) {
226                         -- fOffset;
227                         gotoStringStart(current);
228                         continue;
229                     }
230
231                     return current;
232             }
233
234             return current;
235         }
236
237         return EOF;
238     }
239 }
240
241
Popular Tags