in src/org/jetbrains/r/inspections/UnusedVariableInspection.kt [36:88]
override fun visitAssignmentStatement(element: RAssignmentStatement) {
val assignee = element.assignee ?: return
if (RPsiUtil.isReturnValue(element)) {
return
}
if (isInplaceAssignment(assignee)) {
return
}
// not supported
if (element.isClosureAssignment) {
return
}
val function = PsiTreeUtil.getParentOfType(element, RFunctionExpression::class.java) ?: return
val name = assignee.name
val localVariableInfo = function.getLocalVariableInfo(element)
val variableDefinition = localVariableInfo?.variables?.get(name) ?: return
val controlFlow = function.controlFlow
var found = false
var rewritten = false
ControlFlowUtil.iterate(controlFlow.getInstructionByElement(element)?.num()!!, controlFlow.instructions, { instruction ->
val currentElement = instruction.element ?: return@iterate ControlFlowUtil.Operation.NEXT
if (currentElement == element) {
return@iterate ControlFlowUtil.Operation.NEXT
}
if (variableDefinition.variableDescription.reads.contains(currentElement)) {
found = true
return@iterate ControlFlowUtil.Operation.BREAK
}
val writes = variableDefinition.variableDescription.writes
if (writes.contains(currentElement) && currentElement.parent is RForStatement ||
currentElement is RAssignmentStatement && currentElement.assignee?.let { writes.contains(it) } == true ) {
rewritten = true
return@iterate ControlFlowUtil.Operation.CONTINUE
}
if (currentElement is RFunctionExpression &&
currentElement.localAnalysisResult.closure.contains(variableDefinition.variableDescription)) {
found = true
return@iterate ControlFlowUtil.Operation.BREAK
}
return@iterate ControlFlowUtil.Operation.NEXT
}, false)
if (!found) {
val message = if (!rewritten) RBundle.message("inspection.message.variable.is.never.used", assignee.text)
else RBundle.message("inspection.message.variable.is.never.used.but.assigned", assignee.text)
myProblemHolder.registerProblem(assignee,
message,
ProblemHighlightType.LIKE_UNUSED_SYMBOL)
}
}