/**********************************************************************
 * This file is part of "Object Teams Development Tooling"-Software
 *
 * Copyright 2003, 2015 Fraunhofer Gesellschaft, Munich, Germany,
 * for its Fraunhofer Institute for Computer Architecture and Software
 * Technology (FIRST), Berlin, Germany and Technical University Berlin,
 * Germany.
 *
 * 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
 * $Id: TransformStatementsVisitor.java 23416 2010-02-03 19:59:31Z stephan $
 *
 * Please visit http://www.eclipse.org/objectteams for updates and contact.
 *
 * Contributors:
 * Fraunhofer FIRST - Initial API and implementation
 * Technical University Berlin - Initial API and implementation
 **********************************************************************/
package org.eclipse.objectteams.otdt.internal.core.compiler.statemachine.transformer;

import java.util.Stack;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.impl.CompilerOptions.WeavingScheme;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.core.exceptions.InternalCompilerError;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.ITranslationStates;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.StateHelper;
import org.eclipse.objectteams.otdt.internal.core.compiler.mappings.CallinImplementorDyn;
import org.eclipse.objectteams.otdt.internal.core.compiler.model.MethodModel;
import org.eclipse.objectteams.otdt.internal.core.compiler.smap.SourcePosition;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.AstGenerator;
import org.eclipse.objectteams.otdt.internal.core.compiler.util.TSuperHelper;


/**
 * This visitor performs several replacements within method bodies etc.
 * None of these replacements require resolved types or other non-local information.
 *
 * (1) Each tsuper(...) call -> this(..., markerArg)
 *     Works for constructor calls only.
 * (2) Adjust according to signature enhancing of callin methods:
 *     - 'recursive' calls need more arguments
 *     - return expressions need to be generalized wrt their type.
 *
 * Linking local types to role models is now in RecordLocalTypesVisitor -
 * WHY: recording local types MUST happen in any case, while TransformStatementsVisitor
 *       refuses to operate on types with ignoreFurtherInvestigation (see TypeDeclaration.traverse()).
 *
 * @author stephan
 * @version $Id: TransformStatementsVisitor.java 23416 2010-02-03 19:59:31Z stephan $
 */
public class TransformStatementsVisitor
    extends StackTransformStatementsVisitor
    implements IOTConstants
{

    // -- fields and methods for scope management ---
    private Stack<MethodDeclaration> _methodDeclarationStack = new Stack<MethodDeclaration>();
    private boolean isLocalTypeInCallin = false;

    private WeavingScheme weavingScheme;
    
    public TransformStatementsVisitor(WeavingScheme weavingScheme) {
    	this.weavingScheme = weavingScheme;
    }

    /**
     * If methodDeclaration is a callin method remember it for translating base calls.
     * Only remember methodDeclarations with ignoreFurtherInvestigation==false to
     * avoid NPEs and spurious error messages.
     *
     * @param methodDeclaration
     * @param localInCallin if the method is the enclosing (callin?) method of a local type
     */
	public void checkPushCallinMethod(AbstractMethodDeclaration methodDeclaration, boolean localInCallin) {
		if (   isGoodCallin(methodDeclaration))
		{
    		this._methodDeclarationStack.push((MethodDeclaration)methodDeclaration);
    		this.isLocalTypeInCallin = localInCallin;
		}
	}

	private boolean isGoodCallin(AbstractMethodDeclaration methodDeclaration) {
		return methodDeclaration != null
			&& !methodDeclaration.ignoreFurtherInvestigation
			&& methodDeclaration.isCallin()
			&& methodDeclaration.binding != null
			&& methodDeclaration.binding.isCallin(); // binding's callin flag was reset if callin in illegal context
	}

	protected boolean checkPopCallinMethod(AbstractMethodDeclaration currentMethod) {
		if (   !this._methodDeclarationStack.isEmpty()
			&& this._methodDeclarationStack.peek() == currentMethod)
		{
			assert currentMethod.isCallin();
			this._methodDeclarationStack.pop();
			return true;
		}
		return false;
	}

    // visit member type
    @Override
	public boolean visit (TypeDeclaration type, ClassScope scope)
    {
        if (type.isTeam())
            if (StateHelper.hasState(type.binding, ITranslationStates.STATE_STATEMENTS_TRANSFORMED))
                return false; // don't descend again
        return true;
    }

    /**
     * Within a tsuper constructor call -> add marker argument
     */
    @Override
	public boolean visit (ExplicitConstructorCall call, BlockScope scope)
    {
        if (call.isTsuperAccess())
        {
            call.arguments = TSuperHelper.addMarkerArgument(
                    null/*qualification*/, call, call.arguments, scope);
        }
        return true;
    }

    // === Adjustments following enhancement of callin method signatures:
    @Override
    public boolean visit(BaseCallMessageSend messageSend, BlockScope scope) {
    	if (!this._methodDeclarationStack.isEmpty())
    		messageSend.prepareSuperAccess(this.weavingScheme, this._methodDeclarationStack.peek(), scope);
		messageSend.bits |= ASTNode.HasBeenTransformed; // only the outer has been transformed so far.
    	return true;
    }
    
    /** May need to add arguments to a 'recursive' callin message send. */
    @Override
    public boolean visit(MessageSend messageSend, BlockScope scope) {
    	// scope is not reliable at this point due to unset scopes of block statements like "for"
    	if (this._methodDeclarationStack.isEmpty())
    		return true;
		MethodDeclaration methodDecl = this._methodDeclarationStack.peek();
    	boolean isBaseCall = messageSend.receiver instanceof BaseReference;
		if (   methodDecl.isCallin()
    		&& isRecursiveCall(methodDecl, messageSend, isBaseCall))
    	{
    		// argument enhancing within callin methods:
    		Expression[] args = messageSend.arguments;
    		if (isBaseCall) {
	    		switch (this.weavingScheme) {
	    			case OTDRE:
		    			break;
	    			case OTRE:
		    			if (args != null) {
		    				int len = args.length;
		    				if (methodDecl.isStatic()) // chop of premature isSuperAccess flag:
		    					System.arraycopy(args, 1, args=new Expression[len-1], 0, len-1);
		    			}	
	    		}
    		}
			messageSend.arguments = MethodSignatureEnhancer.enhanceArguments(args, messageSend.sourceEnd+1, this.weavingScheme);
			messageSend.bits |= ASTNode.HasBeenTransformed; // mark only when args have really been enhanced
    	}
    	return true;
    }

    /* these are considered as recursive calls: base calls, this/super/tsuper calls. */
    private boolean isRecursiveCall(MethodDeclaration callinMethod, MessageSend messageSend, boolean isBaseCall) {
    	if (!(messageSend.receiver instanceof ThisReference))
    		return false;
    	if (messageSend.receiver instanceof QualifiedThisReference)
    		return false;
    	if (!CharOperation.equals(callinMethod.selector, messageSend.selector) && !CharOperation.equals(CallinImplementorDyn.OT_CALL_NEXT, messageSend.selector))
    		return false;
    	if (callinMethod.arguments == null)
    		return false;
    	int sendArgs = messageSend.arguments == null ? 0 : messageSend.arguments.length;
    	if (this.weavingScheme == WeavingScheme.OTDRE) {
    		// is already packed in BCMS.prepareSuperAccess(), fetch number of arguments from the packed array in pos [0]
    		if (sendArgs > 0) {
    			Expression firstArg = messageSend.arguments[0];
				if (firstArg instanceof NullLiteral)
    				sendArgs = 0;
    			else if (firstArg instanceof ArrayAllocationExpression)
    				sendArgs = ((ArrayAllocationExpression) firstArg).initializer.expressions.length;
    		}
    	}
    	sendArgs += MethodSignatureEnhancer.getEnhancingArgLen(this.weavingScheme);
    	if (isBaseCall && this.weavingScheme == WeavingScheme.OTRE)
    		sendArgs--; // don't count the isSuperAccess flag
    	return sendArgs == callinMethod.arguments.length;
    }

    /** May need to 'generalize' a return expression. */
    @Override
    public boolean visit(ReturnStatement returnStatement, BlockScope scope) {
    	if (this._methodDeclarationStack.isEmpty() || this.isLocalTypeInCallin)
    		return true;
    	MethodDeclaration methodDecl = this._methodDeclarationStack.peek();
    	if (!isGoodCallin(methodDecl))
    		return true;
    	if (scope != null && scope.methodScope() != methodDecl.scope)
    		return true; // method in a nested type, not the callin itself
    	TypeBinding returnType = MethodModel.getReturnType(methodDecl.binding);
    	if (!returnType.isBaseType())
    		return true;
    	AstGenerator gen = new AstGenerator(returnStatement.sourceStart, returnStatement.sourceEnd);
    	if (returnType == TypeBinding.VOID) {
    		if (returnStatement.expression != null) {
    			if (scope == null && !this._methodDeclarationStack.isEmpty())
    				scope = this._methodDeclarationStack.peek().scope;
    			if (scope != null)
    				scope.problemReporter().attemptToReturnNonVoidExpression(returnStatement, returnType);
    			else
    				throw new InternalCompilerError("Missing scope for error reporting"); //$NON-NLS-1$
    		} else {
    			// return stored value:
    			returnStatement.expression = gen.singleNameReference(OT_RESULT);
    		}
    	}
    	return true;
    }

    @Override
    public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
    	methodDeclaration.bits |= ASTNode.HasBeenTransformed;
    	checkPushCallinMethod(methodDeclaration, false);
    	return true;
    }

    @Override
    public void endVisit(MethodDeclaration methodDecl, ClassScope scope) {
    	if (checkPopCallinMethod(methodDecl)) {
    		// assume method had no errors (else it would not have been pushed)
    		TypeBinding returnType = MethodModel.getReturnType(methodDecl.binding);
    		// return type was already adjusted by SourceTypeBinding.resolveTypesFor()->MethodSignatureEnhance.generalizeReturnType()
    		if (   returnType == TypeBinding.VOID
    			&& !methodDecl.isGenerated
    			&& !methodDecl.isCopied
    			&& !methodDecl.isAbstract())
    		{
    			AstGenerator gen = new AstGenerator(methodDecl.bodyEnd, methodDecl.bodyEnd);
    			if (methodDecl.statements == null) {
    				methodDecl.setStatements(new Statement[] {
    					gen.returnStatement(gen.nullLiteral(), true/*synthetic*/)
    				});
    			} else {
	    			// bracket body with:
	    			// Object _OT$result = null;
	    			// ... ( meanwhile a BaseCallMessageSend might assign to _OT$result )
	    			// return _OT$result;
	    			int len = methodDecl.statements.length;
	    			Statement[] newStatements = new Statement[len+2];
	    			System.arraycopy(methodDecl.statements, 0, newStatements, 1, len);

	    			//save source positions from AstGenerator (ike)
	    	    	SourcePosition savePos = gen.getSourcePosition();

	    			try {
	    				//set to first line of this method (if any)
	    				if (len > 0)
	    					gen.setSourcePosition((((long)methodDecl.statements[0].sourceStart)<<32) + methodDecl.statements[0].sourceEnd);

						//generate local variable (ike)
						newStatements[0] = gen.localVariable(OT_RESULT, scope.getJavaLangObject(), gen.nullLiteral());

	    			} finally {
	    				//restore source postions (ike)
	    				gen.setSourcePosition(savePos);
					}

	    			newStatements[len+1] = gen.returnStatement(gen.singleNameReference(OT_RESULT), true/*synthetic*/);
	    			methodDecl.setStatements(newStatements);
    			}
    		}
    	}
    	super.endVisit(methodDecl, scope);
    }

    /**
     * Cut traversal for types without a scope.
     */
    @Override
	public boolean visit(TypeDeclaration td, BlockScope scope) {
    	if((td.bits & ASTNode.IsLocalType)!=0)
    		if (td.scope == null)
    			return false; // don't descend further, local type is not in a useful state yet.

    	return true;
    }

	// Late transformation for callins within types with errors,
	// required for resilience regarding base calls.
	public static void checkTransformStatements(AbstractMethodDeclaration method)
	{
		ClassScope scope = method.scope.classScope();
		if (   scope.referenceContext.ignoreFurtherInvestigation
			&& method instanceof MethodDeclaration
			&& method.isCallin()
			&& (method.bits & ASTNode.HasBeenTransformed) == 0)
		{
			// but if class has errors the visitor bailed out.
			// need to transform before changing the selector
			method.traverse(new TransformStatementsVisitor(scope.compilerOptions().weavingScheme), scope);
		}
	}
}