mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Javafx: Resolve $null symbol and ${null} expression in FXML (IDEA-112153)
This commit is contained in:
+8
@@ -374,6 +374,14 @@ public class JavaFXHighlightingTest extends AbstractJavaFXTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNullObjectValue() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testNullPrimitiveValue() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testFactoryMethod() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.javaFX.fxml;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -51,6 +53,9 @@ public class FxmlConstants {
|
||||
|
||||
@NonNls public static final String SOURCE = "source";
|
||||
|
||||
@NonNls public static final String NULL_EXPRESSION = "${null}";
|
||||
@NonNls private static final String NULL_VALUE = "$null";
|
||||
|
||||
public static final Set<String> FX_BUILT_IN_ATTRIBUTES =
|
||||
ContainerUtil.immutableSet(FX_ID, FX_CONTROLLER, VALUE, FX_VALUE, FX_FACTORY, FX_CONSTANT);
|
||||
|
||||
@@ -71,4 +76,7 @@ public class FxmlConstants {
|
||||
.put(FX_COPY, Collections.singletonList(SOURCE))
|
||||
.build();
|
||||
|
||||
public static boolean isNullValue(@NotNull String value) {
|
||||
return NULL_VALUE.equals(StringUtil.trimTrailing(value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import com.intellij.xml.XmlAttributeDescriptor;
|
||||
import com.intellij.xml.XmlElementDescriptor;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -804,11 +805,19 @@ public class JavaFxPsiUtil {
|
||||
|
||||
@Nullable
|
||||
public static PsiClass getWritablePropertyClass(@Nullable XmlAttributeValue xmlAttributeValue) {
|
||||
if (xmlAttributeValue != null) {
|
||||
return getPropertyClass(getWritablePropertyType(xmlAttributeValue), xmlAttributeValue);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType getWritablePropertyType(@Nullable XmlAttributeValue xmlAttributeValue) {
|
||||
final PsiClass tagClass = getTagClass(xmlAttributeValue);
|
||||
if (tagClass != null) {
|
||||
final PsiElement declaration = getAttributeDeclaration(xmlAttributeValue);
|
||||
if (declaration != null) {
|
||||
return getPropertyClass(getWritablePropertyType(tagClass, declaration), xmlAttributeValue);
|
||||
return getWritablePropertyType(tagClass, declaration);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -843,6 +852,7 @@ public class JavaFxPsiUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Contract("null->false")
|
||||
public static boolean isPrimitiveOrBoxed(@Nullable PsiType psiType) {
|
||||
return psiType instanceof PsiPrimitiveType || PsiPrimitiveType.getUnboxedType(psiType) != null;
|
||||
}
|
||||
|
||||
+14
-2
@@ -9,6 +9,7 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.xml.impl.BasicXmlAttributeDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonNames;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
|
||||
|
||||
@@ -129,6 +130,9 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript
|
||||
if (value.startsWith("$")) {
|
||||
return validatePropertyExpression(xmlAttributeValue, value);
|
||||
}
|
||||
else if (StringUtil.trimLeading(value).startsWith("$")) {
|
||||
return "Spaces aren't allowed before property or expression";
|
||||
}
|
||||
else {
|
||||
return validateLiteral(xmlAttributeValue, value);
|
||||
}
|
||||
@@ -160,9 +164,17 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript
|
||||
if (isIncompletePropertyChain(propertyNames)) {
|
||||
return "Incorrect expression syntax";
|
||||
}
|
||||
if (FxmlConstants.NULL_EXPRESSION.equals(value)) return null;
|
||||
|
||||
final XmlTag currentTag = PsiTreeUtil.getParentOfType(xmlAttributeValue, XmlTag.class);
|
||||
final PsiClass targetPropertyClass = JavaFxPsiUtil.getWritablePropertyClass(xmlAttributeValue);
|
||||
final PsiType targetPropertyType = JavaFxPsiUtil.getWritablePropertyType(xmlAttributeValue);
|
||||
if (FxmlConstants.isNullValue(value)) {
|
||||
if (JavaFxPsiUtil.isPrimitiveOrBoxed(targetPropertyType)) {
|
||||
return "Unable to coerce to " + targetPropertyType.getPresentableText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
final PsiClass targetPropertyClass = JavaFxPsiUtil.getPropertyClass(targetPropertyType, xmlAttributeValue);
|
||||
if (targetPropertyClass == null || JavaFxPsiUtil.hasConversionFromAnyType(targetPropertyClass)) return null;
|
||||
|
||||
final String firstPropertyName = propertyNames.get(0);
|
||||
@@ -242,7 +254,7 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript
|
||||
|
||||
@Override
|
||||
public PsiReference[] getValueReferences(XmlElement element, @NotNull String text) {
|
||||
return !text.startsWith("${") ? super.getValueReferences(element, text) : PsiReference.EMPTY_ARRAY;
|
||||
return !text.startsWith("${") && !FxmlConstants.isNullValue(text) ? super.getValueReferences(element, text) : PsiReference.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+2
@@ -81,6 +81,7 @@ public class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider {
|
||||
@NotNull XmlAttributeValue xmlAttributeValue,
|
||||
@NotNull String value,
|
||||
@NotNull Map<String, XmlAttributeValue> fileIds) {
|
||||
if (FxmlConstants.NULL_EXPRESSION.equals(value)) return PsiReference.EMPTY_ARRAY;
|
||||
final String expressionBody = value.substring(2, value.length() - 1);
|
||||
final List<String> propertyNames = StringUtil.split(expressionBody, ".", true, false);
|
||||
if (JavaFxPropertyAttributeDescriptor.isIncompletePropertyChain(propertyNames)) return PsiReference.EMPTY_ARRAY;
|
||||
@@ -115,6 +116,7 @@ public class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider {
|
||||
private static PsiReference[] getSinglePropertyReferences(@NotNull XmlAttributeValue xmlAttributeValue,
|
||||
@NotNull String value,
|
||||
@NotNull Map<String, XmlAttributeValue> fileIds) {
|
||||
if (FxmlConstants.isNullValue(value)) return PsiReference.EMPTY_ARRAY;
|
||||
return getSinglePropertyReferences(xmlAttributeValue, fileIds, value.substring(1), 1);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<VBox xmlns="http://javafx.com/javafx/8.0.91">
|
||||
<Label text="${null}" textAlignment="$null "/>
|
||||
<Button text="$null " tooltip="$null" textAlignment="${null}"/>
|
||||
<Label text=<error descr="Spaces aren't allowed before property or expression">" ${null}"</error>/>
|
||||
<Label text=<error descr="Spaces aren't allowed before property or expression">" $null"</error>/>
|
||||
</VBox>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<VBox xmlns="http://javafx.com/javafx/8.0.91">
|
||||
<Button text="Button1" prefWidth=<error descr="Unable to coerce to double">"$null"</error>/>
|
||||
<Button text="Button2" prefWidth="${null}"/>
|
||||
<Button text="Button3" defaultButton=<error descr="Unable to coerce to boolean">"$null"</error>/>
|
||||
</VBox>
|
||||
Reference in New Issue
Block a user