Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2013 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 Jesper S Moller <jesper@selskabet.org> - Contributions for bug 378674 - "The method can be declared as static" is wrong /
 
 package org.eclipse.jdt.internal.eval;
 
This scope is used for code snippet lookup to emulate private, protected and default access. These accesses inside inner classes are not managed yet.
 
 public class CodeSnippetScope extends BlockScope {
CodeSnippetScope constructor comment.

Parameters:
kind int
parent org.eclipse.jdt.internal.compiler.lookup.Scope
 
 protected CodeSnippetScope(int kindScope parent) {
 	super(kindparent);
 }
CodeSnippetScope constructor comment.

Parameters:
parent org.eclipse.jdt.internal.compiler.lookup.BlockScope
 
 public CodeSnippetScope(BlockScope parent) {
 	super(parent);
 }
CodeSnippetScope constructor comment.

Parameters:
parent org.eclipse.jdt.internal.compiler.lookup.BlockScope
variableCount int
 
 public CodeSnippetScope(BlockScope parentint variableCount) {
 	super(parentvariableCount);
 }
 /* Answer true if the receiver is visible to the type provided by the scope.
 * InvocationSite implements isSuperAccess() to provide additional information
 * if the receiver is protected.
 *
 * NOTE: Cannot invoke this method with a compilation unit scope.
 */
 
 public final boolean canBeSeenByForCodeSnippet(FieldBinding fieldBindingTypeBinding receiverTypeInvocationSite invocationSiteScope scope) {
 	if (fieldBinding.isPublic()) return true;
 
 	ReferenceBinding invocationType = (ReferenceBindingreceiverType;
 	if (invocationType == fieldBinding.declaringClassreturn true;
 
 	if (fieldBinding.isProtected()) {
 		// answer true if the invocationType is the declaringClass or they are in the same package
 		// OR the invocationType is a subclass of the declaringClass
 		//    AND the receiverType is the invocationType or its subclass
 		//    OR the field is a static field accessed directly through a type
 		if (invocationType == fieldBinding.declaringClassreturn true;
 		if (invocationType.fPackage == fieldBinding.declaringClass.fPackagereturn true;
 		if (fieldBinding.declaringClass.isSuperclassOf(invocationType)) {
 			if (invocationSite.isSuperAccess()) return true;
 			// receiverType can be an array binding in one case... see if you can change it
 			if (receiverType instanceof ArrayBinding)
 				return false;
 			if (invocationType.isSuperclassOf((ReferenceBindingreceiverType))
 				return true;
 			if (fieldBinding.isStatic())
 				return true// see 1FMEPDL - return invocationSite.isTypeAccess();
 		}
 		return false;
 	}
 
 	if (fieldBinding.isPrivate()) {
 		// answer true if the receiverType is the declaringClass
 		// AND the invocationType and the declaringClass have a common enclosingType
 		if (receiverType != fieldBinding.declaringClassreturn false;
		if (invocationType != fieldBinding.declaringClass) {
			ReferenceBinding outerInvocationType = invocationType;
			ReferenceBinding temp = outerInvocationType.enclosingType();
			while (temp != null) {
				outerInvocationType = temp;
				temp = temp.enclosingType();
			}
			ReferenceBinding outerDeclaringClass = fieldBinding.declaringClass;
			temp = outerDeclaringClass.enclosingType();
			while (temp != null) {
				outerDeclaringClass = temp;
				temp = temp.enclosingType();
			}
			if (outerInvocationType != outerDeclaringClassreturn false;
		}
		return true;
	}
	// isDefault()
	if (invocationType.fPackage != fieldBinding.declaringClass.fPackagereturn false;
	// receiverType can be an array binding in one case... see if you can change it
	if (receiverType instanceof ArrayBinding)
		return false;
	ReferenceBinding type = (ReferenceBindingreceiverType;
	PackageBinding declaringPackage = fieldBinding.declaringClass.fPackage;
	TypeBinding originalDeclaringClass = fieldBinding.declaringClass .original();
	do {
		if (type.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
			if (originalDeclaringClass == type.erasure().original()) return true;	
else {
			if (originalDeclaringClass == type.original()) return true;
		}
		if (declaringPackage != type.fPackagereturn false;
while ((type = type.superclass()) != null);
	return false;
/* Answer true if the receiver is visible to the type provided by the scope.
* InvocationSite implements isSuperAccess() to provide additional information
* if the receiver is protected.
* NOTE: Cannot invoke this method with a compilation unit scope.
*/
public final boolean canBeSeenByForCodeSnippet(MethodBinding methodBindingTypeBinding receiverTypeInvocationSite invocationSiteScope scope) {
	if (methodBinding.isPublic()) return true;
	ReferenceBinding invocationType = (ReferenceBindingreceiverType;
	if (invocationType == methodBinding.declaringClassreturn true;
	if (methodBinding.isProtected()) {
		// answer true if the invocationType is the declaringClass or they are in the same package
		// OR the invocationType is a subclass of the declaringClass
		//    AND the receiverType is the invocationType or its subclass
		//    OR the method is a static method accessed directly through a type
		if (invocationType == methodBinding.declaringClassreturn true;
		if (invocationType.fPackage == methodBinding.declaringClass.fPackagereturn true;
		if (methodBinding.declaringClass.isSuperclassOf(invocationType)) {
			if (invocationSite.isSuperAccess()) return true;
			// receiverType can be an array binding in one case... see if you can change it
			if (receiverType instanceof ArrayBinding)
				return false;
			if (invocationType.isSuperclassOf((ReferenceBindingreceiverType))
				return true;
			if (methodBinding.isStatic())
				return true// see 1FMEPDL - return invocationSite.isTypeAccess();
		}
		return false;
	}
	if (methodBinding.isPrivate()) {
		// answer true if the receiverType is the declaringClass
		// AND the invocationType and the declaringClass have a common enclosingType
		if (receiverType != methodBinding.declaringClassreturn false;
		if (invocationType != methodBinding.declaringClass) {
			ReferenceBinding outerInvocationType = invocationType;
			ReferenceBinding temp = outerInvocationType.enclosingType();
			while (temp != null) {
				outerInvocationType = temp;
				temp = temp.enclosingType();
			}
			ReferenceBinding outerDeclaringClass = methodBinding.declaringClass;
			temp = outerDeclaringClass.enclosingType();
			while (temp != null) {
				outerDeclaringClass = temp;
				temp = temp.enclosingType();
			}
			if (outerInvocationType != outerDeclaringClassreturn false;
		}
		return true;
	}
	// isDefault()
	if (invocationType.fPackage != methodBinding.declaringClass.fPackagereturn false;
	// receiverType can be an array binding in one case... see if you can change it
	if (receiverType instanceof ArrayBinding)
		return false;
	ReferenceBinding type = (ReferenceBindingreceiverType;
	PackageBinding declaringPackage = methodBinding.declaringClass.fPackage;
	TypeBinding originalDeclaringClass = methodBinding.declaringClass .original();
	do {
		if (type.isCapture()) { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=285002
			if (originalDeclaringClass == type.erasure().original()) return true;
else {
			if (originalDeclaringClass == type.original()) return true;
		}
		if (declaringPackage != type.fPackagereturn false;
while ((type = type.superclass()) != null);
	return false;
/* Answer true if the receiver is visible to the type provided by the scope.
* InvocationSite implements isSuperAccess() to provide additional information
* if the receiver is protected.
* NOTE: Cannot invoke this method with a compilation unit scope.
*/
public final boolean canBeSeenByForCodeSnippet(ReferenceBinding referenceBindingReferenceBinding receiverType) {
	if (referenceBinding.isPublic()) return true;
	if (receiverType == referenceBindingreturn true;
	if (referenceBinding.isProtected()) {
		// answer true if the receiver (or its enclosing type) is the superclass
		//	of the receiverType or in the same package
		return receiverType.fPackage == referenceBinding.fPackage
				|| referenceBinding.isSuperclassOf(receiverType)
				|| referenceBinding.enclosingType().isSuperclassOf(receiverType); // protected types always have an enclosing one
	}
	if (referenceBinding.isPrivate()) {
		// answer true if the receiver and the receiverType have a common enclosingType
		// already know they are not the identical type
		ReferenceBinding outerInvocationType = receiverType;
		ReferenceBinding temp = outerInvocationType.enclosingType();
		while (temp != null) {
			outerInvocationType = temp;
			temp = temp.enclosingType();
		}
		ReferenceBinding outerDeclaringClass = referenceBinding;
		temp = outerDeclaringClass.enclosingType();
		while (temp != null) {
			outerDeclaringClass = temp;
			temp = temp.enclosingType();
		}
		return outerInvocationType == outerDeclaringClass;
	}
	// isDefault()
	return receiverType.fPackage == referenceBinding.fPackage;
// Internal use only
public MethodBinding findExactMethod(ReferenceBinding receiverTypechar[] selectorTypeBinding[] argumentTypesInvocationSite invocationSite) {
	MethodBinding exactMethod = receiverType.getExactMethod(selectorargumentTypesnull);
	if (exactMethod != null){
		if (receiverType.isInterface() || canBeSeenByForCodeSnippet(exactMethodreceiverTypeinvocationSitethis))
			return exactMethod;
	}
	return null;
// Internal use only
/*	Answer the field binding that corresponds to fieldName.
	Start the lookup at the receiverType.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered field is visible.
	Only fields defined by the receiverType or its supertypes are answered;
	a field of an enclosing type will not be found using this API.
	If no visible field is discovered, null is answered.
*/
public FieldBinding findFieldForCodeSnippet(TypeBinding receiverTypechar[] fieldNameInvocationSite invocationSite) {
	if (receiverType.isBaseType())
		return null;
	if (receiverType.isArrayType()) {
		TypeBinding leafType = receiverType.leafComponentType();
		if (leafType instanceof ReferenceBinding)
		if (!((ReferenceBinding)leafType).canBeSeenBy(this)) {
		}
		if (CharOperation.equals(fieldName.))
		return null;
	}
	ReferenceBinding currentType = (ReferenceBindingreceiverType;
	if (!currentType.canBeSeenBy(this))
		return new ProblemFieldBinding(currentTypefieldName.);
	FieldBinding field = currentType.getField(fieldNametrue /*resolve*/);
	if (field != null) {
		if (canBeSeenByForCodeSnippet(fieldcurrentTypeinvocationSitethis))
			return field;
		else
			return new ProblemFieldBinding(field /* closest match*/field.declaringClassfieldName.);
	}
	// collect all superinterfaces of receiverType until the field is found in a supertype
	ReferenceBinding[][] interfacesToVisit = null;
	int lastPosition = -1;
	FieldBinding visibleField = null;
	boolean keepLooking = true;
	boolean notVisible = false// we could hold onto the not visible field for extra error reporting
	while (keepLooking) {
		ReferenceBinding[] itsInterfaces = currentType.superInterfaces();
		if (itsInterfaces != .) {
			if (interfacesToVisit == null)
				interfacesToVisit = new ReferenceBinding[5][];
			if (++lastPosition == interfacesToVisit.length)
				System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
			interfacesToVisit[lastPosition] = itsInterfaces;
		}
		if ((currentType = currentType.superclass()) == null)
			break;
		if ((field = currentType.getField(fieldNametrue /*resolve*/)) != null) {
			keepLooking = false;
			if (canBeSeenByForCodeSnippet(fieldreceiverTypeinvocationSitethis)) {
				if (visibleField == null)
					visibleField = field;
				else
					return new ProblemFieldBinding(visibleFieldvisibleField.declaringClassfieldName.);
else {
				notVisible = true;
			}
		}
	}
	// walk all visible interfaces to find ambiguous references
	if (interfacesToVisit != null) {
		ProblemFieldBinding ambiguous = null;
		org.eclipse.jdt.internal.compiler.util.SimpleSet interfacesSeen = new org.eclipse.jdt.internal.compiler.util.SimpleSet(lastPosition * 2);
		done : for (int i = 0; i <= lastPositioni++) {
			ReferenceBinding[] interfaces = interfacesToVisit[i];
			for (int j = 0, length = interfaces.lengthj < lengthj++) {
				ReferenceBinding anInterface = interfaces[j];
				if (interfacesSeen.addIfNotIncluded(anInterface) == anInterface) {
					// if interface as not already been visited
					if ((field = anInterface.getField(fieldNametrue /*resolve*/)) != null) {
						if (visibleField == null) {
							visibleField = field;
else {
							ambiguous = new ProblemFieldBinding(visibleFieldvisibleField.declaringClassfieldName.);
							break done;
						}
else {
						ReferenceBinding[] itsInterfaces = anInterface.superInterfaces();
						if (itsInterfaces != .) {
							if (++lastPosition == interfacesToVisit.length)
								System.arraycopy(interfacesToVisit, 0, interfacesToVisit = new ReferenceBinding[lastPosition * 2][], 0, lastPosition);
							interfacesToVisit[lastPosition] = itsInterfaces;
						}
					}
				}
			}
		}
		if (ambiguous != nullreturn ambiguous;
	}
	if (visibleField != null)
		return visibleField;
	if (notVisible)
		return new ProblemFieldBinding(currentTypefieldName.);
	return null;
// Internal use only
public MethodBinding findMethod(ReferenceBinding receiverTypechar[] selectorTypeBinding[] argumentTypesInvocationSite invocationSite) {
	MethodBinding methodBinding = super.findMethod(receiverTypeselectorargumentTypesinvocationSite);
	if (methodBinding != null && methodBinding.isValidBinding())
		if (!canBeSeenByForCodeSnippet(methodBindingreceiverTypeinvocationSitethis))
			return new ProblemMethodBinding(methodBindingselectorargumentTypes.);
	return methodBinding;
// Internal use only
public MethodBinding findMethodForArray(ArrayBinding receiverTypechar[] selectorTypeBinding[] argumentTypesInvocationSite invocationSite) {
	MethodBinding methodBinding = object.getExactMethod(selectorargumentTypesnull);
	if (methodBinding != null) {
		// handle the method clone() specially... cannot be protected or throw exceptions
		if (argumentTypes == . && CharOperation.equals(selector.))
			return new MethodBinding((methodBinding.modifiers & ~.) | ..methodBinding.returnTypeargumentTypesnullobject);
		if (canBeSeenByForCodeSnippet(methodBindingreceiverTypeinvocationSitethis))
			return methodBinding;
	}
	// answers closest approximation, may not check argumentTypes or visibility
	methodBinding = findMethod(objectselectorargumentTypesinvocationSite);
	if (methodBinding == null)
		return new ProblemMethodBinding(selectorargumentTypes.);
	if (methodBinding.isValidBinding()) {
	    MethodBinding compatibleMethod = computeCompatibleMethod(methodBindingargumentTypesinvocationSite);
	    if (compatibleMethod == null)
			return new ProblemMethodBinding(methodBindingselectorargumentTypes.);
	    methodBinding = compatibleMethod;
		if (!canBeSeenByForCodeSnippet(methodBindingreceiverTypeinvocationSitethis))
			return new ProblemMethodBinding(methodBindingselectormethodBinding.parameters.);
	}
	return methodBinding;
/* API
	flag is a mask of the following values VARIABLE (= FIELD or LOCAL), TYPE.
	Only bindings corresponding to the mask will be answered.
	if the VARIABLE mask is set then
		If the first name provided is a field (or local) then the field (or local) is answered
		Otherwise, package names and type names are consumed until a field is found.
		In this case, the field is answered.
	if the TYPE mask is set,
		package names and type names are consumed until the end of the input.
		Only if all of the input is consumed is the type answered
	All other conditions are errors, and a problem binding is returned.
	NOTE: If a problem binding is returned, senders should extract the compound name
	from the binding & not assume the problem applies to the entire compoundName.
	The VARIABLE mask has precedence over the TYPE mask.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered field is visible.
		setFieldIndex(int); this is used to record the number of names that were consumed.
	For example, getBinding({"foo","y","q", VARIABLE, site) will answer
	the binding for the field or local named "foo" (or an error binding if none exists).
	In addition, setFieldIndex(1) will be sent to the invocation site.
	If a type named "foo" exists, it will not be detected (and an error binding will be answered)
	IMPORTANT NOTE: This method is written under the assumption that compoundName is longer than length 1.
*/
public Binding getBinding(char[][] compoundNameint maskInvocationSite invocationSiteReferenceBinding receiverType) {
	Binding binding = getBinding(compoundName[0], mask | . | .invocationSitetrue /*resolve*/);
	invocationSite.setFieldIndex(1);
	if (!binding.isValidBinding() || binding instanceof VariableBinding)
		return binding;
	int length = compoundName.length;
	int currentIndex = 1;
	foundType: if (binding instanceof PackageBinding) {
		PackageBinding packageBinding = (PackageBindingbinding;
		while (currentIndex < length) {
			binding = packageBinding.getTypeOrPackage(compoundName[currentIndex++]);
			invocationSite.setFieldIndex(currentIndex);
 			if (binding == null) {
	 			if (currentIndex == length// must be a type if its the last name, otherwise we have no idea if its a package or type
					return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null.);
				else
					return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), .);
 			}
 			if (binding instanceof ReferenceBinding) {
	 			if (!binding.isValidBinding())
									CharOperation.subarray(compoundName, 0, currentIndex),
									binding.problemId());
	 			if (!this.canBeSeenByForCodeSnippet((ReferenceBindingbindingreceiverType))
					return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), (ReferenceBindingbinding.);
	 			break foundType;
 			}
 			packageBinding = (PackageBindingbinding;
		}
		// It is illegal to request a PACKAGE from this method.
		return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, currentIndex), null.);
	}
	// know binding is now a ReferenceBinding
	while (currentIndex < length) {
		ReferenceBinding typeBinding = (ReferenceBindingbinding;
		char[] nextName = compoundName[currentIndex++];
		invocationSite.setFieldIndex(currentIndex);
		if ((binding = findFieldForCodeSnippet(typeBindingnextNameinvocationSite)) != null) {
			if (!binding.isValidBinding()) {
				return new ProblemFieldBinding(
						(FieldBinding)binding,
						CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
						binding.problemId());
			}
			break// binding is now a field
		}
		if ((binding = findMemberType(nextNametypeBinding)) == null)
			return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), typeBinding.);
		 if (!binding.isValidBinding())
								CharOperation.subarray(compoundName, 0, currentIndex),
								binding.problemId());
	}
	if ((mask & .) != 0 && (binding instanceof FieldBinding)) { // was looking for a field and found a field
		FieldBinding field = (FieldBindingbinding;
		if (!field.isStatic()) {
			return new ProblemFieldBinding(
					field,
					field.declaringClass,
					CharOperation.concatWith(CharOperation.subarray(compoundName, 0, currentIndex), '.'),
		}
		// Since a qualified reference must be for a static member, it won't affect static-ness of the enclosing method, 
		// so we don't have to call resetEnclosingMethodStaticFlag() in this case
		return binding;
	}
	if ((mask & .) != 0 && (binding instanceof ReferenceBinding)) { // was looking for a type and found a type
		return binding;
	}
	// handle the case when a field or type was asked for but we resolved the compoundName to a type or field
	return new ProblemBinding(CharOperation.subarray(compoundName, 0, currentIndex), .);
/* API
	Answer the constructor binding that corresponds to receiverType, argumentTypes.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered constructor is visible.
	If no visible constructor is discovered, an error binding is answered.
*/
public MethodBinding getConstructor(ReferenceBinding receiverTypeTypeBinding[] argumentTypesInvocationSite invocationSite) {
	MethodBinding methodBinding = receiverType.getExactConstructor(argumentTypes);
	if (methodBinding != null) {
		if (canBeSeenByForCodeSnippet(methodBindingreceiverTypeinvocationSitethis)) {
			return methodBinding;
		}
	}
	MethodBinding[] methods = receiverType.getMethods(.);
	if (methods == .) {
	}
	MethodBinding[] compatible = new MethodBinding[methods.length];
	int compatibleIndex = 0;
	for (int i = 0, length = methods.lengthi < lengthi++) {
	    MethodBinding compatibleMethod = computeCompatibleMethod(methods[i], argumentTypesinvocationSite);
		if (compatibleMethod != null)
			compatible[compatibleIndex++] = compatibleMethod;
	}
	if (compatibleIndex == 0)
		return new ProblemMethodBinding(.argumentTypes.); // need a more descriptive error... cannot convert from X to Y
	MethodBinding[] visible = new MethodBinding[compatibleIndex];
	int visibleIndex = 0;
	for (int i = 0; i < compatibleIndexi++) {
		MethodBinding method = compatible[i];
		if (canBeSeenByForCodeSnippet(methodreceiverTypeinvocationSitethis)) {
			visible[visibleIndex++] = method;
		}
	}
	if (visibleIndex == 1) {
		return visible[0];
	}
	if (visibleIndex == 0) {
		return new ProblemMethodBinding(compatible[0], .compatible[0]..);
	}
	return mostSpecificClassMethodBinding(visiblevisibleIndexinvocationSite);
/* API
	Answer the field binding that corresponds to fieldName.
	Start the lookup at the receiverType.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered field is visible.
	Only fields defined by the receiverType or its supertypes are answered;
	a field of an enclosing type will not be found using this API.
	If no visible field is discovered, an error binding is answered.
*/
public FieldBinding getFieldForCodeSnippet(TypeBinding receiverTypechar[] fieldNameInvocationSite invocationSite) {
	FieldBinding field = findFieldForCodeSnippet(receiverTypefieldNameinvocationSite);
	if (field == null)
		return new ProblemFieldBinding(receiverType instanceof ReferenceBinding ? (ReferenceBindingreceiverType : nullfieldName.);
	else
		return field;
/* API
	Answer the method binding that corresponds to selector, argumentTypes.
	Start the lookup at the enclosing type of the receiver.
	InvocationSite implements
		isSuperAccess(); this is used to determine if the discovered method is visible.
		setDepth(int); this is used to record the depth of the discovered method
			relative to the enclosing type of the receiver. (If the method is defined
			in the enclosing type of the receiver, the depth is 0; in the next enclosing
			type, the depth is 1; and so on
	If no visible method is discovered, an error binding is answered.
*/
public MethodBinding getImplicitMethod(ReferenceBinding receiverTypechar[] selectorTypeBinding[] argumentTypesInvocationSite invocationSite) {
	// retrieve an exact visible match (if possible)
	MethodBinding methodBinding = findExactMethod(receiverTypeselectorargumentTypesinvocationSite);
	if (methodBinding == null)
		methodBinding = findMethod(receiverTypeselectorargumentTypesinvocationSite);
	if (methodBinding != null) { // skip it if we did not find anything
		if (methodBinding.isValidBinding())
		    if (!canBeSeenByForCodeSnippet(methodBindingreceiverTypeinvocationSitethis))
				return new ProblemMethodBinding(methodBindingselectorargumentTypes.);
		return methodBinding;
	}
	return new ProblemMethodBinding(selectorargumentTypes.);
New to GrepCode? Check out our FAQ X