Remove JavaClass.getAllMethods()/getAllFields()

Their behavior is different in PSI and reflection (two things that this
interface is supposed to unify), so there's no point in making it interface
methods, rather we should just walk supertype hierarchy manually

Also make JavaClassImpl.getSupertypes() invoke PsiClass.getSuperTypes(),
because it also contains java.lang.Object for interfaces, which makes
equals/hashCode/toString appear in interfaces' getAllMethods() as well
This commit is contained in:
Alexander Udalov
2014-09-02 11:30:05 +04:00
parent f39c3041d2
commit 73a92c6aa9
7 changed files with 48 additions and 36 deletions
@@ -18,7 +18,6 @@ package org.jetbrains.jet.lang.resolve.java.structure.impl;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiSubstitutorImpl;
import com.intellij.util.containers.ContainerUtil;
import kotlin.Function1;
import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull;
@@ -90,14 +89,10 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
return typeParameters(getPsi().getTypeParameters());
}
@SuppressWarnings("unchecked")
@Override
@NotNull
public Collection<JavaClassifierType> getSupertypes() {
// TODO: getPsi().getSuperTypes() ?
Collection<JavaClassifierType> superClasses = classifierTypes(getPsi().getExtendsListTypes());
Collection<JavaClassifierType> superInterfaces = classifierTypes(getPsi().getImplementsListTypes());
return ContainerUtil.collect(ContainerUtil.concat(superClasses, superInterfaces).iterator());
return classifierTypes(getPsi().getSuperTypes());
}
@Override
@@ -111,29 +106,12 @@ public class JavaClassImpl extends JavaClassifierImpl<PsiClass> implements JavaC
}));
}
@Override
@NotNull
public Collection<JavaMethod> getAllMethods() {
return methods(KotlinPackage.filter(getPsi().getAllMethods(), new Function1<PsiMethod, Boolean>() {
@Override
public Boolean invoke(PsiMethod method) {
return !method.isConstructor();
}
}));
}
@Override
@NotNull
public Collection<JavaField> getFields() {
return fields(getPsi().getFields());
}
@Override
@NotNull
public Collection<JavaField> getAllFields() {
return fields(getPsi().getAllFields());
}
@Override
@NotNull
public Collection<JavaConstructor> getConstructors() {
@@ -0,0 +1,4 @@
package test;
public interface EmptyInterface {
}
@@ -0,0 +1,7 @@
package test
public trait EmptyInterface {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1789,6 +1789,12 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
doTestCompiledJavaIncludeObjectMethods(fileName);
}
@TestMetadata("EmptyInterface.java")
public void testEmptyInterface() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.java");
doTestCompiledJavaIncludeObjectMethods(fileName);
}
@TestMetadata("InterfaceWithObjectMethods.java")
public void testInterfaceWithObjectMethods() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledJavaIncludeObjectMethods/InterfaceWithObjectMethods.java");
@@ -161,7 +161,7 @@ class LazyJavaClassDescriptor(
supertype ->
c.typeResolver.transformJavaType(supertype, TypeUsage.SUPERTYPE.toAttributes())
}
.filter { supertype -> !supertype.isError() }
.filter { supertype -> !supertype.isError() && !KotlinBuiltIns.getInstance().isAnyOrNullableAny(supertype) }
.toList()
.ifEmpty {
listOf(KotlinBuiltIns.getInstance().getAnyType())
@@ -17,12 +17,10 @@
package org.jetbrains.jet.lang.resolve.java.lazy.descriptors
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass
import org.jetbrains.jet.lang.resolve.java.structure.*
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.resolve.java.structure.JavaField
import org.jetbrains.jet.lang.resolve.java.structure.JavaMember
import org.jetbrains.jet.utils.valuesToMap
import java.util.HashSet
trait MemberIndex {
fun findMethodsByName(name: Name): Collection<JavaMethod>
@@ -50,8 +48,33 @@ open class ClassMemberIndex(val jClass: JavaClass, val memberFilter: (JavaMember
private val fields = jClass.getFields().stream().filter(memberFilter).valuesToMap { m -> m.getName() }
override fun findMethodsByName(name: Name): Collection<JavaMethod> = methods[name] ?: listOf()
override fun getAllMethodNames(): Collection<Name> = jClass.getAllMethods().stream().filter(methodFilter).map { m -> m.getName() }.toList()
override fun getAllMethodNames(): Collection<Name> = jClass.getAllMemberNames(methodFilter) { getMethods() }
override fun findFieldByName(name: Name): JavaField? = fields[name]
override fun getAllFieldNames() = jClass.getAllFields().stream().filter(memberFilter).map { m -> m.getName() }.toList()
override fun getAllFieldNames(): Collection<Name> = jClass.getAllMemberNames(memberFilter) { getFields() }
}
private fun <M : JavaMember> JavaClass.getAllMemberNames(filter: (M) -> Boolean, getMembers: JavaClass.() -> Collection<M>): Set<Name> {
val result = HashSet<Name>()
val visitedSuperClasses = HashSet<JavaClass>()
fun JavaClass.visit(): Unit {
if (!visitedSuperClasses.add(this)) return
for (member in getMembers()) {
if (filter(member)) {
result.add(member.getName())
}
}
for (supertype in getSupertypes()) {
val classifier = supertype.getClassifier()
if (classifier is JavaClass) {
classifier.visit()
}
}
}
this.visit()
return result
}
@@ -44,15 +44,9 @@ public interface JavaClass extends JavaClassifier, JavaTypeParameterListOwner, J
@NotNull
Collection<JavaMethod> getMethods();
@NotNull
Collection<JavaMethod> getAllMethods();
@NotNull
Collection<JavaField> getFields();
@NotNull
Collection<JavaField> getAllFields();
@NotNull
Collection<JavaConstructor> getConstructors();