From 5bc0d946024f5fed9e3f397763b181cbfa093025 Mon Sep 17 00:00:00 2001 From: Pavel Dolgov Date: Fri, 11 Mar 2016 18:21:09 +0300 Subject: [PATCH] Javafx: Add inspection in FXML to validate that RGB color components are in valid range (IDEA-103956) --- .../fxml/JavaFxColorRgbInspectionTest.java | 34 ++++++++ .../JavaFxColorRgb.html | 7 ++ .../src/META-INF/common-javaFX-plugin.xml | 2 + .../inspections/JavaFxColorRgbInspection.java | 84 +++++++++++++++++++ .../colorRgb/attributeHighlighting.fxml | 18 ++++ .../inspections/colorRgb/tagHighlighting.fxml | 25 ++++++ 6 files changed, 170 insertions(+) create mode 100644 plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxColorRgbInspectionTest.java create mode 100644 plugins/javaFX/resources/inspectionDescriptions/JavaFxColorRgb.html create mode 100644 plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxColorRgbInspection.java create mode 100644 plugins/javaFX/testData/inspections/colorRgb/attributeHighlighting.fxml create mode 100644 plugins/javaFX/testData/inspections/colorRgb/tagHighlighting.fxml diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxColorRgbInspectionTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxColorRgbInspectionTest.java new file mode 100644 index 000000000000..39a0c63b79a7 --- /dev/null +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxColorRgbInspectionTest.java @@ -0,0 +1,34 @@ +package org.jetbrains.plugins.javaFX.fxml; + +import com.intellij.openapi.application.PluginPathManager; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections.JavaFxColorRgbInspection; + +/** + * @author Pavel.Dolgov + */ +public class JavaFxColorRgbInspectionTest extends AbstractJavaFXTestCase { + @Override + protected void enableInspections() { + myFixture.enableInspections(new JavaFxColorRgbInspection()); + } + + public void testAttributeHighlighting() throws Exception { + doTestHighlighting(); + } + + public void testTagHighlighting() throws Exception { + doTestHighlighting(); + } + + private void doTestHighlighting() { + myFixture.configureByFiles(getTestName(true) + ".fxml"); + myFixture.checkHighlighting(); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("javaFX") + "/testData/inspections/colorRgb/"; + } +} diff --git a/plugins/javaFX/resources/inspectionDescriptions/JavaFxColorRgb.html b/plugins/javaFX/resources/inspectionDescriptions/JavaFxColorRgb.html new file mode 100644 index 000000000000..3f867fb46d31 --- /dev/null +++ b/plugins/javaFX/resources/inspectionDescriptions/JavaFxColorRgb.html @@ -0,0 +1,7 @@ + + +This inspection reports RGB color components which are out of valid range. + +

+ + \ No newline at end of file diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index ca16653de0a9..8a4ae2897de2 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -24,6 +24,8 @@ enabledByDefault="true" level="WARNING" displayName="JavaFX unused imports" groupName="JavaFX"/> + diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxColorRgbInspection.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxColorRgbInspection.java new file mode 100644 index 000000000000..f2f99a924eeb --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/codeInsight/inspections/JavaFxColorRgbInspection.java @@ -0,0 +1,84 @@ +package org.jetbrains.plugins.javaFX.fxml.codeInsight.inspections; + +import com.intellij.codeInspection.ProblemsHolder; +import com.intellij.codeInspection.XmlSuppressableInspectionTool; +import com.intellij.psi.*; +import com.intellij.psi.xml.*; +import com.intellij.xml.XmlAttributeDescriptor; +import com.intellij.xml.XmlElementDescriptor; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonNames; +import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory; +import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil; +import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyAttributeDescriptor; +import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxPropertyElementDescriptor; + +/** + * @author Pavel.Dolgov + */ +public class JavaFxColorRgbInspection extends XmlSuppressableInspectionTool { + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + return new XmlElementVisitor() { + @Override + public void visitXmlFile(XmlFile file) { + if (!JavaFxFileTypeFactory.isFxml(file)) return; + super.visitXmlFile(file); + } + + @Override + public void visitXmlAttribute(XmlAttribute attribute) { + super.visitXmlAttribute(attribute); + + final String attributeValue = attribute.getValue(); + if (attributeValue == null) return; + final XmlAttributeDescriptor descriptor = attribute.getDescriptor(); + if (descriptor instanceof JavaFxPropertyAttributeDescriptor) { + final PsiClass psiClass = ((JavaFxPropertyAttributeDescriptor)descriptor).getPsiClass(); + if (JavaFxCommonNames.JAVAFX_SCENE_COLOR.equals(psiClass.getQualifiedName())) { + final XmlAttributeValue valueElement = attribute.getValueElement(); + final PsiElement location = valueElement != null ? valueElement : attribute; + validateColorComponent(psiClass, attribute.getName(), attributeValue, location); + } + } + } + + @Override + public void visitXmlTag(XmlTag tag) { + super.visitXmlTag(tag); + if (tag.getSubTags().length != 0) return; + + final XmlElementDescriptor descriptor = tag.getDescriptor(); + if (descriptor instanceof JavaFxPropertyElementDescriptor) { + final PsiClass psiClass = ((JavaFxPropertyElementDescriptor)descriptor).getPsiClass(); + if (JavaFxCommonNames.JAVAFX_SCENE_COLOR.equals(psiClass.getQualifiedName())) { + final XmlTagValue valueElement = tag.getValue(); + final XmlText[] textElements = valueElement.getTextElements(); + final PsiElement location = textElements.length == 1 ? textElements[0] : tag; + validateColorComponent(psiClass, tag.getName(), valueElement.getTrimmedText(), location); + } + } + } + + private void validateColorComponent(@NotNull PsiClass psiClass, + @NotNull String propertyName, + @NotNull String propertyValue, + @NotNull PsiElement location) { + final PsiMember declaration = JavaFxPsiUtil.collectProperties(psiClass).get(propertyName); + final String boxedQName = JavaFxPsiUtil.getBoxedPropertyType(psiClass, declaration); + if (CommonClassNames.JAVA_LANG_FLOAT.equals(boxedQName) || CommonClassNames.JAVA_LANG_DOUBLE.equals(boxedQName)) { + try { + double value = Double.parseDouble(propertyValue); + if (value < 0.0 || value > 1.0) { + holder.registerProblem(location, "Color component has to be a number between 0.0 and 1.0, inclusively"); + } + } + catch (NumberFormatException ignored) { + } + } + } + }; + } +} diff --git a/plugins/javaFX/testData/inspections/colorRgb/attributeHighlighting.fxml b/plugins/javaFX/testData/inspections/colorRgb/attributeHighlighting.fxml new file mode 100644 index 000000000000..f23bfbf85d6b --- /dev/null +++ b/plugins/javaFX/testData/inspections/colorRgb/attributeHighlighting.fxml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/plugins/javaFX/testData/inspections/colorRgb/tagHighlighting.fxml b/plugins/javaFX/testData/inspections/colorRgb/tagHighlighting.fxml new file mode 100644 index 000000000000..99f7747155fc --- /dev/null +++ b/plugins/javaFX/testData/inspections/colorRgb/tagHighlighting.fxml @@ -0,0 +1,25 @@ + + + + + + +