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 ecj Show documentation
Show all versions of ecj Show documentation
This is Eclipse JDT Core Batch Compiler used by Scout SDK
The newest version!
/*******************************************************************************
* Copyright (c) 2006, 2014 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.eclipse.jdt.internal.compiler.parser;
import org.eclipse.jdt.core.compiler.CharOperation;
import 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 insertTokenAhead(int token, int index) {
if(!this.record) return;
int length = this.data.insertedTokens[index].length;
int [] tokens = new int [length + 1];
System.arraycopy(this.data.insertedTokens[index], 0, tokens, 1, length);
tokens[0] = token;
this.data.insertedTokens[index] = tokens;
}
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 pendingToken = this.pendingTokens[this.pendingTokensPtr--];
if(pendingToken == TerminalTokens.TokenNameIdentifier){
this.fakeTokenSource = FAKE_IDENTIFIER;
} else {
this.fakeTokenSource = CharOperation.NO_CHAR;
}
return pendingToken;
}
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 pendingToken = this.pendingTokens[this.pendingTokensPtr--];
if(pendingToken == TerminalTokens.TokenNameIdentifier){
this.fakeTokenSource = FAKE_IDENTIFIER;
} else {
this.fakeTokenSource = CharOperation.NO_CHAR;
}
return pendingToken;
}
}
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 pendingToken = this.pendingTokens[this.pendingTokensPtr--];
if(pendingToken == TerminalTokens.TokenNameIdentifier){
this.fakeTokenSource = FAKE_IDENTIFIER;
} else {
this.fakeTokenSource = CharOperation.NO_CHAR;
}
return pendingToken;
}
}
}
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;
}
}