FIR checker: revisit per-label iterations to avoid !!

This commit is contained in:
Jinseong Jeon
2020-12-04 10:04:27 -08:00
committed by Mikhail Glukhikh
parent 762e315ce3
commit c959ad7911
4 changed files with 14 additions and 16 deletions
@@ -128,15 +128,14 @@ class PropertyInitializationInfoCollector(private val localProperties: Set<FirPr
}
internal fun <P : PathAwareControlFlowInfo<P, S>, S : ControlFlowInfo<S, K, EventOccurrencesRange>, K : Any> addRange(
info: P,
pathAwareInfo: P,
key: K,
range: EventOccurrencesRange,
constructor: (PersistentMap<EdgeLabel, S>) -> P
): P {
var resultMap = persistentMapOf<EdgeLabel, S>()
// before: { |-> { p1 |-> PI1 }, l1 |-> { p2 |-> PI2 } }
for (label in info.keys) {
val dataPerLabel = info[label]!!
for ((label, dataPerLabel) in pathAwareInfo) {
val existingKind = dataPerLabel[key] ?: EventOccurrencesRange.ZERO
val kind = existingKind + range
resultMap = resultMap.put(label, dataPerLabel.put(key, kind))
@@ -89,9 +89,9 @@ object FirCallsEffectAnalyzer : FirControlFlowChecker() {
for ((symbol, effectDeclaration) in functionalTypeEffects) {
graph.exitNode.previousCfgNodes.forEach { node ->
val requiredRange = effectDeclaration.kind
val info = invocationData.getValue(node)
for (label in info.keys) {
if (investigate(info.getValue(label), symbol, requiredRange, function, reporter)) {
val pathAwareInfo = invocationData.getValue(node)
for (info in pathAwareInfo.values) {
if (investigate(info, symbol, requiredRange, function, reporter)) {
// To avoid duplicate reports, stop investigating remaining paths once reported.
break
}
@@ -49,8 +49,8 @@ object FirPropertyInitializationAnalyzer : AbstractFirPropertyInitializationChec
if (symbol !in localProperties) return
if (symbol.fir.isLateInit) return
val pathAwareInfo = data.getValue(node)
for (label in pathAwareInfo.keys) {
if (investigate(pathAwareInfo[label]!!, symbol, node)) {
for (info in pathAwareInfo.values) {
if (investigate(info, symbol, node)) {
// To avoid duplicate reports, stop investigating remaining paths if the property is not initialized at any path.
break
}
@@ -44,8 +44,8 @@ object UnusedChecker : FirControlFlowChecker() {
override fun visitVariableAssignmentNode(node: VariableAssignmentNode) {
val variableSymbol = (node.fir.calleeReference as? FirResolvedNamedReference)?.resolvedSymbol ?: return
val dataPerNode = data[node] ?: return
for (label in dataPerNode.keys) {
val data = dataPerNode[label]!![variableSymbol] ?: continue
for (dataPerLabel in dataPerNode.values) {
val data = dataPerLabel[variableSymbol] ?: continue
if (data == VariableStatus.ONLY_WRITTEN_NEVER_READ) {
// todo: report case like "a += 1" where `a` `doesn't writes` different way (special for Idea)
val source = node.fir.lValue.source
@@ -60,8 +60,8 @@ object UnusedChecker : FirControlFlowChecker() {
val variableSymbol = node.fir.symbol
if (variableSymbol.isLoopIterator) return
val dataPerNode = data[node] ?: return
for (label in dataPerNode.keys) {
val data = dataPerNode[label]!![variableSymbol] ?: continue
for (dataPerLabel in dataPerNode.values) {
val data = dataPerLabel[variableSymbol] ?: continue
val variableSource = variableSymbol.fir.source.takeIf { it?.elementType != KtNodeTypes.DESTRUCTURING_DECLARATION }
when {
@@ -242,14 +242,13 @@ object UnusedChecker : FirControlFlowChecker() {
}
private fun update(
info: PathAwareVariableStatusInfo,
pathAwareInfo: PathAwareVariableStatusInfo,
symbol: FirPropertySymbol,
updater: (VariableStatus?) -> VariableStatus?,
): PathAwareVariableStatusInfo {
var resultMap = persistentMapOf<EdgeLabel, VariableStatusInfo>()
var changed = false
for (label in info.keys) {
val dataPerLabel = info[label]!!
for ((label, dataPerLabel) in pathAwareInfo) {
val v = updater.invoke(dataPerLabel[symbol])
if (v != null) {
resultMap = resultMap.put(label, dataPerLabel.put(symbol, v))
@@ -258,7 +257,7 @@ object UnusedChecker : FirControlFlowChecker() {
resultMap = resultMap.put(label, dataPerLabel)
}
}
return if (changed) PathAwareVariableStatusInfo(resultMap) else info
return if (changed) PathAwareVariableStatusInfo(resultMap) else pathAwareInfo
}
}