Guard loading top-level classes with a check that they are not Kotlin binaries

This commit is contained in:
Andrey Breslav
2014-05-14 15:01:04 +04:00
parent 3a9f577d1d
commit 291741754b
7 changed files with 100 additions and 20 deletions
@@ -27,9 +27,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.resolve.java.resolver.JavaPackageFragmentProvider
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaPackageFragment
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass
import org.jetbrains.jet.storage.MemoizedFunctionToNotNull
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaClassDescriptor
import org.jetbrains.kotlin.util.sure
public class LazyJavaPackageFragmentProvider(
outerContext: GlobalJavaResolverContext,
@@ -124,7 +122,7 @@ public class LazyJavaPackageFragmentProvider(
}
val outerClass = javaClass.getOuterClass()
if (outerClass == null) {
return topLevelClasses(javaClass)
return c.lookupBinaryClass(javaClass) ?: topLevelClasses(javaClass)
}
val outerClassScope = resolveClass(outerClass)?.getUnsubstitutedInnerClassesScope()
val nestedClass = outerClassScope?.getClassifier(javaClass.getName()) as? ClassDescriptor
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.resolve.kotlin.header.KotlinClassHeader
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass
trait LazyJavaClassResolver {
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
@@ -67,6 +68,11 @@ fun LazyJavaResolverContext.findJavaClass(fqName: FqName): JavaClass? = findClas
data class JavaClassLookupResult(val jClass: JavaClass? = null, val kClass: ClassDescriptor? = null)
fun LazyJavaResolverContext.lookupBinaryClass(javaClass: JavaClass): ClassDescriptor? {
val kotlinJvmBinaryClass = kotlinClassFinder.findKotlinClass(javaClass)
return resolveBinaryClass(kotlinJvmBinaryClass)?.kClass
}
fun LazyJavaResolverContext.findClassInJava(fqName: FqName): JavaClassLookupResult {
// TODO: this should be governed by module separation logic
// Do not look for JavaClasses for Kotlin binaries & built-ins
@@ -75,22 +81,8 @@ fun LazyJavaResolverContext.findClassInJava(fqName: FqName): JavaClassLookupResu
}
val kotlinClass = kotlinClassFinder.findKotlinClass(fqName)
if (kotlinClass != null) {
val header = kotlinClass.getClassHeader()
if (header.kind == KotlinClassHeader.Kind.CLASS) {
val descriptor = packageFragmentProvider.resolveKotlinBinaryClass(kotlinClass)
if (descriptor != null) {
return JavaClassLookupResult(kClass = descriptor)
}
}
else if (header.kind == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
errorReporter.reportIncompatibleAbiVersion(kotlinClass, header.version)
}
else {
// This is a package or trait-impl or something like that
return JavaClassLookupResult()
}
}
val binaryClassResult = resolveBinaryClass(kotlinClass)
if (binaryClassResult != null) return binaryClassResult
val javaClass = finder.findClass(fqName)
if (javaClass == null) return JavaClassLookupResult()
@@ -100,4 +92,25 @@ fun LazyJavaResolverContext.findClassInJava(fqName: FqName): JavaClassLookupResu
return JavaClassLookupResult(javaClass)
}
}
private fun LazyJavaResolverContext.resolveBinaryClass(kotlinClass: KotlinJvmBinaryClass?): JavaClassLookupResult? {
if (kotlinClass == null) return null
val header = kotlinClass.getClassHeader()
if (header.kind == KotlinClassHeader.Kind.CLASS) {
val descriptor = packageFragmentProvider.resolveKotlinBinaryClass(kotlinClass)
if (descriptor != null) {
return JavaClassLookupResult(kClass = descriptor)
}
}
else if (header.kind == KotlinClassHeader.Kind.INCOMPATIBLE_ABI_VERSION) {
errorReporter.reportIncompatibleAbiVersion(kotlinClass, header.version)
}
else {
// This is a package or trait-impl or something like that
return JavaClassLookupResult()
}
return null
}
@@ -18,10 +18,14 @@ package org.jetbrains.jet.lang.resolve.kotlin;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.java.structure.JavaClass;
import org.jetbrains.jet.lang.resolve.name.FqName;
public interface KotlinClassFinder {
@Nullable
KotlinJvmBinaryClass findKotlinClass(@NotNull FqName fqName);
@Nullable
KotlinJvmBinaryClass findKotlinClass(@NotNull JavaClass javaClass);
}