From 1f0b0c4106367c5abfa231646c23ff0deec753ea Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Fri, 8 Apr 2011 22:55:56 +0200 Subject: [PATCH] Make "Mismatched query and update of collection" inspection configuration work --- .../intellij/util/containers/OrderedSet.java | 4 +- .../ig/bugs/CollectionQueryCalledVisitor.java | 20 +---- .../bugs/CollectionUpdateCalledVisitor.java | 30 ++----- ...atchedCollectionQueryUpdateInspection.java | 69 +++++--------- .../siyeh/ig/ui/ExternalizableStringSet.java | 90 +++++++++++++++++++ 5 files changed, 126 insertions(+), 87 deletions(-) create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java diff --git a/platform/util/src/com/intellij/util/containers/OrderedSet.java b/platform/util/src/com/intellij/util/containers/OrderedSet.java index 68953584df49..5be445d00170 100644 --- a/platform/util/src/com/intellij/util/containers/OrderedSet.java +++ b/platform/util/src/com/intellij/util/containers/OrderedSet.java @@ -121,7 +121,9 @@ public class OrderedSet extends AbstractSet implements List { } public T set(final int index, final T element) { - throw new UnsupportedOperationException(); + final T removed = remove(index); + add(index, element); + return removed; } public void add(final int index, final T element) { diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java index 8b8a95f5a3f7..580371d7c38c 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionQueryCalledVisitor.java @@ -24,26 +24,14 @@ import java.util.Set; class CollectionQueryCalledVisitor extends JavaRecursiveElementVisitor{ - /** - * @noinspection StaticCollection - */ - @NonNls private static final Set queryNames = - new HashSet(6); - static{ - queryNames.add("copyInto"); - queryNames.add("drainTo"); - queryNames.add("propertyNames"); - queryNames.add("save"); - queryNames.add("store"); - queryNames.add("write"); - } + @NonNls private final Set queryNames; private boolean queried = false; private final PsiVariable variable; - CollectionQueryCalledVisitor(PsiVariable variable){ - super(); + CollectionQueryCalledVisitor(PsiVariable variable, Set queryNames){ this.variable = variable; + this.queryNames = queryNames; } @Override public void visitElement(@NotNull PsiElement element){ @@ -139,4 +127,4 @@ class CollectionQueryCalledVisitor extends JavaRecursiveElementVisitor{ public boolean isQueried(){ return queried; } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java index e33936796755..1e2f0e229d11 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/CollectionUpdateCalledVisitor.java @@ -20,39 +20,19 @@ import com.siyeh.ig.psiutils.CollectionUtils; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import java.util.HashSet; -import java.util.Set; +import java.util.*; class CollectionUpdateCalledVisitor extends JavaRecursiveElementVisitor{ - /** - * @noinspection StaticCollection - */ - @NonNls private static final Set updateNames = - new HashSet(14); - static{ - updateNames.add("add"); - updateNames.add("clear"); - updateNames.add("drainTo"); - updateNames.add("insert"); - updateNames.add("load"); - updateNames.add("offer"); - updateNames.add("poll"); - updateNames.add("push"); - updateNames.add("put"); - updateNames.add("remove"); - updateNames.add("replace"); - updateNames.add("retain"); - updateNames.add("set"); - updateNames.add("take"); - } + @NonNls private final Set updateNames; private boolean updated = false; private final PsiVariable variable; - CollectionUpdateCalledVisitor(PsiVariable variable){ - super(); + CollectionUpdateCalledVisitor(PsiVariable variable, + Set updateNames){ this.variable = variable; + this.updateNames = updateNames; } @Override public void visitElement(@NotNull PsiElement element){ diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java index 369961be9c17..1e84180335f5 100644 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/bugs/MismatchedCollectionQueryUpdateInspection.java @@ -17,9 +17,7 @@ package com.siyeh.ig.bugs; import com.intellij.codeInspection.ui.ListTable; import com.intellij.codeInspection.ui.ListWrappingTableModel; -import com.intellij.openapi.actionSystem.*; -import com.intellij.openapi.util.InvalidDataException; -import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.actionSystem.ActionToolbar; import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; @@ -29,29 +27,25 @@ import com.siyeh.ig.BaseInspection; import com.siyeh.ig.BaseInspectionVisitor; import com.siyeh.ig.psiutils.CollectionUtils; import com.siyeh.ig.psiutils.VariableAccessUtils; +import com.siyeh.ig.ui.ExternalizableStringSet; import com.siyeh.ig.ui.UiUtils; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; -import java.util.ArrayList; -import java.util.List; public class MismatchedCollectionQueryUpdateInspection extends BaseInspection { - @NonNls public String queries = "copyInto,drainTo,propertyNames,save,store,write"; - @NonNls public String updates = "add,clear,drainTo,insert,load,offer,poll,push,put,remove,replace,retain,set,take"; + public final ExternalizableStringSet queryNames = + new ExternalizableStringSet("copyInto", "drainTo", "propertyNames", + "save", "store", "write"); + public final ExternalizableStringSet updateNames = + new ExternalizableStringSet("add", "clear", "drainTo", "insert", + "load", "offer", "poll", "push", "put", "remove", "replace", + "retain", "set", "take"); - private final List queryNames = new ArrayList(); - private final List updateNames = new ArrayList(); - - public MismatchedCollectionQueryUpdateInspection() { - parseString(queries, queryNames); - parseString(updates, updateNames); - } + public MismatchedCollectionQueryUpdateInspection() {} @Override @NotNull @@ -82,16 +76,16 @@ public class MismatchedCollectionQueryUpdateInspection @Override public JComponent createOptionsPanel() { final JPanel panel = new JPanel(new GridBagLayout()); - final ListTable table1 = new ListTable(new ListWrappingTableModel( - queryNames, - InspectionGadgetsBundle.message("query.column.name"))); + final ListTable table1 = + new ListTable(new ListWrappingTableModel(queryNames, + InspectionGadgetsBundle.message("query.column.name"))); final JScrollPane scrollPane1 = ScrollPaneFactory.createScrollPane(table1); final ActionToolbar toolbar1 = UiUtils.createAddRemoveToolbar(table1); - final ListTable table2 = new ListTable(new ListWrappingTableModel( - updateNames, - InspectionGadgetsBundle.message("update.column.name"))); + final ListTable table2 = + new ListTable(new ListWrappingTableModel(updateNames, + InspectionGadgetsBundle.message("update.column.name"))); final JScrollPane scrollPane2 = ScrollPaneFactory.createScrollPane(table2); final ActionToolbar toolbar2 = UiUtils.createAddRemoveToolbar(table2); @@ -119,20 +113,6 @@ public class MismatchedCollectionQueryUpdateInspection return panel; } - @Override - public void readSettings(Element node) throws InvalidDataException { - super.readSettings(node); - parseString(queries, queryNames); - parseString(updates, updateNames); - } - - @Override - public void writeSettings(Element node) throws WriteExternalException { - queries = formatString(queryNames); - updates = formatString(updateNames); - super.writeSettings(node); - } - @Override public boolean isEnabledByDefault(){ return true; @@ -176,7 +156,7 @@ public class MismatchedCollectionQueryUpdateInspection return true; } - private static class MismatchedCollectionQueryUpdateVisitor + private class MismatchedCollectionQueryUpdateVisitor extends BaseInspectionVisitor{ @Override public void visitField(@NotNull PsiField field){ @@ -223,7 +203,7 @@ public class MismatchedCollectionQueryUpdateInspection } } - private static boolean collectionContentsAreUpdated( + private boolean collectionContentsAreUpdated( PsiVariable variable, PsiElement context){ if(collectionUpdateCalled(variable, context)){ return true; @@ -261,7 +241,7 @@ public class MismatchedCollectionQueryUpdateInspection context); } - private static boolean collectionContentsAreQueried( + private boolean collectionContentsAreQueried( PsiVariable variable, PsiElement context){ if(collectionQueryCalled(variable, context)){ return true; @@ -288,18 +268,18 @@ public class MismatchedCollectionQueryUpdateInspection context); } - private static boolean collectionQueryCalled(PsiVariable variable, + private boolean collectionQueryCalled(PsiVariable variable, PsiElement context){ final CollectionQueryCalledVisitor visitor = - new CollectionQueryCalledVisitor(variable); + new CollectionQueryCalledVisitor(variable, queryNames); context.accept(visitor); return visitor.isQueried(); } - private static boolean collectionUpdateCalled(PsiVariable variable, + private boolean collectionUpdateCalled(PsiVariable variable, PsiElement context){ final CollectionUpdateCalledVisitor visitor = - new CollectionUpdateCalledVisitor(variable); + new CollectionUpdateCalledVisitor(variable, updateNames); context.accept(visitor); return visitor.isUpdated(); } @@ -320,7 +300,6 @@ public class MismatchedCollectionQueryUpdateInspection @NotNull private final PsiVariable variable; CollectionQueriedByAssignmentVisitor(@NotNull PsiVariable variable){ - super(); this.variable = variable; } @@ -352,4 +331,4 @@ public class MismatchedCollectionQueryUpdateInspection return mayBeQueried; } } -} \ No newline at end of file +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java new file mode 100644 index 000000000000..956ec591faed --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/ui/ExternalizableStringSet.java @@ -0,0 +1,90 @@ +/* + * Copyright 2011 Bas Leijdekkers + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.siyeh.ig.ui; + +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.containers.OrderedSet; +import org.jdom.Element; +import org.jetbrains.annotations.NonNls; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; + +@SuppressWarnings({"HardCodedStringLiteral"}) +public class ExternalizableStringSet extends OrderedSet + implements JDOMExternalizable { + + private static final String SET = "set"; + private static final String ITEM = "item"; + private static final String VALUE = "value"; + + private final String[] defaultValues; + + /** + * note: reference to defaultValues is retained by this set! + */ + public ExternalizableStringSet(@NonNls String... defaultValues) { + this.defaultValues = defaultValues; + for (String defaultValue : defaultValues) { + add(defaultValue); + } + } + + private boolean hasDefaultValues() { + if (size() != defaultValues.length) { + return false; + } + for (String defaultValue : defaultValues) { + if (!contains(defaultValue)) { + return false; + } + } + return true; + } + + public void readExternal(Element element) throws InvalidDataException { + boolean dataFound = false; + for (Element set : (List) element.getChildren(SET)) { + if (!dataFound) { + clear(); + dataFound = true; + } + for (Element item : (List) set.getChildren(ITEM)) { + add(StringUtil.unescapeXml(item.getAttributeValue(VALUE))); + } + } + } + + public void writeExternal(Element element) throws WriteExternalException { + if (hasDefaultValues()) { + return; + } + final Element set = new Element(SET); + element.addContent(set); + for (String value : this) { + if (value != null) { + final Element item = new Element(ITEM); + item.setAttribute(VALUE, StringUtil.escapeXml(value)); + set.addContent(item); + } + } + } +}