diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java index c6941a2d43dc..558c1564ef8b 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/codeInsight/JavaFxGetterSetterPrototypeProvider.java @@ -24,6 +24,7 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager; import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PropertyUtil; +import org.jetbrains.plugins.javaFX.fxml.FxmlConstants; import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames; import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil; @@ -53,10 +54,13 @@ public class JavaFxGetterSetterPrototypeProvider extends GetterSetterPrototypePr final PsiCodeBlock getterBody = getter.getBody(); LOG.assertTrue(getterBody != null); - getterBody.getStatements()[0].replace(factory.createStatementFromText("return " + field.getName() + ".get();", field)); + final String fieldName = field.getName(); + getterBody.getStatements()[0].replace(factory.createStatementFromText("return " + fieldName + ".get();", field)); final PsiMethod propertyGetter = PropertyUtil.generateGetterPrototype(field); - propertyGetter.setName(JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD) + "Property"); + if (propertyGetter != null && fieldName != null) { + propertyGetter.setName(JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(fieldName, VariableKind.FIELD) + FxmlConstants.PROPERTY_FIELD_SUFFIX); + } return new PsiMethod[] {getter, GenerateMembersUtil.annotateOnOverrideImplement(field.getContainingClass(), propertyGetter)}; } @@ -96,7 +100,7 @@ public class JavaFxGetterSetterPrototypeProvider extends GetterSetterPrototypePr @Override public String suggestGetterName(String propertyName) { - return propertyName + "Property"; + return propertyName + FxmlConstants.PROPERTY_FIELD_SUFFIX; } @Override diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlConstants.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlConstants.java index 4cec28f0c0ea..5beac49d1317 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlConstants.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/FxmlConstants.java @@ -40,6 +40,7 @@ public class FxmlConstants { @NonNls public static final String TYPE = "type"; @NonNls public static final String RESOURCES = "resources"; @NonNls public static final String CHARSET = "charset"; + @NonNls public static final String CONTROLLER = "controller"; @NonNls public static final String STYLE_CLASS = "styleClass"; @NonNls public static final String STYLESHEETS = "stylesheets"; @@ -50,6 +51,9 @@ public class FxmlConstants { public static final String FX_ELEMENT_SOURCE = "source"; public static final Map> FX_ELEMENT_ATTRIBUTES = new HashMap>(); + + public static final String PROPERTY_FIELD_SUFFIX = "Property"; + static { FX_ELEMENT_ATTRIBUTES.put(FX_INCLUDE, Arrays.asList(FX_ELEMENT_SOURCE, FX_ID, RESOURCES, CHARSET)); FX_ELEMENT_ATTRIBUTES.put(FX_REFERENCE, Collections.singletonList(FX_ELEMENT_SOURCE)); 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 ae4390aac450..2385c63f785a 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java @@ -33,6 +33,7 @@ import com.intellij.psi.search.searches.ReferencesSearch; import com.intellij.psi.util.*; import com.intellij.psi.xml.*; import com.intellij.util.Processor; +import com.intellij.xml.XmlAttributeDescriptor; import com.intellij.xml.XmlElementDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -373,7 +374,7 @@ public class JavaFxPsiUtil { } @Nullable - public static PsiType getPropertyType(final PsiType type, final Project project) { + public static PsiType getWritablePropertyType(final PsiType type, final Project project) { final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(type); final PsiClass psiClass = resolveResult.getElement(); if (psiClass != null) { @@ -505,7 +506,7 @@ public class JavaFxPsiUtil { private static String canCoerce(PsiClass aClass, PsiType type) { PsiType collectionItemType = JavaGenericsUtil.getCollectionItemType(type, aClass.getResolveScope()); if (collectionItemType == null && InheritanceUtil.isInheritor(type, JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY)) { - collectionItemType = getPropertyType(type, aClass.getProject()); + collectionItemType = getWritablePropertyType(type, aClass.getProject()); } if (collectionItemType != null && PsiPrimitiveType.getUnboxedType(collectionItemType) == null) { final PsiClass baseClass = PsiUtil.resolveClassInType(collectionItemType); @@ -570,6 +571,99 @@ public class JavaFxPsiUtil { }); } + @Nullable + public static PsiType getWritablePropertyType(PsiElement declaration) { + if (declaration instanceof PsiField) { + return getWrappedPropertyType((PsiField)declaration, declaration.getProject(), JavaFxCommonClassNames.ourWritableMap); + } + if (declaration instanceof PsiMethod) { + final PsiParameter[] parameters = ((PsiMethod)declaration).getParameterList().getParameters(); + final boolean isStatic = ((PsiMethod)declaration).hasModifierProperty(PsiModifier.STATIC); + if (isStatic && parameters.length == 2 || !isStatic && parameters.length == 1) { + return parameters[parameters.length - 1].getType(); + } + } + return null; + } + + + @Nullable + public static PsiType getReadablePropertyType(PsiElement declaration) { + if (declaration instanceof PsiField) { + return getWrappedPropertyType((PsiField)declaration, declaration.getProject(), JavaFxCommonClassNames.ourReadOnlyMap); + } + if (declaration instanceof PsiMethod) { + PsiMethod psiMethod = (PsiMethod)declaration; + final PsiParameter[] parameters = psiMethod.getParameterList().getParameters(); + final boolean isStatic = psiMethod.hasModifierProperty(PsiModifier.STATIC); + if (!isStatic && parameters.length == 0) { + return psiMethod.getReturnType(); + } + } + return null; + } + + @NotNull + public static Map collectFileIds(final XmlTag currentTag) { + final Map fileIds = new HashMap(); + currentTag.getContainingFile().accept(new XmlRecursiveElementVisitor() { + @Override + public void visitXmlTag(XmlTag tag) { + super.visitXmlTag(tag); + if (currentTag != tag) { + final XmlAttribute attribute = tag.getAttribute(FxmlConstants.FX_ID); + if (attribute != null) { + fileIds.put(attribute.getValue(), attribute.getValueElement()); + } + } + } + }); + final PsiFile containingFile = currentTag.getContainingFile(); + if (containingFile instanceof XmlFile) { + final XmlTag rootTag = ((XmlFile)containingFile).getRootTag(); + if (rootTag != null) { + final XmlAttribute attribute = rootTag.getAttribute(FxmlConstants.FX_CONTROLLER); + if (attribute != null) { + fileIds.put(FxmlConstants.CONTROLLER, attribute.getValueElement()); + } + } + } + return fileIds; + } + + @Nullable + public static PsiClass getTagClassById(String id, PsiElement context, XmlAttributeValue xmlAttributeValue) { + return FxmlConstants.CONTROLLER.equals(id) ? getControllerClass(context.getContainingFile()) : getTagClass(xmlAttributeValue); + } + + @Nullable + public static PsiClass getPropertyClass(XmlAttributeValue xmlAttributeValue) { + final PsiElement declaration = getPropertyDeclaration(xmlAttributeValue); + return getPropertyClass(getWritablePropertyType(declaration), xmlAttributeValue); + } + + @Nullable + public static PsiClass getPropertyClass(PsiType propertyType, XmlAttributeValue context) { + if (propertyType instanceof PsiPrimitiveType) { + PsiClassType boxedType = ((PsiPrimitiveType)propertyType).getBoxedType(context); + return boxedType != null ? boxedType.resolve() : null; + } + return PsiUtil.resolveClassInType(propertyType); + } + + @Nullable + private static PsiElement getPropertyDeclaration(XmlAttributeValue xmlAttributeValue) { + PsiClass tagClass = getTagClass(xmlAttributeValue); + if (tagClass != null) { + XmlAttribute xmlAttribute = (XmlAttribute)xmlAttributeValue.getParent(); + final XmlAttributeDescriptor attributeDescriptor = xmlAttribute.getDescriptor(); + if (attributeDescriptor != null) { + return attributeDescriptor.getDeclaration(); + } + } + return null; + } + private static class JavaFxControllerCachedValueProvider implements CachedValueProvider { private final Project myProject; private final PsiFile myContainingFile; 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 ab8511e08b2f..3089eaf32271 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 @@ -1,9 +1,13 @@ package org.jetbrains.plugins.javaFX.fxml.descriptors; +import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.codeStyle.JavaCodeStyleManager; +import com.intellij.psi.codeStyle.VariableKind; import com.intellij.psi.util.InheritanceUtil; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.TypeConversionUtil; import com.intellij.psi.xml.*; import com.intellij.util.ArrayUtil; import com.intellij.xml.XmlAttributeDescriptor; @@ -19,6 +23,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import java.util.Map; /** * User: anna @@ -148,6 +153,45 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript } } } + else if (value.startsWith("$")) { + final String referencesId = value.substring(1); + final XmlTag currentTag = PsiTreeUtil.getParentOfType(xmlAttributeValue, XmlTag.class); + final Map fileIds = JavaFxPsiUtil.collectFileIds(currentTag); + final PsiClass targetPropertyClass = JavaFxPsiUtil.getPropertyClass(xmlAttributeValue); + if (targetPropertyClass == null || + Comparing.strEqual(targetPropertyClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING) || + JavaFxPsiUtil.findValueOfMethod(targetPropertyClass) != null) { + return null; + } + final PsiClass valueClass; + if (JavaFxPsiUtil.isExpressionBinding(value)) { + final String expressionText = referencesId.substring(1, referencesId.length() - 1); + final String newId = StringUtil.getPackageName(expressionText); + final PsiClass tagClass = JavaFxPsiUtil.getTagClassById(newId, xmlAttributeValue, fileIds.get(newId)); + if (tagClass == null) return null; + + final String fieldRef = StringUtil.getShortName(expressionText); + final String fieldName = JavaCodeStyleManager.getInstance(tagClass.getProject()).propertyNameToVariableName(fieldRef, VariableKind.FIELD); + PsiField psiField = tagClass.findFieldByName(fieldName, true); + + final PsiMember propertyDeclaration; + if (psiField != null && psiField.hasModifierProperty(PsiModifier.PUBLIC)) { + propertyDeclaration = psiField; + } + else { + propertyDeclaration = JavaFxPsiUtil.findPropertyGetter(fieldRef, tagClass); + } + if (propertyDeclaration == null) return null; + valueClass = JavaFxPsiUtil.getPropertyClass(JavaFxPsiUtil.getReadablePropertyType(propertyDeclaration), xmlAttributeValue); + } + else { + valueClass = JavaFxPsiUtil.getTagClassById(referencesId, xmlAttributeValue, fileIds.get(referencesId)); + } + if (valueClass == null || InheritanceUtil.isInheritorOrSelf(valueClass, targetPropertyClass, true)) { + return null; + } + return "Invalid value: unable to coerce to " + targetPropertyClass.getQualifiedName(); + } else { final XmlAttributeDescriptor attributeDescriptor = ((XmlAttribute)parent).getDescriptor(); if (attributeDescriptor != null) { @@ -199,16 +243,7 @@ public class JavaFxPropertyAttributeDescriptor extends BasicXmlAttributeDescript @Nullable private static String getBoxedPropertyType(PsiElement declaration) { - PsiType attrType = null; - if (declaration instanceof PsiField) { - attrType = JavaFxPsiUtil.getWrappedPropertyType((PsiField)declaration, declaration.getProject(), JavaFxCommonClassNames.ourWritableMap); - } else if (declaration instanceof PsiMethod) { - final PsiParameter[] parameters = ((PsiMethod)declaration).getParameterList().getParameters(); - final boolean isStatic = ((PsiMethod)declaration).hasModifierProperty(PsiModifier.STATIC); - if (isStatic && parameters.length == 2 || !isStatic && parameters.length == 1) { - attrType = parameters[parameters.length - 1].getType(); - } - } + PsiType attrType = JavaFxPsiUtil.getWritablePropertyType(declaration); String boxedQName = null; if (attrType instanceof PsiPrimitiveType) { diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyElementDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyElementDescriptor.java index 617895ff2576..d20c3394508d 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyElementDescriptor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxPropertyElementDescriptor.java @@ -88,7 +88,7 @@ public class JavaFxPropertyElementDescriptor implements XmlElementDescriptor { descriptors.add(new JavaFxClassBackedElementDescriptor(aClass.getName(), aClass)); } } else if (InheritanceUtil.isInheritor(psiType, JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY)) { - final PsiType propertyType = JavaFxPsiUtil.getPropertyType(psiType, project); + final PsiType propertyType = JavaFxPsiUtil.getWritablePropertyType(psiType, project); final PsiClass aClass = PsiUtil.resolveClassInType(propertyType); if (aClass != null) { descriptors.add(new JavaFxClassBackedElementDescriptor(aClass.getName(), aClass)); diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxComponentIdReferenceProvider.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxComponentIdReferenceProvider.java index 20b7fad50d55..e38a6210acb2 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxComponentIdReferenceProvider.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/refs/JavaFxComponentIdReferenceProvider.java @@ -15,9 +15,12 @@ */ package org.jetbrains.plugins.javaFX.fxml.refs; +import com.intellij.codeInsight.lookup.LookupItem; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; +import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.TypeConversionUtil; import com.intellij.psi.xml.XmlAttribute; @@ -32,6 +35,7 @@ import org.jetbrains.plugins.javaFX.fxml.FxmlConstants; import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil; import java.util.*; +import java.util.stream.Collectors; /** * User: anna @@ -46,42 +50,21 @@ class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider { final String value = xmlAttributeValue.getValue(); final boolean startsWithDollar = value.startsWith("$"); final String referencesId = startsWithDollar ? value.substring(1) : value; - final Map fileIds = new HashMap(); - xmlAttributeValue.getContainingFile().accept(new XmlRecursiveElementVisitor() { - @Override - public void visitXmlTag(XmlTag tag) { - super.visitXmlTag(tag); - if (currentTag != tag) { - final XmlAttribute attribute = tag.getAttribute(FxmlConstants.FX_ID); - if (attribute != null) { - fileIds.put(attribute.getValue(), attribute.getValueElement()); - } - } - } - }); + final Map fileIds = JavaFxPsiUtil.collectFileIds(currentTag); if (JavaFxPsiUtil.isExpressionBinding(value)) { final String expressionText = referencesId.substring(1, referencesId.length() - 1); final String newId = StringUtil.getPackageName(expressionText); final String fieldRef = StringUtil.getShortName(expressionText); - final PsiReferenceBase idReferenceBase; - final PsiClass controllerClass = JavaFxPsiUtil.getControllerClass(element.getContainingFile()); - final PsiField controllerField = controllerClass != null ? controllerClass.findFieldByName(newId, false) : null; - if (controllerField == null) { - idReferenceBase = new JavaFxIdReferenceBase(xmlAttributeValue, fileIds, newId); - } else { - idReferenceBase = new JavaFxFieldIdReferenceProvider.JavaFxControllerFieldRef(xmlAttributeValue, controllerField, controllerClass); - } - + final PsiReferenceBase idReferenceBase = getIdReferenceBase(xmlAttributeValue, newId, fileIds, Collections.emptyMap(), controllerClass); final TextRange range = idReferenceBase.getRangeInElement(); final int startOffset = range.getStartOffset() + 2; final int endOffset = startOffset + newId.length(); idReferenceBase.setRangeInElement(new TextRange(startOffset, endOffset)); if (fileIds.containsKey(newId)) { - final XmlAttributeValue attributeValue = fileIds.get(newId); - final PsiClass tagClass = JavaFxPsiUtil.getTagClass(attributeValue); + final PsiClass tagClass = FxmlConstants.CONTROLLER.equals(newId) ? controllerClass : JavaFxPsiUtil.getTagClass(fileIds.get(newId)); if (tagClass != null) { final JavaFxExpressionReferenceBase referenceBase = new JavaFxExpressionReferenceBase(xmlAttributeValue, tagClass, fieldRef); final TextRange textRange = referenceBase.getRangeInElement(); @@ -92,7 +75,20 @@ class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider { return new PsiReference[] {idReferenceBase}; } if (startsWithDollar) { - final JavaFxIdReferenceBase idReferenceBase = new JavaFxIdReferenceBase(xmlAttributeValue, fileIds, referencesId); + final PsiClass controllerClass = JavaFxPsiUtil.getControllerClass(element.getContainingFile()); + + final PsiClass targetPropertyClass = JavaFxPsiUtil.getPropertyClass(xmlAttributeValue); + final boolean isConvertible = targetPropertyClass != null && + (Comparing.strEqual(targetPropertyClass.getQualifiedName(), CommonClassNames.JAVA_LANG_STRING) + || JavaFxPsiUtil.findValueOfMethod(targetPropertyClass) != null); + + final Map typeMatches = fileIds.entrySet().stream().collect( + Collectors.toMap(Map.Entry::getKey, e -> { + final PsiClass valueClass = JavaFxPsiUtil.getTagClassById(e.getKey(), xmlAttributeValue, e.getValue()); + return TypeMatch.getMatch(valueClass, targetPropertyClass, isConvertible); + })); + + final PsiReferenceBase idReferenceBase = getIdReferenceBase(xmlAttributeValue, referencesId, fileIds, typeMatches, controllerClass); final TextRange rangeInElement = idReferenceBase.getRangeInElement(); idReferenceBase.setRangeInElement(new TextRange(rangeInElement.getStartOffset() + 1, rangeInElement.getEndOffset())); return new PsiReference[]{idReferenceBase}; @@ -112,9 +108,50 @@ class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider { } } + @NotNull + private static PsiReferenceBase getIdReferenceBase(XmlAttributeValue xmlAttributeValue, + String referencesId, + Map fileIds, + Map typeMatches, + PsiClass controllerClass) { + if (controllerClass != null && !FxmlConstants.CONTROLLER.equals(referencesId)) { + final PsiField controllerField = controllerClass.findFieldByName(referencesId, false); + if (controllerField != null) { + return new JavaFxFieldIdReferenceProvider.JavaFxControllerFieldRef(xmlAttributeValue, controllerField, controllerClass); + } + } + return new JavaFxIdReferenceBase(xmlAttributeValue, fileIds, typeMatches, referencesId); + } + + private enum TypeMatch { + ASSIGNABLE(3.0), + CONVERTIBLE(2.0), + UNDEFINED(1.0), + INCOMPATIBLE(0.0); + + private final double myPriority; + + TypeMatch(double priority) { + myPriority = priority; + } + + public static double getPriority(TypeMatch match) { + return match != null ? match.myPriority : 0.0; + } + + @NotNull + public static TypeMatch getMatch(PsiClass valueClass, PsiClass targetPropertyClass, boolean isConvertible) { + if (valueClass == null || targetPropertyClass == null) return UNDEFINED; + if (InheritanceUtil.isInheritorOrSelf(valueClass, targetPropertyClass, true)) return ASSIGNABLE; + if (isConvertible) return CONVERTIBLE; + return INCOMPATIBLE; + } + } + private static class JavaFxIdReferenceBase extends PsiReferenceBase { private final Map myFileIds; private final Set myAcceptableIds; + private final Map myTypeMatches; private final String myReferencesId; private JavaFxIdReferenceBase(XmlAttributeValue element, @@ -125,13 +162,16 @@ class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider { myFileIds = fileIds; myAcceptableIds = acceptableIds; myReferencesId = referencesId; + myTypeMatches = Collections.emptyMap(); } public JavaFxIdReferenceBase(XmlAttributeValue xmlAttributeValue, Map fileIds, + Map typeMatches, String referencesId) { super(xmlAttributeValue); myFileIds = fileIds; + myTypeMatches = typeMatches; myReferencesId = referencesId; myAcceptableIds = myFileIds.keySet(); } @@ -145,7 +185,12 @@ class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider { @NotNull @Override public Object[] getVariants() { - return ArrayUtil.toStringArray(myAcceptableIds); + return myAcceptableIds.stream().map( + id -> { + LookupItem item = new LookupItem(id, id); + item.setPriority(TypeMatch.getPriority(myTypeMatches.get(id))); + return item; + }).toArray(LookupItem[]::new); } } @@ -183,7 +228,7 @@ class JavaFxComponentIdReferenceProvider extends PsiReferenceProvider { private Object[] collectProperties(@NotNull PsiField psiField) { final PsiType type = psiField.getType(); - final PsiType propertyType = JavaFxPsiUtil.getPropertyType(type, psiField.getProject()); + final PsiType propertyType = JavaFxPsiUtil.getWritablePropertyType(type, psiField.getProject()); final List objs = new ArrayList(); for (PsiField field : myTagClass.getAllFields()) { if (field.hasModifierProperty(PsiModifier.STATIC)) continue; diff --git a/plugins/javaFX/testData/highlighting/ControllerInExpression.java b/plugins/javaFX/testData/highlighting/ControllerInExpression.java new file mode 100644 index 000000000000..ea530296b714 --- /dev/null +++ b/plugins/javaFX/testData/highlighting/ControllerInExpression.java @@ -0,0 +1,48 @@ +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; +import javafx.fxml.FXML; + +public class ControllerInExpression { + @FXML + private ControllerInExpressionWrapper wrapper; + @FXML + private ControllerInExpressionWrapper wrapper2; + + private StringProperty strProp = new SimpleStringProperty("Text"); + public StringProperty strPropProperty() { + return strProp; + } + public String getStrProp() { + return strProp.get(); + } + public void setStrProp(StringProperty strProp) { + this.strProp = strProp; + } + + private IntegerProperty intProp = new SimpleIntegerProperty(123); + public IntegerProperty intPropProperty() { + return intProp; + } + public int getIntProp() { + return intProp.get(); + } + public void setIntProp(int intProp) { + this.intProp.set(intProp); + } + + private DoubleProperty doubleProp = new SimpleDoubleProperty(123.45); + public DoubleProperty doublePropProperty() { + return doubleProp; + } + public double getDoubleProp() { + return doubleProp.get(); + } + public void setDoubleProp(double doubleProp) { + this.doubleProp.set(doubleProp); + } + + @Override + public String toString() { + return "222.2"; + } +} diff --git a/plugins/javaFX/testData/highlighting/ControllerInExpressionWrapper.java b/plugins/javaFX/testData/highlighting/ControllerInExpressionWrapper.java new file mode 100644 index 000000000000..cc69df2d531d --- /dev/null +++ b/plugins/javaFX/testData/highlighting/ControllerInExpressionWrapper.java @@ -0,0 +1,18 @@ +import javafx.beans.property.ObjectProperty; +import javafx.beans.property.SimpleObjectProperty; + +public class ControllerInExpressionWrapper { + private ObjectProperty controller = new SimpleObjectProperty<>(this, "controller"); + + public ObjectProperty controllerProperty() { + return controller; + } + + public ControllerInExpression getController() { + return controller.get(); + } + + public void setController(ControllerInExpression controller) { + this.controller.set(controller); + } +} diff --git a/plugins/javaFX/testData/highlighting/controllerInExpression.fxml b/plugins/javaFX/testData/highlighting/controllerInExpression.fxml new file mode 100644 index 000000000000..a7cdc942325e --- /dev/null +++ b/plugins/javaFX/testData/highlighting/controllerInExpression.fxml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + "$tooltip"/> + + \ No newline at end of file