/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.jdt.core.source_3.7.1.v_B76_R37x/org/eclipse/jdt/internal/compiler/parser/RecoveryScanner.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus · Java · 261 lines · 221 code · 30 blank · 10 comment · 60 complexity · 31d4c2bad7ca44fbe985a26367782286 MD5 · raw file

  1. /*******************************************************************************
  2. * Copyright (c) 2006, 2009 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.compiler.parser;
  12. import org.eclipse.jdt.core.compiler.CharOperation;
  13. import org.eclipse.jdt.core.compiler.InvalidInputException;
  14. public class RecoveryScanner extends Scanner {
  15. public static final char[] FAKE_IDENTIFIER = "$missing$".toCharArray(); //$NON-NLS-1$
  16. private RecoveryScannerData data;
  17. private int[] pendingTokens;
  18. private int pendingTokensPtr = -1;
  19. private char[] fakeTokenSource = null;
  20. private boolean isInserted = true;
  21. private boolean precededByRemoved = false;
  22. private int skipNextInsertedTokens = -1;
  23. public boolean record = true;
  24. public RecoveryScanner(Scanner scanner, RecoveryScannerData data) {
  25. super(false,
  26. scanner.tokenizeWhiteSpace,
  27. scanner.checkNonExternalizedStringLiterals,
  28. scanner.sourceLevel,
  29. scanner.complianceLevel,
  30. scanner.taskTags,
  31. scanner.taskPriorities,
  32. scanner.isTaskCaseSensitive);
  33. setData(data);
  34. }
  35. public RecoveryScanner(
  36. boolean tokenizeWhiteSpace,
  37. boolean checkNonExternalizedStringLiterals,
  38. long sourceLevel,
  39. long complianceLevel,
  40. char[][] taskTags,
  41. char[][] taskPriorities,
  42. boolean isTaskCaseSensitive,
  43. RecoveryScannerData data) {
  44. super(false,
  45. tokenizeWhiteSpace,
  46. checkNonExternalizedStringLiterals,
  47. sourceLevel,
  48. complianceLevel,
  49. taskTags,
  50. taskPriorities,
  51. isTaskCaseSensitive);
  52. setData(data);
  53. }
  54. public void insertToken(int token, int completedToken, int position) {
  55. insertTokens(new int []{token}, completedToken, position);
  56. }
  57. private int[] reverse(int[] tokens) {
  58. int length = tokens.length;
  59. for(int i = 0, max = length / 2; i < max; i++) {
  60. int tmp = tokens[i];
  61. tokens[i] = tokens[length - i - 1];
  62. tokens[length - i - 1] = tmp;
  63. }
  64. return tokens;
  65. }
  66. public void insertTokens(int[] tokens, int completedToken, int position) {
  67. if(!this.record) return;
  68. if(completedToken > -1 && Parser.statements_recovery_filter[completedToken] != 0) return;
  69. this.data.insertedTokensPtr++;
  70. if(this.data.insertedTokens == null) {
  71. this.data.insertedTokens = new int[10][];
  72. this.data.insertedTokensPosition = new int[10];
  73. this.data.insertedTokenUsed = new boolean[10];
  74. } else if(this.data.insertedTokens.length == this.data.insertedTokensPtr) {
  75. int length = this.data.insertedTokens.length;
  76. System.arraycopy(this.data.insertedTokens, 0, this.data.insertedTokens = new int[length * 2][], 0, length);
  77. System.arraycopy(this.data.insertedTokensPosition, 0, this.data.insertedTokensPosition = new int[length * 2], 0, length);
  78. System.arraycopy(this.data.insertedTokenUsed, 0, this.data.insertedTokenUsed = new boolean[length * 2], 0, length);
  79. }
  80. this.data.insertedTokens[this.data.insertedTokensPtr] = reverse(tokens);
  81. this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
  82. this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
  83. }
  84. public void replaceTokens(int token, int start, int end) {
  85. replaceTokens(new int []{token}, start, end);
  86. }
  87. public void replaceTokens(int[] tokens, int start, int end) {
  88. if(!this.record) return;
  89. this.data.replacedTokensPtr++;
  90. if(this.data.replacedTokensStart == null) {
  91. this.data.replacedTokens = new int[10][];
  92. this.data.replacedTokensStart = new int[10];
  93. this.data.replacedTokensEnd = new int[10];
  94. this.data.replacedTokenUsed= new boolean[10];
  95. } else if(this.data.replacedTokensStart.length == this.data.replacedTokensPtr) {
  96. int length = this.data.replacedTokensStart.length;
  97. System.arraycopy(this.data.replacedTokens, 0, this.data.replacedTokens = new int[length * 2][], 0, length);
  98. System.arraycopy(this.data.replacedTokensStart, 0, this.data.replacedTokensStart = new int[length * 2], 0, length);
  99. System.arraycopy(this.data.replacedTokensEnd, 0, this.data.replacedTokensEnd = new int[length * 2], 0, length);
  100. System.arraycopy(this.data.replacedTokenUsed, 0, this.data.replacedTokenUsed = new boolean[length * 2], 0, length);
  101. }
  102. this.data.replacedTokens[this.data.replacedTokensPtr] = reverse(tokens);
  103. this.data.replacedTokensStart[this.data.replacedTokensPtr] = start;
  104. this.data.replacedTokensEnd[this.data.replacedTokensPtr] = end;
  105. this.data.replacedTokenUsed[this.data.replacedTokensPtr] = false;
  106. }
  107. public void removeTokens(int start, int end) {
  108. if(!this.record) return;
  109. this.data.removedTokensPtr++;
  110. if(this.data.removedTokensStart == null) {
  111. this.data.removedTokensStart = new int[10];
  112. this.data.removedTokensEnd = new int[10];
  113. this.data.removedTokenUsed = new boolean[10];
  114. } else if(this.data.removedTokensStart.length == this.data.removedTokensPtr) {
  115. int length = this.data.removedTokensStart.length;
  116. System.arraycopy(this.data.removedTokensStart, 0, this.data.removedTokensStart = new int[length * 2], 0, length);
  117. System.arraycopy(this.data.removedTokensEnd, 0, this.data.removedTokensEnd = new int[length * 2], 0, length);
  118. System.arraycopy(this.data.removedTokenUsed, 0, this.data.removedTokenUsed = new boolean[length * 2], 0, length);
  119. }
  120. this.data.removedTokensStart[this.data.removedTokensPtr] = start;
  121. this.data.removedTokensEnd[this.data.removedTokensPtr] = end;
  122. this.data.removedTokenUsed[this.data.removedTokensPtr] = false;
  123. }
  124. public int getNextToken() throws InvalidInputException {
  125. if(this.pendingTokensPtr > -1) {
  126. int nextToken = this.pendingTokens[this.pendingTokensPtr--];
  127. if(nextToken == TerminalTokens.TokenNameIdentifier){
  128. this.fakeTokenSource = FAKE_IDENTIFIER;
  129. } else {
  130. this.fakeTokenSource = CharOperation.NO_CHAR;
  131. }
  132. return nextToken;
  133. }
  134. this.fakeTokenSource = null;
  135. this.precededByRemoved = false;
  136. if(this.data.insertedTokens != null) {
  137. for (int i = 0; i <= this.data.insertedTokensPtr; i++) {
  138. if(this.data.insertedTokensPosition[i] == this.currentPosition - 1 && i > this.skipNextInsertedTokens) {
  139. this.data.insertedTokenUsed[i] = true;
  140. this.pendingTokens = this.data.insertedTokens[i];
  141. this.pendingTokensPtr = this.data.insertedTokens[i].length - 1;
  142. this.isInserted = true;
  143. this.startPosition = this.currentPosition;
  144. this.skipNextInsertedTokens = i;
  145. int nextToken = this.pendingTokens[this.pendingTokensPtr--];
  146. if(nextToken == TerminalTokens.TokenNameIdentifier){
  147. this.fakeTokenSource = FAKE_IDENTIFIER;
  148. } else {
  149. this.fakeTokenSource = CharOperation.NO_CHAR;
  150. }
  151. return nextToken;
  152. }
  153. }
  154. this.skipNextInsertedTokens = -1;
  155. }
  156. int previousLocation = this.currentPosition;
  157. int currentToken = super.getNextToken();
  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. public char[] getCurrentIdentifierSource() {
  194. if(this.fakeTokenSource != null) return this.fakeTokenSource;
  195. return super.getCurrentIdentifierSource();
  196. }
  197. public char[] getCurrentTokenSourceString() {
  198. if(this.fakeTokenSource != null) return this.fakeTokenSource;
  199. return super.getCurrentTokenSourceString();
  200. }
  201. public char[] getCurrentTokenSource() {
  202. if(this.fakeTokenSource != null) return this.fakeTokenSource;
  203. return super.getCurrentTokenSource();
  204. }
  205. public RecoveryScannerData getData() {
  206. return this.data;
  207. }
  208. public boolean isFakeToken() {
  209. return this.fakeTokenSource != null;
  210. }
  211. public boolean isInsertedToken() {
  212. return this.fakeTokenSource != null && this.isInserted;
  213. }
  214. public boolean isReplacedToken() {
  215. return this.fakeTokenSource != null && !this.isInserted;
  216. }
  217. public boolean isPrecededByRemovedToken() {
  218. return this.precededByRemoved;
  219. }
  220. public void setData(RecoveryScannerData data) {
  221. if(data == null) {
  222. this.data = new RecoveryScannerData();
  223. } else {
  224. this.data = data;
  225. }
  226. }
  227. public void setPendingTokens(int[] pendingTokens) {
  228. this.pendingTokens = pendingTokens;
  229. this.pendingTokensPtr = pendingTokens.length - 1;
  230. }
  231. }