diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
index da77e2827430..52203a2ab17f 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java
@@ -21,10 +21,12 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
+import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.xml.*;
+import com.intellij.xml.XmlElementDescriptor;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -184,4 +186,38 @@ public class JavaFxPsiUtil {
}
return null;
}
+
+ public static PsiClass getControllerClass(PsiFile containingFile) {
+ if (containingFile instanceof XmlFile) {
+ final XmlTag rootTag = ((XmlFile)containingFile).getRootTag();
+ if (rootTag != null) {
+ final XmlAttribute attribute = rootTag.getAttribute(FxmlConstants.FX_CONTROLLER);
+ if (attribute != null) {
+ final String attributeValue = attribute.getValue();
+ if (!StringUtil.isEmptyOrSpaces(attributeValue)) {
+ return JavaPsiFacade.getInstance(containingFile.getProject()).findClass(attributeValue, containingFile.getResolveScope());
+ }
+ }
+ }
+ }
+ return null;
+ }
+
+ public static boolean checkIfAttributeHandler(XmlAttribute attribute) {
+ final String attributeName = attribute.getName();
+ final XmlTag xmlTag = attribute.getParent();
+ final XmlElementDescriptor descriptor = xmlTag.getDescriptor();
+ if (descriptor == null) return false;
+ final PsiElement currentTagClass = descriptor.getDeclaration();
+ if (!(currentTagClass instanceof PsiClass)) return false;
+ final PsiField handlerField = ((PsiClass)currentTagClass).findFieldByName(attributeName, true);
+ if (handlerField == null) {
+ return false;
+ }
+ final PsiClass objectPropertyClass = getPropertyClass(handlerField);
+ if (objectPropertyClass == null || !InheritanceUtil.isInheritor(objectPropertyClass, JavaFxCommonClassNames.JAVAFX_EVENT_EVENT_HANDLER)) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
index 6b49c7d3abf2..d18941d4777a 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyAttributeDescriptor.java
@@ -2,7 +2,10 @@ package org.jetbrains.plugins.javaFX.fxml.descriptors;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
+import com.intellij.psi.xml.XmlAttribute;
+import com.intellij.psi.xml.XmlAttributeValue;
import com.intellij.psi.xml.XmlElement;
+import com.intellij.psi.xml.XmlFile;
import com.intellij.util.ArrayUtil;
import com.intellij.xml.XmlAttributeDescriptor;
import org.jetbrains.annotations.Nullable;
@@ -92,10 +95,27 @@ public class JavaFxPropertyAttributeDescriptor implements XmlAttributeDescriptor
}
return null;
}
-
+
@Nullable
@Override
public String validateValue(XmlElement context, String value) {
+ if (context instanceof XmlAttributeValue) {
+ final XmlAttributeValue xmlAttributeValue = (XmlAttributeValue)context;
+ final PsiElement parent = xmlAttributeValue.getParent();
+ if (parent instanceof XmlAttribute && JavaFxPsiUtil.checkIfAttributeHandler((XmlAttribute)parent)) {
+ final PsiClass controllerClass = JavaFxPsiUtil.getControllerClass(context.getContainingFile());
+ if (value.startsWith("#")) {
+ if (controllerClass == null) {
+ return "No controller specified for top level element";
+ }
+ }
+ else {
+ if (JavaFxPsiUtil.parseInjectedLanguages((XmlFile)context.getContainingFile()).isEmpty()) {
+ return "Page language not specified.";
+ }
+ }
+ }
+ }
return null;
}
@@ -115,7 +135,8 @@ public class JavaFxPropertyAttributeDescriptor implements XmlAttributeDescriptor
}
@Override
- public void init(PsiElement element) {}
+ public void init(PsiElement element) {
+ }
@Override
public Object[] getDependences() {
diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReferenceProvider.java
index d1b030b514c4..8a7711ebb0b6 100644
--- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReferenceProvider.java
+++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxEventHandlerReferenceProvider.java
@@ -17,14 +17,10 @@ package org.jetbrains.plugins.javaFX.fxml.refs;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.xml.XmlAttribute;
import com.intellij.psi.xml.XmlAttributeValue;
-import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ProcessingContext;
-import com.intellij.xml.XmlElementDescriptor;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
/**
@@ -43,20 +39,8 @@ class JavaFxEventHandlerReferenceProvider extends JavaFxControllerBasedReference
final XmlAttribute attribute = (XmlAttribute)xmlAttributeValue.getContext();
if (attribute == null) return PsiReference.EMPTY_ARRAY;
- final String attributeName = attribute.getName();
- final XmlTag xmlTag = attribute.getParent();
- final XmlElementDescriptor descriptor = xmlTag.getDescriptor();
- if (descriptor == null) return PsiReference.EMPTY_ARRAY;
- final PsiElement currentTagClass = descriptor.getDeclaration();
- if (!(currentTagClass instanceof PsiClass)) return PsiReference.EMPTY_ARRAY;
- final PsiField handlerField = ((PsiClass)currentTagClass).findFieldByName(attributeName, true);
- if (handlerField == null) {
- return PsiReference.EMPTY_ARRAY;
- }
- final PsiClass objectPropertyClass = JavaFxPsiUtil.getPropertyClass(handlerField);
- if (objectPropertyClass == null || !InheritanceUtil.isInheritor(objectPropertyClass, JavaFxCommonClassNames.JAVAFX_EVENT_EVENT_HANDLER)) {
- return PsiReference.EMPTY_ARRAY;
- }
+ if (!JavaFxPsiUtil.checkIfAttributeHandler(attribute)) return PsiReference.EMPTY_ARRAY;
+ final PsiElement currentTagClass = attribute.getParent().getDescriptor().getDeclaration();
final String eventHandlerName = attValueString.substring(1);
final PsiMethod[] methods = controllerClass.findMethodsByName(eventHandlerName, true);
diff --git a/plugins/javaFX/testData/highlighting/handlerWithoutController.fxml b/plugins/javaFX/testData/highlighting/handlerWithoutController.fxml
new file mode 100644
index 000000000000..2662596e3f7d
--- /dev/null
+++ b/plugins/javaFX/testData/highlighting/handlerWithoutController.fxml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/plugins/javaFX/testData/highlighting/handlerWithoutPageLanguage.fxml b/plugins/javaFX/testData/highlighting/handlerWithoutPageLanguage.fxml
new file mode 100644
index 000000000000..987607f5b261
--- /dev/null
+++ b/plugins/javaFX/testData/highlighting/handlerWithoutPageLanguage.fxml
@@ -0,0 +1,6 @@
+
+
+
+
+
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 b5244ca7d2ee..4a30d877f449 100644
--- a/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
+++ b/plugins/javaFX/testSrc/org/jetbrains/plugins/javaFX/fxml/JavaFXHighlightingTest.java
@@ -134,6 +134,14 @@ public class JavaFXHighlightingTest extends DaemonAnalyzerTestCase {
doTest();
}
+ public void testHandlerWithoutController() throws Exception {
+ doTest();
+ }
+
+ public void testHandlerWithoutPageLanguage() throws Exception {
+ doTest();
+ }
+
public void testIncludeBtn() throws Exception {
configureByFiles(null, getTestName(true) + ".fxml", "btn.fxml");
doDoTest(false, false);