org.aspectj.org.eclipse.jdt.internal.compiler.parser.RecoveryScanner Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
Tools from the AspectJ project
/*******************************************************************************
* Copyright (c) 2006, 2012 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.compiler.parser;
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.core.compiler.InvalidInputException;
public class RecoveryScanner extends Scanner {
public static final char[] FAKE_IDENTIFIER = "$missing$".toCharArray(); //$NON-NLS-1$
private RecoveryScannerData data;
private int[] pendingTokens;
private int pendingTokensPtr = -1;
private char[] fakeTokenSource = null;
private boolean isInserted = true;
private boolean precededByRemoved = false;
private int skipNextInsertedTokens = -1;
public boolean record = true;
public RecoveryScanner(Scanner scanner, RecoveryScannerData data) {
super(false,
scanner.tokenizeWhiteSpace,
scanner.checkNonExternalizedStringLiterals,
scanner.sourceLevel,
scanner.complianceLevel,
scanner.taskTags,
scanner.taskPriorities,
scanner.isTaskCaseSensitive);
setData(data);
}
public RecoveryScanner(
boolean tokenizeWhiteSpace,
boolean checkNonExternalizedStringLiterals,
long sourceLevel,
long complianceLevel,
char[][] taskTags,
char[][] taskPriorities,
boolean isTaskCaseSensitive,
RecoveryScannerData data) {
super(false,
tokenizeWhiteSpace,
checkNonExternalizedStringLiterals,
sourceLevel,
complianceLevel,
taskTags,
taskPriorities,
isTaskCaseSensitive);
setData(data);
}
public void insertToken(int token, int completedToken, int position) {
insertTokens(new int []{token}, completedToken, position);
}
private int[] reverse(int[] tokens) {
int length = tokens.length;
for(int i = 0, max = length / 2; i < max; i++) {
int tmp = tokens[i];
tokens[i] = tokens[length - i - 1];
tokens[length - i - 1] = tmp;
}
return tokens;
}
public void insertTokens(int[] tokens, int completedToken, int position) {
if(!this.record) return;
if(completedToken > -1 && Parser.statements_recovery_filter[completedToken] != 0) return;
this.data.insertedTokensPtr++;
if(this.data.insertedTokens == null) {
this.data.insertedTokens = new int[10][];
this.data.insertedTokensPosition = new int[10];
this.data.insertedTokenUsed = new boolean[10];
} else if(this.data.insertedTokens.length == this.data.insertedTokensPtr) {
int length = this.data.insertedTokens.length;
System.arraycopy(this.data.insertedTokens, 0, this.data.insertedTokens = new int[length * 2][], 0, length);
System.arraycopy(this.data.insertedTokensPosition, 0, this.data.insertedTokensPosition = new int[length * 2], 0, length);
System.arraycopy(this.data.insertedTokenUsed, 0, this.data.insertedTokenUsed = new boolean[length * 2], 0, length);
}
this.data.insertedTokens[this.data.insertedTokensPtr] = reverse(tokens);
this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
}
public void replaceTokens(int token, int start, int end) {
replaceTokens(new int []{token}, start, end);
}
public void replaceTokens(int[] tokens, int start, int end) {
if(!this.record) return;
this.data.replacedTokensPtr++;
if(this.data.replacedTokensStart == null) {
this.data.replacedTokens = new int[10][];
this.data.replacedTokensStart = new int[10];
this.data.replacedTokensEnd = new int[10];
this.data.replacedTokenUsed= new boolean[10];
} else if(this.data.replacedTokensStart.length == this.data.replacedTokensPtr) {
int length = this.data.replacedTokensStart.length;
System.arraycopy(this.data.replacedTokens, 0, this.data.replacedTokens = new int[length * 2][], 0, length);
System.arraycopy(this.data.replacedTokensStart, 0, this.data.replacedTokensStart = new int[length * 2], 0, length);
System.arraycopy(this.data.replacedTokensEnd, 0, this.data.replacedTokensEnd = new int[length * 2], 0, length);
System.arraycopy(this.data.replacedTokenUsed, 0, this.data.replacedTokenUsed = new boolean[length * 2], 0, length);
}
this.data.replacedTokens[this.data.replacedTokensPtr] = reverse(tokens);
this.data.replacedTokensStart[this.data.replacedTokensPtr] = start;
this.data.replacedTokensEnd[this.data.replacedTokensPtr] = end;
this.data.replacedTokenUsed[this.data.replacedTokensPtr] = false;
}
public void removeTokens(int start, int end) {
if(!this.record) return;
this.data.removedTokensPtr++;
if(this.data.removedTokensStart == null) {
this.data.removedTokensStart = new int[10];
this.data.removedTokensEnd = new int[10];
this.data.removedTokenUsed = new boolean[10];
} else if(this.data.removedTokensStart.length == this.data.removedTokensPtr) {
int length = this.data.removedTokensStart.length;
System.arraycopy(this.data.removedTokensStart, 0, this.data.removedTokensStart = new int[length * 2], 0, length);
System.arraycopy(this.data.removedTokensEnd, 0, this.data.removedTokensEnd = new int[length * 2], 0, length);
System.arraycopy(this.data.removedTokenUsed, 0, this.data.removedTokenUsed = new boolean[length * 2], 0, length);
}
this.data.removedTokensStart[this.data.removedTokensPtr] = start;
this.data.removedTokensEnd[this.data.removedTokensPtr] = end;
this.data.removedTokenUsed[this.data.removedTokensPtr] = false;
}
protected int getNextToken0() throws InvalidInputException {
if(this.pendingTokensPtr > -1) {
int nextToken = this.pendingTokens[this.pendingTokensPtr--];
if(nextToken == TerminalTokens.TokenNameIdentifier){
this.fakeTokenSource = FAKE_IDENTIFIER;
} else {
this.fakeTokenSource = CharOperation.NO_CHAR;
}
return nextToken;
}
this.fakeTokenSource = null;
this.precededByRemoved = false;
if(this.data.insertedTokens != null) {
for (int i = 0; i <= this.data.insertedTokensPtr; i++) {
if(this.data.insertedTokensPosition[i] == this.currentPosition - 1 && i > this.skipNextInsertedTokens) {
this.data.insertedTokenUsed[i] = true;
this.pendingTokens = this.data.insertedTokens[i];
this.pendingTokensPtr = this.data.insertedTokens[i].length - 1;
this.isInserted = true;
this.startPosition = this.currentPosition;
this.skipNextInsertedTokens = i;
int nextToken = this.pendingTokens[this.pendingTokensPtr--];
if(nextToken == TerminalTokens.TokenNameIdentifier){
this.fakeTokenSource = FAKE_IDENTIFIER;
} else {
this.fakeTokenSource = CharOperation.NO_CHAR;
}
return nextToken;
}
}
this.skipNextInsertedTokens = -1;
}
int previousLocation = this.currentPosition;
int currentToken = super.getNextToken0();
if(this.data.replacedTokens != null) {
for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
if(this.data.replacedTokensStart[i] >= previousLocation &&
this.data.replacedTokensStart[i] <= this.startPosition &&
this.data.replacedTokensEnd[i] >= this.currentPosition - 1) {
this.data.replacedTokenUsed[i] = true;
this.pendingTokens = this.data.replacedTokens[i];
this.pendingTokensPtr = this.data.replacedTokens[i].length - 1;
this.fakeTokenSource = FAKE_IDENTIFIER;
this.isInserted = false;
this.currentPosition = this.data.replacedTokensEnd[i] + 1;
int nextToken = this.pendingTokens[this.pendingTokensPtr--];
if(nextToken == TerminalTokens.TokenNameIdentifier){
this.fakeTokenSource = FAKE_IDENTIFIER;
} else {
this.fakeTokenSource = CharOperation.NO_CHAR;
}
return nextToken;
}
}
}
if(this.data.removedTokensStart != null) {
for (int i = 0; i <= this.data.removedTokensPtr; i++) {
if(this.data.removedTokensStart[i] >= previousLocation &&
this.data.removedTokensStart[i] <= this.startPosition &&
this.data.removedTokensEnd[i] >= this.currentPosition - 1) {
this.data.removedTokenUsed[i] = true;
this.currentPosition = this.data.removedTokensEnd[i] + 1;
this.precededByRemoved = false;
return getNextToken0();
}
}
}
return currentToken;
}
public char[] getCurrentIdentifierSource() {
if(this.fakeTokenSource != null) return this.fakeTokenSource;
return super.getCurrentIdentifierSource();
}
public char[] getCurrentTokenSourceString() {
if(this.fakeTokenSource != null) return this.fakeTokenSource;
return super.getCurrentTokenSourceString();
}
public char[] getCurrentTokenSource() {
if(this.fakeTokenSource != null) return this.fakeTokenSource;
return super.getCurrentTokenSource();
}
public RecoveryScannerData getData() {
return this.data;
}
public boolean isFakeToken() {
return this.fakeTokenSource != null;
}
public boolean isInsertedToken() {
return this.fakeTokenSource != null && this.isInserted;
}
public boolean isReplacedToken() {
return this.fakeTokenSource != null && !this.isInserted;
}
public boolean isPrecededByRemovedToken() {
return this.precededByRemoved;
}
public void setData(RecoveryScannerData data) {
if(data == null) {
this.data = new RecoveryScannerData();
} else {
this.data = data;
}
}
public void setPendingTokens(int[] pendingTokens) {
this.pendingTokens = pendingTokens;
this.pendingTokensPtr = pendingTokens.length - 1;
}
}