From 53df12598d40ca3b19eee5f880ff7a111d10c65c Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Mon, 2 Jun 2014 19:53:03 +0400 Subject: [PATCH] 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 --- .../descriptors/LazyJavaClassMemberScope.kt | 45 ++++++- .../lazy/descriptors/LazyJavaMemberScope.kt | 75 +++-------- .../descriptors/LazyJavaPackageFragment.kt | 22 ++-- .../LazyJavaPackageFragmentScope.kt | 119 ++++++++++++------ 4 files changed, 154 insertions(+), 107 deletions(-) diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt index 17cce121c59..27f37a7a044 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaClassMemberScope.kt @@ -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, 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 { + return descriptor.getTypeConstructor().getSupertypes().flatMap { + it.getMemberScope().getFunctions(name).map { f -> f as SimpleFunctionDescriptor } + }.toSet() + } + + override fun computeNonDeclaredProperties(name: Name, result: MutableCollection) { + val propertiesFromSupertypes = getPropertiesFromSupertypes(name, getContainingDeclaration()) + + result.addAll(DescriptorResolverUtils.resolveOverrides(name, propertiesFromSupertypes, result, getContainingDeclaration(), + c.errorReporter)) + } + + private fun getPropertiesFromSupertypes(name: Name, descriptor: ClassDescriptor): Set { + return descriptor.getTypeConstructor().getSupertypes().flatMap { + it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor } + }.toSet() + } + + override fun resolveMethodSignature( + method: JavaMethod, methodTypeParameters: List, 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 = 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 diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt index 329a7d84829..4be047f677e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -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, name: Name) + private val _functions = c.storageManager.createMemoizedFunction { (name: Name): Collection -> @@ -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, + val errors: List + ) + + abstract fun resolveMethodSignature(method: JavaMethod, methodTypeParameters: List, + 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 - val superFunctions: List - 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(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 { - 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 = memberIndex().getAllMethodNames() + protected abstract fun computeNonDeclaredProperties(name: Name, result: MutableCollection) + val _properties = c.storageManager.createMemoizedFunction { (name: Name) -> val properties = ArrayList() @@ -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 { - return descriptor.getTypeConstructor().getSupertypes().flatMap { - it.getMemberScope().getProperties(name).map { p -> p as PropertyDescriptor } - }.toSet() - } - override fun getProperties(name: Name): Collection = _properties(name) protected open fun getAllPropertyNames(): Collection = memberIndex().getAllFieldNames() diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt index 7e2b05b8181..9997beb9a66 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragment.kt @@ -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 diff --git a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt index f772b939566..7bcea2028ac 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/jet/lang/resolve/java/lazy/descriptors/LazyJavaPackageFragmentScope.kt @@ -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 { + 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 + + // Package fragments are not nested + override fun getPackage(name: Name) = null + abstract fun getSubPackages(): Collection + + override fun getImplicitReceiversHierarchy(): List = listOf() + + override fun resolveMethodSignature( + method: JavaMethod, methodTypeParameters: List, 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) { + //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 -> 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 { - 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 - - // Package fragments are not nested - override fun getPackage(name: Name) = null - abstract fun getSubPackages(): Collection - - override fun getImplicitReceiversHierarchy(): List = 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, name: Name) { + val samConstructor = getClassifier(name)?.createSamConstructor() + if (samConstructor != null) { + result.add(samConstructor) + } + } + override fun getSubPackages() = _subPackages() override fun getAllPropertyNames() = Collections.emptyList() @@ -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 = jClass.getInnerClasses().stream() .filter { c -> c.isStatic() } .map { c -> c.getFqName().sure("Nested class has no fqName: $c}") }.toList() + + override fun computeNonDeclaredFunctions(result: MutableCollection, name: Name) { + val samConstructor = getContainingDeclaration().getCorrespondingClass().getUnsubstitutedInnerClassesScope().getClassifier(name) + ?.createSamConstructor() + if (samConstructor != null) { + result.add(samConstructor) + } + } + + override fun getContainingDeclaration() = super.getContainingDeclaration() as LazyPackageFragmentForJavaClass }