From 34a552abfc39da47c264d691205268221e770e58 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 2 Aug 2013 16:05:51 +0400 Subject: [PATCH] Migrate the rest of resolvers from PSI to JavaElement JavaMethodSignatureUtil needs to be handled specially later --- .../resolve/java/DescriptorResolverUtils.java | 23 +++-- .../java/resolver/JavaFunctionResolver.java | 14 +-- .../resolver/JavaMethodSignatureUtil.java | 38 ++++---- .../java/resolver/JavaNamespaceResolver.java | 34 ++++---- .../resolve/java/resolver/RawTypesCheck.java | 86 ++++++++----------- .../resolve/java/structure/JavaClass.java | 5 ++ 6 files changed, 95 insertions(+), 105 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java index 573f8b2ae17..8af72ca8755 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java @@ -17,7 +17,10 @@ package org.jetbrains.jet.lang.resolve.java; import com.google.common.collect.ImmutableSet; -import com.intellij.psi.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.impl.compiled.ClsClassImpl; import com.intellij.psi.util.PsiFormatUtil; import org.jetbrains.annotations.NotNull; @@ -27,7 +30,9 @@ import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; +import org.jetbrains.jet.lang.resolve.java.structure.JavaField; import org.jetbrains.jet.lang.resolve.java.structure.JavaMember; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; @@ -95,22 +100,22 @@ public final class DescriptorResolverUtils { * @return true if {@code member} is a static member of enum class, which is to be put into its class object (and not into the * corresponding package). This applies to enum entries, values() and valueOf(String) methods */ - public static boolean shouldBeInEnumClassObject(@NotNull PsiMember member) { - PsiClass psiClass = member.getContainingClass(); - if (psiClass == null || !psiClass.isEnum()) return false; + public static boolean shouldBeInEnumClassObject(@NotNull JavaMember member) { + JavaClass javaClass = member.getContainingClass(); + if (javaClass == null || !javaClass.isEnum()) return false; - if (member instanceof PsiEnumConstant) return true; + if (member instanceof JavaField && ((JavaField) member).isEnumEntry()) return true; - if (!(member instanceof PsiMethod)) return false; - String signature = PsiFormatUtil.formatMethod((PsiMethod) member, - PsiSubstitutor.EMPTY, SHOW_NAME | SHOW_PARAMETERS, SHOW_TYPE | SHOW_FQ_CLASS_NAMES); + if (!(member instanceof JavaMethod)) return false; + String signature = PsiFormatUtil.formatMethod(((JavaMethod) member).getPsi(), PsiSubstitutor.EMPTY, SHOW_NAME | SHOW_PARAMETERS, + SHOW_TYPE | SHOW_FQ_CLASS_NAMES); return "values()".equals(signature) || "valueOf(java.lang.String)".equals(signature); } public static boolean isCorrectOwnerForEnumMember(@NotNull ClassOrNamespaceDescriptor ownerDescriptor, @NotNull JavaMember member) { - return isEnumClassObject(ownerDescriptor) == shouldBeInEnumClassObject(member.getPsi()); + return isEnumClassObject(ownerDescriptor) == shouldBeInEnumClassObject(member); } public static boolean isObjectMethodInInterface(@NotNull PsiMember member) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index ed93c79067e..281c73494c2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.psi.PsiMethod; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; @@ -62,9 +61,6 @@ public final class JavaFunctionResolver { private JavaValueParameterResolver valueParameterResolver; private JavaAnnotationResolver annotationResolver; - public JavaFunctionResolver() { - } - @Inject public void setTypeTransformer(JavaTypeTransformer typeTransformer) { this.typeTransformer = typeTransformer; @@ -111,9 +107,7 @@ public final class JavaFunctionResolver { return null; } - PsiMethod psiMethod = method.getPsi(); - - SimpleFunctionDescriptor alreadyResolved = trace.get(BindingContext.FUNCTION, psiMethod); + SimpleFunctionDescriptor alreadyResolved = trace.get(BindingContext.FUNCTION, method.getPsi()); if (alreadyResolved != null) { return alreadyResolved; } @@ -177,15 +171,15 @@ public final class JavaFunctionResolver { ); if (functionDescriptorImpl.getKind() == CallableMemberDescriptor.Kind.DECLARATION && record) { - BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, psiMethod, functionDescriptorImpl); + BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, method.getPsi(), functionDescriptorImpl); } if (record) { trace.record(JavaBindingContext.IS_DECLARED_IN_JAVA, functionDescriptorImpl); } - if (!RawTypesCheck.hasRawTypesInHierarchicalSignature(psiMethod) - && JavaMethodSignatureUtil.isMethodReturnTypeCompatible(psiMethod) + if (!RawTypesCheck.hasRawTypesInHierarchicalSignature(method) + && JavaMethodSignatureUtil.isMethodReturnTypeCompatible(method) && !containsErrorType(superFunctions, functionDescriptorImpl)) { if (signatureErrors.isEmpty()) { checkFunctionsOverrideCorrectly(method, superFunctions, functionDescriptorImpl); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaMethodSignatureUtil.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaMethodSignatureUtil.java index d726b1d5239..dcf4208277a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaMethodSignatureUtil.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaMethodSignatureUtil.java @@ -22,44 +22,44 @@ import com.intellij.psi.util.MethodSignatureUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import java.util.List; // originally from com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil class JavaMethodSignatureUtil { // This and following methods are originally from com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil - static boolean isMethodReturnTypeCompatible(@NotNull PsiMethod method) { - if (method.hasModifierProperty(PsiModifier.STATIC)) return true; - HierarchicalMethodSignature methodSignature = method.getHierarchicalMethodSignature(); + static boolean isMethodReturnTypeCompatible(@NotNull JavaMethod method) { + if (method.isStatic()) return true; + if (method.getContainingClass() == null) return false; + + HierarchicalMethodSignature methodSignature = method.getPsi().getHierarchicalMethodSignature(); List superSignatures = methodSignature.getSuperSignatures(); - PsiType returnType = methodSignature.getSubstitutor().substitute(method.getReturnType()); - PsiClass aClass = method.getContainingClass(); - if (aClass == null) return false; + PsiType returnType = methodSignature.getSubstitutor().substitute(method.getPsi().getReturnType()); + if (returnType == null) return true; + for (MethodSignatureBackedByPsiMethod superMethodSignature : superSignatures) { PsiMethod superMethod = superMethodSignature.getMethod(); PsiType declaredReturnType = superMethod.getReturnType(); - PsiType superReturnType = declaredReturnType; - if (superMethodSignature.isRaw()) superReturnType = TypeConversionUtil.erasure(declaredReturnType); - if (returnType == null || superReturnType == null || method == superMethod) continue; - PsiClass superClass = superMethod.getContainingClass(); - if (superClass == null) continue; - if (!areMethodsReturnTypesCompatible(superMethodSignature, superReturnType, method, methodSignature, returnType)) return false; + PsiType superReturnType = superMethodSignature.isRaw() ? TypeConversionUtil.erasure(declaredReturnType) : declaredReturnType; + if (superReturnType == null || method == superMethod || superMethod.getContainingClass() == null) continue; + if (!areMethodsReturnTypesCompatible(superMethodSignature, superReturnType, methodSignature, returnType)) { + return false; + } } return true; } private static boolean areMethodsReturnTypesCompatible( - MethodSignatureBackedByPsiMethod superMethodSignature, - PsiType superReturnType, - PsiMethod method, - MethodSignatureBackedByPsiMethod methodSignature, - PsiType returnType + @NotNull MethodSignatureBackedByPsiMethod superMethodSignature, + @NotNull PsiType superReturnType, + @NotNull MethodSignatureBackedByPsiMethod methodSignature, + @NotNull PsiType returnType ) { - if (superReturnType == null) return false; PsiType substitutedSuperReturnType; - boolean isJdk15 = PsiUtil.isLanguageLevel5OrHigher(method); + boolean isJdk15 = PsiUtil.isLanguageLevel5OrHigher(methodSignature.getMethod()); if (isJdk15 && !superMethodSignature.isRaw() && superMethodSignature.equals(methodSignature)) { //see 8.4.5 PsiSubstitutor unifyingSubstitutor = MethodSignatureUtil.getSuperMethodSignatureSubstitutor(methodSignature, superMethodSignature); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java index bf13edbd6e7..134b1c3ea55 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaNamespaceResolver.java @@ -19,10 +19,6 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiModifier; -import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; @@ -40,6 +36,8 @@ import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassStaticMembersScope; import org.jetbrains.jet.lang.resolve.java.scope.JavaPackageScope; import org.jetbrains.jet.lang.resolve.java.structure.JavaClass; +import org.jetbrains.jet.lang.resolve.java.structure.JavaField; +import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod; import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage; import org.jetbrains.jet.lang.resolve.java.vfilefinder.VirtualFileFinder; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -69,9 +67,6 @@ public final class JavaNamespaceResolver { private DeserializedDescriptorResolver deserializedDescriptorResolver; private VirtualFileFinder virtualFileFinder; - public JavaNamespaceResolver() { - } - @Inject public void setVirtualFileFinder(VirtualFileFinder virtualFileFinder) { this.virtualFileFinder = virtualFileFinder; @@ -187,18 +182,17 @@ public final class JavaNamespaceResolver { return null; } - PsiClass psiClass = javaClass.getPsi(); - if (DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(psiClass)) { + if (DescriptorResolverUtils.isCompiledKotlinClassOrPackageClass(javaClass.getPsi())) { return null; } - if (!hasStaticMembers(psiClass)) { + if (!hasStaticMembers(javaClass)) { return null; } trace.record(JavaBindingContext.JAVA_NAMESPACE_KIND, namespaceDescriptor, JavaNamespaceKind.CLASS_STATICS); if (record) { - trace.record(BindingContext.NAMESPACE, psiClass, namespaceDescriptor); + trace.record(BindingContext.NAMESPACE, javaClass.getPsi(), namespaceDescriptor); } return new JavaClassStaticMembersScope(namespaceDescriptor, fqName, javaClass, javaDescriptorResolver); @@ -230,18 +224,24 @@ public final class JavaNamespaceResolver { return createNamespaceScope(fqName, namespaceDescriptor, false); } - private static boolean hasStaticMembers(@NotNull PsiClass psiClass) { - for (PsiMember member : ContainerUtil.concat(psiClass.getMethods(), psiClass.getFields())) { - if (member.hasModifierProperty(PsiModifier.STATIC) && !DescriptorResolverUtils.shouldBeInEnumClassObject(member)) { + private static boolean hasStaticMembers(@NotNull JavaClass javaClass) { + for (JavaMethod method : javaClass.getMethods()) { + if (method.isStatic() && !DescriptorResolverUtils.shouldBeInEnumClassObject(method)) { return true; } } - for (PsiClass nestedClass : psiClass.getInnerClasses()) { - if (SingleAbstractMethodUtils.isSamInterface(new JavaClass(nestedClass))) { + for (JavaField field : javaClass.getFields()) { + if (field.isStatic() && !DescriptorResolverUtils.shouldBeInEnumClassObject(field)) { return true; } - if (nestedClass.hasModifierProperty(PsiModifier.STATIC) && hasStaticMembers(nestedClass)) { + } + + for (JavaClass nestedClass : javaClass.getInnerClasses()) { + if (SingleAbstractMethodUtils.isSamInterface(nestedClass)) { + return true; + } + if (nestedClass.isStatic() && hasStaticMembers(nestedClass)) { return true; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/RawTypesCheck.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/RawTypesCheck.java index 5b29e795f57..00f40236690 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/RawTypesCheck.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/RawTypesCheck.java @@ -16,70 +16,56 @@ package org.jetbrains.jet.lang.resolve.java.resolver; -import com.intellij.psi.*; +import com.intellij.psi.HierarchicalMethodSignature; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.resolve.java.structure.*; public class RawTypesCheck { - private static boolean isPartiallyRawType(@NotNull PsiType type) { - return type.accept(new PsiTypeVisitor() { - @Nullable - @Override - public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) { - return false; + private static boolean isPartiallyRawType(@NotNull JavaType type) { + if (type instanceof JavaPrimitiveType) { + return false; + } + else if (type instanceof JavaClassifierType) { + JavaClassifierType classifierType = (JavaClassifierType) type; + + if (classifierType.isRaw()) { + return true; } - @Nullable - @Override - public Boolean visitClassType(PsiClassType classType) { - if (classType.isRaw()) { + for (JavaType argument : classifierType.getTypeArguments()) { + if (isPartiallyRawType(argument)) { return true; } - - for (PsiType argument : classType.getParameters()) { - if (argument.accept(this)) { - return true; - } - } - - return false; } - @Nullable - @Override - public Boolean visitArrayType(PsiArrayType arrayType) { - return arrayType.getComponentType().accept(this); - } - - @Nullable - @Override - public Boolean visitWildcardType(PsiWildcardType wildcardType) { - PsiType bound = wildcardType.getBound(); - return bound == null ? false : bound.accept(this); - } - - @Nullable - @Override - public Boolean visitType(PsiType type) { - throw new IllegalStateException(type.getClass().getSimpleName() + " is unexpected"); - } - }); + return false; + } + else if (type instanceof JavaArrayType) { + return isPartiallyRawType(((JavaArrayType) type).getComponentType()); + } + else if (type instanceof JavaWildcardType) { + JavaType bound = ((JavaWildcardType) type).getBound(); + return bound != null && isPartiallyRawType(bound); + } + else { + throw new IllegalStateException("Unexpected type: " + type); + } } - private static boolean hasRawTypesInSignature(@NotNull PsiMethod method) { - PsiType returnType = method.getReturnType(); + private static boolean hasRawTypesInSignature(@NotNull JavaMethod method) { + JavaType returnType = method.getReturnType(); if (returnType != null && isPartiallyRawType(returnType)) { return true; } - for (PsiParameter parameter : method.getParameterList().getParameters()) { + for (JavaValueParameter parameter : method.getValueParameters()) { if (isPartiallyRawType(parameter.getType())) { return true; } } - for (PsiTypeParameter typeParameter : method.getTypeParameters()) { - for (PsiClassType upperBound : typeParameter.getExtendsList().getReferencedTypes()) { + for (JavaTypeParameter typeParameter : method.getTypeParameters()) { + for (JavaClassifierType upperBound : typeParameter.getUpperBounds()) { if (isPartiallyRawType(upperBound)) { return true; } @@ -89,17 +75,17 @@ public class RawTypesCheck { return false; } - static boolean hasRawTypesInHierarchicalSignature(@NotNull PsiMethod method) { + static boolean hasRawTypesInHierarchicalSignature(@NotNull JavaMethod method) { // This is a very important optimization: package-classes are big and full of static methods // building method hierarchies for such classes takes a very long time - if (method.hasModifierProperty(PsiModifier.STATIC)) return false; + if (method.isStatic()) return false; if (hasRawTypesInSignature(method)) { return true; } - for (HierarchicalMethodSignature superSignature : method.getHierarchicalMethodSignature().getSuperSignatures()) { - PsiMethod superMethod = superSignature.getMethod(); + for (HierarchicalMethodSignature superSignature : method.getPsi().getHierarchicalMethodSignature().getSuperSignatures()) { + JavaMethod superMethod = new JavaMethod(superSignature.getMethod()); if (superSignature.isRaw() || typeParameterIsErased(method, superMethod) || hasRawTypesInSignature(superMethod)) { return true; } @@ -108,12 +94,12 @@ public class RawTypesCheck { return false; } - private static boolean typeParameterIsErased(@NotNull PsiMethod a, @NotNull PsiMethod b) { + private static boolean typeParameterIsErased(@NotNull JavaMethod method, @NotNull JavaMethod superMethod) { // Java allows you to write // T foo(), in the superclass and then // Foo foo(), in the subclass // this is a valid Java override, but in fact it is an erasure - return a.getTypeParameters().length != b.getTypeParameters().length; + return method.getTypeParameters().size() != superMethod.getTypeParameters().size(); } private RawTypesCheck() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java index 9c52124deab..825dbbc75a2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java @@ -123,6 +123,11 @@ public class JavaClass extends JavaClassifier return methods(getPsi().getAllMethods()); } + @NotNull + public Collection getFields() { + return fields(getPsi().getFields()); + } + @NotNull public Collection getAllFields() { return fields(getPsi().getAllFields());