@Override public String toString() { return "FieldFlow<" + source.format("%h.%n") + "\n" + getState() + ">"; }
@Override public void forNullFieldValue(JavaConstant receiver, AnalysisField field) { FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver); if (!fieldTypeFlow.getState().canBeNull()) { /* Signal that the field can contain null. */ fieldTypeFlow.addState(bb, TypeState.forNull()); } }
/** * Returns all possible types that this field can have. The result is not context sensitive, * i.e., it is a union of all types found in all contexts. */ public TypeState getTypeState() { if (getType().getStorageKind() != JavaKind.Object) { return null; } else if (isStatic()) { return staticFieldFlow.getState(); } else { return getInstanceFieldTypeState(); } }
@Override public void forNonNullFieldValue(JavaConstant receiver, AnalysisField field, JavaConstant fieldValue) { AnalysisType fieldType = bb.getMetaAccess().lookupJavaType(bb.getSnippetReflectionProvider().asObject(Object.class, fieldValue).getClass()); assert fieldType.isInstantiated(); /* * *ALL* constants are scanned after each analysis iteration, thus the fieldType will * eventually be added to the AllInstantiatedTypeFlow and the field type flow will * eventually be updated. */ if (bb.getAllInstantiatedTypeFlow().getState().containsType(fieldType)) { /* Add the constant value object to the field's type flow. */ FieldTypeFlow fieldTypeFlow = getFieldTypeFlow(field, receiver); AnalysisObject constantObject = bb.analysisPolicy().createConstantObject(bb, fieldValue, fieldType); if (!fieldTypeFlow.getState().isUnknown() && !fieldTypeFlow.getState().containsObject(constantObject)) { /* Add the new constant to the field's flow state. */ TypeState constantTypeState = TypeState.forNonNullObject(bb, constantObject); fieldTypeFlow.addState(bb, constantTypeState); } } }