mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dev-kit inspection: detect QuickFix's getFamilyName() implementation which are depend on context
This commit is contained in:
@@ -147,6 +147,12 @@
|
||||
groupKey="inspections.group.name"
|
||||
enabledByDefault="false" isInternal="true"
|
||||
level="ERROR" implementationClass="org.jetbrains.idea.devkit.inspections.internal.HighlightVisitorInternalInspection"/>
|
||||
<localInspection groupPath="Java" language="JAVA" shortName="QuickFixGetFamilyNameViolation"
|
||||
displayName="QuickFix's getFamilyName() implementation must not depend on a specific context"
|
||||
groupKey="inspections.group.name"
|
||||
enabledByDefault="true"
|
||||
level="WARNING"
|
||||
implementationClass="org.jetbrains.idea.devkit.inspections.QuickFixGetFamilyNameViolationInspection"/>
|
||||
|
||||
|
||||
<moduleConfigurationEditorProvider implementation="org.jetbrains.idea.devkit.module.PluginModuleEditorsProvider"/>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
Inspection reports cases when <strong>QuickFix#getFamilyName()</strong>
|
||||
implementation uses non-static fields, methods, containing method local variables variables etc.
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.
|
||||
* 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 org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class QuickFixGetFamilyNameViolationInspection extends DevKitInspectionBase {
|
||||
private final static Logger LOG = Logger.getInstance(QuickFixGetFamilyNameViolationInspection.class);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
if ("getFamilyName".equals(method.getName()) && !method.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
final PsiClass aClass = method.getContainingClass();
|
||||
if (InheritanceUtil.isInheritor(aClass, QuickFix.class.getName()) && !isPureMethod(method)) {
|
||||
final PsiIdentifier identifier = method.getNameIdentifier();
|
||||
LOG.assertTrue(identifier != null);
|
||||
//noinspection DialogTitleCapitalization
|
||||
return new ProblemDescriptor[]{
|
||||
manager.createProblemDescriptor(identifier, "QuickFix's getFamilyName() implementation must not depend on a specific context", (LocalQuickFix) null, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, true)};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isPureMethod(final PsiMethod method) {
|
||||
if (method.hasModifierProperty(PsiModifier.STATIC)) return true;
|
||||
final PsiCodeBlock body = method.getBody();
|
||||
if (body == null) return true;
|
||||
final Collection<PsiJavaCodeReferenceElement> referenceIterator =
|
||||
PsiTreeUtil.findChildrenOfType(body, PsiJavaCodeReferenceElement.class);
|
||||
for (PsiJavaCodeReferenceElement reference : referenceIterator) {
|
||||
|
||||
final PsiElement resolved = reference.resolve();
|
||||
if (resolved instanceof PsiVariable) {
|
||||
if (resolved instanceof PsiParameter || (resolved instanceof PsiLocalVariable && !PsiTreeUtil.isAncestor(body, resolved, false))) {
|
||||
return false;
|
||||
}
|
||||
if (resolved instanceof PsiField && !((PsiField)resolved).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (resolved instanceof PsiMethod && !((PsiMethod)resolved).hasModifierProperty(PsiModifier.STATIC)) {
|
||||
final PsiClass resolvedContainingClass = ((PsiMethod)resolved).getContainingClass();
|
||||
if (resolvedContainingClass == method.getContainingClass()) {
|
||||
if (!isPureMethod((PsiMethod)resolved)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
|
||||
class MyQuickFix implements QuickFix {
|
||||
|
||||
public String getName() {
|
||||
return "that fix do some fix";
|
||||
};
|
||||
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
|
||||
class MyQuickFix implements QuickFix {
|
||||
|
||||
static String someField = "Hello";
|
||||
|
||||
public String getName() {
|
||||
return "some name";
|
||||
};
|
||||
|
||||
public String getFamilyName() {
|
||||
return someField + getName() + "123";
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
|
||||
class MyQuickFix implements QuickFix {
|
||||
|
||||
String someField;
|
||||
|
||||
public String getName() {
|
||||
return someField;
|
||||
};
|
||||
|
||||
public String getFamilyName() {
|
||||
return getNameStatic() + "123";
|
||||
};
|
||||
|
||||
static String getNameStatic() {
|
||||
return "Static";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
|
||||
class A {
|
||||
|
||||
QuickFix getFix(final String someParameter) {
|
||||
return new QuickFix() {
|
||||
public String getName() {
|
||||
return "some name";
|
||||
};
|
||||
|
||||
public String <warning descr="QuickFix's getFamilyName() implementation must not depend on a specific context">getFamilyName</warning>() {
|
||||
return someParameter + "123";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
|
||||
class MyQuickFix implements QuickFix {
|
||||
|
||||
String someField;
|
||||
|
||||
public String getName() {
|
||||
return "some name";
|
||||
};
|
||||
|
||||
public String <warning descr="QuickFix's getFamilyName() implementation must not depend on a specific context">getFamilyName</warning>() {
|
||||
return someField + getName() + "123";
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import com.intellij.codeInspection.QuickFix;
|
||||
|
||||
class MyQuickFix implements QuickFix {
|
||||
|
||||
String someField;
|
||||
|
||||
public String getName() {
|
||||
return someField;
|
||||
};
|
||||
|
||||
public String <warning descr="QuickFix's getFamilyName() implementation must not depend on a specific context">getFamilyName</warning>() {
|
||||
return getName() + "123";
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.
|
||||
* 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 org.jetbrains.idea.devkit.inspections;
|
||||
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
@TestDataPath("$CONTENT_ROOT/testData/inspections/getFamilyNameViolation")
|
||||
public class QuickFixGetFamilyNameViolationInspectionTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return PluginPathManager.getPluginHomePathRelative("devkit") + "/testData/inspections/getFamilyNameViolation";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
myFixture.enableInspections(QuickFixGetFamilyNameViolationInspection.class);
|
||||
myFixture.addClass("package com.intellij.codeInspection;" +
|
||||
"public interface QuickFix {" +
|
||||
" String getName();" +
|
||||
" String getFamilyName();" +
|
||||
"}");
|
||||
}
|
||||
|
||||
public void testViolationByField() {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testViolationByGetName() {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testViolationByExternalParameter() {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testNotViolatedStaticField() {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testNotViolatedStaticMethod() {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
|
||||
public void testNotViolatedGetNameMethod() {
|
||||
myFixture.testHighlighting(getTestName(false) + ".java");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user