mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
intention description check
This commit is contained in:
+1
-1
@@ -2,4 +2,4 @@
|
||||
<body>
|
||||
<font face="verdana" size="-1">This inspection detects missing html-description for an inspection.</font>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -17,18 +17,22 @@ package org.jetbrains.idea.devkit;
|
||||
|
||||
import com.intellij.codeInspection.InspectionToolProvider;
|
||||
import org.jetbrains.idea.devkit.inspections.ComponentNotRegisteredInspection;
|
||||
import org.jetbrains.idea.devkit.inspections.DescriptionNotFoundInspection;
|
||||
import org.jetbrains.idea.devkit.inspections.InspectionDescriptionNotFoundInspection;
|
||||
import org.jetbrains.idea.devkit.inspections.IntentionDescriptionNotFoundInspection;
|
||||
import org.jetbrains.idea.devkit.inspections.PluginXmlDomInspection;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class DevKitInspectionToolProvider implements InspectionToolProvider {
|
||||
|
||||
public Class[] getInspectionClasses() {
|
||||
return new Class[] {
|
||||
//RegistrationProblemsInspection.class,
|
||||
PluginXmlDomInspection.class,
|
||||
ComponentNotRegisteredInspection.class,
|
||||
DescriptionNotFoundInspection.class
|
||||
InspectionDescriptionNotFoundInspection.class,
|
||||
IntentionDescriptionNotFoundInspection.class
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -41,7 +41,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class DescriptionNotFoundInspection extends DevKitInspectionBase{
|
||||
public class InspectionDescriptionNotFoundInspection extends DevKitInspectionBase{
|
||||
@NonNls private static final String INSPECTION_PROFILE_ENTRY = "com.intellij.codeInspection.InspectionProfileEntry";
|
||||
@NonNls private static final String INSPECTION_DESCRIPTIONS = "inspectionDescriptions";
|
||||
|
||||
@@ -77,7 +77,7 @@ public class DescriptionNotFoundInspection extends DevKitInspectionBase{
|
||||
final PsiElement problem = getProblemElement(aClass, method);
|
||||
final ProblemDescriptor problemDescriptor = manager
|
||||
.createProblemDescriptor(problem == null ? nameIdentifier : problem,
|
||||
"Inspection does not have a description", isOnTheFly, new LocalQuickFix[]{new CreateHtmlDescriptionFix(filename, module)},
|
||||
"Inspection does not have a description", isOnTheFly, new LocalQuickFix[]{new CreateHtmlDescriptionFix(filename, module, false)},
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
return new ProblemDescriptor[]{problemDescriptor};
|
||||
}
|
||||
@@ -152,7 +152,7 @@ public class DescriptionNotFoundInspection extends DevKitInspectionBase{
|
||||
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "DescriptionNotFoundInspection";
|
||||
return "InspectionDescriptionNotFoundInspection";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright 2000-2010 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.InspectionManager;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ModuleRootManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.idea.devkit.inspections.quickfix.CreateHtmlDescriptionFix;
|
||||
import org.jetbrains.idea.devkit.util.PsiUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Konstantin Bulenkov
|
||||
*/
|
||||
public class IntentionDescriptionNotFoundInspection extends DevKitInspectionBase{
|
||||
@NonNls private static final String INTENTION = "com.intellij.codeInsight.intention.IntentionAction";
|
||||
@NonNls private static final String INSPECTION_DESCRIPTIONS = "intentionDescriptions";
|
||||
|
||||
@Override
|
||||
public ProblemDescriptor[] checkClass(@NotNull PsiClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
|
||||
final Project project = aClass.getProject();
|
||||
final PsiIdentifier nameIdentifier = aClass.getNameIdentifier();
|
||||
final Module module = ModuleUtil.findModuleForPsiElement(aClass);
|
||||
|
||||
if (nameIdentifier == null || module == null || !PsiUtil.isInstanciatable(aClass)) return null;
|
||||
|
||||
final PsiClass base = JavaPsiFacade.getInstance(project).findClass(INTENTION, GlobalSearchScope.allScope(project));
|
||||
|
||||
if (base == null || ! aClass.isInheritor(base, true)) return null;
|
||||
|
||||
final PsiMethod method = findNearestMethod("getFamilyName", aClass);
|
||||
if (method == null) return null;
|
||||
final String filename = PsiUtil.getReturnedLiteral(method, aClass);
|
||||
if (filename == null) return null;
|
||||
|
||||
for (PsiDirectory description : getIntentionDescriptionsDirs(module)) {
|
||||
PsiDirectory dir = description.findSubdirectory(filename);
|
||||
if (dir == null) dir = description.findSubdirectory(aClass.getName());
|
||||
if (dir == null) continue;
|
||||
final PsiFile descr = dir.findFile("description.html");
|
||||
if (descr != null) return null;
|
||||
}
|
||||
|
||||
|
||||
final PsiElement problem = aClass.getNameIdentifier();
|
||||
final ProblemDescriptor problemDescriptor = manager
|
||||
.createProblemDescriptor(problem == null ? nameIdentifier : problem,
|
||||
"Intention does not have a description", isOnTheFly, new LocalQuickFix[]{new CreateHtmlDescriptionFix(aClass.getName(), module, true)},
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
|
||||
return new ProblemDescriptor[]{problemDescriptor};
|
||||
}
|
||||
|
||||
public static List<VirtualFile> getPotentialRoots(Module module) {
|
||||
final PsiDirectory[] dirs = getIntentionDescriptionsDirs(module);
|
||||
final List<VirtualFile> result = new ArrayList<VirtualFile>();
|
||||
if (dirs.length != 0) {
|
||||
for (PsiDirectory dir : dirs) {
|
||||
final PsiDirectory parent = dir.getParentDirectory();
|
||||
if (parent != null) result.add(parent.getVirtualFile());
|
||||
}
|
||||
} else {
|
||||
result.addAll(Arrays.asList(ModuleRootManager.getInstance(module).getSourceRoots()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static PsiDirectory[] getIntentionDescriptionsDirs(Module module) {
|
||||
final PsiPackage aPackage = JavaPsiFacade.getInstance(module.getProject()).findPackage(INSPECTION_DESCRIPTIONS);
|
||||
if (aPackage != null) {
|
||||
return aPackage.getDirectories(GlobalSearchScope.moduleWithDependenciesScope(module));
|
||||
} else {
|
||||
return PsiDirectory.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PsiMethod findNearestMethod(String name, @Nullable PsiClass cls) {
|
||||
if (cls == null) return null;
|
||||
for (PsiMethod method : cls.getMethods()) {
|
||||
if (method.getParameterList().getParametersCount() == 0 && method.getName().equals(name)) {
|
||||
return method.getModifierList().hasModifierProperty(PsiModifier.ABSTRACT) ? null : method;
|
||||
}
|
||||
}
|
||||
return findNearestMethod(name, cls.getSuperClass());
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return "Intention Description Checker";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "IntentionDescriptionNotFoundInspection";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,8 @@ import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.idea.devkit.DevKitBundle;
|
||||
import org.jetbrains.idea.devkit.inspections.DescriptionNotFoundInspection;
|
||||
import org.jetbrains.idea.devkit.inspections.InspectionDescriptionNotFoundInspection;
|
||||
import org.jetbrains.idea.devkit.inspections.IntentionDescriptionNotFoundInspection;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.File;
|
||||
@@ -54,14 +55,15 @@ import java.util.List;
|
||||
*/
|
||||
public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
|
||||
private final String myFilename;
|
||||
private final Module myModule;
|
||||
@NonNls private static final String DESCRIPTIONS_FOLDER = "inspectionDescriptions";
|
||||
private final Module myModule;
|
||||
@NonNls private static final String TEMPLATE_NAME = "InspectionDescription.html";
|
||||
private static final Icon NEW_HTML_ICON = IconLoader.getIcon("/new_html.png");
|
||||
private final boolean isIntention;
|
||||
|
||||
public CreateHtmlDescriptionFix(String filename, Module module) {
|
||||
public CreateHtmlDescriptionFix(String filename, Module module, boolean isIntention) {
|
||||
myModule = module;
|
||||
myFilename = filename + ".html";
|
||||
this.isIntention = isIntention;
|
||||
myFilename = isIntention ? filename : filename + ".html";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -75,7 +77,10 @@ public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
final List<VirtualFile> virtualFiles = DescriptionNotFoundInspection.getPotentialRoots(myModule);
|
||||
final List<VirtualFile> virtualFiles = isIntention ?
|
||||
IntentionDescriptionNotFoundInspection.getPotentialRoots(myModule)
|
||||
:
|
||||
InspectionDescriptionNotFoundInspection.getPotentialRoots(myModule);
|
||||
final VirtualFile[] roots = prepare(VfsUtil.toVirtualFileArray(virtualFiles));
|
||||
if (roots.length == 1) {
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@@ -88,7 +93,11 @@ public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
|
||||
else {
|
||||
List<String> options = new ArrayList<String>();
|
||||
for (VirtualFile file : roots) {
|
||||
options.add(file.getPresentableUrl() + File.separator + DESCRIPTIONS_FOLDER + File.separator + myFilename);
|
||||
String path = file.getPresentableUrl() + File.separator + getDescriptionFolderName() + File.separator + myFilename;
|
||||
if (isIntention) {
|
||||
path += File.separator + "description.html";
|
||||
}
|
||||
options.add(path);
|
||||
}
|
||||
final JList files = new JBList(ArrayUtil.toStringArray(options));
|
||||
final PopupChooserBuilder builder = JBPopupFactory.getInstance().createListPopupBuilder(files);
|
||||
@@ -117,16 +126,22 @@ public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
|
||||
PsiDirectory descrRoot = null;
|
||||
if (psiRoot == null) return;
|
||||
for (PsiDirectory dir : psiRoot.getSubdirectories()) {
|
||||
if (DESCRIPTIONS_FOLDER.equals(dir.getName())) {
|
||||
if (getDescriptionFolderName().equals(dir.getName())) {
|
||||
descrRoot = dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
descrRoot = descrRoot == null ? psiRoot.createSubdirectory(DESCRIPTIONS_FOLDER) : descrRoot;
|
||||
descrRoot = descrRoot == null ? psiRoot.createSubdirectory(getDescriptionFolderName()) : descrRoot;
|
||||
if (isIntention) {
|
||||
PsiDirectory dir = descrRoot.findSubdirectory(myFilename);
|
||||
if (dir == null) {
|
||||
descrRoot = descrRoot.createSubdirectory(myFilename);
|
||||
}
|
||||
}
|
||||
final FileTemplate descrTemplate = FileTemplateManager.getInstance().getJ2eeTemplate(TEMPLATE_NAME);
|
||||
final PsiElement template = FileTemplateUtil.createFromTemplate(descrTemplate, myFilename, null, descrRoot);
|
||||
final PsiElement template = FileTemplateUtil.createFromTemplate(descrTemplate, isIntention? "description.html" : myFilename, null, descrRoot);
|
||||
if (template instanceof PsiFile) {
|
||||
final VirtualFile file = ((PsiFile)template).getVirtualFile();
|
||||
if (file != null) {
|
||||
@@ -142,7 +157,7 @@ public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
|
||||
return NEW_HTML_ICON;
|
||||
}
|
||||
|
||||
private static VirtualFile[] prepare(VirtualFile[] roots) {
|
||||
private VirtualFile[] prepare(VirtualFile[] roots) {
|
||||
List<VirtualFile> found = new ArrayList<VirtualFile>();
|
||||
for (VirtualFile root : roots) {
|
||||
if (containsDescriptionDir(root)) {
|
||||
@@ -152,13 +167,17 @@ public class CreateHtmlDescriptionFix implements LocalQuickFix, Iconable {
|
||||
return found.size() > 0 ? VfsUtil.toVirtualFileArray(found) : roots;
|
||||
}
|
||||
|
||||
private static boolean containsDescriptionDir(VirtualFile root) {
|
||||
private boolean containsDescriptionDir(VirtualFile root) {
|
||||
if (!root.isDirectory()) return false;
|
||||
for (VirtualFile file : root.getChildren()) {
|
||||
if (file.isDirectory() && DESCRIPTIONS_FOLDER.equals(file.getName())) {
|
||||
if (file.isDirectory() && getDescriptionFolderName().equals(file.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private String getDescriptionFolderName() {
|
||||
return isIntention ? "intentionDescriptions" : "inspectionDescriptions";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user