/*******************************************************************************
 * 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 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.*;
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.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
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.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypes;

/**
 * Internal method structure for parsing recovery 
 */

public class RecoveredMethod extends RecoveredElement implements 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 & ~ClassFileConstants.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.IsLocalType) != 0){
		if (methodBody == null){
			Block block = new Block(0);
			block.sourceStart = methodDeclaration.bodyStart;
			this.add(block, 1);
		}
		return methodBody.add(typeDeclaration, bracketBalanceValue, true);	
	}
	switch (TypeDeclaration.kind(typeDeclaration.modifiers)) {
		case TypeDeclaration.INTERFACE_DECL :
		case TypeDeclaration.ANNOTATION_TYPE_DECL :
			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.HasLocalType;
	return methodDeclaration;
}
/*
 * Update the corresponding parse node from parser state which
 * is about to disappear because of restarting recovery
 */
public void updateFromParserState(){
	// if parent is null then recovery already occured in diet parser.
	if(this.bodyStartsAtHeaderEnd() && this.parent != null){
		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
				
				// remove unfinished annotation nodes
				MemberValuePair[] memberValuePairs = null;
				if (argLength > 0 && parser.astStack[parser.astPtr] instanceof MemberValuePair) {
					System.arraycopy(parser.astStack, argStart, memberValuePairs = new MemberValuePair[argLength], 0, argLength);
					parser.astLengthPtr--;
					parser.astPtr -= argLength;
					
					argLength = parser.astLengthStack[parser.astLengthPtr];
					argStart = parser.astPtr - argLength + 1;
					needUpdateRParenPos = true;
				}
				
				// to compute bodyStart, and thus used to set next checkpoint.
				int count;
				for (count = 0; count < argLength; count++){
					ASTNode aNode = parser.astStack[argStart+count];
					if(aNode instanceof Argument) {
						Argument argument = (Argument)aNode;
						/* cannot be an argument if non final */
						char[][] argTypeName = argument.type.getTypeName();
						if ((argument.modifiers & ~ClassFileConstants.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;
					} else {
						parser.astLengthStack[parser.astLengthPtr] = count; 
						parser.astPtr = argStart+count-1; 
						parser.listLength = count;
						parser.currentToken = 0;
						break;
					}
				}
				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.consumeMethodHeaderRightParen();
						/* 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;
						}
					}
				}
				
				if(memberValuePairs != null) {
					System.arraycopy(memberValuePairs, 0, parser.astStack, parser.astPtr + 1, memberValuePairs.length);
					parser.astPtr += memberValuePairs.length;
					parser.astLengthStack[++parser.astLengthPtr] = memberValuePairs.length;
				}
			}
		}
	}
}
public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){
	if(this.methodDeclaration.isAnnotationMethod()) {
		this.updateSourceEndIfNecessary(braceStart, braceEnd);
		if(!this.foundOpeningBrace && this.parent != null) {
			return this.parent.updateOnClosingBrace(braceStart, braceEnd);
		}
		return this;
	}
	return super.updateOnClosingBrace(braceStart, braceEnd);
}
/*
 * 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;
		}
	}
}
void attach(TypeParameter[] parameters, int startPos) {
	if(methodDeclaration.modifiers != ClassFileConstants.AccDefault) return;
	
	int lastParameterEnd = parameters[parameters.length - 1].sourceEnd;
	
	Parser parser = this.parser();
	if(parser.scanner.getLineNumber(methodDeclaration.declarationSourceStart)
			!= parser.scanner.getLineNumber(lastParameterEnd)) return;
	
	if(parser.modifiersSourceStart > lastParameterEnd
			&& parser.modifiersSourceStart < methodDeclaration.declarationSourceStart) return;
	
	if (this.methodDeclaration instanceof MethodDeclaration) {
		((MethodDeclaration)this.methodDeclaration).typeParameters = parameters;
		this.methodDeclaration.declarationSourceStart = startPos;
	} else if (this.methodDeclaration instanceof ConstructorDeclaration){
		((ConstructorDeclaration)this.methodDeclaration).typeParameters = parameters;
		this.methodDeclaration.declarationSourceStart = startPos;
	}
}
}
