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

The following examples show how to use org.eclipse.jdt.internal.compiler.lookup.BlockScope#compilerOptions() . 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: CastExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 6 votes vote down vote up
/**
 * Complain if assigned expression is cast, but not actually used as such, e.g. Object o = (List) object;
 */
public static void checkNeedForAssignedCast(BlockScope scope, TypeBinding expectedType, CastExpression rhs) {
	CompilerOptions compilerOptions = scope.compilerOptions();
	if (compilerOptions.getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return;

	TypeBinding castedExpressionType = rhs.expression.resolvedType;
	//	int i = (byte) n; // cast still had side effect
	// double d = (float) n; // cast to float is unnecessary
	if (castedExpressionType == null || rhs.resolvedType.isBaseType()) return;
	//if (castedExpressionType.id == T_null) return; // tolerate null expression cast
	if (castedExpressionType.isCompatibleWith(expectedType, scope)) {
		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8) {
			// are null annotations compatible, too?
			if (NullAnnotationMatching.analyse(expectedType, castedExpressionType, -1).isAnyMismatch())
				return; // already reported unchecked cast (nullness), say no more.
		}
		scope.problemReporter().unnecessaryCast(rhs);
	}
}
 
Example 2
Source File: ExplicitConstructorCall.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 6 votes vote down vote up
public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
	if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0)	{
		// if constructor from parameterized type got found, use the original constructor at codegen time
		MethodBinding codegenBinding = this.binding.original();

		// perform some emulation work in case there is some and we are inside a local type only
		if (this.binding.isPrivate() && this.accessMode != ExplicitConstructorCall.This) {
			ReferenceBinding declaringClass = codegenBinding.declaringClass;
			// from 1.4 on, local type constructor can lose their private flag to ease emulation
			if ((declaringClass.tagBits & TagBits.IsLocalType) != 0 && currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
				// constructor will not be dumped as private, no emulation required thus
				codegenBinding.tagBits |= TagBits.ClearPrivateModifier;
			} else {
				this.syntheticAccessor = ((SourceTypeBinding) declaringClass).addSyntheticMethod(codegenBinding, isSuperAccess());
				currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
			}
		}
	}
}
 
Example 3
Source File: MessageSend.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
private FlowInfo analyseNullAssertion(BlockScope currentScope, Expression argument,
		FlowContext flowContext, FlowInfo flowInfo, boolean expectingNull)
{
	int nullStatus = argument.nullStatus(flowInfo, flowContext);
	boolean willFail = (nullStatus == (expectingNull ? FlowInfo.NON_NULL : FlowInfo.NULL));
	flowInfo = argument.analyseCode(currentScope, flowContext, flowInfo).unconditionalInits();
	LocalVariableBinding local = argument.localVariableBinding();
	if (local != null) {// beyond this point the argument can only be null/nonnull
		if (expectingNull) 
			flowInfo.markAsDefinitelyNull(local);
		else 
			flowInfo.markAsDefinitelyNonNull(local);
	} else {
		if (!expectingNull
			&& argument instanceof Reference 
			&& currentScope.compilerOptions().enableSyntacticNullAnalysisForFields) 
		{
			FieldBinding field = ((Reference)argument).lastFieldBinding();
			if (field != null && (field.type.tagBits & TagBits.IsBaseType) == 0) {
				flowContext.recordNullCheckedFieldReference((Reference) argument, 3); // survive this assert as a MessageSend and as a Statement
			}
		}
	}
	if (willFail)
		flowInfo.setReachMode(FlowInfo.UNREACHABLE_BY_NULLANALYSIS);
	return flowInfo;
}
 
Example 4
Source File: NullAnnotationMatching.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
/** Check null-ness of 'var' against a possible null annotation */
public static int checkAssignment(BlockScope currentScope, FlowContext flowContext,
								   VariableBinding var, int nullStatus, Expression expression, TypeBinding providedType)
{
	long lhsTagBits = 0L;
	boolean hasReported = false;
	if (currentScope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_8) {
		lhsTagBits = var.tagBits & TagBits.AnnotationNullMASK;
	} else {
		if (expression instanceof ConditionalExpression && expression.isPolyExpression()) {
			// drill into both branches:
			ConditionalExpression ce = ((ConditionalExpression) expression);
			int status1 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, ce.ifTrueNullStatus, ce.valueIfTrue, ce.valueIfTrue.resolvedType);
			int status2 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, ce.ifFalseNullStatus, ce.valueIfFalse, ce.valueIfFalse.resolvedType);
			if (status1 == status2)
				return status1;
			return nullStatus; // if both branches disagree use the precomputed & merged nullStatus
		}
		lhsTagBits = var.type.tagBits & TagBits.AnnotationNullMASK;
		NullAnnotationMatching annotationStatus = analyse(var.type, providedType, nullStatus);
		if (annotationStatus.isDefiniteMismatch()) {
			currentScope.problemReporter().nullityMismatchingTypeAnnotation(expression, providedType, var.type, annotationStatus);
			hasReported = true;
		} else if (annotationStatus.isUnchecked()) {
			flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, nullStatus);
			hasReported = true;
		} else if (annotationStatus.nullStatus != FlowInfo.UNKNOWN) {
			return annotationStatus.nullStatus;
		}
	}
	if (lhsTagBits == TagBits.AnnotationNonNull && nullStatus != FlowInfo.NON_NULL) {
		if (!hasReported)
			flowContext.recordNullityMismatch(currentScope, expression, providedType, var.type, nullStatus);
		return FlowInfo.NON_NULL;
	} else if (lhsTagBits == TagBits.AnnotationNullable && nullStatus == FlowInfo.UNKNOWN) {	// provided a legacy type?
		return FlowInfo.POTENTIALLY_NULL;			// -> use more specific info from the annotation
	}
	return nullStatus;
}
 
Example 5
Source File: ThrowStatement.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
public void resolve(BlockScope scope) {
	this.exceptionType = this.exception.resolveType(scope);
	recordExceptionsForEnclosingLambda(scope, this.exceptionType);
	if (this.exceptionType != null && this.exceptionType.isValidBinding()) {
		if (this.exceptionType == TypeBinding.NULL) {
			if (scope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3){
				// if compliant with 1.4, this problem will not be reported
				scope.problemReporter().cannotThrowNull(this.exception);
			}
	 	} else if (this.exceptionType.findSuperTypeOriginatingFrom(TypeIds.T_JavaLangThrowable, true) == null) {
			scope.problemReporter().cannotThrowType(this.exception, this.exceptionType);
		}
		this.exception.computeConversion(scope, this.exceptionType, this.exceptionType);
	}
}
 
Example 6
Source File: FieldReference.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
	boolean nonStatic = !this.binding.isStatic();
	this.receiver.analyseCode(currentScope, flowContext, flowInfo, nonStatic);
	if (nonStatic) {
		this.receiver.checkNPE(currentScope, flowContext, flowInfo);
	}

	if (valueRequired || currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) {
		manageSyntheticAccessIfNecessary(currentScope, flowInfo, true /*read-access*/);
	}
	return flowInfo;
}
 
Example 7
Source File: SingleNameReference.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
public boolean checkNPE(BlockScope scope, FlowContext flowContext, FlowInfo flowInfo) {
	if (!super.checkNPE(scope, flowContext, flowInfo)) {
		CompilerOptions compilerOptions = scope.compilerOptions();
		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled) {
			VariableBinding var = nullAnnotatedVariableBinding(compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8);
			if (var instanceof FieldBinding) {
				checkNullableFieldDereference(scope, (FieldBinding) var, ((long)this.sourceStart<<32)+this.sourceEnd);
				return true;
			}
		}
	}
	return false;
}
 
Example 8
Source File: CompletionOnReferenceExpressionName.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
@Override
public TypeBinding resolveType(BlockScope scope) {
	
	final CompilerOptions compilerOptions = scope.compilerOptions();
	TypeBinding lhsType;
	boolean typeArgumentsHaveErrors;

	this.constant = Constant.NotAConstant;
	lhsType = this.lhs.resolveType(scope);
	if (this.typeArguments != null) {
		int length = this.typeArguments.length;
		typeArgumentsHaveErrors = compilerOptions.sourceLevel < ClassFileConstants.JDK1_5;
		this.resolvedTypeArguments = new TypeBinding[length];
		for (int i = 0; i < length; i++) {
			TypeReference typeReference = this.typeArguments[i];
			if ((this.resolvedTypeArguments[i] = typeReference.resolveType(scope, true /* check bounds*/)) == null) {
				typeArgumentsHaveErrors = true;
			}
			if (typeArgumentsHaveErrors && typeReference instanceof Wildcard) { // resolveType on wildcard always return null above, resolveTypeArgument is the real workhorse.
				scope.problemReporter().illegalUsageOfWildcard(typeReference);
			}
		}
		if (typeArgumentsHaveErrors || lhsType == null)
			throw new CompletionNodeFound();
	}
   	
	if (lhsType != null && lhsType.isValidBinding())
		throw new CompletionNodeFound(this, lhsType, scope);
	throw new CompletionNodeFound();
}
 
Example 9
Source File: QualifiedAllocationExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
public TypeBinding resolveType(BlockScope scope) {
	// added for code assist...cannot occur with 'normal' code
	if (this.anonymousType == null && this.enclosingInstance == null) {
		return super.resolveType(scope);
	}
	TypeBinding result=resolveTypeForQualifiedAllocationExpression(scope);
	if(result != null && this.binding != null) {
		final CompilerOptions compilerOptions = scope.compilerOptions();
		if (compilerOptions.isAnnotationBasedNullAnalysisEnabled && (this.binding.tagBits & TagBits.IsNullnessKnown) == 0) {
			new ImplicitNullAnnotationVerifier(scope.environment(), compilerOptions.inheritNullAnnotations)
					.checkImplicitNullAnnotations(this.binding, null/*srcMethod*/, false, scope);
		}
	}
	return result;
}
 
Example 10
Source File: ExplicitConstructorCall.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	// must verify that exceptions potentially thrown by this expression are caught in the method.

	try {
		((MethodScope) currentScope).isConstructorCall = true;

		// process enclosing instance
		if (this.qualification != null) {
			flowInfo =
				this.qualification
					.analyseCode(currentScope, flowContext, flowInfo)
					.unconditionalInits();
		}
		// process arguments
		if (this.arguments != null) {
			boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
			for (int i = 0, max = this.arguments.length; i < max; i++) {
				flowInfo =
					this.arguments[i]
						.analyseCode(currentScope, flowContext, flowInfo)
						.unconditionalInits();
				if (analyseResources) {
					// if argument is an AutoCloseable insert info that it *may* be closed (by the target constructor, i.e.)
					flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
				}
				this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
			}
			analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
		}

		ReferenceBinding[] thrownExceptions;
		if ((thrownExceptions = this.binding.thrownExceptions) != Binding.NO_EXCEPTIONS) {
			if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
				// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
				thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
			}				
			// check exceptions
			flowContext.checkExceptionHandlers(
				thrownExceptions,
				(this.accessMode == ExplicitConstructorCall.ImplicitSuper)
					? (ASTNode) currentScope.methodScope().referenceContext
					: (ASTNode) this,
				flowInfo,
				currentScope);
		}
		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
		manageSyntheticAccessIfNecessary(currentScope, flowInfo);
		return flowInfo;
	} finally {
		((MethodScope) currentScope).isConstructorCall = false;
	}
}
 
Example 11
Source File: QualifiedNameReference.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 {
		FieldBinding 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 {
						SyntheticMethodBinding accessor = this.syntheticReadAccessors == null ? null : this.syntheticReadAccessors[this.syntheticReadAccessors.length - 1];
						if (accessor == null) {
							TypeBinding constantPoolDeclaringClass = CodeStream.getConstantPoolDeclaringClass(currentScope, lastFieldBinding, getFinalReceiverType(), isFirst);
							if (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 */);
						}
						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();
									break;
							}
						}
					}

					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);
}
 
Example 12
Source File: QualifiedNameReference.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, boolean valueRequired) {
	// 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 ? valueRequired : !this.otherBindings[0].isStatic();
	boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4;
	switch (this.bits & ASTNode.RestrictiveFlagMASK) {
		case Binding.FIELD : // reading a field
			if (needValue || complyTo14) {
				manageSyntheticAccessIfNecessary(currentScope, (FieldBinding) this.binding, 0, flowInfo);
			}
			FieldBinding fieldBinding = (FieldBinding) this.binding;
			if (this.indexOfFirstFieldBinding == 1) { // was an implicit reference to the first field binding
				// check if reading a final blank field
				if (fieldBinding.isBlankFinal()
						&& currentScope.needBlankFinalFieldInitializationCheck(fieldBinding)) {
					FlowInfo fieldInits = flowContext.getInitsForFinalBlankInitializationCheck(fieldBinding.declaringClass.original(), flowInfo);
					if (!fieldInits.isDefinitelyAssigned(fieldBinding)) {
						currentScope.problemReporter().uninitializedBlankFinalField(fieldBinding, this);
					}
				}
			}
			break;
		case Binding.LOCAL : // reading a local variable
			LocalVariableBinding localBinding;
			if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) {
				currentScope.problemReporter().uninitializedLocalVariable(localBinding, this);
			}
			if ((flowInfo.tagBits & FlowInfo.UNREACHABLE) == 0) {
				localBinding.useFlag = LocalVariableBinding.USED;
			} else if (localBinding.useFlag == LocalVariableBinding.UNUSED) {
				localBinding.useFlag = LocalVariableBinding.FAKE_USED;
			}
	}
	if (needValue) {
		checkInternalNPE(currentScope, flowContext, flowInfo, true);
	}
	if (needValue) {
		manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
		// only for first binding (if value needed only)
	}
	if (this.otherBindings != null) {
		for (int i = 0; i < otherBindingsCount; i++) {
			needValue = i < otherBindingsCount-1 ? !this.otherBindings[i+1].isStatic() : valueRequired;
			if (needValue || complyTo14) {
				manageSyntheticAccessIfNecessary(currentScope, this.otherBindings[i], i + 1, flowInfo);
			}
		}
	}
	return flowInfo;
}
 
Example 13
Source File: ForeachStatement.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	// initialize break and continue labels
	this.breakLabel = new BranchLabel();
	this.continueLabel = new BranchLabel();
	int initialComplaintLevel = (flowInfo.reachMode() & FlowInfo.UNREACHABLE) != 0 ? Statement.COMPLAINED_FAKE_REACHABLE : Statement.NOT_COMPLAINED;

	// process the element variable and collection
	this.collection.checkNPE(currentScope, flowContext, flowInfo);
	flowInfo = this.elementVariable.analyseCode(this.scope, flowContext, flowInfo);		
	FlowInfo condInfo = this.collection.analyseCode(this.scope, flowContext, flowInfo.copy());
	LocalVariableBinding elementVarBinding = this.elementVariable.binding;

	// element variable will be assigned when iterating
	condInfo.markAsDefinitelyAssigned(elementVarBinding);

	this.postCollectionInitStateIndex = currentScope.methodScope().recordInitializationStates(condInfo);


	// process the action
	LoopingFlowContext loopingContext =
		new LoopingFlowContext(flowContext, flowInfo, this, this.breakLabel,
			this.continueLabel, this.scope, true);
	UnconditionalFlowInfo actionInfo =
		condInfo.nullInfoLessUnconditionalCopy();
	actionInfo.markAsDefinitelyUnknown(elementVarBinding);
	if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled) {
		int elementNullStatus = FlowInfo.tagBitsToNullStatus(this.collectionElementType.tagBits);
		int nullStatus = NullAnnotationMatching.checkAssignment(currentScope, flowContext, elementVarBinding, elementNullStatus,
																	this.collection, this.collectionElementType);
		if ((elementVarBinding.type.tagBits & TagBits.IsBaseType) == 0) {
			actionInfo.markNullStatus(elementVarBinding, nullStatus);
		}
	}
	FlowInfo exitBranch;
	if (!(this.action == null || (this.action.isEmptyBlock()
			&& currentScope.compilerOptions().complianceLevel <= ClassFileConstants.JDK1_3))) {

		if (this.action.complainIfUnreachable(actionInfo, this.scope, initialComplaintLevel, true) < Statement.COMPLAINED_UNREACHABLE) {
			actionInfo = this.action.analyseCode(this.scope, loopingContext, actionInfo).unconditionalCopy();
		}

		// code generation can be optimized when no need to continue in the loop
		exitBranch = flowInfo.unconditionalCopy().
				addInitializationsFrom(condInfo.initsWhenFalse());
		// TODO (maxime) no need to test when false: can optimize (same for action being unreachable above)
		if ((actionInfo.tagBits & loopingContext.initsOnContinue.tagBits &
				FlowInfo.UNREACHABLE_OR_DEAD) != 0) {
			this.continueLabel = null;
		} else {
			actionInfo = actionInfo.mergedWith(loopingContext.initsOnContinue);
			loopingContext.complainOnDeferredFinalChecks(this.scope, actionInfo);
			exitBranch.addPotentialInitializationsFrom(actionInfo);
		}
	} else {
		exitBranch = condInfo.initsWhenFalse();
	}

	// we need the variable to iterate the collection even if the
	// element variable is not used
	final boolean hasEmptyAction = this.action == null
	|| this.action.isEmptyBlock()
	|| ((this.action.bits & IsUsefulEmptyStatement) != 0);

	switch(this.kind) {
		case ARRAY :
			if (!hasEmptyAction
					|| elementVarBinding.resolvedPosition != -1) {
				this.collectionVariable.useFlag = LocalVariableBinding.USED;
				if (this.continueLabel != null) {
					this.indexVariable.useFlag = LocalVariableBinding.USED;
					this.maxVariable.useFlag = LocalVariableBinding.USED;
				}
			}
			break;
		case RAW_ITERABLE :
		case GENERIC_ITERABLE :
			this.indexVariable.useFlag = LocalVariableBinding.USED;
			break;
	}
	//end of loop
	loopingContext.complainOnDeferredNullChecks(currentScope, actionInfo);

	FlowInfo mergedInfo = FlowInfo.mergedOptimizedBranches(
			(loopingContext.initsOnBreak.tagBits &
					FlowInfo.UNREACHABLE) != 0 ?
							loopingContext.initsOnBreak :
								flowInfo.addInitializationsFrom(loopingContext.initsOnBreak), // recover upstream null info
								false,
								exitBranch,
								false,
								true /*for(;;){}while(true); unreachable(); */);
	mergedInfo.resetAssignmentInfo(this.elementVariable.binding);
	this.mergedInitStateIndex = currentScope.methodScope().recordInitializationStates(mergedInfo);
	return mergedInfo;
}
 
Example 14
Source File: QualifiedAllocationExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
	// analyse the enclosing instance
	if (this.enclosingInstance != null) {
		flowInfo = this.enclosingInstance.analyseCode(currentScope, flowContext, flowInfo);
	} else {
		if (this.binding != null && this.binding.declaringClass != null) {
			ReferenceBinding superclass = this.binding.declaringClass.superclass();
			if (superclass != null && superclass.isMemberType() && !superclass.isStatic()) {
				// creating an anonymous type of a non-static member type without an enclosing instance of parent type
				currentScope.tagAsAccessingEnclosingInstanceStateOf(superclass.enclosingType(), false /* type variable access */);
				// Reviewed for https://bugs.eclipse.org/bugs/show_bug.cgi?id=378674 :
				// The corresponding problem (when called from static) is not produced until during code generation
			}
		}
		
	}

	// check captured variables are initialized in current context (26134)
	checkCapturedLocalInitializationIfNecessary(
		(ReferenceBinding)(this.anonymousType == null
			? this.binding.declaringClass.erasure()
			: this.binding.declaringClass.superclass().erasure()),
		currentScope,
		flowInfo);

	// process arguments
	if (this.arguments != null) {
		boolean analyseResources = currentScope.compilerOptions().analyseResourceLeaks;
		boolean hasResourceWrapperType = analyseResources 
					&& this.resolvedType instanceof ReferenceBinding 
					&& ((ReferenceBinding)this.resolvedType).hasTypeBit(TypeIds.BitWrapperCloseable);
		for (int i = 0, count = this.arguments.length; i < count; i++) {
			flowInfo = this.arguments[i].analyseCode(currentScope, flowContext, flowInfo);
			if (analyseResources && !hasResourceWrapperType) { // allocation of wrapped closeables is analyzed specially
				// if argument is an AutoCloseable insert info that it *may* be closed (by the target method, i.e.)
				flowInfo = FakedTrackingVariable.markPassedToOutside(currentScope, this.arguments[i], flowInfo, flowContext, false);
			}
			this.arguments[i].checkNPEbyUnboxing(currentScope, flowContext, flowInfo);
		}
		analyseArguments(currentScope, flowContext, flowInfo, this.binding, this.arguments);
	}

	// analyse the anonymous nested type
	if (this.anonymousType != null) {
		flowInfo = this.anonymousType.analyseCode(currentScope, flowContext, flowInfo);
	}

	// record some dependency information for exception types
	ReferenceBinding[] thrownExceptions;
	if (((thrownExceptions = this.binding.thrownExceptions).length) != 0) {
		if ((this.bits & ASTNode.Unchecked) != 0 && this.genericTypeArguments == null) {
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=277643, align with javac on JLS 15.12.2.6
			thrownExceptions = currentScope.environment().convertToRawTypes(this.binding.thrownExceptions, true, true);
		}			
		// check exception handling
		flowContext.checkExceptionHandlers(
			thrownExceptions,
			this,
			flowInfo.unconditionalCopy(),
			currentScope);
	}

	// after having analysed exceptions above start tracking newly allocated resource:
	if (currentScope.compilerOptions().analyseResourceLeaks && FakedTrackingVariable.isAnyCloseable(this.resolvedType)) {
		FakedTrackingVariable.analyseCloseableAllocation(currentScope, flowInfo, this);
	}

	manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo);
	manageSyntheticAccessIfNecessary(currentScope, flowInfo);

	// account for possible exceptions thrown by constructor execution:
	flowContext.recordAbruptExit();

	return flowInfo;
}
 
Example 15
Source File: MessageSend.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
/**
 * Find the method binding; 
 * if this.innersNeedUpdate allow for two attempts where the first round may stop
 * after applicability checking (18.5.1) to include more information into the final
 * invocation type inference (18.5.2).
 */
protected void findMethodBinding(BlockScope scope, TypeBinding[] argumentTypes) {
	this.binding = this.receiver.isImplicitThis()
			? scope.getImplicitMethod(this.selector, argumentTypes, this)
			: scope.getMethod(this.actualReceiverType, this.selector, argumentTypes, this);
	resolvePolyExpressionArguments(this, this.binding, argumentTypes, scope);
	
	/* There are embedded assumptions in the JLS8 type inference scheme that a successful solution of the type equations results in an
	   applicable method. This appears to be a tenuous assumption, at least one not made by the JLS7 engine or the reference compiler and 
	   there are cases where this assumption would appear invalid: See https://bugs.eclipse.org/bugs/show_bug.cgi?id=426537, where we allow 
	   certain compatibility constrains around raw types to be violated. 
       
       Here, we filter out such inapplicable methods with raw type usage that may have sneaked past overload resolution and type inference, 
       playing the devils advocate, blaming the invocations with raw arguments that should not go blameless. At this time this is in the 
       nature of a point fix and is not a general solution which needs to come later (that also includes AE, QAE and ECC)
    */
	final CompilerOptions compilerOptions = scope.compilerOptions();
	if (compilerOptions.sourceLevel >= ClassFileConstants.JDK1_8 && this.binding instanceof ParameterizedGenericMethodBinding && this.binding.isValidBinding()) {
		if (!compilerOptions.postResolutionRawTypeCompatibilityCheck)
			return;
		ParameterizedGenericMethodBinding pgmb = (ParameterizedGenericMethodBinding) this.binding;
		InferenceContext18 ctx = getInferenceContext(pgmb);
		if (ctx == null || ctx.stepCompleted < InferenceContext18.BINDINGS_UPDATED)
			return;
		int length = pgmb.typeArguments == null ? 0 : pgmb.typeArguments.length;
		boolean sawRawType = false;
		for (int i = 0;  i < length; i++) {
			/* Must check compatibility against capture free method. Formal parameters cannot have captures, but our machinery is not up to snuff to
			   construct a PGMB without captures at the moment - for one thing ITCB does not support uncapture() yet, for another, INTERSECTION_CAST_TYPE
			   does not appear fully hooked up into isCompatibleWith and isEquivalent to everywhere. At the moment, bail out if we see capture.
			*/   
			if (pgmb.typeArguments[i].isCapture())
				return;
			if (pgmb.typeArguments[i].isRawType())
				sawRawType = true;
		}
		if (!sawRawType)
			return;
		length = this.arguments == null ? 0 : this.arguments.length;
		if (length == 0)
			return;
		TypeBinding [] finalArgumentTypes = new TypeBinding[length];
		for (int i = 0; i < length; i++) {
			TypeBinding finalArgumentType = this.arguments[i].resolvedType;
			if (finalArgumentType == null || !finalArgumentType.isValidBinding())  // already sided with the devil.
				return;
			finalArgumentTypes[i] = finalArgumentType; 
		}
		if (scope.parameterCompatibilityLevel(this.binding, finalArgumentTypes, false) == Scope.NOT_COMPATIBLE)
			this.binding = new ProblemMethodBinding(this.binding.original(), this.binding.selector, finalArgumentTypes, ProblemReasons.NotFound);
	}
}
 
Example 16
Source File: Reference.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
static void reportOnlyUselesslyReadLocal(BlockScope currentScope, LocalVariableBinding localBinding, boolean valueRequired) {
	if (localBinding.declaration == null)
		return;  // secret local
	if ((localBinding.declaration.bits & ASTNode.IsLocalDeclarationReachable) == 0)
		return;  // declaration is unreachable
	if (localBinding.useFlag >= LocalVariableBinding.USED)
		return;  // we're only interested in cases with only compound access (negative count)

	if (valueRequired) {
		// access is relevant
		localBinding.useFlag = LocalVariableBinding.USED;
		return;
	} else {
		localBinding.useFlag++;
		if (localBinding.useFlag != LocalVariableBinding.UNUSED) // have all negative counts been consumed?
			return; // still waiting to see more usages of this kind
	}
	// at this point we know we have something to report
	if (localBinding.declaration instanceof Argument) {
		// check compiler options to report against unused arguments
		MethodScope methodScope = currentScope.methodScope();
		if (methodScope != null && !methodScope.isLambdaScope()) { // lambda must be congruent with the descriptor.
			MethodBinding method = ((AbstractMethodDeclaration)methodScope.referenceContext()).binding;
			
			boolean shouldReport = !method.isMain();
			if (method.isImplementing()) {
				shouldReport &= currentScope.compilerOptions().reportUnusedParameterWhenImplementingAbstract;
			} else if (method.isOverriding()) {
				shouldReport &= currentScope.compilerOptions().reportUnusedParameterWhenOverridingConcrete;
			}
			
			if (shouldReport) {
				// report the case of an argument that is unread except through a special operator
				currentScope.problemReporter().unusedArgument(localBinding.declaration);
			}
		}
	} else {
		// report the case of a local variable that is unread except for a special operator
		currentScope.problemReporter().unusedLocalVariable(localBinding.declaration);
	}
	localBinding.useFlag = LocalVariableBinding.USED; // don't report again
}
 
Example 17
Source File: CastExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public TypeBinding resolveType(BlockScope scope) {
	// compute a new constant if the cast is effective

	this.constant = Constant.NotAConstant;
	this.implicitConversion = TypeIds.T_undefined;

	boolean exprContainCast = false;

	TypeBinding castType = this.resolvedType = this.type.resolveType(scope);
	if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_8) {
		this.expression.setExpressionContext(CASTING_CONTEXT);
		if (this.expression instanceof FunctionalExpression) {
			this.expression.setExpectedType(this.resolvedType);
			this.bits |= ASTNode.DisableUnnecessaryCastCheck;
		}
	}
	if (this.expression instanceof CastExpression) {
		this.expression.bits |= ASTNode.DisableUnnecessaryCastCheck;
		exprContainCast = true;
	}
	TypeBinding expressionType = this.expression.resolveType(scope);
	if (this.expression instanceof MessageSend) {
		MessageSend messageSend = (MessageSend) this.expression;
		MethodBinding methodBinding = messageSend.binding;
		if (methodBinding != null && methodBinding.isPolymorphic()) {
			messageSend.binding = scope.environment().updatePolymorphicMethodReturnType((PolymorphicMethodBinding) methodBinding, castType);
			if (TypeBinding.notEquals(expressionType, castType)) {
				expressionType = castType;
				this.bits |= ASTNode.DisableUnnecessaryCastCheck;
			}
		}
	}
	if (castType != null) {
		if (expressionType != null) {

			boolean nullAnnotationMismatch = scope.compilerOptions().isAnnotationBasedNullAnalysisEnabled
					&& NullAnnotationMatching.analyse(castType, expressionType, -1).isAnyMismatch();

			boolean isLegal = checkCastTypesCompatibility(scope, castType, expressionType, this.expression);
			if (isLegal) {
				this.expression.computeConversion(scope, castType, expressionType);
				if ((this.bits & ASTNode.UnsafeCast) != 0) { // unsafe cast
					if (scope.compilerOptions().reportUnavoidableGenericTypeProblems
							|| !(expressionType.isRawType() && this.expression.forcedToBeRaw(scope.referenceContext()))) {
						scope.problemReporter().unsafeCast(this, scope);
					}
				} else if (nullAnnotationMismatch) {
					// report null annotation issue at medium priority
					scope.problemReporter().unsafeNullnessCast(this, scope);
				} else {
					if (castType.isRawType() && scope.compilerOptions().getSeverity(CompilerOptions.RawTypeReference) != ProblemSeverities.Ignore){
						scope.problemReporter().rawTypeReference(this.type, castType);
					}
					if ((this.bits & (ASTNode.UnnecessaryCast|ASTNode.DisableUnnecessaryCastCheck)) == ASTNode.UnnecessaryCast) { // unnecessary cast
						if (!isIndirectlyUsed()) // used for generic type inference or boxing ?
							scope.problemReporter().unnecessaryCast(this);
					}
				}
			} else { // illegal cast
				if ((castType.tagBits & TagBits.HasMissingType) == 0) { // no complaint if secondary error
					scope.problemReporter().typeCastError(this, castType, expressionType);
				}
				this.bits |= ASTNode.DisableUnnecessaryCastCheck; // disable further secondary diagnosis
			}
		}
		this.resolvedType = castType.capture(scope, this.sourceEnd);
		if (exprContainCast) {
			checkNeedForCastCast(scope, this);
		}
	}
	return this.resolvedType;
}
 
Example 18
Source File: LambdaExpression.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, final FlowInfo flowInfo) {
	
	if (this.ignoreFurtherInvestigation) 
		return flowInfo;
	
	FlowInfo lambdaInfo = flowInfo.copy(); // what happens in vegas, stays in vegas ...
	ExceptionHandlingFlowContext methodContext =
			new ExceptionHandlingFlowContext(
					flowContext,
					this,
					this.binding.thrownExceptions,
					null,
					this.scope,
					FlowInfo.DEAD_END);

	// nullity and mark as assigned
	MethodBinding methodWithParameterDeclaration = argumentsTypeElided() ? this.descriptor : this.binding;
	AbstractMethodDeclaration.analyseArguments18(lambdaInfo, this.arguments, methodWithParameterDeclaration);

	if (this.arguments != null) {
		for (int i = 0, count = this.arguments.length; i < count; i++) {
			this.bits |= (this.arguments[i].bits & ASTNode.HasTypeAnnotations);
		}
	}
	
	lambdaInfo = this.body.analyseCode(this.scope, methodContext, lambdaInfo);
	
	// check for missing returning path for block body's ...
	if (this.body instanceof Block) {
		TypeBinding returnTypeBinding = expectedResultType();
		if ((returnTypeBinding == TypeBinding.VOID)) {
			if ((lambdaInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0 || ((Block) this.body).statements == null) {
				this.bits |= ASTNode.NeedFreeReturn;
			}
		} else {
			if (lambdaInfo != FlowInfo.DEAD_END) {
				this.scope.problemReporter().shouldReturn(returnTypeBinding, this);
			}
		}
	} else { // Expression
		if (currentScope.compilerOptions().isAnnotationBasedNullAnalysisEnabled 
				&& lambdaInfo.reachMode() == FlowInfo.REACHABLE)
		{
			Expression expression = (Expression)this.body;
			checkAgainstNullAnnotation(flowContext, expression, expression.nullStatus(lambdaInfo, flowContext));
		}
	}
	return flowInfo;
}
 
Example 19
Source File: ExceptionHandlingFlowContext.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
ExceptionHandlingFlowContext(
		FlowContext parent,
		ASTNode associatedNode,
		ReferenceBinding[] handledExceptions,
		int [] exceptionToCatchBlockMap,
		Argument [] catchArguments,
		FlowContext initializationParent,
		BlockScope scope,
		UnconditionalFlowInfo flowInfo) {

	super(parent, associatedNode);
	this.isMethodContext = scope == scope.methodScope();
	this.handledExceptions = handledExceptions;
	this.catchArguments = catchArguments;
	this.exceptionToCatchBlockMap = exceptionToCatchBlockMap;
	int count = handledExceptions.length, cacheSize = (count / ExceptionHandlingFlowContext.BitCacheSize) + 1;
	this.isReached = new int[cacheSize]; // none is reached by default
	this.isNeeded = new int[cacheSize]; // none is needed by default
	this.initsOnExceptions = new UnconditionalFlowInfo[count];
	boolean markExceptionsAndThrowableAsReached =
		!this.isMethodContext || scope.compilerOptions().reportUnusedDeclaredThrownExceptionExemptExceptionAndThrowable;
	for (int i = 0; i < count; i++) {
		ReferenceBinding handledException = handledExceptions[i];
		int catchBlock = this.exceptionToCatchBlockMap != null? this.exceptionToCatchBlockMap[i] : i;
		this.indexes.put(handledException, i); // key type  -> value index
		if (handledException.isUncheckedException(true)) {
			if (markExceptionsAndThrowableAsReached ||
					handledException.id != TypeIds.T_JavaLangThrowable &&
					handledException.id != TypeIds.T_JavaLangException) {
				this.isReached[i / ExceptionHandlingFlowContext.BitCacheSize] |= 1 << (i % ExceptionHandlingFlowContext.BitCacheSize);
			}
			this.initsOnExceptions[catchBlock] = flowInfo.unconditionalCopy();
		} else {
			this.initsOnExceptions[catchBlock] = FlowInfo.DEAD_END;
		}
	}
	if (!this.isMethodContext) {
		System.arraycopy(this.isReached, 0, this.isNeeded, 0, cacheSize);
	}
	this.initsOnReturn = FlowInfo.DEAD_END;
	this.initializationParent = initializationParent;
}
 
Example 20
Source File: CodeSnippetQualifiedNameReference.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.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);
}