diff --git a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java index 666f905be3a2..f66c68429f01 100644 --- a/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java +++ b/plugins/javaFX/javaFX-CE/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java @@ -20,9 +20,7 @@ import com.intellij.codeInsight.daemon.impl.analysis.XmlPathReferenceInspection; import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.htmlInspections.RequiredAttributesInspection; import com.intellij.openapi.application.PluginPathManager; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiField; -import com.intellij.psi.PsiReference; +import com.intellij.psi.*; import com.intellij.psi.search.ProjectScope; import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.ArrayUtil; @@ -144,6 +142,18 @@ public class JavaFXHighlightingTest extends DaemonAnalyzerTestCase { assertEquals(resultField, reference.resolve()); } + public void testNavigationFromMainToFxml() throws Exception { + configureByFiles(null, getTestName(false) + ".java", getTestName(true) + ".fxml"); + final int offset = myEditor.getCaretModel().getOffset(); + final PsiReference reference = myFile.findReferenceAt(offset); + assertNotNull(reference); + final PsiElement resolve = reference.resolve(); + assertNotNull(resolve); + final PsiFile containingFile = resolve.getContainingFile(); + assertNotNull(containingFile); + assertEquals(getTestName(true) + ".fxml", containingFile.getName()); + } + public void testSourceAttrRecognition() throws Exception { doTest(); } diff --git a/plugins/javaFX/javaFX.iml b/plugins/javaFX/javaFX.iml index 62b68b155832..2a8f125eb754 100644 --- a/plugins/javaFX/javaFX.iml +++ b/plugins/javaFX/javaFX.iml @@ -17,6 +17,7 @@ + diff --git a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml index c0ba7df0fc0b..4ddebeb1b51d 100644 --- a/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml +++ b/plugins/javaFX/src/META-INF/common-javaFX-plugin.xml @@ -25,6 +25,7 @@ JavaFX + 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 db043d8ea2f7..73e2d9af1850 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxCommonClassNames.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxCommonClassNames.java @@ -34,4 +34,5 @@ public class JavaFxCommonClassNames { @NonNls public static final String JAVAFX_FXML_BUILDER = "javafx.util.Builder"; @NonNls public static final String JAVAFX_BEANS_OBSERVABLE = "javafx.beans.Observable"; @NonNls public static final String VALUE_OF = "valueOf"; + @NonNls public static final String JAVAFX_FXML_FXMLLOADER = "javafx.fxml.FXMLLoader"; } diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java new file mode 100644 index 000000000000..ab1cfcb22880 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxReferencesContributor.java @@ -0,0 +1,95 @@ +/* + * 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.refs; + +import com.intellij.openapi.vfs.VirtualFileSystem; +import com.intellij.openapi.vfs.newvfs.NewVirtualFileSystem; +import com.intellij.psi.*; +import com.intellij.psi.filters.ElementFilter; +import com.intellij.psi.filters.position.FilterPattern; +import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames; + +import java.util.Collection; +import java.util.Collections; + +import static com.intellij.patterns.PsiJavaPatterns.literalExpression; + +/** + * User: anna + * Date: 2/22/13 + */ +public class JavaFxReferencesContributor extends PsiReferenceContributor { + + @Override + public void registerReferenceProviders(PsiReferenceRegistrar registrar) { + registrar.registerReferenceProvider(literalExpression().and(new FilterPattern(new ElementFilter() { + public boolean isAcceptable(Object element, PsiElement context) { + final PsiLiteralExpression literalExpression = (PsiLiteralExpression)context; + PsiMethodCallExpression callExpression = PsiTreeUtil.getParentOfType(literalExpression, PsiMethodCallExpression.class); + if (callExpression != null && "getResource".equals(callExpression.getMethodExpression().getReferenceName())) { + final PsiMethodCallExpression superCall = PsiTreeUtil.getParentOfType(callExpression, PsiMethodCallExpression.class, true); + if (superCall != null) { + final PsiReferenceExpression methodExpression = superCall.getMethodExpression(); + if ("load".equals(methodExpression.getReferenceName())) { + final PsiExpression qualifierExpression = methodExpression.getQualifierExpression(); + PsiClass psiClass = null; + if (qualifierExpression instanceof PsiReferenceExpression) { + final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve(); + if (resolve instanceof PsiClass) { + psiClass = (PsiClass)resolve; + } + } else if (qualifierExpression != null) { + psiClass = PsiUtil.resolveClassInType(qualifierExpression.getType()); + } + if (psiClass != null && JavaFxCommonClassNames.JAVAFX_FXML_FXMLLOADER.equals(psiClass.getQualifiedName())) { + return true; + } + } + } + } + return false; + } + + public boolean isClassAcceptable(Class hintClass) { + return true; + } + })), new PsiReferenceProvider() { + @NotNull + @Override + public PsiReference[] getReferencesByElement(@NotNull final PsiElement element, @NotNull ProcessingContext context) { + final Object value = ((PsiLiteralExpression)element).getValue(); + final PsiDirectory directory = element.getContainingFile().getParent(); + if (!(value instanceof String) || directory == null) return PsiReference.EMPTY_ARRAY; + final VirtualFileSystem fs = directory.getVirtualFile().getFileSystem(); + return new FileReferenceSet((String)value, element, 1, null, ((NewVirtualFileSystem)fs).isCaseSensitive()) { + @NotNull + @Override + public Collection getDefaultContexts() { + if (!directory.isValid()) { + return super.getDefaultContexts(); + } + return Collections.singletonList(directory); + } + }.getAllReferences(); + } + }); + } +} diff --git a/plugins/javaFX/testData/highlighting/NavigationFromMainToFxml.java b/plugins/javaFX/testData/highlighting/NavigationFromMainToFxml.java new file mode 100644 index 000000000000..707140ca7c04 --- /dev/null +++ b/plugins/javaFX/testData/highlighting/NavigationFromMainToFxml.java @@ -0,0 +1,21 @@ +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class Main extends Application { + + @Override + public void start(Stage primaryStage) throws Exception{ + Parent root = FXMLLoader.load(getClass().getResource("navigationFromMainToFxml.fxml")); + primaryStage.setTitle("Hello World"); + primaryStage.setScene(new Scene(root, 300, 275)); + primaryStage.show(); + } + + + public static void main(String[] args) { + launch(args); + } +} diff --git a/plugins/javaFX/testData/highlighting/navigationFromMainToFxml.fxml b/plugins/javaFX/testData/highlighting/navigationFromMainToFxml.fxml new file mode 100644 index 000000000000..41c1c69d1ff5 --- /dev/null +++ b/plugins/javaFX/testData/highlighting/navigationFromMainToFxml.fxml @@ -0,0 +1,2 @@ + + \ No newline at end of file