Migrate the rest of resolvers from PSI to JavaElement
JavaMethodSignatureUtil needs to be handled specially later
This commit is contained in:
+14
-9
@@ -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) {
|
||||
|
||||
+4
-10
@@ -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);
|
||||
|
||||
+19
-19
@@ -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<HierarchicalMethodSignature> 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);
|
||||
|
||||
+17
-17
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+36
-50
@@ -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<Boolean>() {
|
||||
@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 extends Foo> 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() {
|
||||
|
||||
+5
@@ -123,6 +123,11 @@ public class JavaClass extends JavaClassifier
|
||||
return methods(getPsi().getAllMethods());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JavaField> getFields() {
|
||||
return fields(getPsi().getFields());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<JavaField> getAllFields() {
|
||||
return fields(getPsi().getAllFields());
|
||||
|
||||
Reference in New Issue
Block a user