From f74d85e1bd8894b28cfeeb7abb8a11f62d196810 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 17 Jan 2013 19:15:06 +0100 Subject: [PATCH] javafx: enum attribute values --- .../javaFX/fxml/JavaFxCommonClassNames.java | 1 + .../JavaFxPropertyAttributeDescriptor.java | 66 ++++++++++++++++- ...vaFxStaticPropertyAttributeDescriptor.java | 74 +------------------ .../completion/availablePositions.fxml | 5 ++ .../completion/availablePositions_after.fxml | 5 ++ .../testData/highlighting/enumValues.fxml | 8 ++ .../javaFX/fxml/JavaFXHighlightingTest.java | 4 + .../javaFX/fxml/JavaFxCompletionTest.java | 51 +++++++++++++ 8 files changed, 139 insertions(+), 75 deletions(-) create mode 100644 plugins/javaFX/testData/completion/availablePositions.fxml create mode 100644 plugins/javaFX/testData/completion/availablePositions_after.fxml create mode 100644 plugins/javaFX/testData/highlighting/enumValues.fxml create mode 100644 plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxCompletionTest.java diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxCommonClassNames.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxCommonClassNames.java index b275467c561d..217b989d9ab0 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxCommonClassNames.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxCommonClassNames.java @@ -27,4 +27,5 @@ public class JavaFxCommonClassNames { @NonNls public static final String JAVAFX_EVENT = "javafx.event.Event"; @NonNls public static final String JAVAFX_BEANS_DEFAULT_PROPERTY = "javafx.beans.DefaultProperty"; @NonNls public static final String JAVAFX_FXML_FXML = "javafx.fxml.FXML"; + @NonNls public static final String JAVAFX_BEANS_PROPERTY_OBJECT_PROPERTY = "javafx.beans.property.ObjectProperty"; } diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPropertyAttributeDescriptor.java index 4409429cdc21..1d734992c844 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPropertyAttributeDescriptor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPropertyAttributeDescriptor.java @@ -1,12 +1,16 @@ package org.jetbrains.plugins.javaFX.fxml; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.*; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.psi.xml.XmlElement; import com.intellij.util.ArrayUtil; import com.intellij.xml.XmlAttributeDescriptor; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + /** * User: anna * Date: 1/10/13 @@ -48,21 +52,75 @@ public class JavaFxPropertyAttributeDescriptor implements XmlAttributeDescriptor @Override public boolean isEnumerated() { - return false; + return getEnum() != null; } @Nullable @Override public String[] getEnumeratedValues() { - return new String[0]; + final PsiClass enumClass = getEnum(); + if (enumClass != null) { + final PsiField[] fields = enumClass.getFields(); + final List enumConstants = new ArrayList(); + for (PsiField enumField : fields) { + if (enumField instanceof PsiEnumConstant) { + enumConstants.add(enumField.getName()); + } + } + return ArrayUtil.toStringArray(enumConstants); + } + return null; } + private PsiClass getEnum() { + final PsiElement field = getDeclaration(); + if (field instanceof PsiField) { + final PsiType type = ((PsiField)field).getType(); + if (type instanceof PsiClassType) { + final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics(); + final PsiClass attributeClass = resolveResult.getElement(); + if (attributeClass != null) { + final PsiClass objectProperty = JavaPsiFacade.getInstance(attributeClass.getProject()) + .findClass(JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY_OBJECT_PROPERTY, attributeClass.getResolveScope()); + if (objectProperty != null) { + final PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(objectProperty, attributeClass, resolveResult.getSubstitutor()); + if (superClassSubstitutor != null) { + final PsiType propertyType = superClassSubstitutor.substitute(objectProperty.getTypeParameters()[0]); + if (propertyType instanceof PsiClassType) { + final PsiClass psiClass = ((PsiClassType)propertyType).resolve(); + if (psiClass != null && psiClass.isEnum()) { + return psiClass; + } + } + } + } + } + } + } + return null; + } + @Nullable @Override public String validateValue(XmlElement context, String value) { + if (isEnumerated()) { + final String[] values = getEnumeratedValues(); + if (values != null && !isWithingBounds(value, values)) { + return value + " is not withing its bounds"; + } + } return null; } + private static boolean isWithingBounds(String value, String[] values) { + for (String enumConstant : values) { + if (StringUtil.endsWithIgnoreCase(enumConstant, value)) { + return true; + } + } + return false; + } + @Override public PsiElement getDeclaration() { return myPsiClass != null ? myPsiClass.findFieldByName(myName, true) : null; diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxStaticPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxStaticPropertyAttributeDescriptor.java index 6a6321f97e97..611127a2cf80 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxStaticPropertyAttributeDescriptor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxStaticPropertyAttributeDescriptor.java @@ -15,91 +15,23 @@ */ package org.jetbrains.plugins.javaFX.fxml; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; -import com.intellij.psi.xml.XmlElement; -import com.intellij.util.ArrayUtil; -import com.intellij.xml.XmlAttributeDescriptor; -import org.jetbrains.annotations.Nullable; /** * User: anna * Date: 1/10/13 */ -public class JavaFxStaticPropertyAttributeDescriptor implements XmlAttributeDescriptor { - private static final Logger LOG = Logger.getInstance("#" + JavaFxStaticPropertyAttributeDescriptor.class.getName()); +public class JavaFxStaticPropertyAttributeDescriptor extends JavaFxPropertyAttributeDescriptor { private final PsiMethod mySetter; - private final String myName; - + public JavaFxStaticPropertyAttributeDescriptor(PsiMethod setter, String name) { + super(name, setter.getContainingClass()); mySetter = setter; - myName = name; - } - - @Override - public boolean isRequired() { - return false; - } - - @Override - public boolean isFixed() { - return false; - } - - @Override - public boolean hasIdType() { - return false; - } - - @Override - public boolean hasIdRefType() { - return false; - } - - @Nullable - @Override - public String getDefaultValue() { - return null; - } - - @Override - public boolean isEnumerated() { - return false; - } - - @Nullable - @Override - public String[] getEnumeratedValues() { - return new String[0]; - } - - @Nullable - @Override - public String validateValue(XmlElement context, String value) { - return null; } @Override public PsiElement getDeclaration() { return mySetter; } - - @Override - public String getName(PsiElement context) { - return getName(); - } - - @Override - public String getName() { - return myName; - } - - @Override - public void init(PsiElement element) {} - - @Override - public Object[] getDependences() { - return ArrayUtil.EMPTY_OBJECT_ARRAY; - } } diff --git a/plugins/javaFX/testData/completion/availablePositions.fxml b/plugins/javaFX/testData/completion/availablePositions.fxml new file mode 100644 index 000000000000..507a35ad2fcb --- /dev/null +++ b/plugins/javaFX/testData/completion/availablePositions.fxml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/javaFX/testData/completion/availablePositions_after.fxml b/plugins/javaFX/testData/completion/availablePositions_after.fxml new file mode 100644 index 000000000000..cc95a4106905 --- /dev/null +++ b/plugins/javaFX/testData/completion/availablePositions_after.fxml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/plugins/javaFX/testData/highlighting/enumValues.fxml b/plugins/javaFX/testData/highlighting/enumValues.fxml new file mode 100644 index 000000000000..c149f40fd8e7 --- /dev/null +++ b/plugins/javaFX/testData/highlighting/enumValues.fxml @@ -0,0 +1,8 @@ + + + + + + + "UNKNOWN"/> + \ No newline at end of file diff --git a/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java b/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java index 126b3e53bf7f..d41734ee64ba 100644 --- a/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java +++ b/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java @@ -36,6 +36,10 @@ public class JavaFXHighlightingTest extends DaemonAnalyzerTestCase { doTest(); } + public void testEnumValues() throws Exception { + doTest(); + } + private void doTest() throws Exception { doTest(false, false, getTestName(true) + ".fxml"); } diff --git a/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxCompletionTest.java b/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxCompletionTest.java new file mode 100644 index 000000000000..fbc45669314e --- /dev/null +++ b/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxCompletionTest.java @@ -0,0 +1,51 @@ +/* + * Copyright 2000-2013 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.plugins.javaFX.fxml; + +import com.intellij.codeInsight.completion.CompletionTestCase; +import com.intellij.openapi.application.PluginPathManager; +import com.intellij.testFramework.PsiTestUtil; +import org.jetbrains.annotations.NotNull; + +/** + * User: anna + * Date: 1/17/13 + */ +public class JavaFxCompletionTest extends CompletionTestCase { + + @Override + protected void setUpModule() { + super.setUpModule(); + PsiTestUtil.addLibrary(getModule(), "javafx", PluginPathManager.getPluginHomePath("javaFX") + "/testData", "jfxrt.jar"); + } + + public void testAvailablePositions() throws Exception { + doTest(); + } + + private void doTest() throws Exception { + configureByFile(getTestName(true) + ".fxml"); + assertTrue(myItems.length > 0); + selectItem(myItems[0]); + checkResultByFile(getTestName(true) + "_after.fxml"); + } + + @NotNull + @Override + protected String getTestDataPath() { + return PluginPathManager.getPluginHomePath("javaFX") + "/testData/completion/"; + } +}