Java Code Examples for org.eclipse.jdt.internal.compiler.lookup.TypeBinding#NULL
The following examples show how to use
org.eclipse.jdt.internal.compiler.lookup.TypeBinding#NULL .
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: BindingKeyResolver.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
private TypeBinding getBaseTypeBinding(char[] signature) { switch (signature[0]) { case 'I' : return TypeBinding.INT; case 'Z' : return TypeBinding.BOOLEAN; case 'V' : return TypeBinding.VOID; case 'C' : return TypeBinding.CHAR; case 'D' : return TypeBinding.DOUBLE; case 'B' : return TypeBinding.BYTE; case 'F' : return TypeBinding.FLOAT; case 'J' : return TypeBinding.LONG; case 'S' : return TypeBinding.SHORT; case 'N': return TypeBinding.NULL; default : return null; } }
Example 2
Source File: ASTNode.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
private static int checkInvocationArgument(BlockScope scope, Expression argument, TypeBinding parameterType, TypeBinding argumentType, TypeBinding originalParameterType) { argument.computeConversion(scope, parameterType, argumentType); if (argumentType != TypeBinding.NULL && parameterType.kind() == Binding.WILDCARD_TYPE) { // intersection types are tolerated WildcardBinding wildcard = (WildcardBinding) parameterType; if (wildcard.boundKind != Wildcard.SUPER) { return INVOCATION_ARGUMENT_WILDCARD; } } TypeBinding checkedParameterType = parameterType; // originalParameterType == null ? parameterType : originalParameterType; if (TypeBinding.notEquals(argumentType, checkedParameterType) && argumentType.needsUncheckedConversion(checkedParameterType)) { scope.problemReporter().unsafeTypeConversion(argument, argumentType, checkedParameterType); return INVOCATION_ARGUMENT_UNCHECKED; } return INVOCATION_ARGUMENT_OK; }
Example 3
Source File: CastExpression.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
/** * Casting an enclosing instance will considered as useful if removing it would actually bind to a different type */ public static void checkNeedForEnclosingInstanceCast(BlockScope scope, Expression enclosingInstance, TypeBinding enclosingInstanceType, TypeBinding memberType) { if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return; TypeBinding castedExpressionType = ((CastExpression)enclosingInstance).expression.resolvedType; if (castedExpressionType == null) return; // cannot do better // obvious identity cast if (TypeBinding.equalsEquals(castedExpressionType, enclosingInstanceType)) { scope.problemReporter().unnecessaryCast((CastExpression)enclosingInstance); } else if (castedExpressionType == TypeBinding.NULL){ return; // tolerate null enclosing instance cast } else { TypeBinding alternateEnclosingInstanceType = castedExpressionType; if (castedExpressionType.isBaseType() || castedExpressionType.isArrayType()) return; // error case if (TypeBinding.equalsEquals(memberType, scope.getMemberType(memberType.sourceName(), (ReferenceBinding) alternateEnclosingInstanceType))) { scope.problemReporter().unnecessaryCast((CastExpression)enclosingInstance); } } }
Example 4
Source File: FakedTrackingVariable.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
/** * Before analyzing an assignment of this shape: <code>singleName = new Allocation()</code> * connect any tracking variable of the LHS with the allocation on the RHS. * Also the assignment is temporarily stored in the tracking variable in case we need to * report errors because the assignment leaves the old LHS value unclosed. * In this case the assignment should be used as the error location. * * @param location the assignment/local declaration being analyzed * @param local the local variable being assigned to * @param rhs the rhs of the assignment resp. the initialization of the local variable declaration. * <strong>Precondition:</strong> client has already checked that the resolved type of this expression is either a closeable type or NULL. */ public static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, Expression rhs, FlowInfo flowInfo) { FakedTrackingVariable closeTracker = null; if (containsAllocation(rhs)) { closeTracker = local.closeTracker; if (closeTracker == null) { if (rhs.resolvedType != TypeBinding.NULL) { // not NULL means valid closeable as per method precondition closeTracker = new FakedTrackingVariable(local, location, flowInfo, null, FlowInfo.UNKNOWN); if (local.isParameter()) { closeTracker.globalClosingState |= OWNED_BY_OUTSIDE; } } } if (closeTracker != null) { closeTracker.currentAssignment = location; preConnectTrackerAcrossAssignment(location, local, flowInfo, closeTracker, rhs); } } }
Example 5
Source File: CodeSnippetReturnStatement.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public void generateStoreSaveValueIfNecessary(CodeStream codeStream){ // push receiver codeStream.aload_0(); // push the 2 parameters of "setResult(Object, Class)" if (this.expression == null || this.expression.resolvedType == TypeBinding.VOID) { // expressionType == VoidBinding if code snippet is the expression "System.out.println()" // push null codeStream.aconst_null(); // void.class codeStream.generateClassLiteralAccessForType(TypeBinding.VOID, null); } else { // swap with expression int valueTypeID = this.expression.resolvedType.id; if (valueTypeID == T_long || valueTypeID == T_double) { codeStream.dup_x2(); codeStream.pop(); } else { codeStream.swap(); } // generate wrapper if needed if (this.expression.resolvedType.isBaseType() && this.expression.resolvedType != TypeBinding.NULL) { codeStream.generateBoxingConversion(this.expression.resolvedType.id); } // generate the expression type codeStream.generateClassLiteralAccessForType(this.expression.resolvedType, null); } // generate the invoke virtual to "setResult(Object,Class)" codeStream.invoke(Opcodes.OPC_invokevirtual, this.setResultMethod, null /* default declaringClass */); }
Example 6
Source File: ArrayReference.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public void generateAssignment(BlockScope currentScope, CodeStream codeStream, Assignment assignment, boolean valueRequired) { int pc = codeStream.position; this.receiver.generateCode(currentScope, codeStream, true); if (this.receiver instanceof CastExpression // ((type[])null)[0] && ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ codeStream.checkcast(this.receiver.resolvedType); } codeStream.recordPositionsFrom(pc, this.sourceStart); this.position.generateCode(currentScope, codeStream, true); assignment.expression.generateCode(currentScope, codeStream, true); codeStream.arrayAtPut(this.resolvedType.id, valueRequired); if (valueRequired) { codeStream.generateImplicitConversion(assignment.implicitConversion); } }
Example 7
Source File: ArrayReference.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
/** * Code generation for a array reference */ public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { int pc = codeStream.position; this.receiver.generateCode(currentScope, codeStream, true); if (this.receiver instanceof CastExpression // ((type[])null)[0] && ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ codeStream.checkcast(this.receiver.resolvedType); } this.position.generateCode(currentScope, codeStream, true); codeStream.arrayAt(this.resolvedType.id); // Generating code for the potential runtime type checking 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 : this.resolvedType.id) { case T_long : case T_double : codeStream.pop2(); break; default : codeStream.pop(); } } codeStream.recordPositionsFrom(pc, this.sourceStart); }
Example 8
Source File: ArrayReference.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public void generateCompoundAssignment(BlockScope currentScope, CodeStream codeStream, Expression expression, int operator, int assignmentImplicitConversion, boolean valueRequired) { this.receiver.generateCode(currentScope, codeStream, true); if (this.receiver instanceof CastExpression // ((type[])null)[0] && ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ codeStream.checkcast(this.receiver.resolvedType); } this.position.generateCode(currentScope, codeStream, true); codeStream.dup2(); codeStream.arrayAt(this.resolvedType.id); int operationTypeID; switch(operationTypeID = (this.implicitConversion & TypeIds.IMPLICIT_CONVERSION_MASK) >> 4) { case T_JavaLangString : case T_JavaLangObject : case T_undefined : codeStream.generateStringConcatenationAppend(currentScope, null, expression); break; default : // promote the array reference to the suitable operation type codeStream.generateImplicitConversion(this.implicitConversion); // generate the increment value (will by itself be promoted to the operation value) if (expression == IntLiteral.One) { // prefix operation codeStream.generateConstant(expression.constant, this.implicitConversion); } else { expression.generateCode(currentScope, codeStream, true); } // perform the operation codeStream.sendOperator(operator, operationTypeID); // cast the value back to the array reference type codeStream.generateImplicitConversion(assignmentImplicitConversion); } codeStream.arrayAtPut(this.resolvedType.id, valueRequired); }
Example 9
Source File: ArrayReference.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public void generatePostIncrement(BlockScope currentScope, CodeStream codeStream, CompoundAssignment postIncrement, boolean valueRequired) { this.receiver.generateCode(currentScope, codeStream, true); if (this.receiver instanceof CastExpression // ((type[])null)[0] && ((CastExpression)this.receiver).innermostCastedExpression().resolvedType == TypeBinding.NULL){ codeStream.checkcast(this.receiver.resolvedType); } this.position.generateCode(currentScope, codeStream, true); codeStream.dup2(); codeStream.arrayAt(this.resolvedType.id); if (valueRequired) { switch(this.resolvedType.id) { case TypeIds.T_long : case TypeIds.T_double : codeStream.dup2_x2(); break; default : codeStream.dup_x2(); break; } } codeStream.generateImplicitConversion(this.implicitConversion); codeStream.generateConstant( postIncrement.expression.constant, this.implicitConversion); codeStream.sendOperator(postIncrement.operator, this.implicitConversion & TypeIds.COMPILE_TYPE_MASK); codeStream.generateImplicitConversion( postIncrement.preAssignImplicitConversion); codeStream.arrayAtPut(this.resolvedType.id, false); }
Example 10
Source File: CastExpression.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
/** * Cast expressions will considered as useful if removing them all would actually bind to a different method * (no fine grain analysis on per casted argument basis, simply separate widening cast from narrowing ones) */ public static void checkNeedForArgumentCasts(BlockScope scope, Expression receiver, TypeBinding receiverType, MethodBinding binding, Expression[] arguments, TypeBinding[] argumentTypes, final InvocationSite invocationSite) { if (scope.compilerOptions().getSeverity(CompilerOptions.UnnecessaryTypeCheck) == ProblemSeverities.Ignore) return; int length = argumentTypes.length; // iterate over arguments, and retrieve original argument types (before cast) TypeBinding[] rawArgumentTypes = argumentTypes; for (int i = 0; i < length; i++) { Expression argument = arguments[i]; if (argument instanceof CastExpression) { // narrowing conversion on base type may change value, thus necessary if ((argument.bits & ASTNode.UnnecessaryCast) == 0 && argument.resolvedType.isBaseType()) { continue; } TypeBinding castedExpressionType = ((CastExpression)argument).expression.resolvedType; if (castedExpressionType == null) return; // cannot do better // obvious identity cast if (TypeBinding.equalsEquals(castedExpressionType, argumentTypes[i])) { scope.problemReporter().unnecessaryCast((CastExpression)argument); } else if (castedExpressionType == TypeBinding.NULL){ continue; // tolerate null argument cast } else if ((argument.implicitConversion & TypeIds.BOXING) != 0) { continue; // boxing has a side effect: (int) char is not boxed as simple char } else { if (rawArgumentTypes == argumentTypes) { System.arraycopy(rawArgumentTypes, 0, rawArgumentTypes = new TypeBinding[length], 0, length); } // retain original argument type rawArgumentTypes[i] = castedExpressionType; } } } // perform alternate lookup with original types if (rawArgumentTypes != argumentTypes) { checkAlternateBinding(scope, receiver, receiverType, binding, arguments, argumentTypes, rawArgumentTypes, invocationSite); } }
Example 11
Source File: ThrowStatement.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
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 12
Source File: CodeSnippetAllocationExpression.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) { int pc = codeStream.position; MethodBinding codegenBinding = this.binding.original(); ReferenceBinding allocatedType = codegenBinding.declaringClass; if (codegenBinding.canBeSeenBy(allocatedType, this, currentScope)) { codeStream.new_(this.type, allocatedType); if (valueRequired) { codeStream.dup(); } // better highlight for allocation: display the type individually codeStream.recordPositionsFrom(pc, this.type.sourceStart); // handling innerclass instance allocation - enclosing instance arguments if (allocatedType.isNestedType()) { codeStream.generateSyntheticEnclosingInstanceValues( currentScope, allocatedType, enclosingInstance(), this); } // generate the arguments for constructor if (this.arguments != null) { for (int i = 0, count = this.arguments.length; i < count; i++) { this.arguments[i].generateCode(currentScope, codeStream, true); } } // handling innerclass instance allocation - outer local arguments if (allocatedType.isNestedType()) { codeStream.generateSyntheticOuterArgumentValues( currentScope, allocatedType, this); } // invoke constructor codeStream.invoke(Opcodes.OPC_invokespecial, codegenBinding, null /* default declaringClass */, this.typeArguments); } else { // private emulation using reflect codeStream.generateEmulationForConstructor(currentScope, codegenBinding); // generate arguments if (this.arguments != null) { int argsLength = this.arguments.length; codeStream.generateInlinedValue(argsLength); codeStream.newArray(currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1)); codeStream.dup(); for (int i = 0; i < argsLength; i++) { codeStream.generateInlinedValue(i); this.arguments[i].generateCode(currentScope, codeStream, true); TypeBinding parameterBinding = codegenBinding.parameters[i]; if (parameterBinding.isBaseType() && parameterBinding != TypeBinding.NULL) { codeStream.generateBoxingConversion(codegenBinding.parameters[i].id); } codeStream.aastore(); if (i < argsLength - 1) { codeStream.dup(); } } } else { codeStream.generateInlinedValue(0); codeStream.newArray(currentScope.createArrayType(currentScope.getType(TypeConstants.JAVA_LANG_OBJECT, 3), 1)); } codeStream.invokeJavaLangReflectConstructorNewInstance(); codeStream.checkcast(allocatedType); } codeStream.recordPositionsFrom(pc, this.sourceStart); }
Example 13
Source File: SingleNameReference.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
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 14
Source File: Expression.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
/** * Base types need that the widening is explicitly done by the compiler using some bytecode like i2f. * Also check unsafe type operations. */ public void computeConversion(Scope scope, TypeBinding runtimeType, TypeBinding compileTimeType) { if (runtimeType == null || compileTimeType == null) return; if (this.implicitConversion != 0) return; // already set independently // it is possible for a Byte to be unboxed to a byte & then converted to an int // but it is not possible for a byte to become Byte & then assigned to an Integer, // or to become an int before boxed into an Integer if (runtimeType != TypeBinding.NULL && runtimeType.isBaseType()) { if (!compileTimeType.isBaseType()) { TypeBinding unboxedType = scope.environment().computeBoxingType(compileTimeType); this.implicitConversion = TypeIds.UNBOXING; scope.problemReporter().autoboxing(this, compileTimeType, runtimeType); compileTimeType = unboxedType; } } else if (compileTimeType != TypeBinding.NULL && compileTimeType.isBaseType()) { TypeBinding boxedType = scope.environment().computeBoxingType(runtimeType); if (TypeBinding.equalsEquals(boxedType, runtimeType)) // Object o = 12; boxedType = compileTimeType; this.implicitConversion = TypeIds.BOXING | (boxedType.id << 4) + compileTimeType.id; scope.problemReporter().autoboxing(this, compileTimeType, scope.environment().computeBoxingType(boxedType)); return; } else if (this.constant != Constant.NotAConstant && this.constant.typeID() != TypeIds.T_JavaLangString) { this.implicitConversion = TypeIds.BOXING; return; } int compileTimeTypeID, runtimeTypeID; if ((compileTimeTypeID = compileTimeType.id) >= TypeIds.T_LastWellKnownTypeId) { // e.g. ? extends String ==> String (103227); >= TypeIds.T_LastWellKnownTypeId implies TypeIds.NoId compileTimeTypeID = compileTimeType.erasure().id == TypeIds.T_JavaLangString ? TypeIds.T_JavaLangString : TypeIds.T_JavaLangObject; } else if (runtimeType.isPrimitiveType() && compileTimeType instanceof ReferenceBinding && !compileTimeType.isBoxedPrimitiveType()) { compileTimeTypeID = TypeIds.T_JavaLangObject; // treatment is the same as for jlO. } switch (runtimeTypeID = runtimeType.id) { case T_byte : case T_short : case T_char : if (compileTimeTypeID == TypeIds.T_JavaLangObject) { this.implicitConversion |= (runtimeTypeID << 4) + compileTimeTypeID; } else { this.implicitConversion |= (TypeIds.T_int << 4) + compileTimeTypeID; } break; case T_JavaLangString : case T_float : case T_boolean : case T_double : case T_int : //implicitConversion may result in i2i which will result in NO code gen case T_long : this.implicitConversion |= (runtimeTypeID << 4) + compileTimeTypeID; break; default : // regular object ref // if (compileTimeType.isRawType() && runtimeTimeType.isBoundParameterizedType()) { // scope.problemReporter().unsafeRawExpression(this, compileTimeType, runtimeTimeType); // } } }
Example 15
Source File: FakedTrackingVariable.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
/** * Given the rhs of an assignment or local declaration has a (Auto)Closeable type (or null), setup for leak analysis now: * Create or re-use a tracking variable, and wire and initialize everything. * @param scope scope containing the assignment * @param upstreamInfo info without analysis of the rhs, use this to determine the status of a resource being disconnected * @param flowInfo info with analysis of the rhs, use this for recording resource status because this will be passed downstream * @param flowContext * @param location where to report warnigs/errors against * @param rhs the right hand side of the assignment, this expression is to be analyzed. * The caller has already checked that the rhs is either of a closeable type or null. * @param local the local variable into which the rhs is being assigned */ public static void handleResourceAssignment(BlockScope scope, FlowInfo upstreamInfo, FlowInfo flowInfo, FlowContext flowContext, ASTNode location, Expression rhs, LocalVariableBinding local) { // does the LHS (local) already have a tracker, indicating we may leak a resource by the assignment? FakedTrackingVariable previousTracker = null; FakedTrackingVariable disconnectedTracker = null; if (local.closeTracker != null) { // assigning to a variable already holding an AutoCloseable, has it been closed before? previousTracker = local.closeTracker; int nullStatus = upstreamInfo.nullStatus(local); if (nullStatus != FlowInfo.NULL && nullStatus != FlowInfo.UNKNOWN) // only if previous value may be relevant disconnectedTracker = previousTracker; // report error below, unless we have a self-wrap assignment } rhsAnalyis: if (rhs.resolvedType != TypeBinding.NULL) { // new value is AutoCloseable, start tracking, possibly re-using existing tracker var: FakedTrackingVariable rhsTrackVar = getCloseTrackingVariable(rhs, flowInfo, flowContext); if (rhsTrackVar != null) { // 1. if RHS has a tracking variable... if (local.closeTracker == null) { // null shouldn't occur but let's play safe: if (rhsTrackVar.originalBinding != null) local.closeTracker = rhsTrackVar; // a.: let fresh LHS share it if (rhsTrackVar.currentAssignment == location) { // pre-set tracker from lhs - passed from outside? // now it's a fresh resource rhsTrackVar.globalClosingState &= ~(SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE); } } else { if (rhs instanceof AllocationExpression || rhs instanceof ConditionalExpression) { if (rhsTrackVar == disconnectedTracker) return; // b.: self wrapper: res = new Wrap(res); -> done! if (local.closeTracker == rhsTrackVar && ((rhsTrackVar.globalClosingState & OWNED_BY_OUTSIDE) != 0)) { // c.: assigning a fresh resource (pre-connected alloc) // to a local previously holding an alien resource -> start over local.closeTracker = new FakedTrackingVariable(local, location, flowInfo, flowContext, FlowInfo.NULL); // still check disconnectedTracker below break rhsAnalyis; } } local.closeTracker = rhsTrackVar; // d.: conflicting LHS and RHS, proceed with recordErrorLocation below } // keep close-status of RHS unchanged across this assignment } else if (previousTracker != null) { // 2. re-use tracking variable from the LHS? FlowContext currentFlowContext = flowContext; checkReuseTracker : { if (previousTracker.tryContext != null) { while (currentFlowContext != null) { if (previousTracker.tryContext == currentFlowContext) { // "previous" location was the finally block of the current try statement. // -> This is not a re-assignment. // see https://bugs.eclipse.org/388996 break checkReuseTracker; } currentFlowContext = currentFlowContext.parent; } } // re-assigning from a fresh value, mark as not-closed again: if ((previousTracker.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0 && flowInfo.hasNullInfoFor(previousTracker.binding)) // avoid spilling info into a branch that doesn't see the corresponding resource flowInfo.markAsDefinitelyNull(previousTracker.binding); local.closeTracker = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, previousTracker); } } else { // 3. no re-use, create a fresh tracking variable: rhsTrackVar = analyseCloseableExpression(flowInfo, flowContext, local, location, rhs, null); if (rhsTrackVar != null) { local.closeTracker = rhsTrackVar; // a fresh resource, mark as not-closed: if ((rhsTrackVar.globalClosingState & (SHARED_WITH_OUTSIDE|OWNED_BY_OUTSIDE)) == 0) flowInfo.markAsDefinitelyNull(rhsTrackVar.binding); // TODO(stephan): this might be useful, but I could not find a test case for it: // if (flowContext.initsOnFinally != null) // flowContext.initsOnFinally.markAsDefinitelyNonNull(trackerBinding); } } } if (disconnectedTracker != null) { if (disconnectedTracker.innerTracker != null && disconnectedTracker.innerTracker.binding.declaringScope == scope) { // discard tracker for the wrapper but keep the inner: disconnectedTracker.innerTracker.outerTracker = null; scope.pruneWrapperTrackingVar(disconnectedTracker); } else { int upstreamStatus = upstreamInfo.nullStatus(disconnectedTracker.binding); if (upstreamStatus != FlowInfo.NON_NULL) disconnectedTracker.recordErrorLocation(location, upstreamStatus); } } }
Example 16
Source File: StackMapFrameCodeStream.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
/** * Macro for building a class descriptor object */ public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBinding syntheticFieldBinding) { if (accessedType.isBaseType() && accessedType != TypeBinding.NULL) { getTYPE(accessedType.id); return; } if (this.targetLevel >= ClassFileConstants.JDK1_5) { // generation using the new ldc_w bytecode this.ldc(accessedType); } else { // use in CLDC mode BranchLabel endLabel = new BranchLabel(this); if (syntheticFieldBinding != null) { // non interface case fieldAccess(Opcodes.OPC_getstatic, syntheticFieldBinding, null /* default declaringClass */); dup(); ifnonnull(endLabel); pop(); } /* Macro for building a class descriptor object... using or not a field cache to store it into... this sequence is responsible for building the actual class descriptor. If the fieldCache is set, then it is supposed to be the body of a synthetic access method factoring the actual descriptor creation out of the invocation site (saving space). If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since we have no way to get a hand on the field cache to do better. */ // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError ExceptionLabel classNotFoundExceptionHandler = new ExceptionLabel(this, TypeBinding.NULL /*represents ClassNotFoundException*/); classNotFoundExceptionHandler.placeStart(); this.ldc(accessedType == TypeBinding.NULL ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$ invokeClassForName(); /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565 if (accessedType == BaseTypes.NullBinding) { this.ldc("java.lang.Object"); //$NON-NLS-1$ } else if (accessedType.isArrayType()) { this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.')); } else { // we make it an array type (to avoid class initialization) this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$ } this.invokeClassForName(); if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class this.invokeJavaLangClassGetComponentType(); } */ /* We need to protect the runtime code from binary inconsistencies in case the accessedType is missing, the ClassNotFoundException has to be converted into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */ classNotFoundExceptionHandler.placeEnd(); if (syntheticFieldBinding != null) { // non interface case dup(); fieldAccess(Opcodes.OPC_putstatic, syntheticFieldBinding, null /* default declaringClass */); } int fromPC = this.position; goto_(endLabel); int savedStackDepth = this.stackDepth; // Generate the body of the exception handler /* ClassNotFoundException on stack -- the class literal could be doing more things on the stack, which means that the stack may not be empty at this point in the above code gen. So we save its state and restart it from 1. */ pushExceptionOnStack(TypeBinding.NULL);/*represents ClassNotFoundException*/ classNotFoundExceptionHandler.place(); // Transform the current exception, and repush and throw a // NoClassDefFoundError(ClassNotFound.getMessage()) newNoClassDefFoundError(); dup_x1(); swap(); // Retrieve the message from the old exception invokeThrowableGetMessage(); // Send the constructor taking a message string as an argument invokeNoClassDefFoundErrorStringConstructor(); athrow(); endLabel.place(); addStackMarker(fromPC, this.position); this.stackDepth = savedStackDepth; } }