/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 *
 * 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
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Fraunhofer FIRST - extended API and implementation
 *     Technical University Berlin - extended API and implementation
 *		Stephan Herrmann - Contribution for
 *								bug 400710 - [1.8][compiler] synthetic access to default method generates wrong code
 *								Bug 459967 - [null] compiler should know about nullness of special methods like MyEnum.valueOf()
 *								Bug 470467 - [null] Nullness of special Enum methods not detected from .class file
 *      Andy Clement (GoPivotal, Inc) aclement@gopivotal.com - Contributions for
 *                          	Bug 405104 - [1.8][compiler][codegen] Implement support for serializeable lambdas
 *******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;

import java.util.stream.Stream;

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.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.LambdaExpression;
import org.eclipse.jdt.internal.compiler.ast.ReferenceExpression;
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.util.Util;

/**
 * OTDT changes:
 *
 * What: Changed accessor methods in teams to public
 * Why:  Role methods may depend on those accessors, copy inheritance
 *       possibly moves those methods across packages.
 *
 * @version $Id: SyntheticMethodBinding.java 23405 2010-02-03 17:02:18Z stephan $
 */
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 TypeBinding targetEnumType; 			// enum type
	public LambdaExpression lambda;
	
	/** Switch (one from many) linked to the switch table */
	public SwitchStatement switchStatement; 
	/**
	 * Method reference expression whose target FI is Serializable. Should be set when
	 * purpose is {@link #SerializableMethodReference}
	 */
	public ReferenceExpression serializableMethodRef;
	public int purpose;

	// fields used to generate enum constants when too many
	public int startIndex;
	public int endIndex;

	public final static int FieldReadAccess = 1; 		// field read
	public final static int FieldWriteAccess = 2; 		// field write
	public final static int SuperFieldReadAccess = 3; // super field read
	public final static int SuperFieldWriteAccess = 4; // super field write
	public final static int MethodAccess = 5; 		// normal method
	public final static int ConstructorAccess = 6; 	// constructor
	public final static int SuperMethodAccess = 7; // super method
	public final static int BridgeMethod = 8; // bridge method
	public final static int EnumValues = 9; // enum #values()
	public final static int EnumValueOf = 10; // enum #valueOf(String)
	public final static int SwitchTable = 11; // switch table method
	public final static int TooManyEnumsConstants = 12; // too many enum constants
	public static final int LambdaMethod = 13; // Lambda body emitted as a method.
	public final static int ArrayConstructor = 14; // X[]::new
	public static final int ArrayClone = 15; // X[]::clone
    public static final int FactoryMethod = 16; // for indy call to private constructor.
    public static final int DeserializeLambda = 17; // For supporting lambda deserialization.
    /**
     * Serves as a placeholder for a method reference whose target FI is Serializable.
     * Is never directly materialized in bytecode
     */
    public static final int SerializableMethodReference = 18;
//{ObjectTeams: other purposes:
	public final static int InferredCalloutToField = 19; // calling an inferred callout-to-field
	public final static int RoleMethodBridgeOuter = 20; // a team-level bridge method towards a private role method (for callout)
	public final static int RoleMethodBridgeInner = 21; // a role-level bridge method towards a private role method (for callout)
	public final static int MethodDecapsulation = 22;
// SH}

	public int sourceStart = 0; // start position of the matching declaration
	public int index; // used for sorting access methods in the class file
	public int fakePaddedParameters = 0; // added in synthetic constructor to avoid name clash.

//{ObjectTeams: explicit handling of line number:
	public int lineNumber = -1;
	protected void retrieveLineNumber(SourceTypeBinding sourceType) {
		int[] lineEnds = sourceType.scope.referenceContext.compilationResult.lineSeparatorPositions;
		if (lineEnds != null) // not all scanner record lineEnds
			this.lineNumber = Util.getLineNumber(this.sourceStart, lineEnds, 0, lineEnds.length-1);
	}
	public int getLineNumber() {
		if (this.copyInheritanceSrc != null)
			return ((SyntheticMethodBinding)this.copyInheritanceSrc).getLineNumber();
		return this.lineNumber;
	}
// SH}

//{ObjectTeams: for creation from binary binding:
	public SyntheticMethodBinding(MethodBinding fakedMethod, int purpose) {
		this(fakedMethod.declaringClass, fakedMethod.modifiers, fakedMethod.selector, fakedMethod.parameters, fakedMethod.returnType);
		this.targetMethod = fakedMethod;
		this.purpose = purpose;
	}
	protected SyntheticMethodBinding(ReferenceBinding declaringClass,
						   int modifiers,
						   char[] selector,
						   TypeBinding[] parameters,
						   TypeBinding returnType)
	{
		this.declaringClass = declaringClass;
		this.modifiers = modifiers;
		this.selector = selector;
		this.parameters = parameters;
		this.returnType = returnType;
		this.thrownExceptions = NO_EXCEPTIONS;
	}
	public static boolean isCalloutToStaticField(MethodBinding methodBinding) {
		if (!(methodBinding instanceof SyntheticMethodBinding))
			return false;
		SyntheticMethodBinding synthMeth = (SyntheticMethodBinding) methodBinding;
		return synthMeth.purpose == InferredCalloutToField && synthMeth.targetMethod.isStatic();
	}
	public void generateStaticCTFArgs(CodeStream codeStream, BlockScope scope, ASTNode node, int depth) {
		codeStream.iconst_0(); // dummy
		ReferenceBinding targetType = scope.enclosingSourceType().enclosingTypeAt(depth);
		Object[] emulationPath = scope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
		codeStream.generateOuterAccess(emulationPath, node, targetType, scope);
	}
// SH}

	public SyntheticMethodBinding(FieldBinding targetField, boolean isReadAccess, boolean isSuperAccess, ReferenceBinding declaringClass) {

		this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
//{ObjectTeams: different visibility for team accessors:
		if (declaringClass.isTeam())
			this.modifiers |= ClassFileConstants.AccPublic;
// SH}
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		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());

//{ObjectTeams: declaring class of the field need different parameter: role instead of team:
		TypeBinding receiverParameterType = getReceiverParameterType(targetField, declaringSourceType);
// SH}
		if (isReadAccess) {
			this.returnType = targetField.type;
			if (targetField.isStatic()) {
				this.parameters = Binding.NO_PARAMETERS;
			} else {
				this.parameters = new TypeBinding[1];
//{ObjectTeams: see above:
				this.parameters[0] = receiverParameterType;
/* orig:
				this.parameters[0] = declaringSourceType;
  :giro */
// SH}
			}
			this.targetReadField = targetField;
			this.purpose = isSuperAccess ? SyntheticMethodBinding.SuperFieldReadAccess : SyntheticMethodBinding.FieldReadAccess;
		} else {
			this.returnType = TypeBinding.VOID;
			if (targetField.isStatic()) {
				this.parameters = new TypeBinding[1];
				this.parameters[0] = targetField.type;
			} else {
				this.parameters = new TypeBinding[2];
//{ObjectTeams: see above:
				this.parameters[0] = receiverParameterType;
/* orig:
				this.parameters[0] = declaringSourceType;
  :giro */
// SH}
				this.parameters[1] = targetField.type;
			}
			this.targetWriteField = targetField;
			this.purpose = isSuperAccess ? SyntheticMethodBinding.SuperFieldWriteAccess : SyntheticMethodBinding.FieldWriteAccess;
		}
		this.thrownExceptions = Binding.NO_EXCEPTIONS;
		this.declaringClass = declaringSourceType;

		// check for method collision
		boolean needRename;
		do {
			check : {
				needRename = false;
				// check for collision with known methods
				long range;
				MethodBinding[] methods = declaringSourceType.methods();
				if ((range = ReferenceBinding.binarySearch(this.selector, methods)) >= 0) {
					int paramCount = this.parameters.length;
					nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
						MethodBinding method = methods[imethod];
						if (method.parameters.length == paramCount) {
							TypeBinding[] toMatch = method.parameters;
							for (int i = 0; i < paramCount; i++) {
								if (TypeBinding.notEquals(toMatch[i], this.parameters[i])) {
									continue nextMethod;
								}
							}
							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) && areParametersEqual(methods[i])) {
							needRename = true;
							break check;
						}
					}
				}
			}
			if (needRename) { // retry with a selector postfixed by a growing methodId
				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;
//{ObjectTeams: lineNumber:
					retrieveLineNumber(declaringSourceType);
// SH}
					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
//{ObjectTeams: lineNumber:
		retrieveLineNumber(declaringSourceType);
//SH}
	}

//{ObjectTeams: hook for SyntheticRoleFieldAccess
	protected TypeBinding getReceiverParameterType(FieldBinding targetField, ReferenceBinding declaringSourceType) {
		return declaringSourceType;
	}
// SH}

	public SyntheticMethodBinding(FieldBinding targetField, ReferenceBinding declaringClass, TypeBinding enumBinding, char[] selector,  SwitchStatement switchStatement) {
		this.modifiers = (declaringClass.isInterface() ? ClassFileConstants.AccPublic : ClassFileConstants.AccDefault) | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
//{ObjectTeams: different visibility for team accessors or synthetics in roles:
		if (declaringClass.isTeam() || declaringClass.isRole())
			this.modifiers |= ClassFileConstants.AccPublic;
// SH}
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		SourceTypeBinding declaringSourceType = (SourceTypeBinding) declaringClass;
		SyntheticMethodBinding[] knownAccessMethods = declaringSourceType.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
		this.selector = selector;
		this.returnType = declaringSourceType.scope.createArrayType(TypeBinding.INT, 1);
		this.parameters = Binding.NO_PARAMETERS;
		this.targetReadField = targetField;
		this.targetEnumType = enumBinding;
		this.purpose = SyntheticMethodBinding.SwitchTable;
		this.thrownExceptions = Binding.NO_EXCEPTIONS;
		this.declaringClass = declaringSourceType;
		this.switchStatement = switchStatement;
		if (declaringSourceType.isStrictfp()) {
			this.modifiers |= ClassFileConstants.AccStrictfp;
		}
		// check for method collision
		boolean needRename;
		do {
			check : {
				needRename = false;
				// check for collision with known methods
				long range;
				MethodBinding[] methods = declaringSourceType.methods();
				if ((range = ReferenceBinding.binarySearch(this.selector, methods)) >= 0) {
					int paramCount = this.parameters.length;
					nextMethod: for (int imethod = (int)range, end = (int)(range >> 32); imethod <= end; imethod++) {
						MethodBinding method = methods[imethod];
						if (method.parameters.length == paramCount) {
							TypeBinding[] toMatch = method.parameters;
							for (int i = 0; i < paramCount; i++) {
								if (TypeBinding.notEquals(toMatch[i], this.parameters[i])) {
									continue nextMethod;
								}
							}
							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) && areParametersEqual(methods[i])) {
							needRename = true;
							break check;
						}
					}
				}
			}
			if (needRename) { // retry with a selector postfixed by a growing methodId
				setSelector(CharOperation.concat(selector, String.valueOf(++methodId).toCharArray()));
			}
		} while (needRename);

		// 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
//{ObjectTeams: lineNumber:
		retrieveLineNumber(declaringSourceType);
// SH}
	}

	public SyntheticMethodBinding(MethodBinding targetMethod, boolean isSuperAccess, ReferenceBinding declaringClass) {

		if (targetMethod.isConstructor()) {
			initializeConstructorAccessor(targetMethod);
		} else {
			initializeMethodAccessor(targetMethod, isSuperAccess, declaringClass);
		}
//{ObjectTeams: lineNumber:
		retrieveLineNumber((SourceTypeBinding)declaringClass);
// SH}
	}

	/**
	 * Construct a bridge method
	 */
	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, MethodBinding targetMethod, SourceTypeBinding declaringClass) {

	    this.declaringClass = declaringClass;
	    this.selector = overridenMethodToBridge.selector;
	    // amongst other, clear the AccGenericSignature, so as to ensure no remains of original inherited persist (101794)
	    // also use the modifiers from the target method, as opposed to inherited one (147690)
	    this.modifiers = (targetMethod.modifiers | ClassFileConstants.AccBridge | ClassFileConstants.AccSynthetic) & ~(ClassFileConstants.AccSynchronized | ClassFileConstants.AccAbstract | ClassFileConstants.AccNative  | ClassFileConstants.AccFinal | ExtraCompilerModifiers.AccGenericSignature);
//{ObjectTeams: role class method must be public in byte code:
	    if (targetMethod.declaringClass.isRole())
	    	this.modifiers = (this.modifiers & ~ExtraCompilerModifiers.AccVisibilityMASK) | ClassFileConstants.AccPublic;
// SH}
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
	    this.returnType = overridenMethodToBridge.returnType;
	    this.parameters = overridenMethodToBridge.parameters;
	    this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
	    this.targetMethod = targetMethod;
	    this.purpose = SyntheticMethodBinding.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 = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		LookupEnvironment environment = declaringEnum.scope.environment();
	    this.thrownExceptions = Binding.NO_EXCEPTIONS;
		if (selector == TypeConstants.VALUES) {
		    this.returnType = environment.createArrayType(environment.convertToParameterizedType(declaringEnum), 1);
		    this.parameters = Binding.NO_PARAMETERS;
		    this.purpose = SyntheticMethodBinding.EnumValues;
		} else if (selector == TypeConstants.VALUEOF) {
		    this.returnType = environment.convertToParameterizedType(declaringEnum);
		    this.parameters = new TypeBinding[]{ declaringEnum.scope.getJavaLangString() };
		    this.purpose = SyntheticMethodBinding.EnumValueOf;
		}
		SyntheticMethodBinding[] knownAccessMethods = ((SourceTypeBinding)this.declaringClass).syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
		if (declaringEnum.isStrictfp()) {
			this.modifiers |= ClassFileConstants.AccStrictfp;
		}
	}
	
	/**
	 * Construct $deserializeLambda$ method
	 */
	public SyntheticMethodBinding(SourceTypeBinding declaringClass) {
		this.declaringClass = declaringClass;
		this.selector = TypeConstants.DESERIALIZE_LAMBDA;
		this.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		this.thrownExceptions = Binding.NO_EXCEPTIONS;
		this.returnType = declaringClass.scope.getJavaLangObject();
	    this.parameters = new TypeBinding[]{declaringClass.scope.getJavaLangInvokeSerializedLambda()};
	    this.purpose = SyntheticMethodBinding.DeserializeLambda;
		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, int startIndex, int endIndex) {
		this.declaringClass = declaringEnum;
		SyntheticMethodBinding[] knownAccessMethods = declaringEnum.syntheticMethods();
		this.index = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		StringBuffer buffer = new StringBuffer();
		buffer.append(TypeConstants.SYNTHETIC_ENUM_CONSTANT_INITIALIZATION_METHOD_PREFIX).append(this.index);
		this.selector = String.valueOf(buffer).toCharArray(); 
		this.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		this.purpose = SyntheticMethodBinding.TooManyEnumsConstants;
		this.thrownExceptions = Binding.NO_EXCEPTIONS;
		this.returnType = TypeBinding.VOID;
		this.parameters = Binding.NO_PARAMETERS;
		this.startIndex = startIndex;
		this.endIndex = endIndex;
	}

	// Create a synthetic method that will simply call the super classes method.
	// Used when a public method is inherited from a non-public class into a public class.
	// See https://bugs.eclipse.org/bugs/show_bug.cgi?id=288658
	// Also applies for inherited default methods with the same visibility issue.
	// See https://bugs.eclipse.org/400710
	public SyntheticMethodBinding(MethodBinding overridenMethodToBridge, SourceTypeBinding declaringClass) {

	    this.declaringClass = declaringClass;
	    this.selector = overridenMethodToBridge.selector;
	    // amongst other, clear the AccGenericSignature, so as to ensure no remains of original inherited persist (101794)
	    this.modifiers = (overridenMethodToBridge.modifiers | ClassFileConstants.AccBridge | ClassFileConstants.AccSynthetic) & ~(ClassFileConstants.AccSynchronized | ClassFileConstants.AccAbstract | ClassFileConstants.AccNative  | ClassFileConstants.AccFinal | ExtraCompilerModifiers.AccGenericSignature);
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
	    this.returnType = overridenMethodToBridge.returnType;
	    this.parameters = overridenMethodToBridge.parameters;
	    this.thrownExceptions = overridenMethodToBridge.thrownExceptions;
	    this.targetMethod = overridenMethodToBridge;
	    this.purpose = SyntheticMethodBinding.SuperMethodAccess;
		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
	}

	public SyntheticMethodBinding(int purpose, ArrayBinding arrayType, char [] selector, SourceTypeBinding declaringClass) {
	    this.declaringClass = declaringClass;
	    this.selector = selector;
	    this.modifiers = ClassFileConstants.AccSynthetic | ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
	    this.returnType = arrayType;
	    LookupEnvironment environment = declaringClass.environment;
		if (environment.globalOptions.isAnnotationBasedNullAnalysisEnabled) {
			// mark X[]::new and X[]::clone as returning 'X @NonNull' (don't wait (cf. markNonNull()), because we're called as late as codeGen):
	    	if (environment.usesNullTypeAnnotations())
	    		this.returnType = environment.createAnnotatedType(this.returnType, new AnnotationBinding[]{ environment.getNonNullAnnotation() });
	    	else
	    		this.tagBits |= TagBits.AnnotationNonNull;
	    }
	    this.parameters = new TypeBinding[] { purpose == SyntheticMethodBinding.ArrayConstructor ? TypeBinding.INT : (TypeBinding) arrayType};
	    this.thrownExceptions = Binding.NO_EXCEPTIONS;
	    this.purpose = purpose;
		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
	}

	public SyntheticMethodBinding(LambdaExpression lambda, char [] lambdaName, SourceTypeBinding declaringClass) {
		this.lambda = lambda;
	    this.declaringClass = declaringClass;
	    this.selector = lambdaName;
	    this.modifiers = lambda.binding.modifiers;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved) | (lambda.binding.tagBits & TagBits.HasParameterAnnotations);
	    this.returnType = lambda.binding.returnType;
	    this.parameters = lambda.binding.parameters;
	    TypeVariableBinding[] vars = Stream.of(this.parameters).filter(param -> param.isTypeVariable()).toArray(TypeVariableBinding[]::new);
	    if (vars != null && vars.length > 0)
	    	this.typeVariables = vars;
	    this.thrownExceptions = lambda.binding.thrownExceptions;
	    this.purpose = SyntheticMethodBinding.LambdaMethod;
		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
	}

	public SyntheticMethodBinding(ReferenceExpression ref, SourceTypeBinding declaringClass) {
		this.serializableMethodRef = ref;
	    this.declaringClass = declaringClass;
	    this.selector = ref.binding.selector;
	    this.modifiers = ref.binding.modifiers;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved) | (ref.binding.tagBits & TagBits.HasParameterAnnotations);
	    this.returnType = ref.binding.returnType;
	    this.parameters = ref.binding.parameters;
	    this.thrownExceptions = ref.binding.thrownExceptions;
	    this.purpose = SyntheticMethodBinding.SerializableMethodReference;
		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
	}

	public SyntheticMethodBinding(MethodBinding privateConstructor, MethodBinding publicConstructor, char[] selector, TypeBinding[] enclosingInstances, SourceTypeBinding declaringClass) {
	    this.declaringClass = declaringClass;
	    this.selector = selector;
	    this.modifiers = ClassFileConstants.AccSynthetic | ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
	    this.returnType = publicConstructor.declaringClass;
	
	    int realParametersLength = privateConstructor.parameters.length;
	    int enclosingInstancesLength = enclosingInstances.length;
	    int parametersLength =  enclosingInstancesLength + realParametersLength;
	    this.parameters = new TypeBinding[parametersLength];
	    System.arraycopy(enclosingInstances, 0, this.parameters, 0, enclosingInstancesLength);
	    System.arraycopy(privateConstructor.parameters, 0, this.parameters, enclosingInstancesLength, realParametersLength);
	    this.fakePaddedParameters = publicConstructor.parameters.length - realParametersLength;
	    
	    this.thrownExceptions = publicConstructor.thrownExceptions;
	    this.purpose = SyntheticMethodBinding.FactoryMethod;
	    this.targetMethod = publicConstructor;
		SyntheticMethodBinding[] knownAccessMethods = declaringClass.syntheticMethods();
		int methodId = knownAccessMethods == null ? 0 : knownAccessMethods.length;
		this.index = methodId;
	}

	/**
	 * 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 = ClassFileConstants.AccDefault | ClassFileConstants.AccSynthetic;
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		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.purpose = SyntheticMethodBinding.ConstructorAccess;
		final int parametersLength = accessedConstructor.parameters.length;
		this.parameters = new TypeBinding[parametersLength + 1];
		System.arraycopy(
			accessedConstructor.parameters,
			0,
			this.parameters,
			0,
			parametersLength);
		this.parameters[parametersLength] =
			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) && areParameterErasuresEqual(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) && areParameterErasuresEqual(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;
		if (isSuperAccess && receiverType.isInterface() && !accessedMethod.isStatic())
			this.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccSynthetic;
		else {
			if (receiverType.isInterface()) // default is not allowed. TODO: do we need a target level check here?
				this.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
			else
				this.modifiers = ClassFileConstants.AccDefault | ClassFileConstants.AccStatic | ClassFileConstants.AccSynthetic;
		}
//{ObjectTeams: different visibility for team accessors:
		if (receiverType.isTeam())
			this.modifiers |= ClassFileConstants.AccPublic;
// SH}
		this.tagBits |= (TagBits.AnnotationResolved | TagBits.DeprecatedAnnotationResolved);
		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.purpose = isSuperAccess ? SyntheticMethodBinding.SuperMethodAccess : SyntheticMethodBinding.MethodAccess;

//{ObjectTeams: is accessed role method also static?
		if (accessedMethod.needsSyntheticEnclosingTeamInstance()) { 
			this.parameters = new TypeBinding[accessedMethod.parameters.length + 2];
			this.parameters[0] = TypeBinding.INT;						// dummy
			this.parameters[1] = declaringSourceType.enclosingType();	// synth team arg
			System.arraycopy(accessedMethod.parameters, 0, this.parameters, 2, accessedMethod.parameters.length);
		} else 
// SH}
		if (accessedMethod.isStatic() || (isSuperAccess && receiverType.isInterface())) {
			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) && areParameterErasuresEqual(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) && areParameterErasuresEqual(knownAccessMethods[i])) {
							needRename = true;
							break check;
						}
					}
				}
			}
			if (needRename) { // retry with a selector & a growing methodId
				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 this.purpose == SyntheticMethodBinding.ConstructorAccess;
	}
	
	@Override
	public LambdaExpression sourceLambda() {
		return this.lambda;
	}

	public void markNonNull(LookupEnvironment environment) {
		markNonNull(this, this.purpose, environment);
	}

	static void markNonNull(MethodBinding method, int purpose, LookupEnvironment environment) {
		// deferred update of the return type
	    switch (purpose) {
			case EnumValues:
				if (environment.usesNullTypeAnnotations()) {
					TypeBinding elementType = ((ArrayBinding)method.returnType).leafComponentType();
					AnnotationBinding nonNullAnnotation = environment.getNonNullAnnotation();
					elementType = environment.createAnnotatedType(elementType, new AnnotationBinding[]{ environment.getNonNullAnnotation() });
					method.returnType = environment.createArrayType(elementType, 1, new AnnotationBinding[]{ nonNullAnnotation, null });
				} else {
					method.tagBits |= TagBits.AnnotationNonNull;
				}
				return;
			case EnumValueOf:
				if (environment.usesNullTypeAnnotations()) {
					method.returnType = environment.createAnnotatedType(method.returnType, new AnnotationBinding[]{ environment.getNonNullAnnotation() });
				} else {
					method.tagBits |= TagBits.AnnotationNonNull;
				}
				return;
		}
	}
}
