DataValue (AbstractInsnNode insn, List<? extends DataValue> values) { int insnIndex = methodNode.instructions.indexOf(insn); int opCode = insn.getOpcode(); switch (opCode) { case Opcodes.MULTIANEWARRAY -> { return DataValue.LocalDataValue; } case Opcodes.INVOKEDYNAMIC -> { // Lambda creation (w/o invocation) and StringConcatFactory have no side-effect InvokeDynamicInsnNode indy = (InvokeDynamicInsnNode)insn; if (LambdaIndy.from(indy) == null && !ClassDataIndexer.STRING_CONCAT_FACTORY.equals(indy.bsm.getOwner())) { effects[insnIndex] = EffectQuantum.TopEffectQuantum; } return (ASMUtils.getReturnSizeFast((indy).desc) == 1) ? DataValue.UnknownDataValue1 : DataValue.UnknownDataValue2; } case Opcodes.INVOKEVIRTUAL, Opcodes.INVOKESPECIAL, Opcodes.INVOKESTATIC, Opcodes.INVOKEINTERFACE -> { boolean stable = opCode == Opcodes.INVOKESPECIAL || opCode == Opcodes.INVOKESTATIC; MethodInsnNode mNode = ((MethodInsnNode)insn); DataValue[] data = values.toArray(DataValue.EMPTY); Member method = new Member(mNode.owner, mNode.name, mNode.desc); EKey key = new EKey(method, Direction.Pure, stable); EffectQuantum quantum = new EffectQuantum.CallQuantum(key, data, opCode == Opcodes.INVOKESTATIC); DataValue result; if (ASMUtils.getReturnSizeFast(mNode.desc) == 1) { if (ASMUtils.isReferenceReturnType(mNode.desc)) { result = new DataValue.ReturnDataValue(key); } else { result = DataValue.UnknownDataValue1; } } else { result = DataValue.UnknownDataValue2; } if (HardCodedPurity.getInstance().isPureMethod(method)) { quantum = null; result = HardCodedPurity.getInstance().getReturnValueForPureMethod(method); } else if (HardCodedPurity.getInstance().isThisChangingMethod(method)) { DataValue receiver = ArrayUtil.getFirstElement(data); if (receiver == DataValue.ThisDataValue) { quantum = EffectQuantum.ThisChangeQuantum; } else if (receiver == DataValue.LocalDataValue || receiver == DataValue.OwnedDataValue) { quantum = null; } else if (receiver instanceof DataValue.ParameterDataValue) { quantum = new EffectQuantum.ParamChangeQuantum(((DataValue.ParameterDataValue)receiver).n); } if (HardCodedPurity.getInstance().isBuilderChainCall(method)) { // mostly to support string concatenation result = receiver; } } effects[insnIndex] = quantum; return result; } } return null; }