Javafx: Support resolution of resource keys (IDEA-100213)
authorPavel Dolgov <pavel.dolgov@jetbrains.com>
Mon, 12 Sep 2016 15:12:42 +0000 (18:12 +0300)
committerPavel Dolgov <pavel.dolgov@jetbrains.com>
Tue, 13 Sep 2016 09:54:59 +0000 (12:54 +0300)
13 files changed:
plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXRenameTest.java
plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFxCompletionTest.java
plugins/javaFX/javaFX.iml
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/FxmlReferencesContributor.java
plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxResourcePropertyReferenceProvider.java [new file with mode: 0644]
plugins/javaFX/testData/completion/resourceProperty.fxml [new file with mode: 0644]
plugins/javaFX/testData/completion/resourcePropertyManyFiles.fxml [new file with mode: 0644]
plugins/javaFX/testData/highlighting/resourceKeyInAttribute.fxml [moved from plugins/javaFX/testData/highlighting/resourceIdInFxAttribute.fxml with 74% similarity]
plugins/javaFX/testData/rename/resourceProperty.fxml [new file with mode: 0644]
plugins/javaFX/testData/rename/resourceProperty.properties [new file with mode: 0644]
plugins/javaFX/testData/rename/resourceProperty_after.fxml [new file with mode: 0644]
plugins/javaFX/testData/rename/resourceProperty_after.properties [new file with mode: 0644]

index fc82a64c504d283436ce0698066e477b3a8195b2..b4123606a8da206d7da9f85ff8e5c840699ec532 100644 (file)
@@ -490,7 +490,9 @@ public class JavaFXHighlightingTest extends AbstractJavaFXTestCase {
     myFixture.testHighlighting(true, true, true, superclass + ".java");
   }
 
-  public void testResourceIdInFxAttribute() throws Exception {
+  public void testResourceKeyInAttribute() throws Exception {
+    myFixture.addFileToProject("messages.properties", "string.key=My text\n" +
+                                                      "double.key=123.456\n");
     doTest();
   }
 
index 592432817f71dd1beacc25ef3fc684ab535b9db1..888446423da7942e926a60daf95068cded28ade7 100644 (file)
@@ -219,6 +219,13 @@ public class JavaFXRenameTest extends AbstractJavaFXRenameTest {
     doTestProperty("newName", "model.Data", false);
   }
 
+  public void testResourceProperty() {
+    myFixture.configureByFiles(getTestName(true) + ".fxml", getTestName(true) + ".properties");
+    myFixture.renameElementAtCaret("new.name");
+    myFixture.checkResultByFile(getTestName(true) + "_after.fxml");
+    myFixture.checkResultByFile(getTestName(true) + ".properties", getTestName(true) + "_after.properties", false);
+  }
+
   public void doTestProperty(String name, boolean isBoolean) throws Exception {
     doTestProperty(name, null, isBoolean);
   }
index 03bb60e93ceeac006228eaa328f2be563d77b2ec..41ded06c516e0ced8cb422bc25f11734517fa64b 100644 (file)
@@ -330,6 +330,21 @@ public class JavaFxCompletionTest extends LightFixtureCompletionTestCase {
     }
   }
 
+  public void testResourceProperty() {
+    myFixture.addFileToProject("messages.properties", "double.key=123.456\n" +
+                                                      "string.key=Some text\n");
+    configureAndComplete();
+    assertSameElements(myFixture.getLookupElementStrings(), "double.key", "string.key");
+  }
+
+
+  public void testResourcePropertyManyFiles() {
+    myFixture.addFileToProject("messages1.properties", "double.key=123.456\n");
+    myFixture.addFileToProject("messages2.properties", "string.key=Some text\n");
+    configureAndComplete();
+    assertSameElements(myFixture.getLookupElementStrings(), "double.key", "string.key");
+  }
+
   private void doTest() throws Exception {
     doTest(null);
   }
index 3e4c82d62ae02987c25cefba7789840fe858545b..0936ae44f5a0d15a1e20cbc07ca7cb5e3bedf1e6 100644 (file)
@@ -24,6 +24,7 @@
     <orderEntry type="module" module-name="common-javaFX-plugin" />
     <orderEntry type="module" module-name="manifest" />
     <orderEntry type="module" module-name="idea-ui" />
+    <orderEntry type="module" module-name="properties" />
     <orderEntry type="library" name="SceneBuilderKit" level="project" />
     <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
   </component>
index 7c87fb9758ad786b2069e75e8f98e7db0d4bd4d5..f297e975c5855c48f95bf17ab4037087641e7e7b 100644 (file)
@@ -114,6 +114,12 @@ public class FxmlReferencesContributor extends PsiReferenceContributor {
                                           .and(attributeValueInFxml),
                                         new JavaFxLocationReferenceProvider(false, "css"));
 
+    registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withValue(string().startsWith("%"))
+                                          .withParent(XmlPatterns.xmlAttribute().andNot(
+                                            XmlPatterns.xmlAttribute().withName(
+                                              FxmlConstants.FX_VALUE, FxmlConstants.FX_CONSTANT, FxmlConstants.FX_FACTORY)))
+                                          .and(attributeValueInFxml), new JavaFxResourcePropertyReferenceProvider());
+
     registrar.registerReferenceProvider(PlatformPatterns.psiElement(XmlProcessingInstruction.class).inVirtualFile(virtualFile().withExtension(JavaFxFileTypeFactory.FXML_EXTENSION)),
                                         new ImportReferenceProvider());
 
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxResourcePropertyReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxResourcePropertyReferenceProvider.java
new file mode 100644 (file)
index 0000000..8da9bb4
--- /dev/null
@@ -0,0 +1,35 @@
+package org.jetbrains.plugins.javaFX.fxml.refs;
+
+import com.intellij.lang.properties.references.PropertyReference;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.PsiReferenceProvider;
+import com.intellij.psi.xml.XmlAttributeValue;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Pavel.Dolgov
+ */
+class JavaFxResourcePropertyReferenceProvider extends PsiReferenceProvider {
+  @NotNull
+  @Override
+  public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
+    if (element instanceof XmlAttributeValue) {
+      final String value = ((XmlAttributeValue)element).getValue();
+      if (value != null && value.startsWith("%") && value.length() > 1) {
+        return new PsiReference[]{new JavaFxResourcePropertyReference(value.substring(1), (XmlAttributeValue)element)};
+      }
+    }
+    return PsiReference.EMPTY_ARRAY;
+  }
+
+  static class JavaFxResourcePropertyReference extends PropertyReference {
+    public JavaFxResourcePropertyReference(@NotNull String key, @NotNull XmlAttributeValue element) {
+      super(key, element, null, false, new TextRange(2, key.length() + 2)); // "%key" - shift by 2 because the quote also counts
+    }
+  }
+}
diff --git a/plugins/javaFX/testData/completion/resourceProperty.fxml b/plugins/javaFX/testData/completion/resourceProperty.fxml
new file mode 100644 (file)
index 0000000..588f459
--- /dev/null
@@ -0,0 +1,5 @@
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.VBox?>
+<VBox xmlns:fx="http://javafx.com/fxml">
+  <Label text="%<caret>"/>
+</VBox>
\ No newline at end of file
diff --git a/plugins/javaFX/testData/completion/resourcePropertyManyFiles.fxml b/plugins/javaFX/testData/completion/resourcePropertyManyFiles.fxml
new file mode 100644 (file)
index 0000000..588f459
--- /dev/null
@@ -0,0 +1,5 @@
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.VBox?>
+<VBox xmlns:fx="http://javafx.com/fxml">
+  <Label text="%<caret>"/>
+</VBox>
\ No newline at end of file
similarity index 74%
rename from plugins/javaFX/testData/highlighting/resourceIdInFxAttribute.fxml
rename to plugins/javaFX/testData/highlighting/resourceKeyInAttribute.fxml
index 96dfc950f2be01ba807fa11c191156527f8a0689..9491fd6c6b7154d5fc29e2c277e76ae2086b2789 100644 (file)
@@ -8,5 +8,5 @@
     <Double fx:id="d" fx:value=<error descr="Invalid value: unable to coerce to java.lang.Double">"%double.key"</error>/>
     <String fx:id="s" fx:value="%string.key"/>
   </fx:define>
-  <Label text="%string.key" maxWidth="%double.key"/>
+  <Label text="%string.key" maxWidth="%double.key" maxHeight="%<error descr="Cannot resolve property key">missing.key</error>"/>
 </VBox>
\ No newline at end of file
diff --git a/plugins/javaFX/testData/rename/resourceProperty.fxml b/plugins/javaFX/testData/rename/resourceProperty.fxml
new file mode 100644 (file)
index 0000000..0b3de53
--- /dev/null
@@ -0,0 +1,5 @@
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.VBox?>
+<VBox xmlns:fx="http://javafx.com/fxml">
+  <Label text="%st<caret>ring.key"/>
+</VBox>
\ No newline at end of file
diff --git a/plugins/javaFX/testData/rename/resourceProperty.properties b/plugins/javaFX/testData/rename/resourceProperty.properties
new file mode 100644 (file)
index 0000000..03aebc4
--- /dev/null
@@ -0,0 +1 @@
+string.key=My text
diff --git a/plugins/javaFX/testData/rename/resourceProperty_after.fxml b/plugins/javaFX/testData/rename/resourceProperty_after.fxml
new file mode 100644 (file)
index 0000000..bb8a126
--- /dev/null
@@ -0,0 +1,5 @@
+<?import javafx.scene.control.Label?>
+<?import javafx.scene.layout.VBox?>
+<VBox xmlns:fx="http://javafx.com/fxml">
+  <Label text="%new.name"/>
+</VBox>
\ No newline at end of file
diff --git a/plugins/javaFX/testData/rename/resourceProperty_after.properties b/plugins/javaFX/testData/rename/resourceProperty_after.properties
new file mode 100644 (file)
index 0000000..8f114cd
--- /dev/null
@@ -0,0 +1 @@
+new.name=My text