From 82189d667051e78a4bf3d144afbc25c729d03f3f Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 26 Mar 2013 14:05:15 +0100 Subject: [PATCH] javafx: cache java structure needed to validate .fxml (cherry picked from commit 2466b2d96cb0b5ed83d345c7f41cb370f2a951e6) --- .../plugins/javaFX/fxml/JavaFxPsiUtil.java | 89 +++++++++++-------- .../JavaFxClassBackedElementDescriptor.java | 41 ++++++--- 2 files changed, 78 insertions(+), 52 deletions(-) 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 eb7c1421303a..7c14f02d9467 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/JavaFxPsiUtil.java @@ -417,30 +417,35 @@ public class JavaFxPsiUtil { return null; } - public static boolean hasBuilder(final PsiClass psiClass) { + public static boolean hasBuilder(@NotNull final PsiClass psiClass) { final Project project = psiClass.getProject(); - final PsiClass builderClass = JavaPsiFacade.getInstance(project).findClass(JavaFxCommonClassNames.JAVAFX_FXML_BUILDER, - GlobalSearchScope.allScope(project)); - if (builderClass != null) { - //todo cache this info - final PsiMethod[] buildMethods = builderClass.findMethodsByName("build", false); - if (buildMethods.length == 1 && buildMethods[0].getParameterList().getParametersCount() == 0) { - if (ClassInheritorsSearch.search(builderClass).forEach(new Processor() { - @Override - public boolean process(PsiClass aClass) { - PsiType returnType = null; - final PsiMethod method = MethodSignatureUtil.findMethodBySuperMethod(aClass, buildMethods[0], false); - if (method != null) { - returnType = method.getReturnType(); + return CachedValuesManager.getManager(project).getCachedValue(psiClass, new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + final PsiClass builderClass = JavaPsiFacade.getInstance(project).findClass(JavaFxCommonClassNames.JAVAFX_FXML_BUILDER, + GlobalSearchScope.allScope(project)); + if (builderClass != null) { + final PsiMethod[] buildMethods = builderClass.findMethodsByName("build", false); + if (buildMethods.length == 1 && buildMethods[0].getParameterList().getParametersCount() == 0) { + if (ClassInheritorsSearch.search(builderClass).forEach(new Processor() { + @Override + public boolean process(PsiClass aClass) { + PsiType returnType = null; + final PsiMethod method = MethodSignatureUtil.findMethodBySuperMethod(aClass, buildMethods[0], false); + if (method != null) { + returnType = method.getReturnType(); + } + return !Comparing.equal(psiClass, PsiUtil.resolveClassInClassTypeOnly(returnType)); + } + })) { + return Result.create(false, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } - return !Comparing.equal(psiClass, PsiUtil.resolveClassInClassTypeOnly(returnType)); } - })) { - return false; } + return Result.create(true, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } - } - return true; + }); } public static String isClassAcceptable(@Nullable XmlTag parentTag, final PsiClass aClass) { @@ -502,27 +507,35 @@ public class JavaFxPsiUtil { return false; } - public static PsiType getWrappedPropertyType(PsiField field, Project project, final Map typeMap) { - PsiType substitute = null; + public static PsiType getWrappedPropertyType(PsiField field, final Project project, final Map typeMap) { final PsiType fieldType = field.getType(); - for (String typeName : typeMap.keySet()) { - if (InheritanceUtil.isInheritor(fieldType, typeName)) { - substitute = typeMap.get(typeName); - break; + final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(fieldType); + final PsiClass fieldClass = resolveResult.getElement(); + if (fieldClass == null) return fieldType; + return CachedValuesManager.getManager(project).getCachedValue(fieldClass, new CachedValueProvider() { + @Nullable + @Override + public Result compute() { + PsiType substitute = null; + for (String typeName : typeMap.keySet()) { + if (InheritanceUtil.isInheritor(fieldType, typeName)) { + substitute = typeMap.get(typeName); + break; + } + } + if (substitute == null) { + final PsiClass aClass = JavaPsiFacade.getInstance(project) + .findClass(JavaFxCommonClassNames.JAVAFX_BEANS_VALUE_OBSERVABLE_VALUE, GlobalSearchScope.allScope(project)); + LOG.assertTrue(aClass != null); + final PsiSubstitutor substitutor = + TypeConversionUtil.getSuperClassSubstitutor(aClass, fieldClass, resolveResult.getSubstitutor()); + final PsiMethod[] values = aClass.findMethodsByName("getValue", false); + substitute = substitutor.substitute(values[0].getReturnType()); + } + + return Result.create(substitute, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } - } - if (substitute == null) { - final PsiClass aClass = JavaPsiFacade.getInstance(project) - .findClass(JavaFxCommonClassNames.JAVAFX_BEANS_VALUE_OBSERVABLE_VALUE, GlobalSearchScope.allScope(project)); - LOG.assertTrue(aClass != null); - final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(fieldType); - final PsiClass fieldClass = resolveResult.getElement(); - LOG.assertTrue(fieldClass != null); - final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(aClass, fieldClass, resolveResult.getSubstitutor()); - final PsiMethod[] values = aClass.findMethodsByName("getValue", false); - substitute = substitutor.substitute(values[0].getReturnType()); - } - return substitute; + }); } private static class JavaFxControllerCachedValueProvider implements CachedValueProvider { diff --git a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java index c9081160ede5..c4d9818836e4 100644 --- a/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java +++ b/plugins/javaFX/src/org/jetbrains/plugins/javaFX/fxml/descriptors/JavaFxClassBackedElementDescriptor.java @@ -9,8 +9,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.impl.source.xml.XmlAttributeImpl; import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.InheritanceUtil; -import com.intellij.psi.util.PropertyUtil; +import com.intellij.psi.util.*; import com.intellij.psi.xml.XmlAttribute; import com.intellij.psi.xml.XmlTag; import com.intellij.util.ArrayUtil; @@ -224,19 +223,33 @@ public class JavaFxClassBackedElementDescriptor implements XmlElementDescriptor, return XmlAttributeDescriptor.EMPTY; } - private void collectProperties(List children, Function factory, boolean acceptPrimitive) { - 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 (!JavaFxPsiUtil.isReadOnly(myPsiClass, field) && - InheritanceUtil.isInheritor(fieldType, JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY) || - fieldType.equalsToText(CommonClassNames.JAVA_LANG_STRING) || - (acceptPrimitive && fieldType instanceof PsiPrimitiveType) || - GenericsHighlightUtil.getCollectionItemType(field.getType(), myPsiClass.getResolveScope()) != null) { - children.add(factory.fun(field)); + private void collectProperties(final List children, final Function factory, final boolean acceptPrimitive) { + final List fieldList = + CachedValuesManager.getManager(myPsiClass.getProject()).getCachedValue(myPsiClass, new CachedValueProvider>() { + @Nullable + @Override + public Result> compute() { + List acceptableFields = new ArrayList(); + 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 (!JavaFxPsiUtil.isReadOnly(myPsiClass, field) && + InheritanceUtil.isInheritor(fieldType, JavaFxCommonClassNames.JAVAFX_BEANS_PROPERTY) || + fieldType.equalsToText(CommonClassNames.JAVA_LANG_STRING) || + (acceptPrimitive && fieldType instanceof PsiPrimitiveType) || + GenericsHighlightUtil.getCollectionItemType(field.getType(), myPsiClass.getResolveScope()) != null) { + acceptableFields.add(field); + } + } + } + return Result.create(acceptableFields, PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT); } + }); + if (fieldList != null) { + for (PsiField field : fieldList) { + children.add(factory.fun(field)); } } }