From 66ca2a05e6354752f882a96b2ae228e36345eea7 Mon Sep 17 00:00:00 2001 From: anna Date: Thu, 17 Jan 2013 20:42:55 +0100 Subject: [PATCH] javafx: reference to id-field --- .../fxml/FxmlReferencesContributor.java | 17 +++--- ...avaFxControllerBasedReferenceProvider.java | 53 +++++++++++++++++ .../JavaFxEventHandlerReferenceProvider.java | 53 ++++++----------- .../fxml/JavaFxFieldIdReferenceProvider.java | 58 +++++++++++++++++++ .../highlighting/ControllerIdRef.fxml | 9 +++ .../ControllerIdRefController.java | 4 ++ .../javaFX/fxml/JavaFXHighlightingTest.java | 18 ++++++ 7 files changed, 170 insertions(+), 42 deletions(-) create mode 100644 plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxControllerBasedReferenceProvider.java create mode 100644 plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxFieldIdReferenceProvider.java create mode 100644 plugins/javaFX/testData/highlighting/ControllerIdRef.fxml create mode 100644 plugins/javaFX/testData/highlighting/ControllerIdRefController.java diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlReferencesContributor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlReferencesContributor.java index dfb43d1ed665..b256306547d1 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlReferencesContributor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlReferencesContributor.java @@ -16,10 +16,8 @@ package org.jetbrains.plugins.javaFX.fxml; import com.intellij.patterns.PatternCondition; -import com.intellij.patterns.XmlAttributeValuePattern; import com.intellij.patterns.XmlPatterns; -import com.intellij.psi.PsiReferenceContributor; -import com.intellij.psi.PsiReferenceRegistrar; +import com.intellij.psi.*; import com.intellij.psi.impl.source.resolve.reference.impl.providers.JavaClassReferenceProvider; import com.intellij.psi.xml.XmlAttributeValue; import com.intellij.util.ProcessingContext; @@ -36,13 +34,16 @@ public class FxmlReferencesContributor extends PsiReferenceContributor { @Override public void registerReferenceProviders(PsiReferenceRegistrar registrar) { - registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue() - .withParent(XmlPatterns.xmlAttribute().withName(FxmlConstants.FX_CONTROLLER)), + registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute().withName(FxmlConstants.FX_CONTROLLER)) + .and(XmlPatterns.xmlAttributeValue().with(inFxmlCondition())), CLASS_REFERENCE_PROVIDER); - final XmlAttributeValuePattern attributeValuePattern = XmlPatterns.xmlAttributeValue().withValue(string().startsWith("#")) - .and(XmlPatterns.xmlAttributeValue().with(inFxmlCondition())); - registrar.registerReferenceProvider(attributeValuePattern, + registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute().withName(FxmlConstants.FX_ID)) + .and(XmlPatterns.xmlAttributeValue().with(inFxmlCondition())), + new JavaFxFieldIdReferenceProvider()); + + registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withValue(string().startsWith("#")) + .and(XmlPatterns.xmlAttributeValue().with(inFxmlCondition())), new JavaFxEventHandlerReferenceProvider()); } diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxControllerBasedReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxControllerBasedReferenceProvider.java new file mode 100644 index 000000000000..5b99863395e6 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxControllerBasedReferenceProvider.java @@ -0,0 +1,53 @@ +/* + * 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.psi.*; +import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.psi.xml.XmlFile; +import com.intellij.psi.xml.XmlTag; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; + +/** + * User: anna + * Date: 1/17/13 + */ +public abstract class JavaFxControllerBasedReferenceProvider extends PsiReferenceProvider { + @NotNull + @Override + public final PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) { + final XmlAttributeValue xmlAttrVal = (XmlAttributeValue)element; + final PsiFile containingFile = xmlAttrVal.getContainingFile(); + if (!JavaFxFileTypeFactory.isFxml(containingFile)) return PsiReference.EMPTY_ARRAY; + + final XmlTag rootTag = ((XmlFile)containingFile).getRootTag(); + if (rootTag != null) { + final XmlAttribute attribute = rootTag.getAttribute(FxmlConstants.FX_CONTROLLER); + if (attribute != null) { + final PsiClass controllerClass = + JavaPsiFacade.getInstance(xmlAttrVal.getProject()).findClass(attribute.getValue(), xmlAttrVal.getResolveScope()); + if (controllerClass != null) { + return getReferencesByElement(controllerClass, xmlAttrVal, context); + } + } + } + return PsiReference.EMPTY_ARRAY; + } + + protected abstract PsiReference[] getReferencesByElement(@NotNull PsiClass controllerClass, XmlAttributeValue element, ProcessingContext context); +} diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerReferenceProvider.java index 989789f84048..ddfcb9c8c411 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerReferenceProvider.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxEventHandlerReferenceProvider.java @@ -16,51 +16,36 @@ package org.jetbrains.plugins.javaFX.fxml; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.*; -import com.intellij.psi.xml.XmlAttribute; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiReference; import com.intellij.psi.xml.XmlAttributeValue; -import com.intellij.psi.xml.XmlFile; -import com.intellij.psi.xml.XmlTag; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; /** -* User: anna -* Date: 1/16/13 -*/ -class JavaFxEventHandlerReferenceProvider extends PsiReferenceProvider { + * User: anna + * Date: 1/16/13 + */ +class JavaFxEventHandlerReferenceProvider extends JavaFxControllerBasedReferenceProvider { private static final Logger LOG = Logger.getInstance("#" + JavaFxEventHandlerReferenceProvider.class.getName()); - @NotNull @Override - public PsiReference[] getReferencesByElement(@NotNull PsiElement element, - @NotNull ProcessingContext context) { - final XmlAttributeValue xmlAttrVal = (XmlAttributeValue)element; - final PsiFile containingFile = xmlAttrVal.getContainingFile(); - if (!JavaFxFileTypeFactory.isFxml(containingFile)) return PsiReference.EMPTY_ARRAY; + protected PsiReference[] getReferencesByElement(@NotNull PsiClass controllerClass, + XmlAttributeValue xmlAttributeValue, + ProcessingContext context) { + final String attValueString = xmlAttributeValue.getValue(); + LOG.assertTrue(attValueString.startsWith("#")); + final String eventHandlerName = attValueString.substring(1); + final PsiMethod[] methods = controllerClass.findMethodsByName(eventHandlerName, true); PsiMethod handlerMethod = null; - PsiClass controllerClass = null; - final XmlTag rootTag = ((XmlFile)containingFile).getRootTag(); - if (rootTag != null) { - final XmlAttribute attribute = rootTag.getAttribute(FxmlConstants.FX_CONTROLLER); - if (attribute != null) { - final String controllerClassName = attribute.getValue(); - controllerClass = JavaPsiFacade.getInstance(xmlAttrVal.getProject()).findClass(controllerClassName, xmlAttrVal.getResolveScope()); - if (controllerClass != null) { - final String attValueString = xmlAttrVal.getValue(); - LOG.assertTrue(attValueString.startsWith("#")); - final String eventHandlerName = attValueString.substring(1); - final PsiMethod[] methods = controllerClass.findMethodsByName(eventHandlerName, true); - for (PsiMethod psiMethod : methods) { - if (JavaFxEventHandlerReference.isHandlerMethod(psiMethod)) { - handlerMethod = psiMethod; - break; - } - } - } + for (PsiMethod psiMethod : methods) { + if (JavaFxEventHandlerReference.isHandlerMethod(psiMethod)) { + handlerMethod = psiMethod; + break; } } - return new PsiReference[]{new JavaFxEventHandlerReference(xmlAttrVal, handlerMethod, controllerClass)}; + return new PsiReference[]{new JavaFxEventHandlerReference(xmlAttributeValue, handlerMethod, controllerClass)}; } } diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxFieldIdReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxFieldIdReferenceProvider.java new file mode 100644 index 000000000000..824836376181 --- /dev/null +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxFieldIdReferenceProvider.java @@ -0,0 +1,58 @@ +/* + * 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.psi.*; +import com.intellij.psi.xml.XmlAttributeValue; +import com.intellij.util.ArrayUtil; +import com.intellij.util.ProcessingContext; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** +* User: anna +* Date: 1/17/13 +*/ +class JavaFxFieldIdReferenceProvider extends JavaFxControllerBasedReferenceProvider { + @Override + protected PsiReference[] getReferencesByElement(@NotNull PsiClass aClass, + XmlAttributeValue xmlAttributeValue, + ProcessingContext context) { + final PsiField field = aClass.findFieldByName(xmlAttributeValue.getValue(), false); + return field == null ? PsiReference.EMPTY_ARRAY : new PsiReference[]{new JavaFxIdReference(xmlAttributeValue, field)}; + } + + private static class JavaFxIdReference extends PsiReferenceBase { + private final PsiField myField; + + public JavaFxIdReference(XmlAttributeValue xmlAttributeValue, PsiField field) { + super(xmlAttributeValue); + myField = field; + } + + @Nullable + @Override + public PsiElement resolve() { + return myField; + } + + @NotNull + @Override + public Object[] getVariants() { + return ArrayUtil.EMPTY_OBJECT_ARRAY; + } + } +} diff --git a/plugins/javaFX/testData/highlighting/ControllerIdRef.fxml b/plugins/javaFX/testData/highlighting/ControllerIdRef.fxml new file mode 100644 index 000000000000..90b7dcc85280 --- /dev/null +++ b/plugins/javaFX/testData/highlighting/ControllerIdRef.fxml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/plugins/javaFX/testData/highlighting/ControllerIdRefController.java b/plugins/javaFX/testData/highlighting/ControllerIdRefController.java new file mode 100644 index 000000000000..050f592009d8 --- /dev/null +++ b/plugins/javaFX/testData/highlighting/ControllerIdRefController.java @@ -0,0 +1,4 @@ +import javafx.scene.text.Text; +public class ControllerIdRefController { + public Text accessText; +} \ 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 d41734ee64ba..6c8d07034419 100644 --- a/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java +++ b/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java @@ -2,6 +2,8 @@ package org.jetbrains.plugins.javaFX.fxml; import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase; import com.intellij.openapi.application.PluginPathManager; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiReference; import com.intellij.testFramework.PsiTestUtil; import org.jetbrains.annotations.NotNull; @@ -44,6 +46,22 @@ public class JavaFXHighlightingTest extends DaemonAnalyzerTestCase { doTest(false, false, getTestName(true) + ".fxml"); } + public void testControllerIdRef() throws Exception { + doTestIdController(); + } + + private void doTestIdController() throws Exception { + final String controllerClassName = getTestName(false) + "Controller"; + configureByFiles(null, getTestName(true) + ".fxml", controllerClassName + ".java"); + final PsiClass controllerClass = findClass(controllerClassName); + assertNotNull(controllerClass); + assertTrue(controllerClass.getFields().length > 0); + final int offset = myEditor.getCaretModel().getOffset(); + final PsiReference reference = myFile.findReferenceAt(offset); + assertNotNull(reference); + assertEquals(controllerClass.getFields()[0], reference.resolve()); + } + @NotNull @Override protected String getTestDataPath() {