/*******************************************************************************
 * Copyright (c) 2000, 2005 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.lookup;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;

public class SyntheticMethodBinding extends MethodBinding {

	public FieldBinding targetReadField;		// read access to a field
	public FieldBinding targetWriteField;		// write access to a field
	public MethodBinding targetMethod;	// method or constructor
	
	public int kind;

	public final static int FieldReadAccess = 1; 		// field read
	public final static int FieldWriteAccess = 2; 		// field write
	public final static int MethodAccess = 3; 		// normal method 
	public final static int ConstructorAccess = 4; 	// constructor
	public final static int SuperMethodAccess = 5; // super method
	public final static int BridgeMethod = 6; // bridge method
	public final static int EnumValues = 7; // enum #values()
	public final static int EnumValueOf = 8; // enum #valueOf(String)

	public int sourceStart = 0; // start position of the matching declaration
	public int index; // used for sorting access methods in the class file
	
	public SyntheticMethodBinding(FieldBinding targetField, boolean isReadAccess, ReferenceBinding declaringClass) {

		this.modifiers = AccDefault | AccStatic | AccSynthetic;
		this.tagBits |= TagBits.AnnotationResolved;
		SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
		this.selector = CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(methodId).toCharArray());
		if (isReadAccess) {
			this.returnType = targetField.type;
			if (targetField.isStatic()) {
				this.parameters = NoParameters;
			} else {
				this.parameters = new TypeBinding[1];
				this.parameters[0] = declaringSourceType;
			}
			this.targetReadField = targetField;
			this.kind = FieldReadAccess;
		} else {
			this.returnType = VoidBinding;
			if (targetField.isStatic()) {
				this.parameters = new TypeBinding[1];
				this.parameters[0] = targetField.type;
			} else {
				this.parameters = new TypeBinding[2];
				this.parameters[0] = declaringSourceType;
				this.parameters[1] = targetField.type;
			}
			this.targetWriteField = targetField;
			this.kind = FieldWriteAccess;
		}
		this.thrownExceptions = NoExceptions;
		this.declaringClass = declaringSourceType;
	
		// check for method collision
		boolean needRename;
		do {
			check : {
				needRename = false;
				// check for collision with known methods
				MethodBinding[] methods = declaringSourceType.methods;
				for (int i = 0, length = methods.length; i < length; i++) {
					if (CharOperation.equals(this.selector, methods[i].selector) && this.areParametersEqual(methods[i])) {
						needRename = true;
						break check;
					}
				}
				// check for collision with synthetic accessors
				if (knownAccessMethods != null) {
					for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
						if (knownAccessMethods[i] == null) continue;
						if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && this.areParametersEqual(methods[i])) {
							needRename = true;
							break check;
						}
					}
				}
			}
			if (needRename) { // retry with a selector postfixed by a growing methodId
				this.setSelector(CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(++methodId).toCharArray()));
			}
		} while (needRename);
	
		// retrieve sourceStart position for the target field for line number attributes
		FieldDeclaration[] fieldDecls = declaringSourceType.scope.referenceContext.fields;
		if (fieldDecls != null) {
			for (int i = 0, max = fieldDecls.length; i < max; i++) {
				if (fieldDecls[i].binding == targetField) {
					this.sourceStart = fieldDecls[i].sourceStart;
					return;
				}
			}
		}
	
	/* did not find the target field declaration - it is a synthetic one
		public class A {
			public class B {
				public class C {
					void foo() {
						System.out.println("A.this = " + A.this);
					}
				}
			}
			public static void main(String args[]) {
				new A().new B().new C().foo();
			}
		}	
	*/
		// We now at this point - per construction - it is for sure an enclosing instance, we are going to
		// show the target field type declaration location.
		this.sourceStart = declaringSourceType.scope.referenceContext.sourceStart; // use the target declaring class name position instead
	}

	public SyntheticMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
	
		if (targetMethod.isConstructor()) {
			this.initializeConstructorAccessor(targetMethod);
		} else {
			this.initializeMethodAccessor(targetMethod, isSuperAccess, receiverType);
		}
	}

	/**
	 * Construct a bridge method
	 */
	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, MethodBinding targetMethod, SourceTypeBinding declaringClass) {
		
	    this.declaringClass = declaringClass;
	    this.selector = overridenMethodToBridge.selector;
	    this.modifiers = overridenMethodToBridge.modifiers | AccBridge | AccSynthetic;
		this.tagBits |= TagBits.AnnotationResolved;
	    this.modifiers &= ~(AccAbstract | AccNative);
	    this.returnType = overridenMethodToBridge.returnType;
	    this.parameters = overridenMethodToBridge.parameters;
	    this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
	    this.targetMethod = targetMethod;
	    this.kind = BridgeMethod;
		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;	    
	}
	
	/**
	 * Construct enum special methods: values or valueOf methods
	 */
	public SyntheticMethodBinding(SourceTypeBinding declaringEnum, char[] selector) {
	    this.declaringClass = declaringEnum;
	    this.selector = selector;
	    this.modifiers = AccFinal | AccPublic | AccStatic;
		this.tagBits |= TagBits.AnnotationResolved;
	    this.thrownExceptions = NoExceptions;
		if (selector == TypeConstants.VALUES) {
		    this.returnType = declaringEnum.scope.createArrayType(declaringEnum, 1);
		    this.parameters = NoParameters;
		    this.kind = EnumValues;
		} else if (selector == TypeConstants.VALUEOF) {
		    this.returnType = declaringEnum;
		    this.parameters = new TypeBinding[]{ declaringEnum.scope.getJavaLangString() };
		    this.kind = EnumValueOf;
		}
		SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;	    
		if (declaringEnum.isStrictfp()) {
			this.modifiers |= AccStrictfp;
		}
	}

	/**
	 * An constructor accessor is a constructor with an extra argument (declaringClass), in case of
	 * collision with an existing constructor, then add again an extra argument (declaringClass again).
	 */
	 public void initializeConstructorAccessor(MethodBinding accessedConstructor) {
	
		this.targetMethod = accessedConstructor;
		this.modifiers = AccDefault | AccSynthetic;
		this.tagBits |= TagBits.AnnotationResolved;
		SourceTypeBinding sourceType = (SourceTypeBinding) accessedConstructor.declaringClass; 
		SyntheticMethodBinding[] knownSyntheticMethods = 
			sourceType.syntheticMethods(); 
		this.index = knownSyntheticMethods == null ? 0 : knownSyntheticMethods.length;
	
		this.selector = accessedConstructor.selector;
		this.returnType = accessedConstructor.returnType;
		this.kind = ConstructorAccess;
		this.parameters = new TypeBinding[accessedConstructor.parameters.length + 1];
		System.arraycopy(
			accessedConstructor.parameters, 
			0, 
			this.parameters, 
			0, 
			accessedConstructor.parameters.length); 
		parameters[accessedConstructor.parameters.length] = 
			accessedConstructor.declaringClass; 
		this.thrownExceptions = accessedConstructor.thrownExceptions;
		this.declaringClass = sourceType;
	
		// check for method collision
		boolean needRename;
		do {
			check : {
				needRename = false;
				// check for collision with known methods
				MethodBinding[] methods = sourceType.methods;
				for (int i = 0, length = methods.length; i < length; i++) {
					if (CharOperation.equals(this.selector, methods[i].selector)
						&& this.areParametersEqual(methods[i])) {
						needRename = true;
						break check;
					}
				}
				// check for collision with synthetic accessors
				if (knownSyntheticMethods != null) {
					for (int i = 0, length = knownSyntheticMethods.length; i < length; i++) {
						if (knownSyntheticMethods[i] == null)
							continue;
						if (CharOperation.equals(this.selector, knownSyntheticMethods[i].selector)
							&& this.areParametersEqual(knownSyntheticMethods[i])) {
							needRename = true;
							break check;
						}
					}
				}
			}
			if (needRename) { // retry with a new extra argument
				int length = this.parameters.length;
				System.arraycopy(
					this.parameters, 
					0, 
					this.parameters = new TypeBinding[length + 1], 
					0, 
					length); 
				this.parameters[length] = this.declaringClass;
			}
		} while (needRename);
	
		// retrieve sourceStart position for the target method for line number attributes
		AbstractMethodDeclaration[] methodDecls = 
			sourceType.scope.referenceContext.methods; 
		if (methodDecls != null) {
			for (int i = 0, length = methodDecls.length; i < length; i++) {
				if (methodDecls[i].binding == accessedConstructor) {
					this.sourceStart = methodDecls[i].sourceStart;
					return;
				}
			}
		}
	}

	/**
	 * An method accessor is a method with an access$N selector, where N is incremented in case of collisions.
	 */
	public void initializeMethodAccessor(MethodBinding accessedMethod, boolean isSuperAccess, ReferenceBinding receiverType) {
		
		this.targetMethod = accessedMethod;
		this.modifiers = AccDefault | AccStatic | AccSynthetic;
		this.tagBits |= TagBits.AnnotationResolved;
		SourceTypeBinding declaringSourceType = (SourceTypeBinding) receiverType;
		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
	
		this.selector = CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(methodId).toCharArray());
		this.returnType = accessedMethod.returnType;
		this.kind = isSuperAccess ? SuperMethodAccess : MethodAccess;
		
		if (accessedMethod.isStatic()) {
			this.parameters = accessedMethod.parameters;
		} else {
			this.parameters = new TypeBinding[accessedMethod.parameters.length + 1];
			this.parameters[0] = declaringSourceType;
			System.arraycopy(accessedMethod.parameters, 0, this.parameters, 1, accessedMethod.parameters.length);
		}
		this.thrownExceptions = accessedMethod.thrownExceptions;
		this.declaringClass = declaringSourceType;
	
		// check for method collision
		boolean needRename;
		do {
			check : {
				needRename = false;
				// check for collision with known methods
				MethodBinding[] methods = declaringSourceType.methods;
				for (int i = 0, length = methods.length; i < length; i++) {
					if (CharOperation.equals(this.selector, methods[i].selector) && this.areParametersEqual(methods[i])) {
						needRename = true;
						break check;
					}
				}
				// check for collision with synthetic accessors
				if (knownAccessMethods != null) {
					for (int i = 0, length = knownAccessMethods.length; i < length; i++) {
						if (knownAccessMethods[i] == null) continue;
						if (CharOperation.equals(this.selector, knownAccessMethods[i].selector) && this.areParametersEqual(knownAccessMethods[i])) {
							needRename = true;
							break check;
						}
					}
				}
			}
			if (needRename) { // retry with a selector & a growing methodId
				this.setSelector(CharOperation.concat(TypeConstants.SYNTHETIC_ACCESS_METHOD_PREFIX, String.valueOf(++methodId).toCharArray()));
			}
		} while (needRename);
	
		// retrieve sourceStart position for the target method for line number attributes
		AbstractMethodDeclaration[] methodDecls = declaringSourceType.scope.referenceContext.methods;
		if (methodDecls != null) {
			for (int i = 0, length = methodDecls.length; i < length; i++) {
				if (methodDecls[i].binding == accessedMethod) {
					this.sourceStart = methodDecls[i].sourceStart;
					return;
				}
			}
		}
	}

	protected boolean isConstructorRelated() {
		return kind == ConstructorAccess;
	}
}
