All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aspectj.org.eclipse.jdt.internal.compiler.parser.RecoveryScanner Maven / Gradle / Ivy

Go to download

AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based @AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step. This library is a superset of AspectJ weaver and hence also of AspectJ runtime.

There is a newer version: 1.9.22.1
Show newest version
/*******************************************************************************
 * Copyright (c) 2006, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.aspectj.org.eclipse.jdt.internal.compiler.parser;

import java.util.Arrays;
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,
				scanner.previewEnabled);
		setData(data);
	}

	public RecoveryScanner(
			boolean tokenizeWhiteSpace,
			boolean checkNonExternalizedStringLiterals,
			long sourceLevel,
			long complianceLevel,
			char[][] taskTags,
			char[][] taskPriorities,
			boolean isTaskCaseSensitive,
			boolean isPreviewEnabled,
			RecoveryScannerData data) {
		super(false,
				tokenizeWhiteSpace,
				checkNonExternalizedStringLiterals,
				sourceLevel,
				complianceLevel,
				taskTags,
				taskPriorities,
				isTaskCaseSensitive,
				isPreviewEnabled);
		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 filterTokens(tokens);
	}
	public void insertTokens(int[] tokens, int completedToken, int position) {
		if(!this.record) return;
		tokens = filterTokens(tokens);
		if (tokens.length == 0)
			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;
		if (token == TerminalTokens.TokenNameRestrictedIdentifierrecord)
			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);
	}

	int[] filterTokens(int[] tokens) {
//		if (this.sourceLevel >= ClassFileConstants.JDK14)
//			return tokens;
		return Arrays.stream(tokens)
				.filter(x -> x != TerminalTokens.TokenNameRestrictedIdentifierrecord)
				.toArray();
	}
	public void replaceTokens(int[] tokens, int start, int end) {
		if(!this.record) return;
		tokens = filterTokens(tokens);
		if (tokens.length == 0)
			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;
	}

	@Override
	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;
	}

	@Override
	public char[] getCurrentIdentifierSource() {
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
		return super.getCurrentIdentifierSource();
	}

	@Override
	public char[] getCurrentTokenSourceString() {
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
		return super.getCurrentTokenSourceString();
	}

	@Override
	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;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy