1 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(); 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
|