diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt index 5390b03391e..289cd2ca316 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/synthetic/SamAdapterFunctionsScope.kt @@ -44,6 +44,7 @@ import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.checker.findCorrespondingSupertype import org.jetbrains.kotlin.types.typeUtil.isNothing +import org.jetbrains.kotlin.utils.addIfNotNull import kotlin.properties.Delegates interface SamAdapterExtensionFunctionDescriptor : FunctionDescriptor, FunctionInterfaceAdapterExtensionFunctionDescriptor { @@ -244,14 +245,15 @@ class SamAdapterFunctionsScope( } } - private fun getAllSamConstructors(classifier: ClassifierDescriptor): List { - return getSamAdaptersFromConstructors(classifier) + listOfNotNull(getSamConstructor(classifier)) - } + private fun getAllSamConstructors(classifier: ClassifierDescriptor): List = + getSamAdaptersFromConstructors(classifier).also { + it.addIfNotNull(getSamConstructor(classifier)) + } - private fun getSamAdaptersFromConstructors(classifier: ClassifierDescriptor): List { - if (!shouldGenerateAdditionalSamCandidate || classifier !is JavaClassDescriptor) return emptyList() + private fun getSamAdaptersFromConstructors(classifier: ClassifierDescriptor): MutableList { + if (!shouldGenerateAdditionalSamCandidate || classifier !is JavaClassDescriptor) return SmartList() - return arrayListOf().apply { + return SmartList().apply { for (constructor in classifier.constructors) { val samConstructor = getSyntheticConstructor(constructor) ?: continue add(samConstructor) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportScope.kt index de3f49a5f80..a6df8edfa6d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AllUnderImportScope.kt @@ -24,6 +24,8 @@ import org.jetbrains.kotlin.resolve.scopes.BaseImportingScope import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.computeAllNames +import org.jetbrains.kotlin.util.collectionUtils.flatMapScopes +import org.jetbrains.kotlin.util.collectionUtils.listOfNonEmptyScopes import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable @@ -32,13 +34,13 @@ class AllUnderImportScope( excludedImportNames: Collection ) : BaseImportingScope(null) { - private val scopes: List = if (descriptor is ClassDescriptor) { - listOf(descriptor.staticScope, descriptor.unsubstitutedInnerClassesScope) + private val scopes: Array = if (descriptor is ClassDescriptor) { + listOfNonEmptyScopes(descriptor.staticScope, descriptor.unsubstitutedInnerClassesScope).toTypedArray() } else { assert(descriptor is PackageViewDescriptor) { "Must be class or package view descriptor: $descriptor" } - listOf((descriptor as PackageViewDescriptor).memberScope) + listOfNonEmptyScopes((descriptor as PackageViewDescriptor).memberScope).toTypedArray() } private val excludedNames: Set = if (excludedImportNames.isEmpty()) { // optimization @@ -49,7 +51,11 @@ class AllUnderImportScope( excludedImportNames.mapNotNull { if (it.parent() == fqName) it.shortName() else null }.toSet() } - override fun computeImportedNames(): Set? = scopes.flatMapToNullable(hashSetOf(), MemberScope::computeAllNames) + override fun computeImportedNames(): Set? = when (scopes.size) { + 0 -> null + 1 -> scopes[0].computeAllNames() + else -> scopes.asIterable().flatMapToNullable(hashSetOf(), MemberScope::computeAllNames) + } override fun getContributedDescriptors( kindFilter: DescriptorKindFilter, @@ -64,23 +70,29 @@ class AllUnderImportScope( val noPackagesKindFilter = kindFilter.withoutKinds(DescriptorKindFilter.PACKAGES_MASK) return scopes - .flatMap { it.getContributedDescriptors(noPackagesKindFilter, nameFilterToUse) } + .flatMapScopes { it.getContributedDescriptors(noPackagesKindFilter, nameFilterToUse) } .filter { it !is PackageViewDescriptor } // subpackages are not imported } override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { if (name in excludedNames) return null - return scopes.asSequence().mapNotNull { it.getContributedClassifier(name, location) }.singleOrNull() + var single: ClassifierDescriptor? = null + for (scope in scopes) { + val res = scope.getContributedClassifier(name, location) ?: continue + if (single == null) single = res + else return null + } + return single } - override fun getContributedVariables(name: Name, location: LookupLocation): List { + override fun getContributedVariables(name: Name, location: LookupLocation): Collection { if (name in excludedNames) return emptyList() - return scopes.flatMap { it.getContributedVariables(name, location) } + return scopes.flatMapScopes { it.getContributedVariables(name, location) } } - override fun getContributedFunctions(name: Name, location: LookupLocation): List { + override fun getContributedFunctions(name: Name, location: LookupLocation): Collection { if (name in excludedNames) return emptyList() - return scopes.flatMap { it.getContributedFunctions(name, location) } + return scopes.flatMapScopes { it.getContributedFunctions(name, location) } } override fun recordLookup(name: Name, location: LookupLocation) { @@ -92,3 +104,4 @@ class AllUnderImportScope( } } + diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt index 25c2cf2d9e2..65fa247d916 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/FileScopeFactory.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi.KtImportDirective import org.jetbrains.kotlin.psi.KtImportInfo import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.ImportPath -import org.jetbrains.kotlin.resolve.* +import org.jetbrains.kotlin.resolve.PlatformDependentAnalyzerServices import org.jetbrains.kotlin.resolve.TemporaryBindingTrace import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension import org.jetbrains.kotlin.resolve.scopes.* @@ -85,20 +85,20 @@ class FileScopeFactory( } val explicit = createDefaultImportResolver( - ExplicitImportsIndexed(defaultImportsFiltered), + makeExplicitImportsIndexed(defaultImportsFiltered, components.storageManager), tempTrace, packageFragment = null, aliasImportNames = aliasImportNames ) val allUnder = createDefaultImportResolver( - AllUnderImportsIndexed(defaultImportsFiltered), + makeAllUnderImportsIndexed(defaultImportsFiltered), tempTrace, packageFragment = null, aliasImportNames = aliasImportNames, excludedImports = analyzerServices.excludedImports ) val lowPriority = createDefaultImportResolver( - AllUnderImportsIndexed(defaultLowPriorityImports.also { imports -> + makeAllUnderImportsIndexed(defaultLowPriorityImports.also { imports -> assert(imports.all { it.isAllUnder }) { "All low priority imports must be all-under: $imports" } }), tempTrace, @@ -142,9 +142,13 @@ class FileScopeFactory( val imports = file.importDirectives val aliasImportNames = imports.mapNotNull { if (it.aliasName != null) it.importedFqName else null } - val explicitImportResolver = createImportResolver(ExplicitImportsIndexed(imports), bindingTrace, aliasImportNames, packageFragment) + val explicitImportResolver = + createImportResolver( + makeExplicitImportsIndexed(imports, components.storageManager), + bindingTrace, aliasImportNames, packageFragment + ) val allUnderImportResolver = createImportResolver( - AllUnderImportsIndexed(imports), + makeAllUnderImportsIndexed(imports), bindingTrace, aliasImportNames, packageFragment diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt index 54344da77e5..dca24ef31d7 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/LazyImportScope.kt @@ -39,6 +39,7 @@ import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.ImportingScope +import org.jetbrains.kotlin.storage.LockBasedStorageManager import org.jetbrains.kotlin.storage.NotNullLazyValue import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.expressions.OperatorConventions @@ -47,20 +48,20 @@ import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable import org.jetbrains.kotlin.utils.ifEmpty -interface IndexedImports { - val imports: List - fun importsForName(name: Name): Collection +open class IndexedImports(val imports: Array) { + open fun importsForName(name: Name): Iterable = imports.asIterable() } -class AllUnderImportsIndexed(allImports: Collection) : IndexedImports { - override val imports = allImports.filter { it.isAllUnder } - override fun importsForName(name: Name) = imports -} +inline fun makeAllUnderImportsIndexed(imports: Collection) : IndexedImports = + IndexedImports(imports.filter { it.isAllUnder }.toTypedArray()) -class ExplicitImportsIndexed(allImports: Collection) : IndexedImports { - override val imports = allImports.filter { !it.isAllUnder } - private val nameToDirectives: ListMultimap by lazy { +class ExplicitImportsIndexed( + imports: Array, + storageManager: StorageManager +) : IndexedImports(imports) { + + private val nameToDirectives: NotNullLazyValue> = storageManager.createLazyValue { val builder = ImmutableListMultimap.builder() for (directive in imports) { @@ -71,9 +72,15 @@ class ExplicitImportsIndexed(allImports: Collection) : Inde builder.build() } - override fun importsForName(name: Name) = nameToDirectives.get(name) + override fun importsForName(name: Name) = nameToDirectives().get(name) } +inline fun makeExplicitImportsIndexed( + imports: Collection, + storageManager: StorageManager +) : IndexedImports = + ExplicitImportsIndexed(imports.filter { !it.isAllUnder }.toTypedArray(), storageManager) + interface ImportForceResolver { fun forceResolveNonDefaultImports() fun forceResolveImport(importDirective: KtImportDirective) @@ -119,15 +126,18 @@ open class LazyImportResolver( } val allNames: Set? by lazy(LazyThreadSafetyMode.PUBLICATION) { - indexedImports.imports.flatMapToNullable(THashSet()) { getImportScope(it).computeImportedNames() } + indexedImports.imports.asIterable().flatMapToNullable(THashSet()) { getImportScope(it).computeImportedNames() } } fun definitelyDoesNotContainName(name: Name) = allNames?.let { name !in it } == true fun recordLookup(name: Name, location: LookupLocation) { if (allNames == null) return - indexedImports.importsForName(name).forEach { - getImportScope(it).recordLookup(name, location) + for (it in indexedImports.importsForName(name)) { + val scope = getImportScope(it) + if (scope !== ImportingScope.Empty) { + scope.recordLookup(name, location) + } } } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt index 95f942b573b..532790cf0ed 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassMemberScope.kt @@ -58,25 +58,22 @@ open class LazyClassMemberScope( c, declarationProvider, thisClass, trace, scopeForDeclaredMembers ) { - private val descriptorsFromDeclaredElements = storageManager.createLazyValue { - computeDescriptorsFromDeclaredElements( - DescriptorKindFilter.ALL, - MemberScope.ALL_NAME_FILTER, - NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS + private val allDescriptors = storageManager.createLazyValue { + val result = LinkedHashSet( + computeDescriptorsFromDeclaredElements( + DescriptorKindFilter.ALL, + MemberScope.ALL_NAME_FILTER, + NoLookupLocation.WHEN_GET_ALL_DESCRIPTORS + ) ) - } - private val extraDescriptors: NotNullLazyValue> = storageManager.createLazyValue { - computeExtraDescriptors(NoLookupLocation.FOR_ALREADY_TRACKED) + result.addAll(computeExtraDescriptors(NoLookupLocation.FOR_ALREADY_TRACKED)) + result } override fun getContributedDescriptors( kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean - ): Collection { - val result = LinkedHashSet(descriptorsFromDeclaredElements()) - result.addAll(extraDescriptors()) - return result - } + ): Collection = allDescriptors() protected open fun computeExtraDescriptors(location: LookupLocation): Collection { val result = ArrayList() diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt index 5275d5df8b2..30f6197cf3f 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/descriptors/JvmPackageScope.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.resolve.scopes.flatMapClassifierNamesOrNull import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.util.collectionUtils.getFirstClassifierDiscriminateHeaders import org.jetbrains.kotlin.util.collectionUtils.getFromAllScopes +import org.jetbrains.kotlin.util.collectionUtils.listOfNonEmptyScopes import org.jetbrains.kotlin.utils.Printer class JvmPackageScope( @@ -41,9 +42,11 @@ class JvmPackageScope( internal val javaScope = LazyJavaPackageScope(c, jPackage, packageFragment) private val kotlinScopes by c.storageManager.createLazyValue { - packageFragment.binaryClasses.values.mapNotNull { partClass -> - c.components.deserializedDescriptorResolver.createKotlinPackagePartScope(packageFragment, partClass) - }.toList() + listOfNonEmptyScopes( + packageFragment.binaryClasses.values.mapNotNull { partClass -> + c.components.deserializedDescriptorResolver.createKotlinPackagePartScope(packageFragment, partClass) + } + ).toTypedArray() } override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { @@ -78,7 +81,7 @@ class JvmPackageScope( addAll(javaScope.getVariableNames()) } - override fun getClassifierNames(): Set? = kotlinScopes.flatMapClassifierNamesOrNull()?.apply { + override fun getClassifierNames(): Set? = kotlinScopes.asIterable().flatMapClassifierNamesOrNull()?.apply { addAll(javaScope.getClassifierNames()) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt index f3f4e6e87ef..009e2661867 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/GivenFunctionsMemberScope.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.resolve.NonReportingOverrideStrategy import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue +import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.compact import java.util.* @@ -47,11 +48,11 @@ abstract class GivenFunctionsMemberScope( } override fun getContributedFunctions(name: Name, location: LookupLocation): Collection { - return allDescriptors.filterIsInstance().filter { it.name == name } + return allDescriptors.filterIsInstanceAnd { it.name == name } } override fun getContributedVariables(name: Name, location: LookupLocation): Collection { - return allDescriptors.filterIsInstance().filter { it.name == name } + return allDescriptors.filterIsInstanceAnd { it.name == name } } private fun createFakeOverrides(functionsFromCurrent: List): List { diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt index 84b5b361dc3..bd8224e80ed 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScope.kt @@ -58,9 +58,14 @@ interface MemberScope : ResolutionScope { } } -fun MemberScope.computeAllNames() = getClassifierNames()?.let { getFunctionNames() + getVariableNames() + it } +fun MemberScope.computeAllNames() = getClassifierNames()?.let { classifierNames -> + getFunctionNames().toMutableSet().also { + it.addAll(getVariableNames()) + it.addAll(classifierNames) + } +} -fun Collection.flatMapClassifierNamesOrNull(): MutableSet? = +fun Iterable.flatMapClassifierNamesOrNull(): MutableSet? = flatMapToNullable(hashSetOf(), MemberScope::getClassifierNames) /** @@ -167,7 +172,6 @@ class DescriptorKindFilter( val filter = field.get(null) as? DescriptorKindFilter if (filter != null) MaskToName(filter.kindMask, field.name) else null } - .toList() private val DEBUG_MASK_BIT_NAMES = staticFields() .filter { it.type == Integer.TYPE } @@ -176,7 +180,6 @@ class DescriptorKindFilter( val isOneBitMask = mask == (mask and (-mask)) if (isOneBitMask) MaskToName(mask, field.name) else null } - .toList() private inline fun staticFields() = T::class.java.fields.filter { Modifier.isStatic(it.modifiers) } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt index d4708d062c5..9203618811a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/MemberScopeImpl.kt @@ -16,9 +16,13 @@ package org.jetbrains.kotlin.resolve.scopes -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.descriptors.PropertyDescriptor +import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapTo import org.jetbrains.kotlin.utils.Printer import org.jetbrains.kotlin.utils.alwaysTrue @@ -35,14 +39,14 @@ abstract class MemberScopeImpl : MemberScope { nameFilter: (Name) -> Boolean): Collection = emptyList() override fun getFunctionNames(): Set = - getContributedDescriptors( - DescriptorKindFilter.FUNCTIONS, alwaysTrue() - ).filterIsInstance().mapTo(mutableSetOf()) { it.name } + getContributedDescriptors( + DescriptorKindFilter.FUNCTIONS, alwaysTrue() + ).filterIsInstanceMapTo>(mutableSetOf()) { it.name } override fun getVariableNames(): Set = - getContributedDescriptors( - DescriptorKindFilter.VARIABLES, alwaysTrue() - ).filterIsInstance().mapTo(mutableSetOf()) { it.name } + getContributedDescriptors( + DescriptorKindFilter.VARIABLES, alwaysTrue() + ).filterIsInstanceMapTo>(mutableSetOf()) { it.name } override fun getClassifierNames(): Set? = null diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt index 9bcf640805a..532a53c8a18 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/StaticScopeForKotlinEnum.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory.createEnumValuesMethod import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.utils.Printer -import java.util.* +import org.jetbrains.kotlin.utils.SmartList // We don't need to track lookups here since this scope used only for introduce special Enum class members class StaticScopeForKotlinEnum( @@ -46,7 +46,7 @@ class StaticScopeForKotlinEnum( override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean) = functions override fun getContributedFunctions(name: Name, location: LookupLocation) = - functions.filterTo(ArrayList(1)) { it.name == name } + functions.filterTo(SmartList()) { it.name == name } override fun printScopeStructure(p: Printer) { p.println("Static scope for $containingClass") diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt index 4ea33b75035..cb41c3441d7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/synthetic/FunInterfaceConstructorsSyntheticScope.kt @@ -5,7 +5,10 @@ package org.jetbrains.kotlin.resolve.scopes.synthetic -import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor +import org.jetbrains.kotlin.descriptors.FunctionDescriptor +import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.record @@ -16,6 +19,7 @@ import org.jetbrains.kotlin.resolve.scopes.ResolutionScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScope import org.jetbrains.kotlin.resolve.scopes.SyntheticScopes import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceMapNotNull class FunInterfaceConstructorsScopeProvider( storageManager: StorageManager, @@ -47,11 +51,9 @@ class FunInterfaceConstructorsSyntheticScope( return listOfNotNull(getSamConstructor(classifier)) } - override fun getSyntheticConstructors(scope: ResolutionScope): Collection { - val classifiers = scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS).filterIsInstance() - - return classifiers.mapNotNull { getSamConstructor(it) } - } + override fun getSyntheticConstructors(scope: ResolutionScope): Collection = + scope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS) + .filterIsInstanceMapNotNull { getSamConstructor(it) } private fun getSamConstructor(classifier: ClassifierDescriptor): SamConstructorDescriptor? { if (classifier is TypeAliasDescriptor) { diff --git a/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt b/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt index 3d14118e752..e559b6142c7 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/util/scopeUtils.kt @@ -18,6 +18,8 @@ package org.jetbrains.kotlin.util.collectionUtils import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters +import org.jetbrains.kotlin.resolve.scopes.MemberScope +import org.jetbrains.kotlin.utils.SmartList import java.util.* /** @@ -41,30 +43,20 @@ fun Collection?.concat(collection: Collection): Collection? { return result } -fun concatInOrder(c1: Collection?, c2: Collection?): Collection { - val result = if (c1 == null || c1.isEmpty()) - c2 - else if (c2 == null || c2.isEmpty()) - c1 - else { - val result = LinkedHashSet() - result.addAll(c1) - result.addAll(c2) - result +inline fun getFromAllScopes(scopes: Array, callback: (Scope) -> Collection): Collection = + when (scopes.size) { + 0 -> emptyList() + 1 -> callback(scopes[0]) + else -> { + var result: Collection? = null + for (scope in scopes) { + result = result.concat(callback(scope)) + } + result ?: emptySet() + } } - return result ?: emptySet() -} -inline fun getFromAllScopes(scopes: List, callback: (Scope) -> Collection): Collection { - if (scopes.isEmpty()) return emptySet() - var result: Collection? = null - for (scope in scopes) { - result = result.concat(callback(scope)) - } - return result ?: emptySet() -} - -inline fun getFromAllScopes(firstScope: Scope, restScopes: List, callback: (Scope) -> Collection): Collection { +inline fun getFromAllScopes(firstScope: Scope, restScopes: Array, callback: (Scope) -> Collection): Collection { var result: Collection? = callback(firstScope) for (scope in restScopes) { result = result.concat(callback(scope)) @@ -72,7 +64,20 @@ inline fun getFromAllScopes(firstScope: Scope, restScopes: List getFirstClassifierDiscriminateHeaders(scopes: List, callback: (Scope) -> T?): T? { +inline fun Array.flatMapScopes(transform: (Scope) -> Collection): Collection = + when (size) { + 0 -> emptyList() + 1 -> transform(get(0)) + else -> flatMapTo(ArrayList(), transform) + } + +fun listOfNonEmptyScopes(vararg scopes: MemberScope?): SmartList = + scopes.filterTo(SmartList()) { it != null && it !== MemberScope.Empty } + +fun listOfNonEmptyScopes(scopes: Iterable): SmartList = + scopes.filterTo(SmartList()) { it != null && it !== MemberScope.Empty } + +inline fun getFirstClassifierDiscriminateHeaders(scopes: Array, callback: (Scope) -> T?): T? { // NOTE: This is performance-sensitive; please don't replace with map().firstOrNull() var result: T? = null for (scope in scopes) { @@ -89,3 +94,32 @@ inline fun getFirstClassifierDiscriminateHeade } return result } + +inline fun Iterable<*>.filterIsInstanceAnd(predicate: (R) -> Boolean): Collection = + filterIsInstanceAndTo(SmartList(), predicate) + +inline fun > Iterable<*>.filterIsInstanceAndTo(destination: C, predicate: (R) -> Boolean): C { + for (element in this) if (element is R && predicate(element)) destination.add(element) + return destination +} + +inline fun > Iterable<*>.filterIsInstanceMapTo(destination: C, transform: (T) -> R): C { + for (element in this) if (element is T) { + destination.add(transform(element)) + } + return destination +} + +inline fun Iterable<*>.filterIsInstanceMapNotNull(transform: (T) -> R?): Collection = + filterIsInstanceMapNotNullTo(SmartList(), transform) + +inline fun > Iterable<*>.filterIsInstanceMapNotNullTo(destination: C, transform: (T) -> R?): C { + for (element in this) if (element is T) { + val result = transform(element) + if (result != null) { + destination.add(result) + } + } + return destination +} +