Java Code Examples for org.eclipse.jdt.internal.compiler.lookup.BlockScope#getEmulationPath()

The following examples show how to use org.eclipse.jdt.internal.compiler.lookup.BlockScope#getEmulationPath() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: LambdaExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	if (this.shouldCaptureInstance) {
		this.binding.modifiers &= ~ClassFileConstants.AccStatic;
	} else {
		this.binding.modifiers |= ClassFileConstants.AccStatic;
	}
	SourceTypeBinding sourceType = currentScope.enclosingSourceType();
	this.binding = sourceType.addSyntheticMethod(this);
	int pc = codeStream.position;
	StringBuffer signature = new StringBuffer();
	signature.append('(');
	if (this.shouldCaptureInstance) {
		codeStream.aload_0();
		signature.append(sourceType.signature());
	}
	for (int i = 0, length = this.outerLocalVariables == null ? 0 : this.outerLocalVariables.length; i < length; i++) {
		SyntheticArgumentBinding syntheticArgument = this.outerLocalVariables[i];
		if (this.shouldCaptureInstance) {
			syntheticArgument.resolvedPosition++;
		}
		signature.append(syntheticArgument.type.signature());
		LocalVariableBinding capturedOuterLocal = syntheticArgument.actualOuterLocalVariable;
		VariableBinding[] path = currentScope.getEmulationPath(capturedOuterLocal);
		codeStream.generateOuterAccess(path, this, capturedOuterLocal, currentScope);
	}
	signature.append(')');
	if (this.expectedType instanceof IntersectionCastTypeBinding) {
		signature.append(((IntersectionCastTypeBinding)this.expectedType).getSAMType(currentScope).signature());
	} else {
		signature.append(this.expectedType.signature());
	}
	int invokeDynamicNumber = codeStream.classFile.recordBootstrapMethod(this);
	codeStream.invokeDynamic(invokeDynamicNumber, (this.shouldCaptureInstance ? 1 : 0) + this.outerLocalVariablesSlotSize, 1, this.descriptor.selector, signature.toString().toCharArray());
	if (!valueRequired)
		codeStream.pop();
	codeStream.recordPositionsFrom(pc, this.sourceStart);		
}
 
Example 2
Source File: CodeSnippetSingleNameReference.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	int pc = codeStream.position;
	if (this.constant != Constant.NotAConstant) {
		if (valueRequired) {
			codeStream.generateConstant(this.constant, this.implicitConversion);
		}
	} else {
		switch (this.bits & RestrictiveFlagMASK) {
			case Binding.FIELD : // reading a field
				if (!valueRequired)
					break;
				FieldBinding codegenField = ((FieldBinding) this.binding).original();
				Constant fieldConstant = codegenField.constant();
				if (fieldConstant == Constant.NotAConstant) { // directly use inlined value for constant fields
					if (codegenField.canBeSeenBy(getReceiverType(currentScope), this, currentScope)) {
						TypeBinding someReceiverType = this.delegateThis != null ? this.delegateThis.type : this.actualReceiverType;
						TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenField, someReceiverType, true /* implicit this */);
						if (codegenField.isStatic()) {
							codeStream.fieldAccess(Opcodes.OPC_getstatic, codegenField, constantPoolDeclaringClass);
						} else {
							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);
							}
							codeStream.fieldAccess(Opcodes.OPC_getfield, codegenField, constantPoolDeclaringClass);
						}
					} else {
						// managing private access
						if (!codegenField.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();
						}
						codeStream.generateEmulatedReadAccessForField(codegenField);
					}
					if (this.genericCast != null) codeStream.checkcast(this.genericCast);
					codeStream.generateImplicitConversion(this.implicitConversion);
				} else { // directly use the inlined value
					codeStream.generateConstant(fieldConstant, this.implicitConversion);
				}
				break;
			case Binding.LOCAL : // reading a local
				LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
				if (localBinding.resolvedPosition == -1) {
					if (valueRequired) {
						// restart code gen
						localBinding.useFlag = LocalVariableBinding.USED;
						throw new AbortMethod(CodeStream.RESTART_CODE_GEN_FOR_UNUSED_LOCALS_MODE, null);
					}
					codeStream.recordPositionsFrom(pc, this.sourceStart);
					return;
				}
				if (!valueRequired)
					break;
				// 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 {
					// regular local variable read
					codeStream.load(localBinding);
				}
				codeStream.generateImplicitConversion(this.implicitConversion);
				break;
		}
	}
	codeStream.recordPositionsFrom(pc, this.sourceStart);
}
 
Example 3
Source File: ReferenceExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	this.actualMethodBinding = this.binding; // grab before synthetics come into play.
	// Handle some special cases up front and transform them into implicit lambdas.
	if (shouldGenerateImplicitLambda(currentScope)) {
		generateImplicitLambda(currentScope, codeStream, valueRequired);
		return;
	}
	SourceTypeBinding sourceType = currentScope.enclosingSourceType();
	if (this.receiverType.isArrayType()) {
		if (isConstructorReference()) {
			this.actualMethodBinding = this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayConstructor);
		} else if (CharOperation.equals(this.selector, TypeConstants.CLONE)) {
			this.actualMethodBinding = this.binding = sourceType.addSyntheticArrayMethod((ArrayBinding) this.receiverType, SyntheticMethodBinding.ArrayClone);
		}
	} else if (this.syntheticAccessor != null) {
		if (this.lhs.isSuper() || isMethodReference())
			this.binding = this.syntheticAccessor;
	} else { // cf. MessageSend.generateCode()'s call to CodeStream.getConstantPoolDeclaringClass. We have extracted the relevant portions sans side effect here. 
		if (this.binding != null && isMethodReference()) {
			if (TypeBinding.notEquals(this.binding.declaringClass, this.lhs.resolvedType.erasure())) {
				if (!this.binding.declaringClass.canBeSeenBy(currentScope)) {
					this.binding = new MethodBinding(this.binding, (ReferenceBinding) this.lhs.resolvedType.erasure());
				}
			}
		}
	}
	
	int pc = codeStream.position;
	StringBuffer buffer = new StringBuffer();
	int argumentsSize = 0;
	buffer.append('(');
	if (this.haveReceiver) {
		this.lhs.generateCode(currentScope, codeStream, true);
		if (this.lhs.isSuper() && !this.actualMethodBinding.isPrivate()) {
			if (this.lhs instanceof QualifiedSuperReference) {
				QualifiedSuperReference qualifiedSuperReference = (QualifiedSuperReference) this.lhs;
				TypeReference qualification = qualifiedSuperReference.qualification;
				if (qualification.resolvedType.isInterface()) {
					buffer.append(sourceType.signature());
				} else {
					buffer.append(((QualifiedSuperReference) this.lhs).currentCompatibleType.signature());
				}
			} else { 
				buffer.append(sourceType.signature());
			}
		} else {
			buffer.append(this.receiverType.signature());
		}
		argumentsSize = 1;
	} else {
		if (this.isConstructorReference()) {
			ReferenceBinding[] enclosingInstances = Binding.UNINITIALIZED_REFERENCE_TYPES;
			if (this.receiverType.isNestedType()) {
				ReferenceBinding nestedType = (ReferenceBinding) this.receiverType;
				if ((enclosingInstances = nestedType.syntheticEnclosingInstanceTypes()) != null) {
					int length = enclosingInstances.length;
					argumentsSize = length;
					for (int i = 0 ; i < length; i++) {
						ReferenceBinding syntheticArgumentType = enclosingInstances[i];
						buffer.append(syntheticArgumentType.signature());
						Object[] emulationPath = currentScope.getEmulationPath(
								syntheticArgumentType,
								false /* allow compatible match */,
								true /* disallow instance reference in explicit constructor call */);
						codeStream.generateOuterAccess(emulationPath, this, syntheticArgumentType, currentScope);
					}
				} else {
					enclosingInstances = Binding.NO_REFERENCE_TYPES;
				}
				// Reject types that capture outer local arguments, these cannot be manufactured by the metafactory.
				if (nestedType.syntheticOuterLocalVariables() != null) {
					currentScope.problemReporter().noSuchEnclosingInstance(nestedType.enclosingType(), this, false);
					return;
				}
			}
			if (this.syntheticAccessor != null) {
				this.binding = sourceType.addSyntheticFactoryMethod(this.binding, this.syntheticAccessor, enclosingInstances);
			}
		}
	}
	buffer.append(')');
	buffer.append('L');
	buffer.append(this.resolvedType.constantPoolName());
	buffer.append(';');
	int invokeDynamicNumber = codeStream.classFile.recordBootstrapMethod(this);
	codeStream.invokeDynamic(invokeDynamicNumber, argumentsSize, 1, this.descriptor.selector, buffer.toString().toCharArray(), 
			this.isConstructorReference(), (this.lhs instanceof TypeReference? (TypeReference) this.lhs : null), this.typeArguments);
	if (!valueRequired)
		codeStream.pop();
	codeStream.recordPositionsFrom(pc, this.sourceStart);
}
 
Example 4
Source File: SingleNameReference.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) {
	// optimizing assignment like: i = i + 1 or i = 1 + i
	if (assignment.expression.isCompactableOperation()) {
		BinaryExpression operation = (BinaryExpression) assignment.expression;
		int operator = (operation.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT;
		SingleNameReference variableReference;
		if ((operation.left instanceof SingleNameReference) && ((variableReference = (SingleNameReference) operation.left).binding == this.binding)) {
			// i = i + value, then use the variable on the right hand side, since it has the correct implicit conversion
			variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], operation.right, operator, operation.implicitConversion, valueRequired);
			if (valueRequired) {
				codeStream.generateImplicitConversion(assignment.implicitConversion);
			}
			return;
		}
		if ((operation.right instanceof SingleNameReference)
				&& ((operator == OperatorIds.PLUS) || (operator == OperatorIds.MULTIPLY)) // only commutative operations
				&& ((variableReference = (SingleNameReference) operation.right).binding == this.binding)
				&& (operation.left.constant != Constant.NotAConstant) // exclude non constant expressions, since could have side-effect
				&& (((operation.left.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) != TypeIds.T_JavaLangString) // exclude string concatenation which would occur backwards
				&& (((operation.right.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) != TypeIds.T_JavaLangString)) { // exclude string concatenation which would occur backwards
			// i = value + i, then use the variable on the right hand side, since it has the correct implicit conversion
			variableReference.generateCompoundAssignment(currentScope, codeStream, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], operation.left, operator, operation.implicitConversion, valueRequired);
			if (valueRequired) {
				codeStream.generateImplicitConversion(assignment.implicitConversion);
			}
			return;
		}
	}
	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
		case Binding.FIELD : // assigning to a field
			int pc = codeStream.position;
			FieldBinding codegenBinding = ((FieldBinding) this.binding).original();
			if (!codegenBinding.isStatic()) { // need a receiver?
				if ((this.bits & ASTNode.DepthMASK) != 0) {
					ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
					Object[] emulationPath = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
					codeStream.generateOuterAccess(emulationPath, this, targetType, currentScope);
				} else {
					generateReceiver(codeStream);
				}
			}
			codeStream.recordPositionsFrom(pc, this.sourceStart);
			assignment.expression.generateCode(currentScope, codeStream, true);
			fieldStore(currentScope, codeStream, codegenBinding, this.syntheticAccessors == null ? null : this.syntheticAccessors[SingleNameReference.WRITE], this.actualReceiverType, true /*implicit this*/, valueRequired);
			if (valueRequired) {
				codeStream.generateImplicitConversion(assignment.implicitConversion);
			}
			// no need for generic cast as value got dupped
			return;
		case Binding.LOCAL : // assigning to a local variable
			LocalVariableBinding localBinding = (LocalVariableBinding) this.binding;
			if (localBinding.resolvedPosition != -1) {
				assignment.expression.generateCode(currentScope, codeStream, true);
			} else {
				if (assignment.expression.constant != Constant.NotAConstant) {
					// assigning an unused local to a constant value = no actual assignment is necessary
					if (valueRequired) {
						codeStream.generateConstant(assignment.expression.constant, assignment.implicitConversion);
					}
				} else {
					assignment.expression.generateCode(currentScope, codeStream, true);
					/* Even though the value may not be required, we force it to be produced, and discard it later
					on if it was actually not necessary, so as to provide the same behavior as JDK1.2beta3.	*/
					if (valueRequired) {
						codeStream.generateImplicitConversion(assignment.implicitConversion); // implicit conversion
					} else {
						switch(localBinding.type.id) {
							case TypeIds.T_long :
							case TypeIds.T_double :
								codeStream.pop2();
								break;
							default :
								codeStream.pop();
								break;
						}						
					}
				}
				return;
			}
			// 26903, need extra cast to store null in array local var
			if (localBinding.type.isArrayType()
				&& ((assignment.expression instanceof CastExpression)	// arrayLoc = (type[])null
						&& (((CastExpression)assignment.expression).innermostCastedExpression().resolvedType == TypeBinding.NULL))){
				codeStream.checkcast(localBinding.type);
			}

			// normal local assignment (since cannot store in outer local which are final locations)
			codeStream.store(localBinding, valueRequired);
			if ((this.bits & ASTNode.FirstAssignmentToLocal) != 0) { // for local variable debug attributes
				localBinding.recordInitializationStartPC(codeStream.position);
			}
			// implicit conversion
			if (valueRequired) {
				codeStream.generateImplicitConversion(assignment.implicitConversion);
			}
	}
}
 
Example 5
Source File: MessageSend.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * MessageSend code generation
 *
 * @param currentScope org.eclipse.jdt.internal.compiler.lookup.BlockScope
 * @param codeStream org.eclipse.jdt.internal.compiler.codegen.CodeStream
 * @param valueRequired boolean
 */
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
	int pc = codeStream.position;
	// generate receiver/enclosing instance access
	MethodBinding codegenBinding = this.binding instanceof PolymorphicMethodBinding ? this.binding : this.binding.original();
	boolean isStatic = codegenBinding.isStatic();
	if (isStatic) {
		this.receiver.generateCode(currentScope, codeStream, false);
	} else if ((this.bits & ASTNode.DepthMASK) != 0 && this.receiver.isImplicitThis()) { // outer access ?
		// outer method can be reached through emulation if implicit access
		ReferenceBinding targetType = currentScope.enclosingSourceType().enclosingTypeAt((this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
		Object[] path = currentScope.getEmulationPath(targetType, true /*only exact match*/, false/*consider enclosing arg*/);
		codeStream.generateOuterAccess(path, this, targetType, currentScope);
	} else {
		this.receiver.generateCode(currentScope, codeStream, true);
		if ((this.bits & NeedReceiverGenericCast) != 0) {
			codeStream.checkcast(this.actualReceiverType);
		}
	}
	codeStream.recordPositionsFrom(pc, this.sourceStart);
	// generate arguments
	generateArguments(this.binding, this.arguments, currentScope, codeStream);
	pc = codeStream.position;
	// actual message invocation
	if (this.syntheticAccessor == null){
		TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, codegenBinding, this.actualReceiverType, this.receiver.isImplicitThis());
		if (isStatic){
			codeStream.invoke(Opcodes.OPC_invokestatic, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
		} else if((this.receiver.isSuper()) || codegenBinding.isPrivate()){
			codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
		} else if (constantPoolDeclaringClass.isInterface()) { // interface or annotation type
			codeStream.invoke(Opcodes.OPC_invokeinterface, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
		} else {
			codeStream.invoke(Opcodes.OPC_invokevirtual, codegenBinding, constantPoolDeclaringClass, this.typeArguments);
		}
	} else {
		codeStream.invoke(Opcodes.OPC_invokestatic, this.syntheticAccessor, null /* default declaringClass */, this.typeArguments);
	}
	// required cast must occur even if no value is required
	if (this.valueCast != null) codeStream.checkcast(this.valueCast);
	if (valueRequired){
		// implicit conversion if necessary
		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 : codegenBinding.returnType.id) {
			case T_long :
			case T_double :
				codeStream.pop2();
				break;
			case T_void :
				break;
			default :
				codeStream.pop();
		}
	}
	codeStream.recordPositionsFrom(pc, (int)(this.nameSourcePosition >>> 32)); // highlight selector
}