Refactor Java resolver components

- Move components from LazyJavaResolverContext to JavaResolverComponents
- Drop LazyJavaClassResolver replacing it's usages with module resolver
(now enum entries from another module as annotation arguments are being resolved, see test)
This commit is contained in:
Denis Zharkov
2016-04-18 11:21:12 +03:00
parent bbbc910e02
commit 12bbbb6ff1
16 changed files with 66 additions and 66 deletions
+1 -1
View File
@@ -7,5 +7,5 @@ public class KotlinA: AClass() {
fun paramA(p: AClass) {} fun paramA(p: AClass) {}
@AAnnotation fun annoA() {} @AAnnotation(AEnum.AX) fun annoA() {}
} }
@@ -1,5 +1,5 @@
package custom; package custom;
public @interface AAnnotation { public @interface AAnnotation {
AEnum value();
} }
@@ -3,6 +3,6 @@ package custom;
public class AClass { public class AClass {
public AClass returnA() {} public AClass returnA() {}
public void paramA(AClass a) {} public void paramA(AClass a) {}
@AAnnotation @AAnnotation(AEnum.AX)
public void annoA() {} public void annoA() {}
} }
@@ -0,0 +1,5 @@
package custom;
public enum AEnum {
AX;
}
+1 -1
View File
@@ -11,7 +11,7 @@ public class KotlinB: AClass() {
public fun returnB(): BClass { } public fun returnB(): BClass { }
@AAnnotation fun annoA() {} @AAnnotation(AEnum.AX) fun annoA() {}
@BAnnotation fun annoB() {} @BAnnotation fun annoB() {}
} }
@@ -3,7 +3,7 @@ package custom;
public class BClass extends AClass { public class BClass extends AClass {
public AClass returnA() {} public AClass returnA() {}
public void paramA(AClass a) {} public void paramA(AClass a) {}
@AAnnotation @AAnnotation(AEnum.AX)
public void annoA() {} public void annoA() {}
public BClass returnB() {} public BClass returnB() {}
public void paramB(BClass b) {} public void paramB(BClass b) {}
+1 -1
View File
@@ -11,7 +11,7 @@ public class KotlinC: AClass() {
public fun returnB(): BClass { } public fun returnB(): BClass { }
@AAnnotation fun annoA() {} @AAnnotation(AEnum.AX) fun annoA() {}
@BAnnotation fun annoB() {} @BAnnotation fun annoB() {}
} }
@@ -3,7 +3,7 @@ package custom;
public class CClass extends BClass { public class CClass extends BClass {
public AClass returnA() {} public AClass returnA() {}
public void paramA(AClass a) {} public void paramA(AClass a) {}
@AAnnotation @AAnnotation(AEnum.AX)
public void annoA() {} public void annoA() {}
public BClass returnB() {} public BClass returnB() {}
public void paramB(BClass b) {} public void paramB(BClass b) {}
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JvmBuiltIns import org.jetbrains.kotlin.platform.JvmBuiltIns
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.CompilerEnvironment import org.jetbrains.kotlin.resolve.CompilerEnvironment
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade
import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters import org.jetbrains.kotlin.resolve.jvm.JvmPlatformParameters
@@ -85,7 +86,7 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
val configuration = KotlinTestUtils.compilerConfigurationForTests( val configuration = KotlinTestUtils.compilerConfigurationForTests(
ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, emptyList(), moduleDirs.toList() ConfigurationKind.JDK_ONLY, TestJdkKind.MOCK_JDK, emptyList(), moduleDirs.toList()
) )
return KotlinCoreEnvironment.createForTests(testRootDisposable!!, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) return KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
} }
private fun setupModules(environment: KotlinCoreEnvironment, moduleDirs: Array<File>): List<TestModule> { private fun setupModules(environment: KotlinCoreEnvironment, moduleDirs: Array<File>): List<TestModule> {
@@ -151,9 +152,22 @@ class MultiModuleJavaAnalysisCustomTest : KtUsefulTestCase() {
it.type.constructor.declarationDescriptor!! it.type.constructor.declarationDescriptor!!
}.forEach { checkDescriptor(it, callable) } }.forEach { checkDescriptor(it, callable) }
callable.annotations.map { callable.annotations.forEach {
it.type.constructor.declarationDescriptor!! val annotationClassDescriptor = it.type.constructor.declarationDescriptor as ClassDescriptor
}.forEach { checkDescriptor(it, callable) } checkDescriptor(annotationClassDescriptor, callable)
Assert.assertEquals(
"Annotation value arguments number is not equal to number of parameters in $callable",
annotationClassDescriptor.constructors.single().valueParameters.size, it.allValueArguments.size)
it.allValueArguments.forEach {
val argument = it.value
if (argument is EnumValue) {
Assert.assertEquals("Enum entry name should be <module-name>X", "X", argument.value.name.identifier.last().toString())
checkDescriptor(argument.value, callable)
}
}
}
} }
private fun checkSupertypes(classDescriptor: ClassDescriptor) { private fun checkSupertypes(classDescriptor: ClassDescriptor) {
@@ -16,26 +16,18 @@
package org.jetbrains.kotlin.load.java.lazy package org.jetbrains.kotlin.load.java.lazy
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaPackageFragment
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.MemoizedFunctionToNullable import org.jetbrains.kotlin.storage.MemoizedFunctionToNullable
import org.jetbrains.kotlin.utils.emptyOrSingletonList import org.jetbrains.kotlin.utils.emptyOrSingletonList
class LazyJavaPackageFragmentProvider( class LazyJavaPackageFragmentProvider(
components: JavaResolverComponents, components: JavaResolverComponents
module: ModuleDescriptor,
reflectionTypes: ReflectionTypes
) : PackageFragmentProvider { ) : PackageFragmentProvider {
private val c = private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY)
LazyJavaResolverContext(components, this, FragmentClassResolver(), module, reflectionTypes, TypeParameterResolver.EMPTY)
private val packageFragments: MemoizedFunctionToNullable<FqName, LazyJavaPackageFragment> = private val packageFragments: MemoizedFunctionToNullable<FqName, LazyJavaPackageFragment> =
c.storageManager.createMemoizedFunctionWithNullableValues { c.storageManager.createMemoizedFunctionWithNullableValues {
@@ -53,24 +45,4 @@ class LazyJavaPackageFragmentProvider(
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) = override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean) =
getPackageFragment(fqName)?.getSubPackageFqNames().orEmpty() getPackageFragment(fqName)?.getSubPackageFqNames().orEmpty()
fun getClass(javaClass: JavaClass): ClassDescriptor? = c.javaClassResolver.resolveClass(javaClass)
private inner class FragmentClassResolver : LazyJavaClassResolver {
override fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
val fqName = javaClass.fqName
if (fqName != null && javaClass.isKotlinLightClass) {
return c.components.javaResolverCache.getClassResolvedFromSource(fqName)
}
javaClass.outerClass?.let { outerClass ->
val outerClassScope = resolveClass(outerClass)?.unsubstitutedInnerClassesScope
return outerClassScope?.getContributedClassifier(javaClass.name, NoLookupLocation.FROM_JAVA_LOADER) as? ClassDescriptor
}
if (fqName == null) return null
return getPackageFragment(fqName.parent())?.findClassifierByJavaClass(javaClass)
}
}
} }
@@ -47,7 +47,9 @@ class JavaResolverComponents(
val moduleClassResolver: ModuleClassResolver, val moduleClassResolver: ModuleClassResolver,
val packageMapper: PackagePartProvider, val packageMapper: PackagePartProvider,
val supertypeLoopChecker: SupertypeLoopChecker, val supertypeLoopChecker: SupertypeLoopChecker,
val lookupTracker: LookupTracker val lookupTracker: LookupTracker,
val module: ModuleDescriptor,
val reflectionTypes: ReflectionTypes
) { ) {
fun replace( fun replace(
javaResolverCache: JavaResolverCache = this.javaResolverCache javaResolverCache: JavaResolverCache = this.javaResolverCache
@@ -55,30 +57,28 @@ class JavaResolverComponents(
storageManager, finder, kotlinClassFinder, deserializedDescriptorResolver, storageManager, finder, kotlinClassFinder, deserializedDescriptorResolver,
externalAnnotationResolver, signaturePropagator, errorReporter, javaResolverCache, externalAnnotationResolver, signaturePropagator, errorReporter, javaResolverCache,
javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory, javaPropertyInitializerEvaluator, samConversionResolver, sourceElementFactory,
moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker) moduleClassResolver, packageMapper, supertypeLoopChecker, lookupTracker, module, reflectionTypes)
} }
open class LazyJavaResolverContext( open class LazyJavaResolverContext(
val components: JavaResolverComponents, val components: JavaResolverComponents,
val packageFragmentProvider: LazyJavaPackageFragmentProvider,
val javaClassResolver: LazyJavaClassResolver,
val module: ModuleDescriptor,
val reflectionTypes: ReflectionTypes,
val typeParameterResolver: TypeParameterResolver val typeParameterResolver: TypeParameterResolver
) { ) {
val typeResolver = LazyJavaTypeResolver(this, typeParameterResolver) val typeResolver = LazyJavaTypeResolver(this, typeParameterResolver)
val storageManager: StorageManager val storageManager: StorageManager
get() = components.storageManager get() = components.storageManager
val module: ModuleDescriptor get() = components.module
} }
fun LazyJavaResolverContext.child( fun LazyJavaResolverContext.child(
typeParameterResolver: TypeParameterResolver typeParameterResolver: TypeParameterResolver
) = LazyJavaResolverContext(components, packageFragmentProvider, javaClassResolver, module, reflectionTypes, typeParameterResolver) ) = LazyJavaResolverContext(components, typeParameterResolver)
fun LazyJavaResolverContext.replaceComponents( fun LazyJavaResolverContext.replaceComponents(
components: JavaResolverComponents components: JavaResolverComponents
) = LazyJavaResolverContext(components, packageFragmentProvider, javaClassResolver, module, reflectionTypes, typeParameterResolver) ) = LazyJavaResolverContext(components, typeParameterResolver)
fun LazyJavaResolverContext.child( fun LazyJavaResolverContext.child(
containingDeclaration: DeclarationDescriptor, containingDeclaration: DeclarationDescriptor,
@@ -118,8 +118,7 @@ class LazyJavaAnnotationDescriptor(
val containingJavaClass = element.containingClass val containingJavaClass = element.containingClass
//TODO: (module refactoring) moduleClassResolver should be used here val enumClass = c.components.moduleClassResolver.resolveClass(containingJavaClass) ?: return null
val enumClass = c.javaClassResolver.resolveClass(containingJavaClass) ?: return null
val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(element.name, NoLookupLocation.FROM_JAVA_LOADER) val classifier = enumClass.unsubstitutedInnerClassesScope.getContributedClassifier(element.name, NoLookupLocation.FROM_JAVA_LOADER)
if (classifier !is ClassDescriptor) return null if (classifier !is ClassDescriptor) return null
@@ -16,20 +16,13 @@
package org.jetbrains.kotlin.load.java.lazy package org.jetbrains.kotlin.load.java.lazy
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
import org.jetbrains.kotlin.utils.mapToIndex import org.jetbrains.kotlin.utils.mapToIndex
//TODO: (module refactoring) usages of this interface should be replaced by ModuleClassResolver
interface LazyJavaClassResolver {
fun resolveClass(javaClass: JavaClass): ClassDescriptor?
}
interface TypeParameterResolver { interface TypeParameterResolver {
object EMPTY : TypeParameterResolver { object EMPTY : TypeParameterResolver {
override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? = null override fun resolveTypeParameter(javaTypeParameter: JavaTypeParameter): TypeParameterDescriptor? = null
@@ -133,7 +133,7 @@ class LazyJavaTypeResolver(
private fun mapKotlinClass(fqName: FqName): ClassDescriptor? { private fun mapKotlinClass(fqName: FqName): ClassDescriptor? {
if (attr.isForAnnotationParameter && fqName == JAVA_LANG_CLASS_FQ_NAME) { if (attr.isForAnnotationParameter && fqName == JAVA_LANG_CLASS_FQ_NAME) {
return c.reflectionTypes.kClass return c.components.reflectionTypes.kClass
} }
val javaToKotlin = JavaToKotlinClassMap.INSTANCE val javaToKotlin = JavaToKotlinClassMap.INSTANCE
@@ -17,11 +17,28 @@
package org.jetbrains.kotlin.resolve.jvm package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.components.JavaResolverCache
import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider import org.jetbrains.kotlin.load.java.lazy.LazyJavaPackageFragmentProvider
import org.jetbrains.kotlin.load.java.structure.JavaClass import org.jetbrains.kotlin.load.java.structure.JavaClass
class JavaDescriptorResolver(val packageFragmentProvider: LazyJavaPackageFragmentProvider) { class JavaDescriptorResolver(
val packageFragmentProvider: LazyJavaPackageFragmentProvider,
private val javaResolverCache: JavaResolverCache
) {
fun resolveClass(javaClass: JavaClass): ClassDescriptor? { fun resolveClass(javaClass: JavaClass): ClassDescriptor? {
return packageFragmentProvider.getClass(javaClass) val fqName = javaClass.fqName
if (fqName != null && javaClass.isKotlinLightClass) {
return javaResolverCache.getClassResolvedFromSource(fqName)
}
javaClass.outerClass?.let { outerClass ->
val outerClassScope = resolveClass(outerClass)?.unsubstitutedInnerClassesScope
return outerClassScope?.getContributedClassifier(javaClass.name, NoLookupLocation.FROM_JAVA_LOADER) as? ClassDescriptor
}
if (fqName == null) return null
return packageFragmentProvider.getPackageFragments(fqName.parent()).firstOrNull()?.findClassifierByJavaClass(javaClass)
} }
} }
@@ -55,19 +55,19 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization
val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter) val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter)
val singleModuleClassResolver = SingleModuleClassResolver() val singleModuleClassResolver = SingleModuleClassResolver()
val runtimePackageFacadeProvider = RuntimePackagePartProvider(classLoader) val runtimePackageFacadeProvider = RuntimePackagePartProvider(classLoader)
val javaResolverCache = JavaResolverCache.EMPTY
val globalJavaResolverContext = JavaResolverComponents( val globalJavaResolverContext = JavaResolverComponents(
storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver, storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver,
ExternalAnnotationResolver.EMPTY, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY, ExternalAnnotationResolver.EMPTY, SignaturePropagator.DO_NOTHING, RuntimeErrorReporter, javaResolverCache,
JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver, JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver,
runtimePackageFacadeProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING runtimePackageFacadeProvider, SupertypeLoopChecker.EMPTY, LookupTracker.DO_NOTHING, module, ReflectionTypes(module)
) )
val lazyJavaPackageFragmentProvider = val lazyJavaPackageFragmentProvider = LazyJavaPackageFragmentProvider(globalJavaResolverContext)
LazyJavaPackageFragmentProvider(globalJavaResolverContext, module, ReflectionTypes(module))
builtIns.setOwnerModuleDescriptor(module) builtIns.setOwnerModuleDescriptor(module)
val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider) val javaDescriptorResolver = JavaDescriptorResolver(lazyJavaPackageFragmentProvider, javaResolverCache)
val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver) val javaClassDataFinder = JavaClassDataFinder(reflectKotlinClassFinder, deserializedDescriptorResolver)
val notFoundClasses = NotFoundClasses(storageManager, module) val notFoundClasses = NotFoundClasses(storageManager, module)
val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl( val binaryClassAnnotationAndConstantLoader = BinaryClassAnnotationAndConstantLoaderImpl(