JDR: Eliminate another usage of LazyJavaClassResolver#resolveClassByFqName()

Refactor Java scopes:
Use abstract functions instead of "is" checks in LazyJavaMemberScope
Move some code to derived classes
This commit is contained in:
Pavel V. Talanov
2014-06-02 19:53:03 +04:00
parent b69ab12db7
commit 53df12598d
4 changed files with 154 additions and 107 deletions
@@ -36,6 +36,9 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
import org.jetbrains.jet.lang.resolve.java.JavaVisibilities
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaConstructorDescriptor
import org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaMemberScope.MethodSignatureData
public class LazyJavaClassMemberScope(
c: LazyJavaResolverContextWithTypes,
@@ -66,6 +69,44 @@ public class LazyJavaClassMemberScope(
emptyOrSingletonList(createDefaultConstructor())
}
}
override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
val functionsFromSupertypes = getFunctionsFromSupertypes(name, getContainingDeclaration())
result.addAll(DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, result, getContainingDeclaration(), c.errorReporter))
}
private fun getFunctionsFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<SimpleFunctionDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getFunctions(name).map { f -> f as SimpleFunctionDescriptor }
}.toSet()
}
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
val propertiesFromSupertypes = getPropertiesFromSupertypes(name, getContainingDeclaration())
result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(),
c.errorReporter))
}
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
}.toSet()
}
override fun resolveMethodSignature(
method: JavaMethod, methodTypeParameters: List<TypeParameterDescriptor>, returnType: JetType,
valueParameters: LazyJavaMemberScope.ResolvedValueParameters
): LazyJavaMemberScope.MethodSignatureData {
val propagated = c.externalSignatureResolver.resolvePropagatedSignature(
method, getContainingDeclaration(), returnType, null, valueParameters.descriptors, methodTypeParameters)
val superFunctions = propagated.getSuperMethods()
val effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature(
method, !superFunctions.isEmpty(), propagated.getReturnType(),
propagated.getReceiverType(), propagated.getValueParameters(), propagated.getTypeParameters(),
propagated.hasStableParameterNames())
return MethodSignatureData(effectiveSignature, superFunctions, propagated.getErrors() + effectiveSignature.getErrors())
}
private fun resolveSamAdapter(original: ConstructorDescriptor): ConstructorDescriptor? {
return if (SingleAbstractMethodUtils.isSamAdapterNecessary(original))
@@ -205,9 +246,7 @@ public class LazyJavaClassMemberScope(
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = listOf()
override fun getContainingDeclaration(): ClassDescriptor {
return super.getContainingDeclaration() as ClassDescriptor
}
override fun getContainingDeclaration() = super.getContainingDeclaration() as ClassDescriptor
// namespaces should be resolved elsewhere
override fun getPackage(name: Name) = null
@@ -46,8 +46,6 @@ import org.jetbrains.jet.lang.descriptors.impl.PropertyDescriptorImpl
import java.util.Collections
import org.jetbrains.jet.lang.resolve.java.resolver.ExternalSignatureResolver
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor
import org.jetbrains.jet.lang.resolve.java.structure.JavaPropertyInitializerEvaluator
import org.jetbrains.jet.utils.*
public abstract class LazyJavaMemberScope(
@@ -71,6 +69,8 @@ public abstract class LazyJavaMemberScope(
protected abstract fun computeMemberIndex(): MemberIndex
protected abstract fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name)
private val _functions = c.storageManager.createMemoizedFunction {
(name: Name): Collection<FunctionDescriptor>
->
@@ -89,18 +89,7 @@ public abstract class LazyJavaMemberScope(
listOf(function).stream()
}.toList())
if (_containingDeclaration is JavaPackageFragmentDescriptor) {
val klass = c.javaClassResolver.resolveClassByFqName(_containingDeclaration.fqName.child(name))
if (klass is LazyJavaClassDescriptor && klass.getFunctionTypeForSamInterface() != null) {
functions.add(SingleAbstractMethodUtils.createSamConstructorFunction(_containingDeclaration, klass))
}
}
if (_containingDeclaration is ClassDescriptor) {
val functionsFromSupertypes = getFunctionsFromSupertypes(name, _containingDeclaration);
functions.addAll(DescriptorResolverUtils.resolveOverrides(name, functionsFromSupertypes, functions, _containingDeclaration, c.errorReporter));
}
computeNonDeclaredFunctions(functions, name)
// Make sure that lazy things are computed before we release the lock
for (f in functions) {
@@ -112,7 +101,16 @@ public abstract class LazyJavaMemberScope(
functions
}
internal fun resolveMethodToFunctionDescriptor(method: JavaMethod, record: Boolean = true): SimpleFunctionDescriptor {
data class MethodSignatureData(
val effectiveSignature: ExternalSignatureResolver.AlternativeMethodSignature,
val superFunctions: List<FunctionDescriptor>,
val errors: List<String>
)
abstract fun resolveMethodSignature(method: JavaMethod, methodTypeParameters: List<TypeParameterDescriptor>,
returnType: JetType, valueParameters: ResolvedValueParameters): MethodSignatureData
fun resolveMethodToFunctionDescriptor(method: JavaMethod, record: Boolean = true): SimpleFunctionDescriptor {
val functionDescriptorImpl = JavaMethodDescriptor.createJavaMethod(_containingDeclaration, c.resolveAnnotations(method), method.getName())
@@ -134,30 +132,7 @@ public abstract class LazyJavaMemberScope(
if (method.getContainingClass().isAnnotationType()) TypeUtils.makeNotNullable(it) else it
}
val signatureErrors: MutableList<String>
val superFunctions: List<FunctionDescriptor>
val effectiveSignature: ExternalSignatureResolver.AlternativeMethodSignature
if (_containingDeclaration is PackageFragmentDescriptor) {
superFunctions = Collections.emptyList()
effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature(
method, false, returnType, null, valueParameters.descriptors, methodTypeParameters, false)
signatureErrors = effectiveSignature.getErrors()
}
else if (_containingDeclaration is ClassDescriptor) {
val propagated = c.externalSignatureResolver.resolvePropagatedSignature(
method, _containingDeclaration, returnType, null, valueParameters.descriptors, methodTypeParameters)
superFunctions = propagated.getSuperMethods()
effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature(
method, !superFunctions.isEmpty(), propagated.getReturnType(),
propagated.getReceiverType(), propagated.getValueParameters(), propagated.getTypeParameters(),
propagated.hasStableParameterNames())
signatureErrors = ArrayList<String>(propagated.getErrors())
signatureErrors.addAll(effectiveSignature.getErrors())
}
else {
throw IllegalStateException("Unknown class or namespace descriptor: " + _containingDeclaration)
}
val (effectiveSignature, superFunctions, signatureErrors) = resolveMethodSignature(method, methodTypeParameters, returnType, valueParameters)
functionDescriptorImpl.initialize(
effectiveSignature.getReceiverType(),
@@ -247,15 +222,11 @@ public abstract class LazyJavaMemberScope(
else null
}
private fun getFunctionsFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<SimpleFunctionDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getFunctions(name).map { f -> f as SimpleFunctionDescriptor }
}.toSet()
}
override fun getFunctions(name: Name) = _functions(name)
protected open fun getAllFunctionNames(): Collection<Name> = memberIndex().getAllMethodNames()
protected abstract fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>)
val _properties = c.storageManager.createMemoizedFunction {
(name: Name) ->
val properties = ArrayList<PropertyDescriptor>()
@@ -267,13 +238,7 @@ public abstract class LazyJavaMemberScope(
}
}
if (_containingDeclaration is ClassDescriptor) {
val propertiesFromSupertypes = getPropertiesFromSupertypes(name, _containingDeclaration);
properties.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, properties, _containingDeclaration,
c.errorReporter));
}
computeNonDeclaredProperties(name, properties)
properties
}
@@ -322,12 +287,6 @@ public abstract class LazyJavaMemberScope(
return propertyType
}
private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set<PropertyDescriptor> {
return descriptor.getTypeConstructor().getSupertypes().flatMap {
it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor }
}.toSet()
}
override fun getProperties(name: Name): Collection<VariableDescriptor> = _properties(name)
protected open fun getAllPropertyNames(): Collection<Name> = memberIndex().getAllFieldNames()
@@ -34,13 +34,15 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotations
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassStaticsPackageFragmentDescriptor
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaClassDescriptor
import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptorImpl
import kotlin.properties.Delegates
class LazyPackageFragmentForJavaPackage(
c: LazyJavaResolverContext,
containingDeclaration: ModuleDescriptor,
jPackage: JavaPackage
) : LazyJavaPackageFragment(c, containingDeclaration, jPackage.getFqName(),
{ LazyPackageFragmentScopeForJavaPackage(c, jPackage, this) })
private val jPackage: JavaPackage
) : LazyJavaPackageFragment(c, containingDeclaration, jPackage.getFqName()) {
override fun createMemberScope() = LazyPackageFragmentScopeForJavaPackage(c, jPackage, this)
}
class LazyPackageFragmentForJavaClass(
c: LazyJavaResolverContext,
@@ -48,8 +50,10 @@ class LazyPackageFragmentForJavaClass(
private val jClass: JavaClass
) : JavaClassStaticsPackageFragmentDescriptor,
LazyJavaPackageFragment(c, containingDeclaration,
jClass.getFqName().sure("Attempt to build a package of an anonymous/local class: $jClass"),
{ LazyPackageFragmentScopeForJavaClass(c, jClass, this) }) {
jClass.getFqName().sure("Attempt to build a package of an anonymous/local class: $jClass")) {
override fun createMemberScope() = LazyPackageFragmentScopeForJavaClass(c, jClass, this)
override fun getCorrespondingClass(): JavaClassDescriptor {
val classDescriptor = c.javaClassResolver.resolveClass(jClass)
if (classDescriptor !is JavaClassDescriptor) {
@@ -62,12 +66,14 @@ class LazyPackageFragmentForJavaClass(
abstract class LazyJavaPackageFragment(
protected val c: LazyJavaResolverContext,
containingDeclaration: ModuleDescriptor,
fqName: FqName,
createMemberScope: LazyJavaPackageFragment.() -> LazyJavaPackageFragmentScope
fqName: FqName
) : PackageFragmentDescriptorImpl(containingDeclaration, fqName),
JavaPackageFragmentDescriptor, LazyJavaDescriptor
{
private val _memberScope = createMemberScope()
private val _memberScope by Delegates.lazy { createMemberScope() }
abstract fun createMemberScope(): LazyJavaPackageFragmentScope
override fun getMemberScope(): LazyJavaPackageFragmentScope = _memberScope
override fun toString() = "lazy java package fragment: " + fqName
@@ -22,7 +22,6 @@ import org.jetbrains.jet.lang.resolve.name.Name
import java.util.Collections
import org.jetbrains.jet.lang.resolve.java.lazy.LazyJavaResolverContext
import org.jetbrains.jet.lang.resolve.java.lazy.withTypes
import org.jetbrains.jet.lang.resolve.java.lazy.TypeParameterResolver
import org.jetbrains.jet.lang.resolve.java.structure.JavaPackage
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.utils.flatten
@@ -33,7 +32,12 @@ import org.jetbrains.jet.lang.resolve.java.lazy.findJavaClass
import org.jetbrains.jet.lang.resolve.java.lazy.findClassInJava
import org.jetbrains.jet.lang.resolve.java.PackageClassUtils
import org.jetbrains.jet.lang.resolve.scopes.JetScope
import org.jetbrains.jet.storage.NotNullLazyValue
import org.jetbrains.jet.lang.resolve.java.descriptor.JavaPackageFragmentDescriptor
import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils
import org.jetbrains.jet.lang.resolve.java.structure.JavaMethod
import org.jetbrains.jet.lang.types.JetType
import org.jetbrains.jet.lang.resolve.java.lazy.descriptors.LazyJavaMemberScope.MethodSignatureData
import org.jetbrains.jet.lang.resolve.java.descriptor.SamConstructorDescriptor
public abstract class LazyJavaPackageFragmentScope(
c: LazyJavaResolverContext,
@@ -41,6 +45,63 @@ public abstract class LazyJavaPackageFragmentScope(
) : LazyJavaMemberScope(c.withTypes(), packageFragment) {
protected val fqName: FqName = DescriptorUtils.getFqName(packageFragment).toSafe()
protected fun computeMemberIndexForSamConstructors(delegate: MemberIndex): MemberIndex = object : MemberIndex by delegate {
override fun getAllMethodNames(): Collection<Name> {
val jClass = c.findJavaClass(fqName)
return delegate.getAllMethodNames() +
// For SAM-constructors
getAllClassNames() +
jClass.inn({ jC -> jC.getInnerClasses().map { c -> c.getName() }}, listOf())
}
}
public abstract override fun getAllClassNames(): Collection<Name>
// Package fragments are not nested
override fun getPackage(name: Name) = null
abstract fun getSubPackages(): Collection<FqName>
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = listOf()
override fun resolveMethodSignature(
method: JavaMethod, methodTypeParameters: List<TypeParameterDescriptor>, returnType: JetType,
valueParameters: LazyJavaMemberScope.ResolvedValueParameters
): LazyJavaMemberScope.MethodSignatureData {
val effectiveSignature = c.externalSignatureResolver.resolveAlternativeMethodSignature(
method, false, returnType, null, valueParameters.descriptors, methodTypeParameters, false)
return MethodSignatureData(effectiveSignature, listOf(), effectiveSignature.getErrors())
}
override fun computeNonDeclaredProperties(name: Name, result: MutableCollection<PropertyDescriptor>) {
//no undeclared properties
}
override fun getContainingDeclaration() = super.getContainingDeclaration() as LazyJavaPackageFragment
fun ClassifierDescriptor.createSamConstructor(): SamConstructorDescriptor? {
if (this is LazyJavaClassDescriptor && this.getFunctionTypeForSamInterface() != null) {
return SingleAbstractMethodUtils.createSamConstructorFunction(this@LazyJavaPackageFragmentScope.getContainingDeclaration(), this)
}
return null
}
}
public class LazyPackageFragmentScopeForJavaPackage(
c: LazyJavaResolverContext,
private val jPackage: JavaPackage,
packageFragment: LazyPackageFragmentForJavaPackage
) : LazyJavaPackageFragmentScope(c, packageFragment) {
private val deserializedPackageScope = c.storageManager.createLazyValue {
val packageClassFqName = PackageClassUtils.getPackageClassFqName(fqName)
val kotlinBinaryClass = c.kotlinClassFinder.findKotlinClass(packageClassFqName)
if (kotlinBinaryClass == null)
JetScope.EMPTY
else
c.deserializedDescriptorResolver.createKotlinPackageScope(packageFragment, kotlinBinaryClass) ?: JetScope.EMPTY
}
private val classes = c.storageManager.createMemoizedFunctionWithNullableValues<Name, ClassDescriptor> {
name ->
val fqName = fqName.child(name)
@@ -63,42 +124,7 @@ public abstract class LazyJavaPackageFragmentScope(
}
}
protected fun computeMemberIndexForSamConstructors(delegate: MemberIndex): MemberIndex = object : MemberIndex by delegate {
override fun getAllMethodNames(): Collection<Name> {
val jClass = c.findJavaClass(fqName)
return delegate.getAllMethodNames() +
// For SAM-constructors
getAllClassNames() +
jClass.inn({ jC -> jC.getInnerClasses().map { c -> c.getName() }}, listOf())
}
}
override fun getClassifier(name: Name): ClassifierDescriptor? = classes(name)
public abstract override fun getAllClassNames(): Collection<Name>
// Package fragments are not nested
override fun getPackage(name: Name) = null
abstract fun getSubPackages(): Collection<FqName>
override fun getImplicitReceiversHierarchy(): List<ReceiverParameterDescriptor> = listOf()
override fun getContainingDeclaration()= super.getContainingDeclaration() as LazyJavaPackageFragment
}
public class LazyPackageFragmentScopeForJavaPackage(
c: LazyJavaResolverContext,
private val jPackage: JavaPackage,
packageFragment: LazyJavaPackageFragment
) : LazyJavaPackageFragmentScope(c, packageFragment) {
private val deserializedPackageScope = c.storageManager.createLazyValue {
val packageClassFqName = PackageClassUtils.getPackageClassFqName(fqName)
val kotlinBinaryClass = c.kotlinClassFinder.findKotlinClass(packageClassFqName)
if (kotlinBinaryClass == null)
JetScope.EMPTY
else
c.deserializedDescriptorResolver.createKotlinPackageScope(packageFragment, kotlinBinaryClass) ?: JetScope.EMPTY
}
override fun getProperties(name: Name) = deserializedPackageScope().getProperties(name)
override fun getFunctions(name: Name) = deserializedPackageScope().getFunctions(name) + super.getFunctions(name)
@@ -127,6 +153,13 @@ public class LazyPackageFragmentScopeForJavaPackage(
// This breaks infinite recursion between loading Java descriptors and building light classes
onRecursiveCall = listOf())
override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
val samConstructor = getClassifier(name)?.createSamConstructor()
if (samConstructor != null) {
result.add(samConstructor)
}
}
override fun getSubPackages() = _subPackages()
override fun getAllPropertyNames() = Collections.emptyList<Name>()
@@ -135,7 +168,7 @@ public class LazyPackageFragmentScopeForJavaPackage(
public class LazyPackageFragmentScopeForJavaClass(
c: LazyJavaResolverContext,
private val jClass: JavaClass,
packageFragment: LazyJavaPackageFragment
packageFragment: LazyPackageFragmentForJavaClass
) : LazyJavaPackageFragmentScope(c, packageFragment) {
override fun computeMemberIndex(): MemberIndex = computeMemberIndexForSamConstructors(ClassMemberIndex(jClass, { m -> m.isStatic() }))
@@ -149,4 +182,14 @@ public class LazyPackageFragmentScopeForJavaClass(
override fun getSubPackages(): Collection<FqName> = jClass.getInnerClasses().stream()
.filter { c -> c.isStatic() }
.map { c -> c.getFqName().sure("Nested class has no fqName: $c}") }.toList()
override fun computeNonDeclaredFunctions(result: MutableCollection<SimpleFunctionDescriptor>, name: Name) {
val samConstructor = getContainingDeclaration().getCorrespondingClass().getUnsubstitutedInnerClassesScope().getClassifier(name)
?.createSamConstructor()
if (samConstructor != null) {
result.add(samConstructor)
}
}
override fun getContainingDeclaration() = super.getContainingDeclaration() as LazyPackageFragmentForJavaClass
}