From 722c5c656e32e2879b7be0af1d1b4818d0cdf5a6 Mon Sep 17 00:00:00 2001 From: JohnHake Date: Fri, 7 Feb 2020 11:54:11 -0800 Subject: [PATCH] Port to Gradle, update unit tests --- comparing_references_inspection/build.gradle | 5 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../resources/META-INF/plugin.xml | 73 ------- .../ComparingReferences.html | 7 - .../ComparingReferencesInspection.java | 199 ------------------ .../ComparingReferencesInspection.java | 8 +- .../src/main/resources/META-INF/plugin.xml | 6 +- .../sdk/codeInspection/CompRefInspTest.java | 62 ------ .../ComparingReferencesInspectionTest.java | 66 ++++++ .../Eq.after.java} | 2 +- .../before.java => resources/Eq.java} | 2 +- .../Neq.after.java} | 2 +- .../before1.java => resources/Neq.java} | 2 +- 13 files changed, 80 insertions(+), 356 deletions(-) delete mode 100644 comparing_references_inspection/resources/META-INF/plugin.xml delete mode 100644 comparing_references_inspection/resources/inspectionDescriptions/ComparingReferences.html delete mode 100644 comparing_references_inspection/source/com/intellij/codeInspection/ComparingReferencesInspection.java delete mode 100644 comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/CompRefInspTest.java create mode 100644 comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java rename comparing_references_inspection/src/test/{testData/before.after.java => resources/Eq.after.java} (86%) rename comparing_references_inspection/src/test/{testData/before.java => resources/Eq.java} (87%) rename comparing_references_inspection/src/test/{testData/before1.after.java => resources/Neq.after.java} (85%) rename comparing_references_inspection/src/test/{testData/before1.java => resources/Neq.java} (85%) diff --git a/comparing_references_inspection/build.gradle b/comparing_references_inspection/build.gradle index 8f2649e1a..0c3f7e725 100644 --- a/comparing_references_inspection/build.gradle +++ b/comparing_references_inspection/build.gradle @@ -1,4 +1,4 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. plugins { id 'java' @@ -35,6 +35,3 @@ intellij { patchPluginXml { version = project.version } - -// Force javadoc rebuild before jar is built -jar.dependsOn javadoc \ No newline at end of file diff --git a/comparing_references_inspection/gradle/wrapper/gradle-wrapper.properties b/comparing_references_inspection/gradle/wrapper/gradle-wrapper.properties index 91f72d8e0..6da6ba8b0 100644 --- a/comparing_references_inspection/gradle/wrapper/gradle-wrapper.properties +++ b/comparing_references_inspection/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip diff --git a/comparing_references_inspection/resources/META-INF/plugin.xml b/comparing_references_inspection/resources/META-INF/plugin.xml deleted file mode 100644 index f8c63c7d9..000000000 --- a/comparing_references_inspection/resources/META-INF/plugin.xml +++ /dev/null @@ -1,73 +0,0 @@ - - - - - org.intelliJ.sdk.codeInspection - - - SDK Comparing References Inspection Sample - - - 1.1.0 - - - - - - com.intellij.modules.java - - - - Adds entries to Preferences | Editor | Inspections | Java | Probable Bugs. - ]]> - - - -
  • 1.1.0 Refactor resources, register this inspection.
  • -
  • 1.0.0 Release 2018.3 and earlier.
  • - - ]]> -
    - - - IntelliJ Platform SDK - - - - - - - - -
    diff --git a/comparing_references_inspection/resources/inspectionDescriptions/ComparingReferences.html b/comparing_references_inspection/resources/inspectionDescriptions/ComparingReferences.html deleted file mode 100644 index e6eb316ea..000000000 --- a/comparing_references_inspection/resources/inspectionDescriptions/ComparingReferences.html +++ /dev/null @@ -1,7 +0,0 @@ - - -SDK: This inspection reports when the '==' or '!=' operator was used between expressions of -reference types.
    -Classes to be inspected are controlled by a semi-colon separated Options list in the preferences panel for this inspection. - - diff --git a/comparing_references_inspection/source/com/intellij/codeInspection/ComparingReferencesInspection.java b/comparing_references_inspection/source/com/intellij/codeInspection/ComparingReferencesInspection.java deleted file mode 100644 index 907ca82f6..000000000 --- a/comparing_references_inspection/source/com/intellij/codeInspection/ComparingReferencesInspection.java +++ /dev/null @@ -1,199 +0,0 @@ -package com.intellij.codeInspection; - -import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.psi.*; -import com.intellij.psi.tree.IElementType; -import com.intellij.ui.DocumentAdapter; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NonNls; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import java.awt.*; -import java.util.StringTokenizer; - -import static com.siyeh.ig.psiutils.ExpressionUtils.isNullLiteral; - -/** - * @author max - * @author jhake - */ -public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspectionTool { - private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ComparingReferencesInspection"); - private final CriQuickFix myQuickFix = new CriQuickFix(); - - // Defines the text of the quick fix intention - public static final String QUICK_FIX_NAME = "SDK: " + InspectionsBundle.message("inspection.comparing.references.use.quickfix"); - - // This string holds a list of classes relevant to this inspection. - @SuppressWarnings({"WeakerAccess"}) - @NonNls - public String CHECKED_CLASSES = "java.lang.String;java.util.Date"; - - /** - * This method is called to get the panel describing the inspection. - * It is called every time the user selects the inspection in preferences. - * The user has the option to edit the list of CHECKED_CLASSES. - * Adds a document listener to see if - * - * @return panel to display inspection information. - */ - @Override - public JComponent createOptionsPanel() { - JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); - final JTextField checkedClasses = new JTextField(CHECKED_CLASSES); - checkedClasses.getDocument().addDocumentListener(new DocumentAdapter() { - public void textChanged(DocumentEvent event) { - CHECKED_CLASSES = checkedClasses.getText(); - } - }); - panel.add(checkedClasses); - return panel; - } - - /** - * This method is overridden to provide a custom visitor - * that inspects expressions with relational operators '==' and '!=' - * The visitor must not be recursive and must be thread-safe. - * - * @param holder object for visitor to register problems found. - * @param isOnTheFly true if inspection was run in non-batch mode - * @return non-null visitor for this inspection. - * @see JavaElementVisitor - */ - @NotNull - @Override - public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { - return new JavaElementVisitor() { - - /** - * This string defines the short message shown to a user signaling the inspection - * found a problem. It reuses a string from the inspections bundle. - */ - @NonNls - private final String DESCRIPTION_TEMPLATE = "SDK " + InspectionsBundle.message("inspection.comparing.references.problem.descriptor"); - - /** - * Avoid defining visitors for both Reference and Binary expressions. - * - * @param psiReferenceExpression The expression to be evaluated. - */ - @Override - public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) { - } - - /** - * Evaluate binary psi expressions to see if they contain - * relational operators '==' and '!=', AND they contain - * classes contained in CHECKED_CLASSES. The evaluation - * ignores expressions comparing an object to null. - * IF this criteria is met, add the expression to the - * problems list. - * - * @param expression The binary expression to be evaluated. - */ - @Override - public void visitBinaryExpression(PsiBinaryExpression expression) { - super.visitBinaryExpression(expression); - IElementType opSign = expression.getOperationTokenType(); - if (opSign == JavaTokenType.EQEQ || opSign == JavaTokenType.NE) { - // The binary expression is the correct type for this inspection - PsiExpression lOperand = expression.getLOperand(); - PsiExpression rOperand = expression.getROperand(); - if (rOperand == null || isNullLiteral(lOperand) || isNullLiteral(rOperand)) - return; - // Nothing is compared to null, now check the types being compared - PsiType lType = lOperand.getType(); - PsiType rType = rOperand.getType(); - if (isCheckedType(lType) || isCheckedType(rType)) { - // Identified an expression with potential problems, add to list with fix object. - holder.registerProblem(expression, - DESCRIPTION_TEMPLATE, myQuickFix); - } - } - } - - /** - * Verifies the input is the correct {@code PsiType} for this inspection. - * - * @param type The {@code PsiType} to be examined for a match - * @return {@code true} if input is {@code PsiClassType} and matches - * one of the classes in the CHECKED_CLASSES list. - */ - private boolean isCheckedType(PsiType type) { - if (!(type instanceof PsiClassType)) - return false; - StringTokenizer tokenizer = new StringTokenizer(CHECKED_CLASSES, ";"); - while (tokenizer.hasMoreTokens()) { - String className = tokenizer.nextToken(); - if (type.equalsToText(className)) - return true; - } - return false; - } - - }; - } - - /** - * This class provides a solution to inspection problem expressions by manipulating - * the PSI tree to use a.equals(b) instead of '==' or '!=' - */ - private static class CriQuickFix implements LocalQuickFix { - - /** - * Returns a partially localized string for the quick fix intention. - * Used by the test code for this plugin. - * - * @return Quick fix short name. - */ - @NotNull - @Override - public String getName() { - return QUICK_FIX_NAME; - } - - /** - * This method manipulates the PSI tree to replace 'a==b' with 'a.equals(b) - * or 'a!=b' with '!a.equals(b)' - * - * @param project The project that contains the file being edited. - * @param descriptor A problem found by this inspection. - */ - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - try { - PsiBinaryExpression binaryExpression = (PsiBinaryExpression) descriptor.getPsiElement(); - IElementType opSign = binaryExpression.getOperationTokenType(); - PsiExpression lExpr = binaryExpression.getLOperand(); - PsiExpression rExpr = binaryExpression.getROperand(); - if (rExpr == null) - return; - - PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); - PsiMethodCallExpression equalsCall = - (PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null); - - equalsCall.getMethodExpression().getQualifierExpression().replace(lExpr); - equalsCall.getArgumentList().getExpressions()[0].replace(rExpr); - - PsiExpression result = (PsiExpression) binaryExpression.replace(equalsCall); - - if (opSign == JavaTokenType.NE) { - PsiPrefixExpression negation = (PsiPrefixExpression) factory.createExpressionFromText("!a", null); - negation.getOperand().replace(result); - result.replace(negation); - } - } catch (IncorrectOperationException e) { - LOG.error(e); - } - } - - @NotNull - public String getFamilyName() { - return getName(); - } - } - -} diff --git a/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java b/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java index 8ff934e0c..87395f26a 100644 --- a/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java +++ b/comparing_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingReferencesInspection.java @@ -1,3 +1,5 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + package org.intellij.sdk.codeInspection; import com.intellij.codeInspection.*; @@ -18,8 +20,8 @@ import java.util.StringTokenizer; import static com.siyeh.ig.psiutils.ExpressionUtils.isNullLiteral; /** - * @author max - * @author jhake + * Implements an inspection to detect when object references are compared using 'a==b' or 'a!=b' + * The quick fix converts these comparisons to 'a.equals(b) or '!a.equals(b)' respectively. */ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspectionTool { private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ComparingReferencesInspection"); @@ -46,7 +48,7 @@ public class ComparingReferencesInspection extends AbstractBaseJavaLocalInspecti JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); final JTextField checkedClasses = new JTextField(CHECKED_CLASSES); checkedClasses.getDocument().addDocumentListener(new DocumentAdapter() { - public void textChanged(DocumentEvent event) { + public void textChanged(@NotNull DocumentEvent event) { CHECKED_CLASSES = checkedClasses.getText(); } }); diff --git a/comparing_references_inspection/src/main/resources/META-INF/plugin.xml b/comparing_references_inspection/src/main/resources/META-INF/plugin.xml index d0119b6ef..3edcf9b05 100644 --- a/comparing_references_inspection/src/main/resources/META-INF/plugin.xml +++ b/comparing_references_inspection/src/main/resources/META-INF/plugin.xml @@ -1,4 +1,4 @@ - + @@ -11,9 +11,9 @@ 2.0.0 - + - + com.intellij.modules.java diff --git a/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/CompRefInspTest.java b/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/CompRefInspTest.java deleted file mode 100644 index c1267d083..000000000 --- a/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/CompRefInspTest.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - -package org.intellij.sdk.codeInspection; - -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; -import org.jetbrains.annotations.NotNull; -import org.junit.After; -import org.junit.Before; - -/** - * -ea -Xbootclasspath/p:../out/classes/production/boot -XX:+HeapDumpOnOutOfMemoryError -Xmx512m -XX:MaxPermSize=320m - * -Didea.system.path=../test-system -Didea.home.path=../ -Didea.config.path=../test-config -Didea.test.group=ALL_EXCLUDE_DEFINED - */ -public class CompRefInspTest extends LightJavaCodeInsightFixtureTestCase { - - /** - * Returns path to the test data relative to "idea.home.path" defined in build.gradle. - */ - @Override - protected String getBasePath() { - return "sdk/code_samples/comparing_references_inspection/src/test/testData"; - } - - /** - * Specifies the requirements for this project needed in this test, - * such as the module type, the configured SDK, facets, libraries, etc. - * @return - */ - @NotNull - protected LightProjectDescriptor getProjectDescriptor() { - return LightJavaCodeInsightFixtureTestCase.JAVA_8_ANNOTATED; - } - - /** - * Test the "==" case - * Note the hint must match CriQuickFix#getName - * - */ - public void testRelationalEq() { - myFixture.configureByFiles("before.java"); - final IntentionAction action = myFixture.findSingleIntention(ComparingReferencesInspection.QUICK_FIX_NAME); - assertNotNull(action); - myFixture.launchAction(action); - myFixture.checkResultByFile("before.after.java"); - } - - /** - * Test the "!=" case - * Note the hint must match CriQuickFix#getName - * - */ - public void testRelationalNeq() { - myFixture.configureByFiles("before1.java"); - final IntentionAction action = myFixture.findSingleIntention(ComparingReferencesInspection.QUICK_FIX_NAME); - assertNotNull(action); - myFixture.launchAction(action); - myFixture.checkResultByFile("before1.after.java"); - } - -} diff --git a/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java b/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java new file mode 100644 index 000000000..362cd8953 --- /dev/null +++ b/comparing_references_inspection/src/test/java/org/intellij/sdk/codeInspection/ComparingReferencesInspectionTest.java @@ -0,0 +1,66 @@ +// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. + +package org.intellij.sdk.codeInspection; + +import com.intellij.codeInsight.daemon.impl.HighlightInfo; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * Class for testing ComparingReferencesInspection. + * Requires idea.home.path to be set in build.gradle + * doTest() does the work for individual test cases. + */ +public class ComparingReferencesInspectionTest extends LightJavaCodeInsightFixtureTestCase { + + /** + * Defines path to files used for running tests + * + * @return The path from this module's root directory ($MODULE_WORKING_DIR$) to the + * directory containing files for these tests. + */ + @Override + protected String getTestDataPath() { + return "src/test/resources"; + } + + /** + * Given the name of a test file, runs comparing references inspection quick fix and tests + * the results against a reference outcome file. File name pattern 'foo.java' and 'foo.after.java' + * are matching before and after files in the testData directory. + * + * @param testName The name of the test file before comparing references inspection. + */ + protected void doTest(@NotNull String testName) throws Throwable { + // Initialize the test based on the testData file + myFixture.configureByFile(testName + ".java"); + // Initialize the inspection and get a list of highlighted + myFixture.enableInspections(new ComparingReferencesInspection()); + List highlightInfos = myFixture.doHighlighting(); + assertFalse(highlightInfos.isEmpty()); + // Get the quick fix action for comparing references inspection and apply it to the file + final IntentionAction action = myFixture.findSingleIntention(ComparingReferencesInspection.QUICK_FIX_NAME); + assertNotNull(action); + myFixture.launchAction(action); + // Verify the results + myFixture.checkResultByFile(testName + ".after.java"); + } + + /** + * Test the "==" case + */ + public void testRelationalEq() throws Throwable { + doTest("Eq"); + } + + /** + * Test the "!=" case + */ + public void testRelationalNeq() throws Throwable { + doTest("Neq"); + } + +} diff --git a/comparing_references_inspection/src/test/testData/before.after.java b/comparing_references_inspection/src/test/resources/Eq.after.java similarity index 86% rename from comparing_references_inspection/src/test/testData/before.after.java rename to comparing_references_inspection/src/test/resources/Eq.after.java index a3058effc..20a37653b 100644 --- a/comparing_references_inspection/src/test/testData/before.after.java +++ b/comparing_references_inspection/src/test/resources/Eq.after.java @@ -1,4 +1,4 @@ -public class X { +public class Eq { public boolean compare2Strings(java.lang.String s1, java.lang.String s2) { return (s1.equals(s2)); } diff --git a/comparing_references_inspection/src/test/testData/before.java b/comparing_references_inspection/src/test/resources/Eq.java similarity index 87% rename from comparing_references_inspection/src/test/testData/before.java rename to comparing_references_inspection/src/test/resources/Eq.java index 23095bcfa..43e40a40b 100644 --- a/comparing_references_inspection/src/test/testData/before.java +++ b/comparing_references_inspection/src/test/resources/Eq.java @@ -1,4 +1,4 @@ -public class X { +public class Eq { public boolean compare2Strings(java.lang.String s1, java.lang.String s2) { return (s1 == s2); } diff --git a/comparing_references_inspection/src/test/testData/before1.after.java b/comparing_references_inspection/src/test/resources/Neq.after.java similarity index 85% rename from comparing_references_inspection/src/test/testData/before1.after.java rename to comparing_references_inspection/src/test/resources/Neq.after.java index acedf90e0..440f8bf4a 100644 --- a/comparing_references_inspection/src/test/testData/before1.after.java +++ b/comparing_references_inspection/src/test/resources/Neq.after.java @@ -1,4 +1,4 @@ -public class X { +public class Neq { public boolean compare2Dates(java.util.Date dt1, java.util.Date dt2){ return (!dt1.equals(dt2)); } diff --git a/comparing_references_inspection/src/test/testData/before1.java b/comparing_references_inspection/src/test/resources/Neq.java similarity index 85% rename from comparing_references_inspection/src/test/testData/before1.java rename to comparing_references_inspection/src/test/resources/Neq.java index 325c4ebf5..aa7a04f22 100644 --- a/comparing_references_inspection/src/test/testData/before1.java +++ b/comparing_references_inspection/src/test/resources/Neq.java @@ -1,4 +1,4 @@ -public class X { +public class Neq { public boolean compare2Dates(java.util.Date dt1, java.util.Date dt2){ return (dt1 != dt2); }