javafx: fx:root (IDEA-100132)

This commit is contained in:
Anna Kozlova
2013-02-01 20:56:44 +04:00
parent ba11acfa05
commit deaf2c404d
9 changed files with 54 additions and 22 deletions
@@ -39,6 +39,8 @@ public class FxmlConstants {
@NonNls public static final String FX_DEFINE = "fx:define";
@NonNls public static final String FX_SCRIPT = "fx:script";
@NonNls public static final String FX_INCLUDE = "fx:include";
@NonNls public static final String FX_ROOT = "fx:root";
@NonNls public static final String TYPE = "type";
public static final List<String> FX_DEFAULT_PROPERTIES = Arrays.asList(FX_ID, FX_CONTROLLER, VALUE, FX_VALUE, FX_FACTORY, FX_CONSTANT);
public static final List<String> FX_DEFAULT_ELEMENTS = Arrays.asList(FX_INCLUDE, FX_REFERENCE, FX_COPY, FX_DEFINE, FX_SCRIPT);
@@ -49,12 +51,15 @@ public class FxmlConstants {
static {
FX_ELEMENT_ATTRIBUTES.put(FX_INCLUDE, Arrays.asList(FX_ELEMENT_SOURCE, FX_ID));
FX_ELEMENT_ATTRIBUTES.put(FX_REFERENCE, Arrays.asList(FX_ELEMENT_SOURCE));
FX_ELEMENT_ATTRIBUTES.put(FX_ROOT, Arrays.asList(TYPE));
}
public static final Map<String, List<String>> FX_REQUIRED_ELEMENT_ATTRIBUTES = new HashMap<String, List<String>>();
static {
FX_REQUIRED_ELEMENT_ATTRIBUTES.put(FX_INCLUDE, Arrays.asList(FX_ELEMENT_SOURCE));
FX_REQUIRED_ELEMENT_ATTRIBUTES.put(FX_REFERENCE, Arrays.asList(FX_ELEMENT_SOURCE));
FX_REQUIRED_ELEMENT_ATTRIBUTES.put(FX_ROOT, Arrays.asList(TYPE));
}
}
@@ -9,6 +9,7 @@ import com.intellij.xml.XmlNSDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxClassBackedElementDescriptor;
import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxDefaultPropertyElementDescriptor;
/**
* User: anna
@@ -22,7 +23,9 @@ public class JavaFXNSDescriptor implements XmlNSDescriptor, Validator<XmlDocumen
public XmlElementDescriptor getElementDescriptor(@NotNull XmlTag tag) {
final String name = tag.getName();
if (JavaFxPsiUtil.isClassTag(name)) {
if (tag.getName().equals(FxmlConstants.FX_ROOT)) {
return new JavaFxDefaultPropertyElementDescriptor(name, tag);
} else if (JavaFxPsiUtil.isClassTag(name)) {
return new JavaFxClassBackedElementDescriptor(name, tag);
}
else {
@@ -66,7 +66,7 @@ public class JavaFxDefaultPropertyElementDescriptor implements XmlElementDescrip
@Nullable
@Override
public XmlElementDescriptor getElementDescriptor(XmlTag childTag, XmlTag contextTag) {
if (myName.equals(FxmlConstants.FX_DEFINE)) {
if (myName.equals(FxmlConstants.FX_DEFINE) || myName.equals(FxmlConstants.FX_ROOT)) {
final String name = childTag.getName();
if (JavaFxPsiUtil.isClassTag(name)) {
return new JavaFxClassBackedElementDescriptor(name, childTag);
@@ -41,6 +41,12 @@ public class FxmlReferencesContributor extends PsiReferenceContributor {
.and(attributeValueInFxml),
CLASS_REFERENCE_PROVIDER);
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue()
.withParent(XmlPatterns.xmlAttribute().withName("type")
.withParent(XmlPatterns.xmlTag().withName(FxmlConstants.FX_ROOT)))
.and(attributeValueInFxml),
CLASS_REFERENCE_PROVIDER);
registrar.registerReferenceProvider(XmlPatterns.xmlAttributeValue().withParent(XmlPatterns.xmlAttribute().withName(FxmlConstants.FX_ID))
.and(attributeValueInFxml),
new JavaFxFieldIdReferenceProvider());
@@ -15,16 +15,12 @@
*/
package org.jetbrains.plugins.javaFX.fxml.refs;
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.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
/**
* User: anna
@@ -38,21 +34,8 @@ public abstract class JavaFxControllerBasedReferenceProvider extends PsiReferenc
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 String attributeValue = attribute.getValue();
if (!StringUtil.isEmptyOrSpaces(attributeValue)) {
final PsiClass controllerClass =
JavaPsiFacade.getInstance(xmlAttrVal.getProject()).findClass(attributeValue, xmlAttrVal.getResolveScope());
if (controllerClass != null) {
return getReferencesByElement(controllerClass, xmlAttrVal, context);
}
}
}
}
return PsiReference.EMPTY_ARRAY;
final PsiClass controllerClass = JavaFxPsiUtil.getControllerClass(containingFile);
return controllerClass != null ? getReferencesByElement(controllerClass, xmlAttrVal, context) : PsiReference.EMPTY_ARRAY;
}
protected abstract PsiReference[] getReferencesByElement(@NotNull PsiClass controllerClass, XmlAttributeValue element, ProcessingContext context);
@@ -0,0 +1,7 @@
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Label?>
<fx:root type="javafx.scene.layout.VBox" xmlns:fx="http://javafx.com/fxml">
<TextField fx:id="textField" text=""/>
<Label text="Hello"/>
</fx:root>
@@ -0,0 +1,7 @@
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Label?>
<<error descr="Element fx:root doesn't have required attribute type">fx:root</error> xmlns:fx="http://javafx.com/fxml">
<TextField fx:id="textField" text=""/>
<Label text="Hello"/>
</<error descr="Element fx:root doesn't have required attribute type">fx:root</error>>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Label?>
<fx:root type="<error descr="Cannot resolve class or package 'unknownPackage'">unknownPackage</error>.<error descr="Cannot resolve class 'unknownClass'">unknownClass</error>" xmlns:fx="http://javafx.com/fxml">
<TextField fx:id="textField" text=""/>
<Label text="Hello"/>
</fx:root>
@@ -159,6 +159,18 @@ public class JavaFXHighlightingTest extends DaemonAnalyzerTestCase {
doTest();
}
public void testRootTag() throws Exception {
doTest();
}
public void testUnresolvedRootTag() throws Exception {
doTest();
}
public void testRootTagWithoutType() throws Exception {
doTest();
}
@NotNull
@Override
protected String getTestDataPath() {