/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.eval;

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.FieldReference;
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.flow.FlowInfo;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.InvocationSite;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
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.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;

public class CodeSnippetQualifiedNameReference extends QualifiedNameReference implements EvaluationConstants, InvocationSite, 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) {
	// check for forward references
	this.bits &= ~RestrictiveFlagMASK; // clear bits
	this.bits |= FIELD;
	return getOtherFieldBindings(scope);
}
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {

	generateReadSequence(currentScope, codeStream);
	if (this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
		// the last field access is a write access
		assignment.expression.generateCode(currentScope, codeStream, true);
		fieldStore(codeStream, this.lastFieldBinding, null, valueRequired);
	} else {
		((CodeSnippetCodeStream) codeStream).generateEmulationForField(this.lastFieldBinding);
		codeStream.swap();
		assignment.expression.generateCode(currentScope, codeStream, true);
		if (valueRequired) {
			if ((this.lastFieldBinding.type == LongBinding) || (this.lastFieldBinding.type == DoubleBinding)) {
				codeStream.dup2_x2();
			} else {
				codeStream.dup_x2();
			}
		}
		((CodeSnippetCodeStream) codeStream).generateEmulatedWriteAccessForField(this.lastFieldBinding);	
	}
	if (valueRequired) {
		codeStream.generateImplicitConversion(assignment.implicitConversion);
	}
}
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	int pc = codeStream.position;
	if (this.constant != NotAConstant) {
		if (valueRequired) {
			codeStream.generateConstant(this.constant, this.implicitConversion);
		}
	} else {
		generateReadSequence(currentScope, codeStream); 
		if (valueRequired) {
			if (this.lastFieldBinding.declaringClass == null) { // array length
				codeStream.arraylength();
				codeStream.generateImplicitConversion(this.implicitConversion);
			} else {
				if (this.lastFieldBinding.constant != NotAConstant) {
					if (!this.lastFieldBinding.isStatic()){
						codeStream.invokeObjectGetClass();
						codeStream.pop();
					}
					// inline the last field constant
					codeStream.generateConstant(this.lastFieldBinding.constant, this.implicitConversion);
				} else {	
					if (this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
						if (this.lastFieldBinding.isStatic()) {
							codeStream.getstatic(this.lastFieldBinding);
						} else {
							codeStream.getfield(this.lastFieldBinding);
						}
					} else {
						((CodeSnippetCodeStream) codeStream).generateEmulatedReadAccessForField(this.lastFieldBinding);
					}	
					codeStream.generateImplicitConversion(this.implicitConversion);
				}
			}
		} else {
			if (this.lastFieldBinding != null && !this.lastFieldBinding.isStatic()){
				codeStream.invokeObjectGetClass(); // perform null check
				codeStream.pop();
			}
		}		
	}
	codeStream.recordPositionsFrom(pc, this.sourceStart);
}
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) {
	
	generateReadSequence(currentScope, codeStream);
	if (this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
		if (this.lastFieldBinding.isStatic()){
			codeStream.getstatic(this.lastFieldBinding);
		} else {
			codeStream.dup();
			codeStream.getfield(this.lastFieldBinding);
		}
		// the last field access is a write access
		// perform the actual compound operation
		int operationTypeID;
		if ((operationTypeID = this.implicitConversion >> 4) == T_String) {
			codeStream.generateStringAppend(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
		fieldStore(codeStream, this.lastFieldBinding, null, valueRequired);
	} else {
		if (this.lastFieldBinding.isStatic()){
			((CodeSnippetCodeStream) codeStream).generateEmulationForField(this.lastFieldBinding);
			codeStream.swap();
			codeStream.aconst_null();
			codeStream.swap();

			((CodeSnippetCodeStream) codeStream).generateEmulatedReadAccessForField(this.lastFieldBinding);
		} else {
			((CodeSnippetCodeStream) codeStream).generateEmulationForField(this.lastFieldBinding);
			codeStream.swap();
			codeStream.dup();

			((CodeSnippetCodeStream) codeStream).generateEmulatedReadAccessForField(this.lastFieldBinding);
		}
		// the last field access is a write access
		// perform the actual compound operation
		int operationTypeID;
		if ((operationTypeID = this.implicitConversion >> 4) == T_String) {
			codeStream.generateStringAppend(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) {
			if ((this.lastFieldBinding.type == LongBinding) || (this.lastFieldBinding.type == DoubleBinding)) {
				codeStream.dup2_x2();
			} else {
				codeStream.dup_x2();
			}
		}
		// current stack is:
		// value field receiver value				
		((CodeSnippetCodeStream) codeStream).generateEmulatedWriteAccessForField(this.lastFieldBinding);
	}
}
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) {
	generateReadSequence(currentScope, codeStream);

	if (this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
		if (this.lastFieldBinding.isStatic()){
			codeStream.getstatic(this.lastFieldBinding);
		} else {
			codeStream.dup();
			codeStream.getfield(this.lastFieldBinding);
		}	
		// duplicate the old field value
		if (valueRequired) {
			if (this.lastFieldBinding.isStatic()) {
				if ((this.lastFieldBinding.type == LongBinding) || (this.lastFieldBinding.type == DoubleBinding)) {
					codeStream.dup2();
				} else {
					codeStream.dup();
				}
			} else { // Stack:  [owner][old field value]  ---> [old field value][owner][old field value]
				if ((this.lastFieldBinding.type == LongBinding) || (this.lastFieldBinding.type == DoubleBinding)) {
					codeStream.dup2_x1();
				} else {
					codeStream.dup_x1();
				}
			}
		}
		codeStream.generateConstant(postIncrement.expression.constant, this.implicitConversion);
		codeStream.sendOperator(postIncrement.operator, this.lastFieldBinding.type.id);
		codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
		
		fieldStore(codeStream, this.lastFieldBinding, null, false);
	} else {
		((CodeSnippetCodeStream) codeStream).generateEmulatedReadAccessForField(this.lastFieldBinding);
		if (valueRequired) {
			if ((this.lastFieldBinding.type == LongBinding) || (this.lastFieldBinding.type == DoubleBinding)) {
				codeStream.dup2();
			} else {
				codeStream.dup();
			}
		}
		((CodeSnippetCodeStream) codeStream).generateEmulationForField(this.lastFieldBinding);
		if ((this.lastFieldBinding.type == LongBinding) || (this.lastFieldBinding.type == DoubleBinding)) {
			codeStream.dup_x2();
			codeStream.pop();
			if (this.lastFieldBinding.isStatic()) {
				codeStream.aconst_null();
			} else {
				generateReadSequence(currentScope, codeStream);
			}
			codeStream.dup_x2();
			codeStream.pop();					
		} else {
			codeStream.dup_x1();
			codeStream.pop();
			if (this.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, this.lastFieldBinding.type.id);
		codeStream.generateImplicitConversion(postIncrement.assignmentImplicitConversion);
		((CodeSnippetCodeStream) codeStream).generateEmulatedWriteAccessForField(this.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.
 */
public void 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.otherCodegenBindings == null ? 0 : this.otherCodegenBindings.length;

	boolean needValue = otherBindingsCount == 0 || !this.otherBindings[0].isStatic();
	switch (this.bits & RestrictiveFlagMASK) {
		case FIELD :
			this.lastFieldBinding = (FieldBinding) this.codegenBinding;
			// if first field is actually constant, we can inline it
			if (this.lastFieldBinding.constant != NotAConstant) {
				break;
			}
			if (needValue) {
				if (this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
					if (!this.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*/);
							if (emulationPath == null) {
								// internal error, per construction we should have found it
								currentScope.problemReporter().needImplementation();
							} else {
								codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
							}
						} else {
							generateReceiver(codeStream);
						}
					}
				} else {
					if (!this.lastFieldBinding.isStatic()) {
						if ((this.bits & DepthMASK) != 0) {
							// internal error, per construction we should have found it
							// not yet supported
							currentScope.problemReporter().needImplementation();
						} else {
							generateReceiver(codeStream);
						}
					} else {
						codeStream.aconst_null();
					}
				}				
			}
			break;
		case LOCAL : // reading the first local variable
			if (!needValue) break; // no value needed
			this.lastFieldBinding = null;
			LocalVariableBinding localBinding = (LocalVariableBinding) this.codegenBinding;
			// regular local variable read
			if (localBinding.constant != NotAConstant) {
				codeStream.generateConstant(localBinding.constant, 0);
				// no implicit conversion
			} else {
				// outer local?
				if ((this.bits & DepthMASK) != 0) {
					// outer local can be reached either through a synthetic arg or a synthetic field
					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
					if (path == null) {
						// emulation was not possible (should not happen per construction)
						currentScope.problemReporter().needImplementation();
					} else {
						codeStream.generateOuterAccess(path, this, localBinding, currentScope);
					}
				} else {
					codeStream.load(localBinding);
				}
			}
	}

	// all intermediate field accesses are read accesses
	// only the last field binding is a write access
	if (this.otherCodegenBindings != null) {
		for (int i = 0; i < otherBindingsCount; i++) {
			FieldBinding nextField = this.otherCodegenBindings[i];
			if (this.lastFieldBinding != null) {
				needValue = !nextField.isStatic();
				if (needValue) {
					if (this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
						if (this.lastFieldBinding.constant != NotAConstant) {
							if (this.lastFieldBinding != this.codegenBinding && !this.lastFieldBinding.isStatic()) {
								codeStream.invokeObjectGetClass(); // perform null check
								codeStream.pop();
							}
							codeStream.generateConstant(this.lastFieldBinding.constant, 0);
						} else if (this.lastFieldBinding.isStatic()) {
							codeStream.getstatic(this.lastFieldBinding);
						} else {
							codeStream.getfield(this.lastFieldBinding);
						}
					} else {
						((CodeSnippetCodeStream) codeStream).generateEmulatedReadAccessForField(this.lastFieldBinding);
					}
				} else {
					if (this.codegenBinding != this.lastFieldBinding && !this.lastFieldBinding.isStatic()){
						codeStream.invokeObjectGetClass(); // perform null check
						codeStream.pop();
					}						
				}
			}
			this.lastFieldBinding = nextField;
			if (this.lastFieldBinding != null && !this.lastFieldBinding.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
				if (this.lastFieldBinding.isStatic()) {
					codeStream.aconst_null();
				}
			}
		}			
	}
}

public void generateReceiver(CodeStream codeStream) {
	codeStream.aload_0();
	if (this.delegateThis != null) {
		codeStream.getfield(this.delegateThis); // delegated field access
	}
}
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 & 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.bits & IsStrictlyAssignedMASK) !=0 && this.indexOfFirstFieldBinding == length)) {
			scope.problemReporter().deprecatedField((FieldBinding) this.binding, this);
		}
	}

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

	// allocation of the fieldBindings array	and its respective constants
	int otherBindingsLength = length - index;
	this.otherCodegenBindings = this.otherBindings = new FieldBinding[otherBindingsLength];
	
	// fill the first constant (the one of the binding)
	this.constant =
		((this.bits & FIELD) != 0)
			? FieldReference.getConstantFor((FieldBinding) this.binding, this, false, scope)
			: ((VariableBinding) this.binding).constant;

	// 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);
					}
				} else {
					this.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, (this.bits & IsStrictlyAssignedMASK) !=0 && index+1 == length)) {
				scope.problemReporter().deprecatedField(field, this);
			}
			Constant someConstant = FieldReference.getConstantFor(field, this, false, scope);
			// constant propagation can only be performed as long as the previous one is a constant too.
			if (this.constant != NotAConstant){
				this.constant = someConstant;
			}
			type = field.type;
			index++;
		} else {
			this.constant = NotAConstant; //don't fill other constants slots...
			scope.problemReporter().invalidField(this, field, index, type);
			return null;
		}
	}
	return (this.otherBindings[otherBindingsLength - 1]).type;
}
/**
 * Check and/or redirect the field access to the delegate receiver if any
 */
public TypeBinding getReceiverType(BlockScope currentScope) {
	if (this.receiverType != null) return this.receiverType;
	Scope scope = currentScope.parent;
	while (true) {
			switch (scope.kind) {
				case Scope.CLASS_SCOPE :
					return this.receiverType = ((ClassScope) scope).referenceContext.binding;
				default:
					scope = scope.parent;
			}
	}
}
		
	public void manageSyntheticReadAccessIfNecessary(
		BlockScope currentScope,
		FieldBinding fieldBinding,
		TypeBinding lastReceiverType,
		int index,
		FlowInfo flowInfo) {

		if (!flowInfo.isReachable()) return;
	

		// if the binding declaring class is not visible, need special action
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
		boolean useDelegate = index == 0 && this.delegateThis != null;
		if (useDelegate) {
			lastReceiverType = this.delegateThis.type;
		}
		if (fieldBinding.declaringClass != lastReceiverType
			&& !lastReceiverType.isArrayType()			
			&& fieldBinding.declaringClass != null
			&& fieldBinding.constant == NotAConstant
			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
					&& (index > 0 || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
					&& fieldBinding.declaringClass.id != T_Object)
				|| !(useDelegate
						? new CodeSnippetScope(currentScope).canBeSeenByForCodeSnippet(fieldBinding.declaringClass, (ReferenceBinding) this.delegateThis.type)
						: fieldBinding.declaringClass.canBeSeenBy(currentScope)))){
			if (index == 0){
				this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType);
			} else {
				if (this.otherCodegenBindings == this.otherBindings){
					int l = this.otherBindings.length;
					System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l);
				}
				this.otherCodegenBindings[index-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType);
			}
		}
	}
	/*
	 * No need to emulate access to protected fields since not implicitly accessed
	 */
	public void manageSyntheticWriteAccessIfNecessary(
		BlockScope currentScope,
		FieldBinding fieldBinding,
		TypeBinding lastReceiverType,
		FlowInfo flowInfo) {

		if (!flowInfo.isReachable()) return;
	
		// if the binding declaring class is not visible, need special action
		// for runtime compatibility on 1.2 VMs : change the declaring class of the binding
		// NOTE: from target 1.2 on, field's declaring class is touched if any different from receiver type
		boolean useDelegate = fieldBinding == this.binding && this.delegateThis != null;
		if (useDelegate) {
			lastReceiverType = this.delegateThis.type;
		}
		if (fieldBinding.declaringClass != lastReceiverType
			&& !lastReceiverType.isArrayType()			
			&& fieldBinding.declaringClass != null
			&& fieldBinding.constant == NotAConstant
			&& ((currentScope.environment().options.targetJDK >= ClassFileConstants.JDK1_2
					&& (fieldBinding != this.binding || this.indexOfFirstFieldBinding > 1 || !fieldBinding.isStatic())
					&& fieldBinding.declaringClass.id != T_Object)
				|| !(useDelegate
						? new CodeSnippetScope(currentScope).canBeSeenByForCodeSnippet(fieldBinding.declaringClass, (ReferenceBinding) this.delegateThis.type)
						: fieldBinding.declaringClass.canBeSeenBy(currentScope)))){
			if (fieldBinding == this.binding){
				this.codegenBinding = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType);
			} else {
				if (this.otherCodegenBindings == this.otherBindings){
					int l = this.otherBindings.length;
					System.arraycopy(this.otherBindings, 0, this.otherCodegenBindings = new FieldBinding[l], 0, l);
				}
				this.otherCodegenBindings[this.otherCodegenBindings.length-1] = currentScope.enclosingSourceType().getUpdatedFieldBinding(fieldBinding, (ReferenceBinding)lastReceiverType);
			}
		}
	}

/**
 * Normal field binding did not work, try to bind to a field of the delegate receiver.
 */
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);
		}
	} 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.codegenBinding = 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.codegenBinding = this.binding = fieldBinding;
		return checkFieldAccess(scope);
	}

	TypeBinding result;
	if (this.binding instanceof ProblemFieldBinding
		&& ((ProblemFieldBinding) this.binding).problemId() == NotVisible) {
		result = resolveTypeVisibility(scope);
		if (result == null) {
			return super.reportError(scope);
		}
		if (result.isValidBinding()) {
			return result;
		}
	}

	return super.reportError(scope);
}
public TypeBinding resolveTypeVisibility(BlockScope scope) {
	// 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.codegenBinding = this.binding = localScope.getBinding(this.tokens, this.bits & RestrictiveFlagMASK, this, (ReferenceBinding) this.delegateThis.type)).isValidBinding()) {
		this.bits &= ~RestrictiveFlagMASK; // clear bits
		this.bits |= FIELD;
		return getOtherFieldBindings(scope);
	}
	//========error cases===============
	return super.reportError(scope);
}
}
