+++ /dev/null
-/*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Common Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/cpl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-package org.eclipse.jdt.internal.compiler.parser;
-
-import org.eclipse.jdt.core.compiler.*;
-import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Argument;
-import org.eclipse.jdt.internal.compiler.ast.ASTNode;
-import org.eclipse.jdt.internal.compiler.ast.Block;
-import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
-import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.Statement;
-import org.eclipse.jdt.internal.compiler.ast.SuperReference;
-import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
-import org.eclipse.jdt.internal.compiler.ast.TypeReference;
-import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;
-import org.eclipse.jdt.internal.compiler.lookup.CompilerModifiers;
-
-/**
- * Internal method structure for parsing recovery
- */
-
-public class RecoveredMethod extends RecoveredElement implements CompilerModifiers, TerminalTokens, BaseTypes {
-
- public AbstractMethodDeclaration methodDeclaration;
-
- public RecoveredType[] localTypes;
- public int localTypeCount;
-
- public RecoveredBlock methodBody;
- public boolean discardBody = true;
-
-public RecoveredMethod(AbstractMethodDeclaration methodDeclaration, RecoveredElement parent, int bracketBalance, Parser parser){
- super(parent, bracketBalance, parser);
- this.methodDeclaration = methodDeclaration;
- this.foundOpeningBrace = !bodyStartsAtHeaderEnd();
- if(this.foundOpeningBrace) {
- this.bracketBalance++;
- }
-}
-/*
- * Record a nested block declaration
- */
-public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) {
-
- /* default behavior is to delegate recording to parent if any,
- do not consider elements passed the known end (if set)
- it must be belonging to an enclosing element
- */
- if (methodDeclaration.declarationSourceEnd > 0
- && nestedBlockDeclaration.sourceStart
- > methodDeclaration.declarationSourceEnd){
- if (this.parent == null){
- return this; // ignore
- } else {
- return this.parent.add(nestedBlockDeclaration, bracketBalanceValue);
- }
- }
- /* consider that if the opening brace was not found, it is there */
- if (!foundOpeningBrace){
- foundOpeningBrace = true;
- this.bracketBalance++;
- }
-
- methodBody = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue);
- if (nestedBlockDeclaration.sourceEnd == 0) return methodBody;
- return this;
-}
-/*
- * Record a field declaration
- */
-public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) {
-
- /* local variables inside method can only be final and non void */
- char[][] fieldTypeName;
- if ((fieldDeclaration.modifiers & ~AccFinal) != 0 // local var can only be final
- || (fieldDeclaration.type == null) // initializer
- || ((fieldTypeName = fieldDeclaration.type.getTypeName()).length == 1 // non void
- && CharOperation.equals(fieldTypeName[0], VoidBinding.sourceName()))){
-
- if (this.parent == null){
- return this; // ignore
- } else {
- this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1));
- return this.parent.add(fieldDeclaration, bracketBalanceValue);
- }
- }
- /* default behavior is to delegate recording to parent if any,
- do not consider elements passed the known end (if set)
- it must be belonging to an enclosing element
- */
- if (methodDeclaration.declarationSourceEnd > 0
- && fieldDeclaration.declarationSourceStart
- > methodDeclaration.declarationSourceEnd){
- if (this.parent == null){
- return this; // ignore
- } else {
- return this.parent.add(fieldDeclaration, bracketBalanceValue);
- }
- }
- /* consider that if the opening brace was not found, it is there */
- if (!foundOpeningBrace){
- foundOpeningBrace = true;
- this.bracketBalance++;
- }
- // still inside method, treat as local variable
- return this; // ignore
-}
-/*
- * Record a local declaration - regular method should have been created a block body
- */
-public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) {
-
- /* local variables inside method can only be final and non void */
-/*
- char[][] localTypeName;
- if ((localDeclaration.modifiers & ~AccFinal) != 0 // local var can only be final
- || (localDeclaration.type == null) // initializer
- || ((localTypeName = localDeclaration.type.getTypeName()).length == 1 // non void
- && CharOperation.equals(localTypeName[0], VoidBinding.sourceName()))){
-
- if (this.parent == null){
- return this; // ignore
- } else {
- this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1));
- return this.parent.add(localDeclaration, bracketBalance);
- }
- }
-*/
- /* do not consider a type starting passed the type end (if set)
- it must be belonging to an enclosing type */
- if (methodDeclaration.declarationSourceEnd != 0
- && localDeclaration.declarationSourceStart > methodDeclaration.declarationSourceEnd){
-
- if (this.parent == null) {
- return this; // ignore
- } else {
- return this.parent.add(localDeclaration, bracketBalanceValue);
- }
- }
- if (methodBody == null){
- Block block = new Block(0);
- block.sourceStart = methodDeclaration.bodyStart;
- RecoveredElement currentBlock = this.add(block, 1);
- if (this.bracketBalance > 0){
- for (int i = 0; i < this.bracketBalance - 1; i++){
- currentBlock = currentBlock.add(new Block(0), 1);
- }
- this.bracketBalance = 1;
- }
- return currentBlock.add(localDeclaration, bracketBalanceValue);
- }
- return methodBody.add(localDeclaration, bracketBalanceValue, true);
-}
-/*
- * Record a statement - regular method should have been created a block body
- */
-public RecoveredElement add(Statement statement, int bracketBalanceValue) {
-
- /* do not consider a type starting passed the type end (if set)
- it must be belonging to an enclosing type */
- if (methodDeclaration.declarationSourceEnd != 0
- && statement.sourceStart > methodDeclaration.declarationSourceEnd){
-
- if (this.parent == null) {
- return this; // ignore
- } else {
- return this.parent.add(statement, bracketBalanceValue);
- }
- }
- if (methodBody == null){
- Block block = new Block(0);
- block.sourceStart = methodDeclaration.bodyStart;
- RecoveredElement currentBlock = this.add(block, 1);
- if (this.bracketBalance > 0){
- for (int i = 0; i < this.bracketBalance - 1; i++){
- currentBlock = currentBlock.add(new Block(0), 1);
- }
- this.bracketBalance = 1;
- }
- return currentBlock.add(statement, bracketBalanceValue);
- }
- return methodBody.add(statement, bracketBalanceValue, true);
-}
-public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) {
-
- /* do not consider a type starting passed the type end (if set)
- it must be belonging to an enclosing type */
- if (methodDeclaration.declarationSourceEnd != 0
- && typeDeclaration.declarationSourceStart > methodDeclaration.declarationSourceEnd){
-
- if (this.parent == null) {
- return this; // ignore
- }
- return this.parent.add(typeDeclaration, bracketBalanceValue);
- }
- if ((typeDeclaration.bits & ASTNode.IsLocalTypeMASK) != 0){
- if (methodBody == null){
- Block block = new Block(0);
- block.sourceStart = methodDeclaration.bodyStart;
- this.add(block, 1);
- }
- return methodBody.add(typeDeclaration, bracketBalanceValue, true);
- }
- if (typeDeclaration.isInterface()) {
- this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1));
- if (this.parent == null) {
- return this; // ignore
- }
- // close the constructor
- return this.parent.add(typeDeclaration, bracketBalanceValue);
- }
- if (localTypes == null) {
- localTypes = new RecoveredType[5];
- localTypeCount = 0;
- } else {
- if (localTypeCount == localTypes.length) {
- System.arraycopy(
- localTypes,
- 0,
- (localTypes = new RecoveredType[2 * localTypeCount]),
- 0,
- localTypeCount);
- }
- }
- RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue);
- localTypes[localTypeCount++] = element;
-
- /* consider that if the opening brace was not found, it is there */
- if (!foundOpeningBrace){
- foundOpeningBrace = true;
- this.bracketBalance++;
- }
- return element;
-}
-public boolean bodyStartsAtHeaderEnd(){
- return methodDeclaration.bodyStart == methodDeclaration.sourceEnd+1;
-}
-/*
- * Answer the associated parsed structure
- */
-public ASTNode parseTree(){
- return methodDeclaration;
-}
-/*
- * Answer the very source end of the corresponding parse node
- */
-public int sourceEnd(){
- return this.methodDeclaration.declarationSourceEnd;
-}
-public String toString(int tab) {
- StringBuffer result = new StringBuffer(tabString(tab));
- result.append("Recovered method:\n"); //$NON-NLS-1$
- this.methodDeclaration.print(tab + 1, result);
- if (this.localTypes != null) {
- for (int i = 0; i < this.localTypeCount; i++) {
- result.append("\n"); //$NON-NLS-1$
- result.append(this.localTypes[i].toString(tab + 1));
- }
- }
- if (this.methodBody != null) {
- result.append("\n"); //$NON-NLS-1$
- result.append(this.methodBody.toString(tab + 1));
- }
- return result.toString();
-}
-/*
- * Update the bodyStart of the corresponding parse node
- */
-public void updateBodyStart(int bodyStart){
- this.foundOpeningBrace = true;
- this.methodDeclaration.bodyStart = bodyStart;
-}
-public AbstractMethodDeclaration updatedMethodDeclaration(){
-
- if (methodBody != null){
- Block block = methodBody.updatedBlock();
- if (block != null){
- methodDeclaration.statements = block.statements;
-
- /* first statement might be an explict constructor call destinated to a special slot */
- if (methodDeclaration.isConstructor()) {
- ConstructorDeclaration constructor = (ConstructorDeclaration)methodDeclaration;
- if (methodDeclaration.statements != null
- && methodDeclaration.statements[0] instanceof ExplicitConstructorCall){
- constructor.constructorCall = (ExplicitConstructorCall)methodDeclaration.statements[0];
- int length = methodDeclaration.statements.length;
- System.arraycopy(
- methodDeclaration.statements,
- 1,
- (methodDeclaration.statements = new Statement[length-1]),
- 0,
- length-1);
- }
- if (constructor.constructorCall == null){ // add implicit constructor call
- constructor.constructorCall = SuperReference.implicitSuperConstructorCall();
- }
- }
- }
- }
- if (localTypeCount > 0) methodDeclaration.bits |= ASTNode.HasLocalTypeMASK;
- return methodDeclaration;
-}
-/*
- * Update the corresponding parse node from parser state which
- * is about to disappear because of restarting recovery
- */
-public void updateFromParserState(){
-
- if(this.bodyStartsAtHeaderEnd()){
- Parser parser = this.parser();
- /* might want to recover arguments or thrown exceptions */
- if (parser.listLength > 0 && parser.astLengthPtr > 0){ // awaiting interface type references
- /* has consumed the arguments - listed elements must be thrown exceptions */
- if (methodDeclaration.sourceEnd == parser.rParenPos) {
-
- // protection for bugs 15142
- int length = parser.astLengthStack[parser.astLengthPtr];
- int astPtr = parser.astPtr - length;
- boolean canConsume = astPtr >= 0;
- if(canConsume) {
- if((!(parser.astStack[astPtr] instanceof AbstractMethodDeclaration))) {
- canConsume = false;
- }
- for (int i = 1, max = length + 1; i < max; i++) {
- if(!(parser.astStack[astPtr + i ] instanceof TypeReference)) {
- canConsume = false;
- }
- }
- }
- if (canConsume){
- parser.consumeMethodHeaderThrowsClause();
- // will reset typeListLength to zero
- // thus this check will only be performed on first errorCheck after void foo() throws X, Y,
- } else {
- parser.listLength = 0;
- }
- } else {
- /* has not consumed arguments yet, listed elements must be arguments */
- if (parser.currentToken == TokenNameLPAREN || parser.currentToken == TokenNameSEMICOLON){
- /* if currentToken is parenthesis this last argument is a method/field signature */
- parser.astLengthStack[parser.astLengthPtr] --;
- parser.astPtr --;
- parser.listLength --;
- parser.currentToken = 0;
- }
- int argLength = parser.astLengthStack[parser.astLengthPtr];
- int argStart = parser.astPtr - argLength + 1;
- boolean needUpdateRParenPos = parser.rParenPos < parser.lParenPos; // 12387 : rParenPos will be used
- // to compute bodyStart, and thus used to set next checkpoint.
- int count;
- for (count = 0; count < argLength; count++){
- Argument argument = (Argument)parser.astStack[argStart+count];
- /* cannot be an argument if non final */
- char[][] argTypeName = argument.type.getTypeName();
- if ((argument.modifiers & ~AccFinal) != 0
- || (argTypeName.length == 1
- && CharOperation.equals(argTypeName[0], VoidBinding.sourceName()))){
- parser.astLengthStack[parser.astLengthPtr] = count;
- parser.astPtr = argStart+count-1;
- parser.listLength = count;
- parser.currentToken = 0;
- break;
- }
- if (needUpdateRParenPos) parser.rParenPos = argument.sourceEnd + 1;
- }
- if (parser.listLength > 0 && parser.astLengthPtr > 0){
-
- // protection for bugs 15142
- int length = parser.astLengthStack[parser.astLengthPtr];
- int astPtr = parser.astPtr - length;
- boolean canConsume = astPtr >= 0;
- if(canConsume) {
- if((!(parser.astStack[astPtr] instanceof AbstractMethodDeclaration))) {
- canConsume = false;
- }
- for (int i = 1, max = length + 1; i < max; i++) {
- if(!(parser.astStack[astPtr + i ] instanceof Argument)) {
- canConsume = false;
- }
- }
- }
- if(canConsume) {
- parser.consumeMethodHeaderParameters();
- /* fix-up positions, given they were updated against rParenPos, which did not get set */
- if (parser.currentElement == this){ // parameter addition might have added an awaiting (no return type) method - see 1FVXQZ4 */
- methodDeclaration.sourceEnd = methodDeclaration.arguments[methodDeclaration.arguments.length-1].sourceEnd;
- methodDeclaration.bodyStart = methodDeclaration.sourceEnd+1;
- parser.lastCheckPoint = methodDeclaration.bodyStart;
- }
- }
- }
- }
- }
- }
-}
-/*
- * An opening brace got consumed, might be the expected opening one of the current element,
- * in which case the bodyStart is updated.
- */
-public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){
-
- /* in case the opening brace is close enough to the signature */
- if (bracketBalance == 0){
- /*
- if (parser.scanner.searchLineNumber(methodDeclaration.sourceEnd)
- != parser.scanner.searchLineNumber(braceEnd)){
- */
- switch(parser().lastIgnoredToken){
- case -1 :
- case TokenNamethrows :
- break;
- default:
- this.foundOpeningBrace = true;
- bracketBalance = 1; // pretend the brace was already there
- }
- }
- return super.updateOnOpeningBrace(braceStart, braceEnd);
-}
-public void updateParseTree(){
- this.updatedMethodDeclaration();
-}
-/*
- * Update the declarationSourceEnd of the corresponding parse node
- */
-public void updateSourceEndIfNecessary(int braceStart, int braceEnd){
- if (this.methodDeclaration.declarationSourceEnd == 0) {
- if(parser().rBraceSuccessorStart >= braceEnd) {
- this.methodDeclaration.declarationSourceEnd = parser().rBraceEnd;
- this.methodDeclaration.bodyEnd = parser().rBraceStart;
- } else {
- this.methodDeclaration.declarationSourceEnd = braceEnd;
- this.methodDeclaration.bodyEnd = braceStart - 1;
- }
- }
-}
-}