Skip to content

Commit

Permalink
javafx: read-only properties
Browse files Browse the repository at this point in the history
  • Loading branch information
akozlova committed Feb 4, 2013
1 parent bd1f02e commit a3e0672
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,32 @@ public static PsiMethod findValueOfMethod(@NotNull final PsiClass tagClass) {
}
return null;
}

public static boolean isReadOnly(String attributeName, XmlTag tag) {
final XmlElementDescriptor descriptor = tag.getDescriptor();
if (descriptor != null) {
final PsiElement declaration = descriptor.getDeclaration();
if (declaration instanceof PsiClass) {
final PsiClass psiClass = (PsiClass)declaration;
final PsiField psiField = psiClass.findFieldByName(attributeName, true);
if (psiField != null) {
if (findPropertySetter(attributeName, (PsiClass)declaration) == null &&
findPropertySetter(attributeName, tag) == null) {
//todo read only condition?
final PsiMethod[] constructors = psiClass.getConstructors();
for (PsiMethod constructor : constructors) {
for (PsiParameter parameter : constructor.getParameterList().getParameters()) {
if (psiField.getType().equals(parameter.getType())) {
return false;
}
}
}
return true;
}
}
}
}
return false;

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public XmlElementDescriptor[] getElementsDescriptors(XmlTag context) {
if (context != null) {
if (myPsiClass != null) {
final List<XmlElementDescriptor> children = new ArrayList<XmlElementDescriptor>();
collectProperties(children, true, new Function<PsiField, XmlElementDescriptor>() {
collectProperties(children, true, context, new Function<PsiField, XmlElementDescriptor>() {
@Override
public XmlElementDescriptor fun(PsiField field) {
return new JavaFxPropertyElementDescriptor(myPsiClass, field.getName(), false);
Expand Down Expand Up @@ -172,7 +172,7 @@ public XmlAttributeDescriptor[] getAttributesDescriptors(@Nullable XmlTag contex
final String name = context.getName();
if (Comparing.equal(name, getName()) && myPsiClass != null) {
final List<XmlAttributeDescriptor> simpleAttrs = new ArrayList<XmlAttributeDescriptor>();
collectProperties(simpleAttrs, false, new Function<PsiField, XmlAttributeDescriptor>() {
collectProperties(simpleAttrs, false, context, new Function<PsiField, XmlAttributeDescriptor>() {
@Override
public XmlAttributeDescriptor fun(PsiField field) {
return new JavaFxPropertyAttributeDescriptor(field.getName(), myPsiClass);
Expand All @@ -188,13 +188,13 @@ public XmlAttributeDescriptor fun(PsiField field) {
return XmlAttributeDescriptor.EMPTY;
}

private <T> void collectProperties(List<T> children, boolean includeListProperties, Function<PsiField, T> factory) {
private <T> void collectProperties(List<T> children, boolean includeListProperties, XmlTag context, Function<PsiField, T> factory) {
final PsiField[] fields = myPsiClass.getAllFields();
if (fields.length > 0) {
for (PsiField field : fields) {
if (field.hasModifierProperty(PsiModifier.STATIC)) continue;
final PsiType fieldType = field.getType();
if (PropertyUtil.findPropertyGetter(myPsiClass, field.getName(), false, true) != null &&
if (!JavaFxPsiUtil.isReadOnly(field.getName(), context) &&
InheritanceUtil.isInheritor(fieldType, JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY_PROPERTY) ||
fieldType.equalsToText(CommonClassNames.JAVA_LANG_STRING) ||
includeListProperties && GenericsHighlightUtil.getCollectionItemType(field.getType(), myPsiClass.getResolveScope()) != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,14 @@
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.ui.ColorUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.ColorIcon;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlElementDescriptor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
Expand Down Expand Up @@ -75,6 +78,13 @@ public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolde
attachColorIcon(element, holder, attributeValueText);
}
}
} else if (element instanceof XmlAttribute) {
final String attributeName = ((XmlAttribute)element).getName();
if (!FxmlConstants.FX_DEFAULT_PROPERTIES.contains(attributeName) &&
!((XmlAttribute)element).isNamespaceDeclaration() &&
JavaFxPsiUtil.isReadOnly(attributeName, ((XmlAttribute)element).getParent())) {
holder.createErrorAnnotation(element.getNavigationElement(), "Property '" + attributeName + "' is read-only");
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions plugins/javaFX/testData/completion/readOnly.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Region?>
<GridPane xmlns:fx="http://javafx.com/fxml">
<Region <caret>/>
</GridPane>
5 changes: 5 additions & 0 deletions plugins/javaFX/testData/highlighting/readOnly.fxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.Region?>
<GridPane xmlns:fx="http://javafx.com/fxml">
<Region <error descr="Property 'backgroundFills' is read-only">backgroundFills=""</error>/>
</GridPane>
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ public void testRootTagWithoutType() throws Exception {
doTest();
}

public void testReadOnly() throws Exception {
doTest();
}

@NotNull
@Override
protected String getTestDataPath() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ public void testVariableCompletion() throws Exception {
doTest();
}

public void testReadOnly() throws Exception {
configureByFile(getTestName(true) + ".fxml");
assertTrue(myItems.length > 0);
LookupElement selectionElement = null;
for (LookupElement item : myItems) {
if (item.getLookupString().equals("backgroundFills")) {
selectionElement = item;
break;
}
}
if (selectionElement != null) {
fail("Read only attribute was suggested");
}
}

private void doTest() throws Exception {
doTest(null);
}
Expand Down

0 comments on commit a3e0672

Please sign in to comment.