/*******************************************************************************
 * Copyright (c) 2000, 2015 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
 *     Stephan Herrmann - Contributions for
 *								Bug 185682 - Increment/decrement operators mark local variables as read
 *								Bug 458396 - NPE in CodeStream.invoke()
 *******************************************************************************/
package org.eclipse.jdt.internal.eval;

import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.codegen.Opcodes;
import org.eclipse.jdt.internal.compiler.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemFieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReasons;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;

public class CodeSnippetQualifiedNameReference extends QualifiedNameReference implements EvaluationConstants, ProblemReasons {

	EvaluationContext evaluationContext;
	FieldBinding delegateThis;
/**
 * CodeSnippetQualifiedNameReference constructor comment.
 * @param sources char[][]
 * @param sourceStart int
 * @param sourceEnd int
 */
public CodeSnippetQualifiedNameReference(char[][] sources, long[] positions, int sourceStart, int sourceEnd, EvaluationContext evaluationContext) {
	super(sources, positions, sourceStart, sourceEnd);
	this.evaluationContext = evaluationContext;
}

/**
 * Check and/or redirect the field access to the delegate receiver if any
 */
public TypeBinding checkFieldAccess(BlockScope scope) {
	FieldBinding fieldBinding = (FieldBinding) this.binding;
	MethodScope methodScope = scope.methodScope();
	TypeBinding declaringClass = fieldBinding.original().declaringClass;
	// check for forward references
	if ((this.indexOfFirstFieldBinding == 1 || declaringClass.isEnum())
			&& TypeBinding.equalsEquals(methodScope.enclosingSourceType(), declaringClass)
			&& methodScope.lastVisibleFieldID >= 0
			&& fieldBinding.id >= methodScope.lastVisibleFieldID
			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
		scope.problemReporter().forwardReference(this, this.indexOfFirstFieldBinding-1, fieldBinding);
	}
	this.bits &= ~ASTNode.RestrictiveFlagMASK; // clear bits
	this.bits |= Binding.FIELD;
	return getOtherFieldBindings(scope);
}

@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	int pc = codeStream.position;
	if ((this.bits & Binding.VARIABLE) == 0) { // nothing to do if type ref
		codeStream.recordPositionsFrom(pc, this.sourceStart);
		return;
	}
	FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
		super.generateCode(currentScope, codeStream, valueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScope, codeStream);
	if (lastFieldBinding != null) {
		boolean isStatic = lastFieldBinding.isStatic();
		Constant fieldConstant = lastFieldBinding.constant();
		if (fieldConstant != Constant.NotAConstant) {
			if (!isStatic){
				codeStream.invokeObjectGetClass();
				codeStream.pop();
			}
			if (valueRequired) { // inline the last field constant
				codeStream.generateConstant(fieldConstant, this.implicitConversion);
			}
		} else {
			boolean isFirst = lastFieldBinding == this.binding
											&& (this.indexOfFirstFieldBinding == 1 || TypeBinding.equalsEquals(lastFieldBinding.declaringClass, currentScope.enclosingReceiverType()))
											&& this.otherBindings == null; // could be dup: next.next.next
			TypeBinding requiredGenericCast = getGenericCast(this.otherBindings == null ? 0 : this.otherBindings.length);
			if (valueRequired
					|| (!isFirst && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4)
					|| ((this.implicitConversion & TypeIds.UNBOXING) != 0)
					|| requiredGenericCast != null) {
				int lastFieldPc = codeStream.position;
				if (lastFieldBinding.declaringClass == null) { // array length
					codeStream.arraylength();
					if (valueRequired) {
						codeStream.generateImplicitConversion(this.implicitConversion);
					} else {
						// could occur if !valueRequired but compliance >= 1.4
						codeStream.pop();
					}
				} else {
					codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
					if (requiredGenericCast != null) codeStream.checkcast(requiredGenericCast);
					if (valueRequired) {
						codeStream.generateImplicitConversion(this.implicitConversion);
					} else {
						boolean isUnboxing = (this.implicitConversion & TypeIds.UNBOXING) != 0;
						// conversion only generated if unboxing
						if (isUnboxing) codeStream.generateImplicitConversion(this.implicitConversion);
						switch (isUnboxing ? postConversionType(currentScope).id : lastFieldBinding.type.id) {
							case T_long :
							case T_double :
								codeStream.pop2();
								break;
							default :
								codeStream.pop();
						}
					}
				}

				int fieldPosition = (int) (this.sourcePositions[this.sourcePositions.length - 1] >>> 32);
				codeStream.recordPositionsFrom(lastFieldPc, fieldPosition);
			} else {
				if (!isStatic){
					codeStream.invokeObjectGetClass(); // perform null check
					codeStream.pop();
				}
			}
		}
	}
	codeStream.recordPositionsFrom(pc, this.sourceStart);
}
/**
 * Check and/or redirect the field access to the delegate receiver if any
 */
@Override
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
    FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
		super.generateAssignment(currentScope, codeStream, assignment, valueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScope, codeStream);
	codeStream.generateEmulationForField(lastFieldBinding);
	codeStream.swap();
	assignment.expression.generateCode(currentScope, codeStream, true);
	if (valueRequired) {
		switch (lastFieldBinding.type.id) {
			case TypeIds.T_long :
			case TypeIds.T_double :
				codeStream.dup2_x2();
				break;
			default :
				codeStream.dup_x2();
			break;	
		}		
	}
	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
	if (valueRequired) {
		codeStream.generateImplicitConversion(assignment.implicitConversion);
	}
}

@Override
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
    FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
		super.generateCompoundAssignment(currentScope, codeStream, expression, operator, assignmentImplicitConversion, valueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScope, codeStream);
	if (lastFieldBinding.isStatic()){
		codeStream.generateEmulationForField(lastFieldBinding);
		codeStream.swap();
		codeStream.aconst_null();
		codeStream.swap();
		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
	} else {
		codeStream.generateEmulationForField(lastFieldBinding);
		codeStream.swap();
		codeStream.dup();

		codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
	}
	// the last field access is a write access
	// perform the actual compound operation
	int operationTypeID;
	if ((operationTypeID = (this.implicitConversion & IMPLICIT_CONVERSION_MASK) >> 4) == T_JavaLangString) {
		codeStream.generateStringConcatenationAppend(currentScope, null, expression);
	} else {
		// promote the array reference to the suitable operation type
		codeStream.generateImplicitConversion(this.implicitConversion);
		// generate the increment value (will by itself  be promoted to the operation value)
		if (expression == IntLiteral.One){ // prefix operation
			codeStream.generateConstant(expression.constant, this.implicitConversion);
		} else {
			expression.generateCode(currentScope, codeStream, true);
		}
		// perform the operation
		codeStream.sendOperator(operator, operationTypeID);
		// cast the value back to the array reference type
		codeStream.generateImplicitConversion(assignmentImplicitConversion);
	}
	// actual assignment

	// current stack is:
	// field receiver value
	if (valueRequired) {
		switch (lastFieldBinding.type.id) {
			case TypeIds.T_long :
			case TypeIds.T_double :
				codeStream.dup2_x2();
				break;
			default :
				codeStream.dup_x2();
			break;	
		}
	}
	// current stack is:
	// value field receiver value
	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
}
@Override
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
    FieldBinding lastFieldBinding = this.otherBindings == null ? (FieldBinding) this.binding : this.otherBindings[this.otherBindings.length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), this, currentScope)) {
		super.generatePostIncrement(currentScope, codeStream, postIncrement, valueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScope, codeStream);
	codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
	if (valueRequired) {
		switch (lastFieldBinding.type.id) {
			case TypeIds.T_long :
			case TypeIds.T_double :
				codeStream.dup2();
				break;
			default :
				codeStream.dup();
			break;	
		}		
	}
	codeStream.generateEmulationForField(lastFieldBinding);
	if ((TypeBinding.equalsEquals(lastFieldBinding.type, TypeBinding.LONG)) || (TypeBinding.equalsEquals(lastFieldBinding.type, TypeBinding.DOUBLE))) {
		codeStream.dup_x2();
		codeStream.pop();
		if (lastFieldBinding.isStatic()) {
			codeStream.aconst_null();
		} else {
			generateReadSequence(currentScope, codeStream);
		}
		codeStream.dup_x2();
		codeStream.pop();
	} else {
		codeStream.dup_x1();
		codeStream.pop();
		if (lastFieldBinding.isStatic()) {
			codeStream.aconst_null();
		} else {
			generateReadSequence(currentScope, codeStream);
		}
		codeStream.dup_x1();
		codeStream.pop();
	}
	codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
	codeStream.sendOperator(postIncrement.operator, lastFieldBinding.type.id);
	codeStream.generateImplicitConversion(postIncrement.preAssignImplicitConversion);
	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
}

/*
 * Generate code for all bindings (local and fields) excluding the last one, which may then be generated code
 * for a read or write access.
 */
@Override
public FieldBinding generateReadSequence(BlockScope currentScope, CodeStream codeStream) {
	// determine the rank until which we now we do not need any actual value for the field access
	int otherBindingsCount = this.otherBindings == null ? 0 : this.otherBindings.length;
	boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
	FieldBinding lastFieldBinding;
	TypeBinding lastGenericCast;
	TypeBinding lastReceiverType;
	boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
	
	switch (this.bits & RestrictiveFlagMASK) {
		case Binding.FIELD :
			lastFieldBinding = ((FieldBinding) this.binding).original();
			lastGenericCast = this.genericCast;
			lastReceiverType = this.actualReceiverType;
			// if first field is actually constant, we can inline it
			if (lastFieldBinding.constant() != Constant.NotAConstant) {
				break;
			}
			if (needValue) {
				if (lastFieldBinding.canBeSeenBy(this.actualReceiverType, this, currentScope)) {
					if (!lastFieldBinding.isStatic()) {
						if ((this.bits & DepthMASK) != 0) {
							ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & DepthMASK) >> DepthSHIFT);
							Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
							codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
						} else {
							generateReceiver(codeStream);
						}
					}
				} else {
					if (!lastFieldBinding.isStatic()) {
						if ((this.bits & DepthMASK) != 0) {
							// internal error, per construction we should have found it
							// not yet supported
							currentScope.problemReporter().needImplementation(this);
						} else {
							generateReceiver(codeStream);
						}
					} else {
						codeStream.aconst_null();
					}
				}
			}
			break;
		case Binding.LOCAL : // reading the first local variable
			lastFieldBinding = null;
			lastGenericCast = null;
			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
			lastReceiverType = localBinding.type;
			if (!needValue) break; // no value needed
			// regular local variable read
			Constant localConstant = localBinding.constant();
			if (localConstant != Constant.NotAConstant) {
				codeStream.generateConstant(localConstant, 0);
				// no implicit conversion
			} else {
				// outer local?
				if ((this.bits & IsCapturedOuterLocal) != 0) {
					checkEffectiveFinality(localBinding, currentScope);
					// outer local can be reached either through a synthetic arg or a synthetic field
					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
					codeStream.generateOuterAccess(path, this, localBinding, currentScope);
				} else {
					codeStream.load(localBinding);
				}
			}
			break;
		default : // should not occur
			return null;			
	}
	// all intermediate field accesses are read accesses
	// only the last field binding is a write access
	int positionsLength = this.sourcePositions.length;
	FieldBinding initialFieldBinding = lastFieldBinding; // can be null if initial was a local binding
	if (this.otherBindings != null) {
		for (int i = 0; i < otherBindingsCount; i++) {
			int pc = codeStream.position;
			FieldBinding nextField = this.otherBindings[i].original();
			TypeBinding nextGenericCast = this.otherGenericCasts == null ? null : this.otherGenericCasts[i];
			if (lastFieldBinding != null) {
				needValue = !nextField.isStatic();
				Constant fieldConstant = lastFieldBinding.constant();
				if (fieldConstant != Constant.NotAConstant) {
					if (i > 0 && !lastFieldBinding.isStatic()) {
						codeStream.invokeObjectGetClass(); // perform null check
						codeStream.pop();
					}
					if (needValue) {
						codeStream.generateConstant(fieldConstant, 0);
					}
				} else {
					if (needValue || (i > 0 && complyTo14) || lastGenericCast != null) {
						if (lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
							MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
							if (accessor == null) {
								TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
								if (lastFieldBinding.isStatic()) {
									codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
								} else {
									codeStream.fieldAccess(Opcodes.OPC_getfield, lastFieldBinding, constantPoolDeclaringClass);
								}
							} else {
								codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
							}
						} else {
							codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
						}
						if (lastGenericCast != null) {
							codeStream.checkcast(lastGenericCast);
							lastReceiverType = lastGenericCast;
						} else {
							lastReceiverType = lastFieldBinding.type;
						}
						if (!needValue) codeStream.pop();
					} else {
						if (lastFieldBinding == initialFieldBinding) {
							if (lastFieldBinding.isStatic()){
								// if no valueRequired, still need possible side-effects of <clinit> invocation, if field belongs to different class
								if (TypeBinding.notEquals(initialFieldBinding.declaringClass, this.actualReceiverType.erasure())) {
									if (lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
										MethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[i];
										if (accessor == null) {
											TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, lastReceiverType, i == 0 && this.indexOfFirstFieldBinding == 1);
											codeStream.fieldAccess(Opcodes.OPC_getstatic, lastFieldBinding, constantPoolDeclaringClass);
										} else {
											codeStream.invoke(Opcodes.OPC_invokestatic, accessor, null /* default declaringClass */);
										}
									} else {
										codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
									}
									codeStream.pop();
								}
							}
						} else if (!lastFieldBinding.isStatic()){
							codeStream.invokeObjectGetClass(); // perform null check
							codeStream.pop();
						}
						lastReceiverType = lastFieldBinding.type;
					}
					if ((positionsLength - otherBindingsCount + i - 1) >= 0) {
						int fieldPosition = (int) (this.sourcePositions[positionsLength - otherBindingsCount + i - 1] >>>32);
						codeStream.recordPositionsFrom(pc, fieldPosition);
					}
				}
			}
			lastFieldBinding = nextField;
			lastGenericCast = nextGenericCast;
			if (lastFieldBinding != null && !lastFieldBinding.canBeSeenBy(lastReceiverType, this, currentScope)) {
				if (lastFieldBinding.isStatic()) {
					codeStream.aconst_null();
				}
			}			
		}
	}
	return lastFieldBinding;	
}


@Override
public void generateReceiver(CodeStream codeStream) {
	codeStream.aload_0();
	if (this.delegateThis != null) {
		codeStream.fieldAccess(Opcodes.OPC_getfield, this.delegateThis, null /* default declaringClass */); // delegated field access
	}
}

@Override
public TypeBinding getOtherFieldBindings(BlockScope scope) {
	// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
	int length = this.tokens.length;
	if ((this.bits & Binding.FIELD) != 0) {
		if (!((FieldBinding) this.binding).isStatic()) { //must check for the static status....
			if (this.indexOfFirstFieldBinding == 1) {
				//the field is the first token of the qualified reference....
				if (scope.methodScope().isStatic) {
					scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) this.binding);
					return null;
				}
			} else { //accessing to a field using a type as "receiver" is allowed only with static field
				scope.problemReporter().staticFieldAccessToNonStaticVariable(this, (FieldBinding) this.binding);
				return null;
			}
		}
		// only last field is actually a write access if any
		if (isFieldUseDeprecated((FieldBinding) this.binding, scope, this.indexOfFirstFieldBinding == length ? this.bits : 0)) {
			scope.problemReporter().deprecatedField((FieldBinding) this.binding, this);
		}
	}

	TypeBinding type = ((VariableBinding) this.binding).type;
	int index = this.indexOfFirstFieldBinding;
	if (index == length) { //	restrictiveFlag == FIELD
		this.constant = ((FieldBinding) this.binding).constant(scope);
		return type;
	}

	// allocation of the fieldBindings array	and its respective constants
	int otherBindingsLength = length - index;
	this.otherBindings = new FieldBinding[otherBindingsLength];

	// fill the first constant (the one of the binding)
	this.constant =((VariableBinding) this.binding).constant(scope);

	// iteration on each field
	while (index < length) {
		char[] token = this.tokens[index];
		if (type == null) return null; // could not resolve type prior to this point
		FieldBinding field = scope.getField(type, token, this);
		int place = index - this.indexOfFirstFieldBinding;
		this.otherBindings[place] = field;
		if (!field.isValidBinding()) {
			// try to retrieve the field as private field
			CodeSnippetScope localScope = new CodeSnippetScope(scope);
			if (this.delegateThis == null) {
				if (this.evaluationContext.declaringTypeName != null) {
					this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
					if (this.delegateThis == null){  // if not found then internal error, field should have been found
						return super.reportError(scope);
					}
					this.actualReceiverType = this.delegateThis.type;
				} else {
					this.constant = Constant.NotAConstant; //don't fill other constants slots...
					scope.problemReporter().invalidField(this, field, index, type);
					return null;
				}
			}
			field = localScope.getFieldForCodeSnippet(this.delegateThis.type, token, this);
			this.otherBindings[place] = field;
		}
		if (field.isValidBinding()) {
			// only last field is actually a write access if any
			if (isFieldUseDeprecated(field, scope, index+1 == length ? this.bits : 0)) {
				scope.problemReporter().deprecatedField(field, this);
			}
			// constant propagation can only be performed as long as the previous one is a constant too.
			if (this.constant != Constant.NotAConstant){
				this.constant = field.constant(scope);
			}
			type = field.type;
			index++;
		} else {
			this.constant = Constant.NotAConstant; //don't fill other constants slots...
			scope.problemReporter().invalidField(this, field, index, type);
			return null;
		}
	}
	return (this.otherBindings[otherBindingsLength - 1]).type;
}

/**
 * index is <0 to denote write access emulation
 */
@Override
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FieldBinding fieldBinding, int index, FlowInfo flowInfo) {
	// do nothing
}

/**
 * Normal field binding did not work, try to bind to a field of the delegate receiver.
 */
@Override
public TypeBinding reportError(BlockScope scope) {
	if (this.evaluationContext.declaringTypeName != null) {
		this.delegateThis = scope.getField(scope.enclosingSourceType(), DELEGATE_THIS, this);
		if (this.delegateThis == null){  // if not found then internal error, field should have been found
			return super.reportError(scope);
		}
		this.actualReceiverType = this.delegateThis.type;
	} else {
		return super.reportError(scope);
	}

	if ((this.binding instanceof ProblemFieldBinding && ((ProblemFieldBinding) this.binding).problemId() == NotFound)
		|| (this.binding instanceof ProblemBinding && ((ProblemBinding) this.binding).problemId() == NotFound)){
		// will not support innerclass emulation inside delegate
		FieldBinding fieldBinding = scope.getField(this.delegateThis.type, this.tokens[0], this);
		if (!fieldBinding.isValidBinding()) {
			if (((ProblemFieldBinding) fieldBinding).problemId() == NotVisible) {
				// manage the access to a private field of the enclosing type
				CodeSnippetScope localScope = new CodeSnippetScope(scope);
				this.binding = localScope.getFieldForCodeSnippet(this.delegateThis.type, this.tokens[0], this);
				if (this.binding.isValidBinding()) {
					return checkFieldAccess(scope);
				} else {
					return super.reportError(scope);
				}
			} else {
				return super.reportError(scope);
			}
		}
		this.binding = fieldBinding;
		return checkFieldAccess(scope);
	}

	TypeBinding result;
	if (this.binding instanceof ProblemFieldBinding && ((ProblemFieldBinding) this.binding).problemId() == NotVisible) {
		// field and/or local are done before type lookups
		// the only available value for the restrictiveFlag BEFORE
		// the TC is Flag_Type Flag_LocalField and Flag_TypeLocalField
		CodeSnippetScope localScope = new CodeSnippetScope(scope);
		if ((this.binding = localScope.getBinding(this.tokens, this.bits & RestrictiveFlagMASK, this, (ReferenceBinding) this.delegateThis.type)).isValidBinding()) {
			this.bits &= ~RestrictiveFlagMASK; // clear bits
			this.bits |= Binding.FIELD;
			result = getOtherFieldBindings(scope);
		} else {
			return super.reportError(scope);
		}
		if (result != null && result.isValidBinding()) {
			return result;
		}
	}
	return super.reportError(scope);
}
}
