private DfaValue popQualifier( MethodCallInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) { @NotNull final DfaValue qualifier = memState.pop(); boolean unboxing = instruction.getMethodType() == MethodCallInstruction.MethodType.UNBOXING; NullabilityProblem problem = unboxing ? NullabilityProblem.unboxingNullable : NullabilityProblem.callNPE; PsiExpression anchor = unboxing ? instruction.getContext() : instruction.getCallExpression(); if (!checkNotNullable(memState, qualifier, problem, anchor)) { forceNotNull(runner, memState, qualifier); } return qualifier; }
@NotNull private DfaValue getMethodResultValue( MethodCallInstruction instruction, @Nullable DfaValue qualifierValue, DfaValueFactory factory) { DfaValue precalculated = instruction.getPrecalculatedReturnValue(); if (precalculated != null) { return precalculated; } final PsiType type = instruction.getResultType(); final MethodCallInstruction.MethodType methodType = instruction.getMethodType(); if (methodType == MethodCallInstruction.MethodType.UNBOXING) { return factory.getBoxedFactory().createUnboxed(qualifierValue); } if (methodType == MethodCallInstruction.MethodType.BOXING) { DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue); return boxed == null ? factory.createTypeValue(type, Nullness.NOT_NULL) : boxed; } if (methodType == MethodCallInstruction.MethodType.CAST) { assert qualifierValue != null; if (qualifierValue instanceof DfaConstValue) { Object casted = TypeConversionUtil.computeCastTo(((DfaConstValue) qualifierValue).getValue(), type); return factory .getConstFactory() .createFromValue(casted, type, ((DfaConstValue) qualifierValue).getConstant()); } return qualifierValue; } if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) { Nullness nullability = myReturnTypeNullability.get(instruction); if (nullability == Nullness.UNKNOWN && factory.isUnknownMembersAreNullable()) { nullability = Nullness.NULLABLE; } return factory.createTypeValue(type, nullability); } return DfaUnknownValue.getInstance(); }