diff options
Diffstat (limited to 'plugins/devkit/src/inspections/PluginXmlDomInspection.java')
-rw-r--r-- | plugins/devkit/src/inspections/PluginXmlDomInspection.java | 126 |
1 files changed, 124 insertions, 2 deletions
diff --git a/plugins/devkit/src/inspections/PluginXmlDomInspection.java b/plugins/devkit/src/inspections/PluginXmlDomInspection.java index b160cbf5dbd1..af691d283e0e 100644 --- a/plugins/devkit/src/inspections/PluginXmlDomInspection.java +++ b/plugins/devkit/src/inspections/PluginXmlDomInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -15,12 +15,28 @@ */ package org.jetbrains.idea.devkit.inspections; +import com.intellij.codeInspection.ProblemHighlightType; +import com.intellij.openapi.module.Module; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.xml.DomElement; +import com.intellij.util.xml.DomUtil; +import com.intellij.util.xml.GenericAttributeValue; import com.intellij.util.xml.highlighting.BasicDomElementsInspection; +import com.intellij.util.xml.highlighting.DomElementAnnotationHolder; +import com.intellij.util.xml.highlighting.DomHighlightingHelper; +import com.intellij.util.xml.highlighting.RemoveDomElementQuickFix; +import com.intellij.util.xml.reflect.DomAttributeChildDescription; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.idea.devkit.DevKitBundle; -import org.jetbrains.idea.devkit.dom.IdeaPlugin; +import org.jetbrains.idea.devkit.dom.*; +import org.jetbrains.idea.devkit.util.PsiUtil; + +import java.util.List; /** * @author mike @@ -47,4 +63,110 @@ public class PluginXmlDomInspection extends BasicDomElementsInspection<IdeaPlugi public String getShortName() { return "PluginXmlValidity"; } + + @Override + protected void checkDomElement(DomElement element, DomElementAnnotationHolder holder, DomHighlightingHelper helper) { + super.checkDomElement(element, holder, helper); + + if (element instanceof IdeaPlugin) { + checkJetBrainsPlugin((IdeaPlugin)element, holder); + } + else if (element instanceof Extension) { + annotateExtension((Extension)element, holder); + } + else if (element instanceof Vendor) { + annotateVendor((Vendor)element, holder); + } + else if (element instanceof IdeaVersion) { + annotateIdeaVersion((IdeaVersion)element, holder); + } + else if (element instanceof Extensions) { + annotateExtensions((Extensions)element, holder); + } + } + + private static void checkJetBrainsPlugin(IdeaPlugin ideaPlugin, DomElementAnnotationHolder holder) { + final Module module = ideaPlugin.getModule(); + if (module == null) return; + if (!PsiUtil.isIdeaProject(module.getProject())) return; + + if (ideaPlugin.getPluginId() == null) return; + + final Vendor vendor = ContainerUtil.getFirstItem(ideaPlugin.getVendors()); + if (vendor == null) return; + if (!"JetBrains".equals(vendor.getValue())) return; + + for (Extensions extensions : ideaPlugin.getExtensions()) { + final List<Extension> definedEps = DomUtil.getDefinedChildrenOfType(extensions, Extension.class, true, false); + for (Extension extension : definedEps) { + final ExtensionPoint extensionPoint = extension.getExtensionPoint(); + if (extensionPoint == null) continue; + if ("com.intellij.errorHandler".equals(extensionPoint.getEffectiveQualifiedName())) { + return; + } + } + } + + holder.createProblem(DomUtil.getFileElement(ideaPlugin), + "JetBrains plugin should provide <errorHandler>"); + } + + private static void annotateExtensions(Extensions extensions, DomElementAnnotationHolder holder) { + final GenericAttributeValue<IdeaPlugin> xmlnsAttribute = extensions.getXmlns(); + if (!DomUtil.hasXml(xmlnsAttribute)) return; + + holder.createProblem(xmlnsAttribute, + ProblemHighlightType.LIKE_DEPRECATED, + "Use defaultExtensionNs instead", null).highlightWholeElement(); + } + + private static void annotateIdeaVersion(IdeaVersion ideaVersion, DomElementAnnotationHolder holder) { + highlightNotUsedAnymore(ideaVersion.getMin(), holder); + highlightNotUsedAnymore(ideaVersion.getMax(), holder); + } + + private static void annotateExtension(Extension extension, DomElementAnnotationHolder holder) { + final ExtensionPoint extensionPoint = extension.getExtensionPoint(); + if (extensionPoint == null) return; + final GenericAttributeValue<PsiClass> interfaceAttribute = extensionPoint.getInterface(); + if (DomUtil.hasXml(interfaceAttribute)) { + final PsiClass value = interfaceAttribute.getValue(); + if (value != null && value.isDeprecated()) { + holder.createProblem(extension, ProblemHighlightType.LIKE_DEPRECATED, "Deprecated EP", null); + return; + } + } + + final List<? extends DomAttributeChildDescription> descriptions = extension.getGenericInfo().getAttributeChildrenDescriptions(); + for (DomAttributeChildDescription attributeDescription : descriptions) { + final GenericAttributeValue attributeValue = attributeDescription.getDomAttributeValue(extension); + if (attributeValue == null || !DomUtil.hasXml(attributeValue)) continue; + + final PsiElement declaration = attributeDescription.getDeclaration(extension.getManager().getProject()); + if (declaration instanceof PsiField) { + PsiField psiField = (PsiField)declaration; + if (psiField.isDeprecated()) { + holder.createProblem(attributeValue, ProblemHighlightType.LIKE_DEPRECATED, + "Deprecated attribute '" + attributeDescription.getName() + "'", + null) + .highlightWholeElement(); + } + } + } + } + + private static void annotateVendor(Vendor vendor, DomElementAnnotationHolder holder) { + highlightNotUsedAnymore(vendor.getLogo(), holder); + } + + private static void highlightNotUsedAnymore(GenericAttributeValue attributeValue, + DomElementAnnotationHolder holder) { + if (!DomUtil.hasXml(attributeValue)) return; + + holder.createProblem(attributeValue, + ProblemHighlightType.LIKE_DEPRECATED, + "Not used anymore", + null, new RemoveDomElementQuickFix(attributeValue)) + .highlightWholeElement(); + } } |