From 73a92c6aa9d63a7791394e9e3a9aff4c2ebb1d8b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 2 Sep 2014 11:30:05 +0400 Subject: [PATCH] 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 --- .../java/structure/impl/JavaClassImpl.java | 24 +------------ .../EmptyInterface.java | 4 +++ .../EmptyInterface.txt | 7 ++++ .../jvm/compiler/LoadJavaTestGenerated.java | 6 ++++ .../descriptors/LazyJavaClassDescriptor.kt | 2 +- .../java/lazy/descriptors/MemberIndex.kt | 35 +++++++++++++++---- .../resolve/java/structure/JavaClass.java | 6 ---- 7 files changed, 48 insertions(+), 36 deletions(-) create mode 100644 compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.java create mode 100644 compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaClassImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaClassImpl.java index c0436579fb6..7cccb816203 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaClassImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/structure/impl/JavaClassImpl.java @@ -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 implements JavaC return typeParameters(getPsi().getTypeParameters()); } - @SuppressWarnings("unchecked") @Override @NotNull public Collection getSupertypes() { - // TODO: getPsi().getSuperTypes() ? - Collection superClasses = classifierTypes(getPsi().getExtendsListTypes()); - Collection 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 implements JavaC })); } - @Override - @NotNull - public Collection getAllMethods() { - return methods(KotlinPackage.filter(getPsi().getAllMethods(), new Function1() { - @Override - public Boolean invoke(PsiMethod method) { - return !method.isConstructor(); - } - })); - } - @Override @NotNull public Collection getFields() { return fields(getPsi().getFields()); } - @Override - @NotNull - public Collection getAllFields() { - return fields(getPsi().getAllFields()); - } - @Override @NotNull public Collection getConstructors() { diff --git a/compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.java b/compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.java new file mode 100644 index 00000000000..5905e2c2ab4 --- /dev/null +++ b/compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.java @@ -0,0 +1,4 @@ +package test; + +public interface EmptyInterface { +} diff --git a/compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.txt b/compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.txt new file mode 100644 index 00000000000..ce635110762 --- /dev/null +++ b/compiler/testData/loadJava/compiledJavaIncludeObjectMethods/EmptyInterface.txt @@ -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 +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 30700beb146..960ad6e2704 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -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"); diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt index 4bb826bb1f6..6e83ac2b704 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassDescriptor.kt @@ -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()) diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt index 69bb7f1cd3f..28e0493c091 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/MemberIndex.kt @@ -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 @@ -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 = methods[name] ?: listOf() - override fun getAllMethodNames(): Collection = jClass.getAllMethods().stream().filter(methodFilter).map { m -> m.getName() }.toList() + override fun getAllMethodNames(): Collection = 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 = jClass.getAllMemberNames(memberFilter) { getFields() } +} + +private fun JavaClass.getAllMemberNames(filter: (M) -> Boolean, getMembers: JavaClass.() -> Collection): Set { + val result = HashSet() + val visitedSuperClasses = HashSet() + + 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 } diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java index d91796c25e6..b5ec1a9e71d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/structure/JavaClass.java @@ -44,15 +44,9 @@ public interface JavaClass extends JavaClassifier, JavaTypeParameterListOwner, J @NotNull Collection getMethods(); - @NotNull - Collection getAllMethods(); - @NotNull Collection getFields(); - @NotNull - Collection getAllFields(); - @NotNull Collection getConstructors();