KT-1175 Mark unused literals

This commit is contained in:
svtk
2012-01-27 18:28:54 +04:00
parent ca1abed3a9
commit 11ad28812d
27 changed files with 183 additions and 89 deletions
@@ -82,7 +82,7 @@ public class JetControlFlowProcessor {
}
@Override
public void visitWhenConditionExpression(JetWhenConditionWithExpression condition) {
public void visitWhenConditionWithExpression(JetWhenConditionWithExpression condition) {
JetExpressionPattern pattern = condition.getPattern();
if (pattern != null) {
pattern.accept(patternVisitor);
@@ -641,6 +641,39 @@ public class JetFlowInformationProvider {
}
}
////////////////////////////////////////////////////////////////////////////////
// "Unused literals" in block
public void markUnusedLiteralsInBlock(@NotNull JetElement subroutine) {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
JetControlFlowGraphTraverser<Void> traverser = JetControlFlowGraphTraverser.create(pseudocode, true, true);
traverser.traverseAndAnalyzeInstructionGraph(new JetControlFlowGraphTraverser.InstructionDataAnalyzeStrategy<Void>() {
@Override
public void execute(@NotNull Instruction instruction, @Nullable Void enterData, @Nullable Void exitData) {
if (!(instruction instanceof ReadValueInstruction)) return;
JetElement element = ((ReadValueInstruction) instruction).getElement();
if (!(element instanceof JetFunctionLiteralExpression
|| element instanceof JetConstantExpression
|| element instanceof JetStringTemplateExpression
|| element instanceof JetSimpleNameExpression)) {
return;
}
PsiElement parent = element.getParent();
if (parent instanceof JetBlockExpression) {
if (!JetPsiUtil.isImplicitlyUsed(element)) {
if (element instanceof JetFunctionLiteralExpression) {
trace.report(Errors.UNUSED_FUNCTION_LITERAL.on((JetFunctionLiteralExpression) element));
}
else {
trace.report(Errors.UNUSED_EXPRESSION.on(element));
}
}
}
}
});
}
////////////////////////////////////////////////////////////////////////////////
// Util methods 7
@@ -167,6 +167,8 @@ public interface Errors {
return argument.getText();
}
};
SimpleDiagnosticFactory UNUSED_EXPRESSION = SimpleDiagnosticFactory.create(WARNING, "The expression is unused");
SimplePsiElementOnlyDiagnosticFactory<JetFunctionLiteralExpression> UNUSED_FUNCTION_LITERAL = SimplePsiElementOnlyDiagnosticFactory.create(WARNING, "The function literal is unused. If you mean block, you can use 'run { ... }'");
PsiElementOnlyDiagnosticFactory1<JetExpression, DeclarationDescriptor> VAL_REASSIGNMENT = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Val can not be reassigned", NAME);
PsiElementOnlyDiagnosticFactory1<JetExpression, DeclarationDescriptor> INITIALIZATION_BEFORE_DECLARATION = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable cannot be initialized before declaration", NAME);
@@ -1,12 +1,14 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetTokens;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@@ -85,11 +87,12 @@ public class JetPsiUtil {
if (quoted.startsWith("`") && quoted.endsWith("`") && quoted.length() >= 2) {
return quoted.substring(1, quoted.length() - 1);
} else {
}
else {
return quoted;
}
}
@NotNull
public static String unquoteIdentifierOrFieldReference(@NotNull String quoted) {
if (quoted.indexOf('`') < 0) {
@@ -98,7 +101,8 @@ public class JetPsiUtil {
if (quoted.startsWith("$")) {
return "$" + unquoteIdentifier(quoted.substring(1));
} else {
}
else {
return unquoteIdentifier(quoted);
}
}
@@ -167,4 +171,51 @@ public class JetPsiUtil {
}
return false;
}
@Nullable
public static <T extends PsiElement> T getDirectParentOfTypeForBlock(@NotNull JetBlockExpression block, @NotNull Class<T> aClass) {
T parent = PsiTreeUtil.getParentOfType(block, aClass);
if (parent instanceof JetIfExpression) {
JetIfExpression ifExpression = (JetIfExpression) parent;
if (ifExpression.getElse() == block || ifExpression.getThen() == block) {
return parent;
}
}
if (parent instanceof JetWhenExpression) {
JetWhenExpression whenExpression = (JetWhenExpression) parent;
for (JetWhenEntry whenEntry : whenExpression.getEntries()) {
if (whenEntry.getExpression() == block) {
return parent;
}
}
}
if (parent instanceof JetFunctionLiteral) {
JetFunctionLiteral functionLiteral = (JetFunctionLiteral) parent;
if (functionLiteral.getBodyExpression() == block) {
return parent;
}
}
return null;
}
public static boolean isImplicitlyUsed(@NotNull JetElement element) {
PsiElement parent = element.getParent();
if (!(parent instanceof JetBlockExpression)) return true;
JetBlockExpression block = (JetBlockExpression) parent;
List<JetElement> statements = block.getStatements();
if (statements.get(statements.size() - 1) == element) {
JetExpression expression = getDirectParentOfTypeForBlock(block, JetIfExpression.class);
if (expression == null) {
expression = getDirectParentOfTypeForBlock(block, JetWhenExpression.class);
}
if (expression == null) {
expression = getDirectParentOfTypeForBlock(block, JetFunctionLiteral.class);
}
if (expression != null) {
return isImplicitlyUsed(expression);
}
}
return false;
}
}
@@ -358,7 +358,7 @@ public class JetVisitorVoid extends PsiElementVisitor {
visitJetElement(condition);
}
public void visitWhenConditionExpression(JetWhenConditionWithExpression condition) {
public void visitWhenConditionWithExpression(JetWhenConditionWithExpression condition) {
visitJetElement(condition);
}
@@ -20,7 +20,7 @@ public class JetWhenConditionWithExpression extends JetWhenCondition {
@Override
public void accept(@NotNull JetVisitorVoid visitor) {
visitor.visitWhenConditionExpression(this);
visitor.visitWhenConditionWithExpression(this);
}
@Override
@@ -81,5 +81,7 @@ public class ControlFlowAnalyzer {
flowInformationProvider.markUninitializedVariables(function.asElement(), context.isDeclaredLocally());
flowInformationProvider.markUnusedVariables(function.asElement());
flowInformationProvider.markUnusedLiteralsInBlock(function.asElement());
}
}
@@ -143,7 +143,7 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
}
@Override
public void visitWhenConditionExpression(JetWhenConditionWithExpression condition) {
public void visitWhenConditionWithExpression(JetWhenConditionWithExpression condition) {
JetPattern pattern = condition.getPattern();
if (pattern != null) {
newDataFlowInfo[0] = checkPatternType(pattern, subjectType, subjectExpression == null, scopeToExtend, context, subjectVariables);