package org.eclipse.jdt.internal.compiler.ast;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */
import org.eclipse.jdt.internal.compiler.*;
import org.eclipse.jdt.internal.compiler.impl.*;
import org.eclipse.jdt.internal.compiler.codegen.*;
import org.eclipse.jdt.internal.compiler.flow.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.problem.*;
import org.eclipse.jdt.internal.compiler.parser.*;

public abstract class AbstractMethodDeclaration extends AstNode implements ProblemSeverities, ReferenceContext {
	public MethodScope scope;
	//it is not relevent for constructor but it helps to have the name of the constructor here 
	//which is always the name of the class.....parsing do extra work to fill it up while it do not have to....
	public char[] selector;
	public int declarationSourceStart;
	public int declarationSourceEnd;
	public int modifiers;
	public int modifiersSourceStart;
	public Argument[] arguments;
	public TypeReference[] thrownExceptions;
	public Statement[] statements;
	public int explicitDeclarations;
	public MethodBinding binding;
	public boolean ignoreFurtherInvestigation = false;
	public boolean needFreeReturn = false;
	public LocalVariableBinding secretReturnValue;
	static final char[] SecretLocalDeclarationName = " returnValue".toCharArray(); //$NON-NLS-1$

	public int bodyStart;
	public int bodyEnd = -1;
/**
 * AbstractMethodDeclaration constructor comment.
 */
public AbstractMethodDeclaration() {
	super();
}
/*
 *	We cause the compilation task to abort to a given extent.
 */
public void abort(int abortLevel) {

	if (scope == null){
		throw new AbortCompilation(); // cannot do better
	}
	
	CompilationResult compilationResult = scope.referenceCompilationUnit().compilationResult;
	
	switch (abortLevel) {
		case AbortCompilation :
			throw new AbortCompilation(compilationResult);
		case AbortCompilationUnit :
			throw new AbortCompilationUnit(compilationResult);
		case AbortType :
			throw new AbortType(compilationResult);
		default :
			throw new AbortMethod(compilationResult);
	}
}
public void analyseCode(ClassScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {

	// starting of the code analysis for methods
	if (ignoreFurtherInvestigation)	return;
	try {
		if (binding == null) return;// may be in a non necessary <clinit> for innerclass with static final constant fields
		if (binding.isAbstract() || binding.isNative())	return;
			
		ExceptionHandlingFlowContext methodContext = new ExceptionHandlingFlowContext(flowContext, this, binding.thrownExceptions, scope, FlowInfo.DeadEnd);

		// propagate to statements
		if (statements != null) {
			for (int i = 0, count = statements.length; i < count; i++) {
				Statement stat;
				if (!flowInfo.complainIfUnreachable((stat = statements[i]), scope)) {
					flowInfo = stat.analyseCode(scope, methodContext, flowInfo);
				}
			}
		}
		// check for missing returning path
		TypeBinding returnType = binding.returnType;
		if ((returnType == VoidBinding) || isAbstract()) {
			needFreeReturn = !((flowInfo == FlowInfo.DeadEnd) || flowInfo.isFakeReachable());
		} else {
			if (flowInfo != FlowInfo.DeadEnd) {
				// special test for empty methods that should return something
				if ((statements == null) && (returnType != VoidBinding)) {
					scope.problemReporter().shouldReturn(returnType, this);
				} else {
					scope.problemReporter().shouldReturn(returnType, statements[statements.length - 1]);
				}
			}
		}
	} catch (AbortMethod e) {
		this.ignoreFurtherInvestigation = true;		
	}
}
public void bindArguments() {
	//bind and add argument's binding into the scope of the method

	if (arguments != null) {
		int length = arguments.length;
		for (int i = 0; i < length; i++) {
			Argument argument = arguments[i];
			if (argument.type != null) argument.type.binding = binding.parameters[i]; // record the resolved type into the type reference
			int modifierFlag = argument.modifiers;
			if ((argument.binding = scope.duplicateName(argument.name)) != null) {
				//the name already exist....may carry on with the first binding ....
				scope.problemReporter().redefineArgument(argument);
			} else {
				scope.addLocalVariable(argument.binding = new LocalVariableBinding(argument.name, binding.parameters[i], modifierFlag, true)); //true stand for argument instead of just local
				if (isTypeUseDeprecated(binding.parameters[i], scope))
					scope.problemReporter().deprecatedType(binding.parameters[i], argument.type);
				argument.binding.declaration = argument;
				argument.binding.used = binding.isAbstract() | binding.isNative(); // by default arguments in abstract/native methods are considered to be used (no complaint is expected)
			}
		}
	}
}
public void checkName(){
	//look if the name of the method is correct
}
public CompilationResult compilationResult(){
	return scope.referenceCompilationUnit().compilationResult;
}
/**
 * Bytecode generation for a method
 */
public void generateCode(ClassScope classScope, ClassFile classFile) {
	int problemResetPC = 0;
	if (ignoreFurtherInvestigation) {
		if (this.binding == null)
			return; // Handle methods with invalid signature or duplicates
		int problemsLength;
		IProblem[] problems = scope.referenceCompilationUnit().compilationResult.getProblems();
		IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
		classFile.addProblemMethod(this, binding, problemsCopy);
		return;
	}
	try {
		problemResetPC = classFile.contentsOffset;
		classFile.generateMethodInfoHeader(binding);
		int methodAttributeOffset = classFile.contentsOffset;
		int attributeNumber = classFile.generateMethodInfoAttribute(binding);
		if ((!binding.isNative()) && (!binding.isAbstract())) {
			int codeAttributeOffset = classFile.contentsOffset;
			classFile.generateCodeAttributeHeader();
			CodeStream codeStream = classFile.codeStream;
			codeStream.reset(this, classFile);
			// initialize local positions
			scope.computeLocalVariablePositions(binding.isStatic() ? 0 : 1, codeStream);

			// arguments initialization for local variable debug attributes
			if (arguments != null) {
				for (int i = 0, max = arguments.length; i < max; i++) {
					LocalVariableBinding argBinding;
					codeStream.addVisibleLocalVariable(argBinding = arguments[i].binding);
					argBinding.recordInitializationStartPC(0);
				}
			}
			if (statements != null) {
				for (int i = 0, max = statements.length; i < max; i++)
					statements[i].generateCode(scope, codeStream);
			}
			if (needFreeReturn) {
				codeStream.return_();
			}
			// local variable attributes
			codeStream.exitUserScope(scope);
			codeStream.recordPositionsFrom(0, this);
			classFile.completeCodeAttribute(codeAttributeOffset);
			attributeNumber++;
		}
		classFile.completeMethodInfo(methodAttributeOffset, attributeNumber);

		// if a problem got reported during code gen, then trigger problem method creation
		if (ignoreFurtherInvestigation){
			throw new AbortMethod(scope.referenceCompilationUnit().compilationResult);
		}
	} catch (AbortMethod e) {
		int problemsLength;
		IProblem[] problems = scope.referenceCompilationUnit().compilationResult.getProblems();
		IProblem[] problemsCopy = new IProblem[problemsLength = problems.length];
		System.arraycopy(problems, 0, problemsCopy, 0, problemsLength);
		classFile.addProblemMethod(this, binding, problemsCopy, problemResetPC);
	}
}
public boolean isAbstract(){

	if (binding != null) return binding.isAbstract();
	return (modifiers & AccAbstract) != 0 ;
}
public boolean isClinit() {
	return false;
}
/**
 * @return boolean
 */
public boolean isConstructor() {
	return false;
}
public boolean isDefaultConstructor() {
	return false;
}
public boolean isInitializationMethod() {
	return false;
}
public boolean isNative(){
	
	if (binding != null) return binding.isNative();
	return (modifiers & AccNative) != 0 ;
}
public boolean isStatic() {
	if (binding != null) return binding.isStatic();	
	return (modifiers & AccStatic) != 0;
}
public abstract void  parseStatements(Parser parser, CompilationUnitDeclaration unit);
	//fill up the method body with statement
public void resolve(ClassScope upperScope) {
	if (binding == null) {
		ignoreFurtherInvestigation = true;
		return;
	}

	// ========= abort on fatal error =============
	try {
		bindArguments(); //<-- shoud be done at binding/scope creation time
		checkName();

		// create secret value location
		scope.addLocalVariable(
			secretReturnValue = new LocalVariableBinding(SecretLocalDeclarationName, binding.returnType, AccDefault));
		secretReturnValue.constant = NotAConstant; // not inlinable

		// and then ....deep jump into statements.....
		if (statements != null) {
			int i = 0, length = statements.length;
			while (i < length)
				statements[i++].resolve(scope);
		}
	} catch (AbortMethod e) {
		this.ignoreFurtherInvestigation = true;		
	}
}
public String returnTypeToString(int tab) {
	/*slow code */

	return ""; //$NON-NLS-1$
}
public void tagAsHavingErrors() {
	ignoreFurtherInvestigation = true;
}
public String toString(int tab) {
	/* slow code */

	String s = tabString(tab);
	if (modifiers != AccDefault) {
		s += modifiersString(modifiers);
	}

	s += returnTypeToString(0);

	s += new String(selector) + "("; //$NON-NLS-1$
	if (arguments != null) {
		for (int i = 0; i < arguments.length; i++) {
			s += arguments[i].toString(0);
			if (i != (arguments.length - 1))
				s = s + ", "; //$NON-NLS-1$
		};
	};
	s += ")"; //$NON-NLS-1$
	if (thrownExceptions != null) {
		s += " throws "; //$NON-NLS-1$
		for (int i = 0; i < thrownExceptions.length; i++) {
			s += thrownExceptions[i].toString(0);
			if (i != (thrownExceptions.length - 1))
				s = s + ", "; //$NON-NLS-1$
		};
	};

	s += toStringStatements(tab + 1);

	return s;
}
public String toStringStatements(int tab) {
	/* slow code */

	if (isAbstract() || (this.modifiers & AccSemicolonBody) != 0) return ";"; //$NON-NLS-1$
	
	String s = " {"; //$NON-NLS-1$
	if (statements != null) {
		for (int i = 0; i < statements.length; i++){
			s = s + "\n" + statements[i].toString(tab); //$NON-NLS-1$
			if (!(statements[i] instanceof Block)){
				s += ";"; //$NON-NLS-1$
			}
		}
	}
	s += "\n" + tabString(tab == 0 ? 0 : tab - 1) + "}"; //$NON-NLS-2$ //$NON-NLS-1$
	return s;
}
public void traverse(IAbstractSyntaxTreeVisitor visitor, ClassScope classScope) {
}
}
