From 651a3288c12a6ec7c7c103859cd5feb3961a67c6 Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 30 Jul 2013 12:19:15 +0200 Subject: [PATCH] IDEA-111089 (Intention/Inspection "Create missing 'switch' branches" should add before default) --- .../CreateEnumSwitchBranchesIntention.java | 55 +++++++++++-------- .../ipp/enumswitch/EnumSwitchPredicate.java | 45 ++++++++------- .../siyeh/ipp/enumswitch/BeforeDefault.java | 16 ++++++ .../ipp/enumswitch/BeforeDefault_after.java | 18 ++++++ .../EnumSwitchBranchesIntentionTest.java | 11 ++-- 5 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault_after.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java index 773b483cd9e0..c82d84242192 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/CreateEnumSwitchBranchesIntention.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,7 +16,6 @@ package com.siyeh.ipp.enumswitch; import com.intellij.psi.*; -import com.intellij.util.IncorrectOperationException; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; import org.jetbrains.annotations.NonNls; @@ -32,8 +31,7 @@ public class CreateEnumSwitchBranchesIntention extends Intention { return new EnumSwitchPredicate(); } - public void processIntention(@NotNull PsiElement element) - throws IncorrectOperationException { + public void processIntention(@NotNull PsiElement element) { if (element instanceof PsiWhiteSpace) { element = element.getPrevSibling(); } @@ -43,8 +41,7 @@ public class CreateEnumSwitchBranchesIntention extends Intention { if (switchExpression == null) { return; } - final PsiClassType switchType = - (PsiClassType)switchExpression.getType(); + final PsiClassType switchType = (PsiClassType)switchExpression.getType(); if (switchType == null) { return; } @@ -53,8 +50,7 @@ public class CreateEnumSwitchBranchesIntention extends Intention { return; } final PsiField[] fields = enumClass.getFields(); - final List missingEnumElements = - new ArrayList(fields.length); + final List missingEnumElements = new ArrayList(fields.length); for (final PsiField field : fields) { if (field instanceof PsiEnumConstant) { missingEnumElements.add(field.getName()); @@ -66,14 +62,12 @@ public class CreateEnumSwitchBranchesIntention extends Intention { if (!(statement instanceof PsiSwitchLabelStatement)) { continue; } - final PsiSwitchLabelStatement labelStatement = - (PsiSwitchLabelStatement)statement; + final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement)statement; final PsiExpression value = labelStatement.getCaseValue(); if (!(value instanceof PsiReferenceExpression)) { continue; } - final PsiReferenceExpression reference = - (PsiReferenceExpression)value; + final PsiReferenceExpression reference = (PsiReferenceExpression)value; final PsiElement resolved = reference.resolve(); if (!(resolved instanceof PsiEnumConstant)) { continue; @@ -82,23 +76,36 @@ public class CreateEnumSwitchBranchesIntention extends Intention { missingEnumElements.remove(enumConstant.getName()); } } - @NonNls final StringBuilder buffer = new StringBuilder(); - buffer.append("switch("); - buffer.append(switchExpression.getText()); - buffer.append("){"); + @NonNls final StringBuilder newStatementText = new StringBuilder(); + newStatementText.append("switch(").append(switchExpression.getText()).append("){"); if (body != null) { + int position = 0; final PsiElement[] children = body.getChildren(); - for (int i = 1; i < children.length - 1; i++) { - buffer.append(children[i].getText()); + for (position = 1; position < children.length - 1; position++) { + final PsiElement child = children[position]; + if (child instanceof PsiSwitchLabelStatement) { + final PsiSwitchLabelStatement switchLabelStatement = (PsiSwitchLabelStatement)child; + if (switchLabelStatement.isDefaultCase()) { + break; + } + } + newStatementText.append(child.getText()); + } + appendMissingEnumCases(missingEnumElements, newStatementText); + for (; position< children.length - 1; position++) { + newStatementText.append(children[position].getText()); } } + else { + appendMissingEnumCases(missingEnumElements, newStatementText); + } + newStatementText.append('}'); + replaceStatement(newStatementText.toString(), switchStatement); + } + + private static void appendMissingEnumCases(List missingEnumElements, @NonNls StringBuilder newStatementText) { for (String missingEnumElement : missingEnumElements) { - buffer.append("case "); - buffer.append(missingEnumElement); - buffer.append(": break;"); + newStatementText.append("case ").append(missingEnumElement).append(": break;"); } - buffer.append('}'); - final String newStatement = buffer.toString(); - replaceStatement(newStatement, switchStatement); } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/EnumSwitchPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/EnumSwitchPredicate.java index 2cc7cbd61d61..6ea35f076f1b 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/EnumSwitchPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/enumswitch/EnumSwitchPredicate.java @@ -1,5 +1,5 @@ /* - * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers + * Copyright 2003-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -35,7 +35,6 @@ class EnumSwitchPredicate implements PsiElementPredicate { return false; } final PsiSwitchStatement switchStatement = (PsiSwitchStatement)element; - final PsiCodeBlock body = switchStatement.getBody(); final PsiExpression expression = switchStatement.getExpression(); if (expression == null) { return false; @@ -49,31 +48,35 @@ class EnumSwitchPredicate implements PsiElementPredicate { return false; } final PsiField[] fields = enumClass.getFields(); + if (fields.length == 0) { + return false; + } + final PsiCodeBlock body = switchStatement.getBody(); + if (body == null) { + return true; + } final Set enumElements = new HashSet(fields.length); for (final PsiField field : fields) { final PsiType fieldType = field.getType(); - if (fieldType.equals(type)) { - final String fieldName = field.getName(); - enumElements.add(fieldName); + if (!fieldType.equals(type)) { + continue; } + final String fieldName = field.getName(); + enumElements.add(fieldName); } - if (body != null) { - final PsiStatement[] statements = body.getStatements(); - for (PsiStatement statement : statements) { - if (statement instanceof PsiSwitchLabelStatement) { - final PsiSwitchLabelStatement labelStatement = - (PsiSwitchLabelStatement)statement; - final PsiExpression value = labelStatement.getCaseValue(); - if (value != null) { - final String valueText = value.getText(); - enumElements.remove(valueText); - } - } + final PsiStatement[] statements = body.getStatements(); + for (PsiStatement statement : statements) { + if (!(statement instanceof PsiSwitchLabelStatement)) { + continue; } + final PsiSwitchLabelStatement labelStatement = (PsiSwitchLabelStatement)statement; + final PsiExpression value = labelStatement.getCaseValue(); + if (value == null) { + continue; + } + final String valueText = value.getText(); + enumElements.remove(valueText); } - if (enumElements.isEmpty()) { - return false; - } - return true; + return !enumElements.isEmpty(); } } diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault.java new file mode 100644 index 000000000000..855e655283fe --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault.java @@ -0,0 +1,16 @@ +package com.siyeh.ipp.enumswitch; + +class BeforeDefault { + enum Status { ACTIVE, INACTIVE, ERROR } + + private void foo (Status status) { + switch (status) { + case ACTIVE: + break; + case INACTIVE: + break; + default: + throw new IllegalArgumentException("Unknown Status " + status); + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault_after.java new file mode 100644 index 000000000000..7a69b04e6403 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/enumswitch/BeforeDefault_after.java @@ -0,0 +1,18 @@ +package com.siyeh.ipp.enumswitch; + +class BeforeDefault { + enum Status { ACTIVE, INACTIVE, ERROR } + + private void foo (Status status) { + switch (status) { + case ACTIVE: + break; + case INACTIVE: + break; + case ERROR: + break; + default: + throw new IllegalArgumentException("Unknown Status " + status); + } + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java index f03b8db07b13..b8ae35f25f74 100644 --- a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/enumswitch/EnumSwitchBranchesIntentionTest.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2011 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,10 @@ import com.siyeh.IntentionPowerPackBundle; import com.siyeh.ipp.IPPTestCase; public class EnumSwitchBranchesIntentionTest extends IPPTestCase { - public void testWithoutBraces() throws Exception { - doTest(); - } - public void testNoActionAfterBraces() throws Exception { - assertIntentionNotAvailable(); - } + public void testWithoutBraces() { doTest(); } + public void testBeforeDefault() { doTest(); } + public void testNoActionAfterBraces() { assertIntentionNotAvailable(); } @Override protected String getIntentionName() {