Makefile fixup
[org.ibex.tool.git] / src / org / eclipse / jdt / internal / compiler / parser / diagnose / LexStream.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2004 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package org.eclipse.jdt.internal.compiler.parser.diagnose;
12
13 import org.eclipse.jdt.core.compiler.CharOperation;
14 import org.eclipse.jdt.core.compiler.InvalidInputException;
15 import org.eclipse.jdt.internal.compiler.parser.Scanner;
16 import org.eclipse.jdt.internal.compiler.parser.TerminalTokens;
17
18 public class LexStream implements TerminalTokens {
19         public static final int IS_AFTER_JUMP = 1;
20         public static final int LBRACE_MISSING = 2;
21                 
22         public class Token{
23                 int kind;
24                 char[] name;
25                 int start;
26                 int end;
27                 int line;
28                 int flags;
29                 
30                 public String toString() {
31                         StringBuffer buffer = new StringBuffer();
32                         buffer.append(name).append('[').append(kind).append(']');
33                         buffer.append('{').append(start).append(',').append(end).append('}').append(line);
34                         return buffer.toString();
35                 }
36
37         }
38
39         private int tokenCacheIndex;
40         private int tokenCacheEOFIndex;
41         private Token[] tokenCache;
42
43         private int currentIndex = -1;
44
45         private Scanner scanner;
46         private int[] intervalStartToSkip;
47         private int[] intervalEndToSkip;
48         private int[] intervalFlagsToSkip;
49         
50         private int previousInterval = -1;
51         
52         public LexStream(int size, Scanner scanner, int[] intervalStartToSkip, int[] intervalEndToSkip, int[] intervalFlagsToSkip, int firstToken, int init, int eof) {
53                 this.tokenCache = new Token[size];
54                 this.tokenCacheIndex = 0;
55                 this.tokenCacheEOFIndex = Integer.MAX_VALUE;
56                 this.tokenCache[0] = new Token();
57                 this.tokenCache[0].kind = firstToken;
58                 this.tokenCache[0].name = CharOperation.NO_CHAR;
59                 this.tokenCache[0].start = init;
60                 this.tokenCache[0].end = init;
61                 this.tokenCache[0].line = 0;
62                 
63                 this.intervalStartToSkip = intervalStartToSkip;
64                 this.intervalEndToSkip = intervalEndToSkip;
65                 this.intervalFlagsToSkip = intervalFlagsToSkip;
66                 
67                 scanner.resetTo(init, eof);
68                 this.scanner = scanner;
69         }
70         
71         private void readTokenFromScanner(){
72                 int length = tokenCache.length;
73                 boolean tokenNotFound = true;
74                 
75                 while(tokenNotFound) {
76                         try {
77                                 int tokenKind =  scanner.getNextToken();
78                                 if(tokenKind != TokenNameEOF) {
79                                         int start = scanner.getCurrentTokenStartPosition();
80                                         int end = scanner.getCurrentTokenEndPosition();
81                                         if(!RangeUtil.isInInterval(start, end, intervalStartToSkip, intervalEndToSkip)) {
82                                                 Token token = new Token();
83                                                 token.kind = tokenKind;
84                                                 token.name = scanner.getCurrentTokenSource();
85                                                 token.start = start;
86                                                 token.end = end;
87                                                 token.line = scanner.getLineNumber(end);
88                                                 
89                                                 int pInterval = RangeUtil.getPreviousInterval(start, end, intervalStartToSkip, intervalEndToSkip);
90                                                 if(pInterval != previousInterval && (intervalFlagsToSkip[previousInterval + 1] & RangeUtil.IGNORE) == 0){
91                                                         token.flags = IS_AFTER_JUMP;
92                                                         if((intervalFlagsToSkip[pInterval] & RangeUtil.LBRACE_MISSING) != 0){
93                                                                 token.flags |= LBRACE_MISSING;
94                                                         }
95                                                 }
96                                                 previousInterval = pInterval;
97
98                                                 tokenCache[++tokenCacheIndex % length] = token;
99                                                 
100                                                 tokenNotFound = false;
101                                         }
102                                 } else {
103                                         int start = scanner.getCurrentTokenStartPosition();
104                                         int end = scanner.getCurrentTokenEndPosition();
105                                         Token token = new Token();
106                                         token.kind = tokenKind;
107                                         token.name = CharOperation.NO_CHAR;
108                                         token.start = start;
109                                         token.end = end;
110                                         token.line = scanner.getLineNumber(end);
111                                         
112                                         tokenCache[++tokenCacheIndex % length] = token;
113                                         
114                                         tokenCacheEOFIndex = tokenCacheIndex;
115                                         tokenNotFound = false;
116                                 }
117                         } catch (InvalidInputException e) {
118                                 // return next token
119                         }
120                 }
121         }
122         
123         public Token token(int index) {
124                 if(index < 0) {
125                         Token eofToken = new Token();
126                         eofToken.kind = TokenNameEOF;
127                         eofToken.name = CharOperation.NO_CHAR;
128                         return eofToken;
129                 }
130                 if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) {
131                         return token(this.tokenCacheEOFIndex);
132                 }
133                 int length = tokenCache.length;
134                 if(index > this.tokenCacheIndex) {
135                         int tokensToRead = index - this.tokenCacheIndex;
136                         while(tokensToRead-- != 0) {
137                                 readTokenFromScanner();
138                         }
139                 } else if(this.tokenCacheIndex - length >= index) {
140                         return null;
141                 }
142                 
143                 return tokenCache[index % length];
144         }
145         
146         
147         
148         public int getToken() {
149                 return currentIndex = next(currentIndex);
150         }
151         
152         public int previous(int tokenIndex) {
153                 return tokenIndex > 0 ? tokenIndex - 1 : 0;
154         }
155
156         public int next(int tokenIndex) {
157                 return tokenIndex < this.tokenCacheEOFIndex ? tokenIndex + 1 : this.tokenCacheEOFIndex;
158         }
159
160         public boolean afterEol(int i) {
161                 return i < 1 ? true : line(i - 1) < line(i);
162         }
163         
164         public void reset() {
165                 currentIndex = -1;
166         }
167         
168         public void reset(int i) {
169                 currentIndex = previous(i);
170         }
171
172         public int badtoken() {
173                 return 0;
174         }
175
176         public int kind(int tokenIndex) {
177                 return token(tokenIndex).kind;
178         }
179         
180         public char[] name(int tokenIndex) {
181                 return token(tokenIndex).name;
182         }
183
184         public int line(int tokenIndex) {
185                 return token(tokenIndex).line;
186         }
187         
188         public int start(int tokenIndex) {
189                 return token(tokenIndex).start;
190         }
191         
192         public int end(int tokenIndex) {
193                 return token(tokenIndex).end;
194         }
195         
196         public int flags(int tokenIndex) {
197                 return token(tokenIndex).flags;
198         }
199         
200         public boolean isInsideStream(int index) {
201                 if(this.tokenCacheEOFIndex >= 0 && index > this.tokenCacheEOFIndex) {
202                         return false;
203                 } else if(index > this.tokenCacheIndex) {
204                         return true;
205                 } else if(this.tokenCacheIndex - tokenCache.length >= index) {
206                         return false;
207                 } else {
208                         return true;
209                 }
210         }
211         
212         /* (non-Javadoc)
213          * @see java.lang.Object#toString()
214          */
215         public String toString() {
216                 StringBuffer res = new StringBuffer();
217                 
218                 String source = new String(scanner.source);
219                 if(currentIndex < 0) {
220                         res.append(source);
221                 } else {
222                         Token token = token(currentIndex);
223                         int curtokKind = token.kind;
224                         int curtokStart = token.start;
225                         int curtokEnd = token.end;
226                         
227                         int previousEnd = -1;
228                         for (int i = 0; i < intervalStartToSkip.length; i++) {
229                                 int intervalStart = intervalStartToSkip[i];
230                                 int intervalEnd = intervalEndToSkip[i];
231                                 
232                                 if(curtokStart >= previousEnd && curtokEnd <= intervalStart) {
233                                         res.append(source.substring(previousEnd + 1, curtokStart));
234                                         res.append('<');
235                                         res.append('#');
236                                         res.append(source.substring(curtokStart, curtokEnd + 1));
237                                         res.append('#');
238                                         res.append('>');
239                                         res.append(source.substring(curtokEnd+1, intervalStart));
240                                 } else {
241                                         res.append(source.substring(previousEnd + 1, intervalStart));
242                                 }
243                                 res.append('<');
244                                 res.append('@');
245                                 res.append(source.substring(intervalStart, intervalEnd + 1));
246                                 res.append('@');
247                                 res.append('>');
248                                 
249                                 previousEnd = intervalEnd;
250                         }
251                         if(curtokStart >= previousEnd) {
252                                 res.append(source.substring(previousEnd + 1, curtokStart));
253                                 res.append('<');
254                                 res.append('#');
255                                 if(curtokKind == TokenNameEOF) {
256                                         res.append("EOF#>"); //$NON-NLS-1$
257                                 } else {
258                                         res.append(source.substring(curtokStart, curtokEnd + 1));
259                                         res.append('#');
260                                         res.append('>');
261                                         res.append(source.substring(curtokEnd+1));
262                                 }
263                         } else {
264                                 res.append(source.substring(previousEnd + 1));
265                         }
266                 }
267                 
268                 return res.toString();
269         }
270 }