KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > compiler > parser > RecoveryScanner


1 /*******************************************************************************
2  * Copyright (c) 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
12 package org.eclipse.jdt.internal.compiler.parser;
13
14 import org.eclipse.jdt.core.compiler.CharOperation;
15 import org.eclipse.jdt.core.compiler.InvalidInputException;
16
17 public class RecoveryScanner extends Scanner {
18     public static final char[] FAKE_IDENTIFIER = "$missing$".toCharArray(); //$NON-NLS-1$
19

20     private RecoveryScannerData data;
21     
22     private int[] pendingTokens;
23     private int pendingTokensPtr = -1;
24     private char[] fakeTokenSource = null;
25     private boolean isInserted = true;
26     private boolean precededByRemoved = false;
27     private int skipNextInsertedTokens = -1;
28
29     public boolean record = true;
30     
31     public RecoveryScanner(Scanner scanner, RecoveryScannerData data) {
32         super(false,
33                 scanner.tokenizeWhiteSpace,
34                 scanner.checkNonExternalizedStringLiterals,
35                 scanner.sourceLevel,
36                 scanner.complianceLevel,
37                 scanner.taskTags,
38                 scanner.taskPriorities,
39                 scanner.isTaskCaseSensitive);
40         this.setData(data);
41     }
42     
43     public void insertToken(int token, int completedToken, int position) {
44         insertTokens(new int []{token}, completedToken, position);
45     }
46     
47     private int[] reverse(int[] tokens) {
48         int length = tokens.length;
49         for(int i = 0, max = length / 2; i < max; i++) {
50             int tmp = tokens[i];
51             tokens[i] = tokens[length - i - 1];
52             tokens[length - i - 1] = tmp;
53         }
54         return tokens;
55     }
56     public void insertTokens(int[] tokens, int completedToken, int position) {
57         if(!this.record) return;
58         
59         if(completedToken > -1 && Parser.statements_recovery_filter[completedToken] != 0) return;
60         
61         this.data.insertedTokensPtr++;
62         if(this.data.insertedTokens == null) {
63             this.data.insertedTokens = new int[10][];
64             this.data.insertedTokensPosition = new int[10];
65             this.data.insertedTokenUsed = new boolean[10];
66         } else if(this.data.insertedTokens.length == this.data.insertedTokensPtr) {
67             int length = this.data.insertedTokens.length;
68             System.arraycopy(this.data.insertedTokens, 0, this.data.insertedTokens = new int[length * 2][], 0, length);
69             System.arraycopy(this.data.insertedTokensPosition, 0, this.data.insertedTokensPosition = new int[length * 2], 0, length);
70             System.arraycopy(this.data.insertedTokenUsed, 0, this.data.insertedTokenUsed = new boolean[length * 2], 0, length);
71         }
72         this.data.insertedTokens[this.data.insertedTokensPtr] = reverse(tokens);
73         this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
74         this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
75     }
76     
77     public void replaceTokens(int token, int start, int end) {
78         replaceTokens(new int []{token}, start, end);
79     }
80     
81     public void replaceTokens(int[] tokens, int start, int end) {
82         if(!this.record) return;
83         this.data.replacedTokensPtr++;
84         if(this.data.replacedTokensStart == null) {
85             this.data.replacedTokens = new int[10][];
86             this.data.replacedTokensStart = new int[10];
87             this.data.replacedTokensEnd = new int[10];
88             this.data.replacedTokenUsed= new boolean[10];
89         } else if(this.data.replacedTokensStart.length == this.data.replacedTokensPtr) {
90             int length = this.data.replacedTokensStart.length;
91             System.arraycopy(this.data.replacedTokens, 0, this.data.replacedTokens = new int[length * 2][], 0, length);
92             System.arraycopy(this.data.replacedTokensStart, 0, this.data.replacedTokensStart = new int[length * 2], 0, length);
93             System.arraycopy(this.data.replacedTokensEnd, 0, this.data.replacedTokensEnd = new int[length * 2], 0, length);
94             System.arraycopy(this.data.replacedTokenUsed, 0, this.data.replacedTokenUsed = new boolean[length * 2], 0, length);
95         }
96         this.data.replacedTokens[this.data.replacedTokensPtr] = reverse(tokens);
97         this.data.replacedTokensStart[this.data.replacedTokensPtr] = start;
98         this.data.replacedTokensEnd[this.data.replacedTokensPtr] = end;
99         this.data.replacedTokenUsed[this.data.replacedTokensPtr] = false;
100     }
101     
102     public void removeTokens(int start, int end) {
103         if(!this.record) return;
104         this.data.removedTokensPtr++;
105         if(this.data.removedTokensStart == null) {
106             this.data.removedTokensStart = new int[10];
107             this.data.removedTokensEnd = new int[10];
108             this.data.removedTokenUsed = new boolean[10];
109         } else if(this.data.removedTokensStart.length == this.data.removedTokensPtr) {
110             int length = this.data.removedTokensStart.length;
111             System.arraycopy(this.data.removedTokensStart, 0, this.data.removedTokensStart = new int[length * 2], 0, length);
112             System.arraycopy(this.data.removedTokensEnd, 0, this.data.removedTokensEnd = new int[length * 2], 0, length);
113             System.arraycopy(this.data.removedTokenUsed, 0, this.data.removedTokenUsed = new boolean[length * 2], 0, length);
114         }
115         this.data.removedTokensStart[this.data.removedTokensPtr] = start;
116         this.data.removedTokensEnd[this.data.removedTokensPtr] = end;
117         this.data.removedTokenUsed[this.data.removedTokensPtr] = false;
118     }
119     
120     public int getNextToken() throws InvalidInputException {
121         if(this.pendingTokensPtr > -1) {
122             int nextToken = this.pendingTokens[this.pendingTokensPtr--];
123             if(nextToken == TerminalTokens.TokenNameIdentifier){
124                 this.fakeTokenSource = FAKE_IDENTIFIER;
125             } else {
126                 this.fakeTokenSource = CharOperation.NO_CHAR;
127             }
128             return nextToken;
129         }
130         
131         this.fakeTokenSource = null;
132         this.precededByRemoved = false;
133         
134         if(this.data.insertedTokens != null) {
135             for (int i = 0; i <= this.data.insertedTokensPtr; i++) {
136                 if(this.data.insertedTokensPosition[i] == this.currentPosition - 1 && i > skipNextInsertedTokens) {
137                     this.data.insertedTokenUsed[i] = true;
138                     this.pendingTokens = this.data.insertedTokens[i];
139                     this.pendingTokensPtr = this.data.insertedTokens[i].length - 1;
140                     this.isInserted = true;
141                     this.startPosition = this.currentPosition;
142                     this.skipNextInsertedTokens = i;
143                     int nextToken = this.pendingTokens[this.pendingTokensPtr--];
144                     if(nextToken == TerminalTokens.TokenNameIdentifier){
145                         this.fakeTokenSource = FAKE_IDENTIFIER;
146                     } else {
147                         this.fakeTokenSource = CharOperation.NO_CHAR;
148                     }
149                     return nextToken;
150                 }
151             }
152             this.skipNextInsertedTokens = -1;
153         }
154
155         int previousLocation = this.currentPosition;
156         int currentToken = super.getNextToken();
157         
158         if(this.data.replacedTokens != null) {
159             for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
160                 if(this.data.replacedTokensStart[i] >= previousLocation &&
161                         this.data.replacedTokensStart[i] <= this.startPosition &&
162                         this.data.replacedTokensEnd[i] >= this.currentPosition - 1) {
163                     this.data.replacedTokenUsed[i] = true;
164                     this.pendingTokens = this.data.replacedTokens[i];
165                     this.pendingTokensPtr = this.data.replacedTokens[i].length - 1;
166                     this.fakeTokenSource = FAKE_IDENTIFIER;
167                     this.isInserted = false;
168                     this.currentPosition = this.data.replacedTokensEnd[i] + 1;
169                     int nextToken = this.pendingTokens[this.pendingTokensPtr--];
170                     if(nextToken == TerminalTokens.TokenNameIdentifier){
171                         this.fakeTokenSource = FAKE_IDENTIFIER;
172                     } else {
173                         this.fakeTokenSource = CharOperation.NO_CHAR;
174                     }
175                     return nextToken;
176                 }
177             }
178         }
179         if(this.data.removedTokensStart != null) {
180             for (int i = 0; i <= this.data.removedTokensPtr; i++) {
181                 if(this.data.removedTokensStart[i] >= previousLocation &&
182                         this.data.removedTokensStart[i] <= this.startPosition &&
183                         this.data.removedTokensEnd[i] >= this.currentPosition - 1) {
184                     this.data.removedTokenUsed[i] = true;
185                     this.currentPosition = this.data.removedTokensEnd[i] + 1;
186                     this.precededByRemoved = false;
187                     return getNextToken();
188                 }
189             }
190         }
191         return currentToken;
192     }
193     
194     public char[] getCurrentIdentifierSource() {
195         if(this.fakeTokenSource != null) return this.fakeTokenSource;
196         return super.getCurrentIdentifierSource();
197     }
198     
199     public char[] getCurrentTokenSourceString() {
200         if(this.fakeTokenSource != null) return this.fakeTokenSource;
201         return super.getCurrentTokenSourceString();
202     }
203     
204     public char[] getCurrentTokenSource() {
205         if(this.fakeTokenSource != null) return this.fakeTokenSource;
206         return super.getCurrentTokenSource();
207     }
208     
209     public RecoveryScannerData getData() {
210         return this.data;
211     }
212     
213     public boolean isFakeToken() {
214         return this.fakeTokenSource != null;
215     }
216     
217     public boolean isInsertedToken() {
218         return this.fakeTokenSource != null && this.isInserted;
219     }
220     
221     public boolean isReplacedToken() {
222         return this.fakeTokenSource != null && !this.isInserted;
223     }
224     
225     public boolean isPrecededByRemovedToken() {
226         return this.precededByRemoved;
227     }
228     
229     public void setData(RecoveryScannerData data) {
230         if(data == null) {
231             this.data = new RecoveryScannerData();
232         } else {
233             this.data = data;
234         }
235     }
236     
237     public void setPendingTokens(int[] pendingTokens) {
238         this.pendingTokens = pendingTokens;
239         this.pendingTokensPtr = pendingTokens.length - 1;
240     }
241 }
242
Popular Tags