From 89b4faa6feb17b23acb72c4c96a13a1f60c82139 Mon Sep 17 00:00:00 2001 From: svtk Date: Thu, 10 Nov 2011 19:42:53 +0400 Subject: [PATCH] started work on "unused value" analysis --- .../lang/cfg/JetFlowInformationProvider.java | 27 +++++++++++++++++++ .../jet/lang/diagnostics/Errors.java | 1 + .../jet/lang/resolve/ControlFlowAnalyzer.java | 2 ++ 3 files changed, 30 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 966adee2c24..0220fe6114e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -356,6 +356,33 @@ public class JetFlowInformationProvider { } }); } + + public void markUnusedVariables(@NotNull JetElement subroutine) { + Pseudocode pseudocode = pseudocodeMap.get(subroutine); + assert pseudocode != null; + + final Set usedVariables = Sets.newHashSet(); + JetControlFlowGraphTraverser.create(pseudocode, true).traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy() { + @Override + public void execute(Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) { + if (instruction instanceof ReadValueInstruction) { + VariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction, false); + usedVariables.add(variableDescriptor); + } + } + }); + Collection declaredVariables = collectDeclaredVariables(subroutine); + for (VariableDescriptor declaredVariable : declaredVariables) { + if (!usedVariables.contains(declaredVariable)) { + PsiElement element = trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declaredVariable); + if (element instanceof JetProperty) { + PsiElement nameIdentifier = ((JetProperty) element).getNameIdentifier(); + PsiElement elementToMark = nameIdentifier != null ? nameIdentifier : element; + trace.report(Errors.UNUSED_VARIABLE.on((JetProperty)element, elementToMark, declaredVariable)); + } + } + } + } @Nullable private VariableDescriptor extractVariableDescriptorIfAny(Instruction instruction, boolean onlyReference) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 52b22dbcb3c..3d39c74cb01 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -143,6 +143,7 @@ public interface Errors { PsiElementOnlyDiagnosticFactory3 VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT); PsiElementOnlyDiagnosticFactory1 UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be initialized", NAME); + PsiElementOnlyDiagnosticFactory1 UNUSED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(WARNING, "Variable ''{0}'' is never used", NAME); PsiElementOnlyDiagnosticFactory2 VAL_REASSIGNMENT = new PsiElementOnlyDiagnosticFactory2(ERROR, "Val can not be reassigned", NAME) { @NotNull @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java index efd8b63c65c..601668ac784 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java @@ -83,5 +83,7 @@ public class ControlFlowAnalyzer { flowInformationProvider.checkDefiniteReturn(function, expectedReturnType); flowInformationProvider.markUninitializedVariables(function.asElement(), false, inLocalDeclaration); + +// flowInformationProvider.markUnusedVariables(function.asElement()); } }