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 break; case Binding.LOCAL: // reading a local variable LocalVariableBinding localBinding; if (!flowInfo.isDefinitelyAssigned(localBinding = (LocalVariableBinding) this.binding)) { if (localBinding.declaringScope instanceof CompilationUnitScope) currentScope.problemReporter().uninitializedGlobalVariable(localBinding, this); else 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; } checkNPE(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) { TypeBinding lastReceiverType = getGenericCast(i); if (lastReceiverType == null) { if (i == 0) { lastReceiverType = ((VariableBinding) this.binding).type; } else { lastReceiverType = this.otherBindings[i - 1].type; } } } } } return flowInfo; }
public FlowInfo analyseAssignment( BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo, Assignment assignment, boolean isCompound) { // 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 || !this.otherBindings[0].isStatic(); boolean complyTo14 = currentScope.compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4; FieldBinding lastFieldBinding = null; switch (this.bits & ASTNode.RestrictiveFlagMASK) { case Binding.FIELD: // reading a field lastFieldBinding = (FieldBinding) this.binding; break; case Binding.LOCAL: // first binding is 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; } checkNPE(currentScope, flowContext, flowInfo, true); } if (needValue) { manageEnclosingInstanceAccessIfNecessary(currentScope, flowInfo); // only for first binding } // all intermediate field accesses are read accesses if (this.otherBindings != null) { for (int i = 0; i < otherBindingsCount - 1; i++) { lastFieldBinding = this.otherBindings[i]; needValue = !this.otherBindings[i + 1].isStatic(); } lastFieldBinding = this.otherBindings[otherBindingsCount - 1]; } if (isCompound) { TypeBinding lastReceiverType; switch (otherBindingsCount) { case 0: lastReceiverType = this.actualReceiverType; break; case 1: lastReceiverType = ((VariableBinding) this.binding).type; break; default: lastReceiverType = this.otherBindings[otherBindingsCount - 2].type; break; } } if (assignment.expression != null) { flowInfo = assignment .expression .analyseCode(currentScope, flowContext, flowInfo) .unconditionalInits(); } // equivalent to valuesRequired[maxOtherBindings] TypeBinding lastReceiverType; switch (otherBindingsCount) { case 0: lastReceiverType = this.actualReceiverType; break; case 1: lastReceiverType = ((VariableBinding) this.binding).type; break; default: lastReceiverType = this.otherBindings[otherBindingsCount - 2].type; break; } return flowInfo; }