Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2000, 2010 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 Stephan Herrmann <stephan@cs.tu-berlin.de> - Contribution for bug 185682 - Increment/decrement operators mark local variables as read /
 
 package org.eclipse.jdt.internal.eval;
 
 
 
CodeSnippetQualifiedNameReference constructor comment.

Parameters:
sources char[][]
sourceStart int
sourceEnd int
 
 public CodeSnippetQualifiedNameReference(char[][] sourceslong[] positionsint sourceStartint sourceEndEvaluationContext evaluationContext) {
 	super(sourcespositionssourceStartsourceEnd);
 	this. = evaluationContext;
 }

Check and/or redirect the field access to the delegate receiver if any
 
 	FieldBinding fieldBinding = (FieldBindingthis.;
 	MethodScope methodScope = scope.methodScope();
 	TypeBinding declaringClass = fieldBinding.original().;
 	// check for forward references
 	if ((this. == 1 || declaringClass.isEnum())
 			&& methodScope.enclosingSourceType() == declaringClass
 			&& methodScope.lastVisibleFieldID >= 0
 			&& fieldBinding.id >= methodScope.lastVisibleFieldID
 			&& (!fieldBinding.isStatic() || methodScope.isStatic)) {
 		scope.problemReporter().forwardReference(thisthis.-1, fieldBinding);
 	}
 	this. &= ~.// clear bits
 	this. |= .;
 	return getOtherFieldBindings(scope);
 }
 
 public void generateCode(BlockScope currentScopeCodeStream codeStreamboolean valueRequired) {
 	int pc = codeStream.position;
 	if ((this. & .) == 0) { // nothing to do if type ref
 		codeStream.recordPositionsFrom(pcthis.);
 		return;
 	}
 	FieldBinding lastFieldBinding = this. == null ? (FieldBindingthis. : this.[this..length-1];
 	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), thiscurrentScope)) {
 		super.generateCode(currentScopecodeStreamvalueRequired);
 		return;
 	}
 	lastFieldBinding = generateReadSequence(currentScopecodeStream);
 	if (lastFieldBinding != null) {
 		boolean isStatic = lastFieldBinding.isStatic();
 		Constant fieldConstant = lastFieldBinding.constant();
 		if (fieldConstant != .) {
 			if (!isStatic){
 				codeStream.invokeObjectGetClass();
 				codeStream.pop();
 			}
 			if (valueRequired) { // inline the last field constant
 				codeStream.generateConstant(fieldConstantthis.);
 			}
 		} else {
 			boolean isFirst = lastFieldBinding == this.
 											&& (this. == 1 || lastFieldBinding.declaringClass == currentScope.enclosingReceiverType())
											&& this. == null// could be dup: next.next.next
			TypeBinding requiredGenericCast = getGenericCast(this. == null ? 0 : this..length);
			if (valueRequired
					|| (!isFirst && currentScope.compilerOptions(). >= .)
					|| ((this. & .) != 0)
					|| requiredGenericCast != null) {
				int lastFieldPc = codeStream.position;
				if (lastFieldBinding.declaringClass == null) { // array length
					codeStream.arraylength();
					if (valueRequired) {
else {
						// could occur if !valueRequired but compliance >= 1.4
						codeStream.pop();
					}
else {
					codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
					if (requiredGenericCast != nullcodeStream.checkcast(requiredGenericCast);
					if (valueRequired) {
else {
						boolean isUnboxing = (this. & .) != 0;
						// conversion only generated if unboxing
						if (isUnboxingcodeStream.generateImplicitConversion(this.);
						switch (isUnboxing ? postConversionType(currentScope). : lastFieldBinding.type.id) {
							case  :
							case  :
								codeStream.pop2();
								break;
							default :
								codeStream.pop();
						}
					}
				}
				int fieldPosition = (int) (this.[this..length - 1] >>> 32);
				codeStream.recordPositionsFrom(lastFieldPcfieldPosition);
else {
				if (!isStatic){
					codeStream.invokeObjectGetClass(); // perform null check
					codeStream.pop();
				}
			}
		}
	}
	codeStream.recordPositionsFrom(pcthis.);
Check and/or redirect the field access to the delegate receiver if any
public void generateAssignment(BlockScope currentScopeCodeStream codeStreamAssignment assignmentboolean valueRequired) {
    FieldBinding lastFieldBinding = this. == null ? (FieldBindingthis. : this.[this..length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), thiscurrentScope)) {
		super.generateAssignment(currentScopecodeStreamassignmentvalueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScopecodeStream);
	codeStream.generateEmulationForField(lastFieldBinding);
	codeStream.swap();
	assignment.expression.generateCode(currentScopecodeStreamtrue);
	if (valueRequired) {
		switch (lastFieldBinding.type.id) {
			case . :
				codeStream.dup2_x2();
				break;
			default :
				codeStream.dup_x2();
			break;	
		}		
	}
	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
	if (valueRequired) {
		codeStream.generateImplicitConversion(assignment.implicitConversion);
	}
public void generateCompoundAssignment(BlockScope currentScopeCodeStream codeStreamExpression expressionint operatorint assignmentImplicitConversionboolean valueRequired) {
    FieldBinding lastFieldBinding = this. == null ? (FieldBindingthis. : this.[this..length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), thiscurrentScope)) {
		super.generateCompoundAssignment(currentScopecodeStreamexpressionoperatorassignmentImplicitConversionvalueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScopecodeStream);
	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. & ) >> 4) == ) {
		codeStream.generateStringConcatenationAppend(currentScopenullexpression);
else {
		// promote the array reference to the suitable operation type
		// generate the increment value (will by itself  be promoted to the operation value)
		if (expression == .){ // prefix operation
			codeStream.generateConstant(expression.constantthis.);
else {
			expression.generateCode(currentScopecodeStreamtrue);
		}
		// perform the operation
		codeStream.sendOperator(operatoroperationTypeID);
		// 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 . :
				codeStream.dup2_x2();
				break;
			default :
				codeStream.dup_x2();
			break;	
		}
	}
	// current stack is:
	// value field receiver value
	codeStream.generateEmulatedWriteAccessForField(lastFieldBinding);
public void generatePostIncrement(BlockScope currentScopeCodeStream codeStreamCompoundAssignment postIncrementboolean valueRequired) {
    FieldBinding lastFieldBinding = this. == null ? (FieldBindingthis. : this.[this..length-1];
	if (lastFieldBinding.canBeSeenBy(getFinalReceiverType(), thiscurrentScope)) {
		super.generatePostIncrement(currentScopecodeStreampostIncrementvalueRequired);
		return;
	}
	lastFieldBinding = generateReadSequence(currentScopecodeStream);
	codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
	if (valueRequired) {
		switch (lastFieldBinding.type.id) {
			case . :
				codeStream.dup2();
				break;
			default :
				codeStream.dup();
			break;	
		}		
	}
	codeStream.generateEmulationForField(lastFieldBinding);
	if ((lastFieldBinding.type == .) || (lastFieldBinding.type == .)) {
		codeStream.dup_x2();
		codeStream.pop();
		if (lastFieldBinding.isStatic()) {
			codeStream.aconst_null();
else {
			generateReadSequence(currentScopecodeStream);
		}
		codeStream.dup_x2();
		codeStream.pop();
else {
		codeStream.dup_x1();
		codeStream.pop();
		if (lastFieldBinding.isStatic()) {
			codeStream.aconst_null();
else {
			generateReadSequence(currentScopecodeStream);
		}
		codeStream.dup_x1();
		codeStream.pop();
	}
	codeStream.generateConstant(postIncrement.expression.constantthis.);
	codeStream.sendOperator(postIncrement.operatorlastFieldBinding.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.
 */
public FieldBinding generateReadSequence(BlockScope currentScopeCodeStream codeStream) {
	// determine the rank until which we now we do not need any actual value for the field access
	int otherBindingsCount = this. == null ? 0 : this..length;
	boolean needValue = otherBindingsCount == 0 || !this.[0].isStatic();
	FieldBinding lastFieldBinding;
	TypeBinding lastGenericCast;
	TypeBinding lastReceiverType;
	boolean complyTo14 = currentScope.compilerOptions(). >= .;
	switch (this. & ) {
		case . :
			lastFieldBinding = ((FieldBindingthis.).original();
			lastGenericCast = this.;
			lastReceiverType = this.;
			// if first field is actually constant, we can inline it
			if (lastFieldBinding.constant() != .) {
				break;
			}
			if (needValue) {
				if (lastFieldBinding.canBeSeenBy(this.thiscurrentScope)) {
					if (!lastFieldBinding.isStatic()) {
						if ((this. & ) != 0) {
							ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this. & ) >> );
							Object[] emulationPath = currentScope.getEmulationPath(targetTypetrue /*only exact match*/false/*consider enclosing arg*/);
							codeStream.generateOuterAccess(emulationPaththistargetTypecurrentScope);
else {
							generateReceiver(codeStream);
						}
					}
else {
					if (!lastFieldBinding.isStatic()) {
						if ((this. & ) != 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 . : // reading the first local variable
			lastFieldBinding = null;
			lastGenericCast = null;
			lastReceiverType = localBinding.type;
			if (!needValuebreak// no value needed
			// regular local variable read
			Constant localConstant = localBinding.constant();
			if (localConstant != .) {
				codeStream.generateConstant(localConstant, 0);
				// no implicit conversion
else {
				// outer local?
				if ((this. & ) != 0) {
					// outer local can be reached either through a synthetic arg or a synthetic field
					VariableBinding[] path = currentScope.getEmulationPath(localBinding);
					codeStream.generateOuterAccess(paththislocalBindingcurrentScope);
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..length;
	FieldBinding initialFieldBinding = lastFieldBinding// can be null if initial was a local binding
	if (this. != null) {
		for (int i = 0; i < otherBindingsCounti++) {
			int pc = codeStream.position;
			FieldBinding nextField = this.[i].original();
			TypeBinding nextGenericCast = this. == null ? null : this.[i];
			if (lastFieldBinding != null) {
				needValue = !nextField.isStatic();
				Constant fieldConstant = lastFieldBinding.constant();
				if (fieldConstant != .) {
					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(lastReceiverTypethiscurrentScope)) {
							MethodBinding accessor = this. == null ? null : this.[i];
							if (accessor == null) {
								TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScopelastFieldBindinglastReceiverTypei == 0 && this. == 1);
								if (lastFieldBinding.isStatic()) {
									codeStream.fieldAccess(.lastFieldBindingconstantPoolDeclaringClass);
else {
									codeStream.fieldAccess(.lastFieldBindingconstantPoolDeclaringClass);
								}
else {
								codeStream.invoke(.accessornull /* default declaringClass */);
							}
else {
							codeStream.generateEmulatedReadAccessForField(lastFieldBinding);
						}
						if (lastGenericCast != null) {
							codeStream.checkcast(lastGenericCast);
							lastReceiverType = lastGenericCast;
else {
							lastReceiverType = lastFieldBinding.type;
						}
						if (!needValuecodeStream.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 (initialFieldBinding.declaringClass != this..erasure()) {
									if (lastFieldBinding.canBeSeenBy(lastReceiverTypethiscurrentScope)) {
										MethodBinding accessor = this. == null ? null : this.[i];
										if (accessor == null) {
											TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScopelastFieldBindinglastReceiverTypei == 0 && this. == 1);
											codeStream.fieldAccess(.lastFieldBindingconstantPoolDeclaringClass);
else {
											codeStream.invoke(.accessornull /* 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.[positionsLength - otherBindingsCount + i - 1] >>>32);
						codeStream.recordPositionsFrom(pcfieldPosition);
					}
				}
			}
			lastFieldBinding = nextField;
			lastGenericCast = nextGenericCast;
			if (lastFieldBinding != null && !lastFieldBinding.canBeSeenBy(lastReceiverTypethiscurrentScope)) {
				if (lastFieldBinding.isStatic()) {
					codeStream.aconst_null();
				}
			}			
		}
	}
	return lastFieldBinding;	
public void generateReceiver(CodeStream codeStream) {
	codeStream.aload_0();
	if (this. != null) {
		codeStream.fieldAccess(.this.null /* default declaringClass */); // delegated field access
	}
	// At this point restrictiveFlag may ONLY have two potential value : FIELD LOCAL (i.e cast <<(VariableBinding) binding>> is valid)
	int length = this..length;
	if ((this. & .) != 0) {
		if (!((FieldBindingthis.).isStatic()) { //must check for the static status....
			if (this. == 1) {
				//the field is the first token of the qualified reference....
				if (scope.methodScope().) {
					return null;
				}
else { //accessing to a field using a type as "receiver" is allowed only with static field
				return null;
			}
		}
		// only last field is actually a write access if any
		if (isFieldUseDeprecated((FieldBindingthis.scopethis. == length ? this. : 0)) {
		}
	}
	int index = this.;
	if (index == length) { //	restrictiveFlag == FIELD
		this. = ((FieldBindingthis.).constant();
		return type;
	}
	// allocation of the fieldBindings array	and its respective constants
	int otherBindingsLength = length - index;
	this. = new FieldBinding[otherBindingsLength];
	// fill the first constant (the one of the binding)
	// iteration on each field
	while (index < length) {
		char[] token = this.[index];
		if (type == nullreturn null// could not resolve type prior to this point
		FieldBinding field = scope.getField(typetokenthis);
		int place = index - this.;
		this.[place] = field;
		if (!field.isValidBinding()) {
			// try to retrieve the field as private field
			CodeSnippetScope localScope = new CodeSnippetScope(scope);
			if (this. == null) {
				if (this.. != null) {
					this. = scope.getField(scope.enclosingSourceType(), this);
					if (this. == null){  // if not found then internal error, field should have been found
						return super.reportError(scope);
					}
else {
					this. = .//don't fill other constants slots...
					scope.problemReporter().invalidField(thisfieldindextype);
					return null;
				}
			}
			field = localScope.getFieldForCodeSnippet(this..tokenthis);
			this.[place] = field;
		}
		if (field.isValidBinding()) {
			// only last field is actually a write access if any
			if (isFieldUseDeprecated(fieldscopeindex+1 == length ? this. : 0)) {
				scope.problemReporter().deprecatedField(fieldthis);
			}
			// constant propagation can only be performed as long as the previous one is a constant too.
				this. = field.constant();
			}
			type = field.type;
			index++;
else {
			this. = .//don't fill other constants slots...
			scope.problemReporter().invalidField(thisfieldindextype);
			return null;
		}
	}
	return (this.[otherBindingsLength - 1]).;
index is <0 to denote write access emulation
public void manageSyntheticAccessIfNecessary(BlockScope currentScopeFieldBinding fieldBindingint indexFlowInfo flowInfo) {
	// do nothing
Normal field binding did not work, try to bind to a field of the delegate receiver.
	if (this.. != null) {
		this. = scope.getField(scope.enclosingSourceType(), this);
		if (this. == null){  // if not found then internal error, field should have been found
			return super.reportError(scope);
		}
else {
		return super.reportError(scope);
	}
	if ((this. instanceof ProblemFieldBinding && ((ProblemFieldBindingthis.).problemId() == )
		|| (this. instanceof ProblemBinding && ((ProblemBindingthis.).problemId() == )){
		// will not support innerclass emulation inside delegate
		FieldBinding fieldBinding = scope.getField(this..this.[0], this);
		if (!fieldBinding.isValidBinding()) {
			if (((ProblemFieldBindingfieldBinding).problemId() == ) {
				// manage the access to a private field of the enclosing type
				CodeSnippetScope localScope = new CodeSnippetScope(scope);
				this. = localScope.getFieldForCodeSnippet(this..this.[0], this);
				if (this..isValidBinding()) {
					return checkFieldAccess(scope);
else {
					return super.reportError(scope);
				}
else {
				return super.reportError(scope);
			}
		}
		this. = fieldBinding;
		return checkFieldAccess(scope);
	}
	TypeBinding result;
	if (this. instanceof ProblemFieldBinding && ((ProblemFieldBindingthis.).problemId() == ) {
		// 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. = localScope.getBinding(this.this. & this, (ReferenceBindingthis..)).isValidBinding()) {
			this. &= ~// clear bits
			this. |= .;
			result = getOtherFieldBindings(scope);
else {
			return super.reportError(scope);
		}
		if (result != null && result.isValidBinding()) {
			return result;
		}
	}
	return super.reportError(scope);
New to GrepCode? Check out our FAQ X