[Analysis API] optimize KotlinPackageProvider.getSubPackageFqNames
Previously, we queried heavy kotlin package provider two times which affected performance
Now it's queries only a single time
^KTIJ-24640
diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt
index 70783a4..7bac535 100644
--- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt
+++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/scopes/KtFirPackageScope.kt
@@ -26,7 +26,6 @@
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
-import org.jetbrains.kotlin.platform.jvm.isJvm
internal class KtFirPackageScope(
private val fqName: FqName,
@@ -111,21 +110,8 @@
override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence<KtPackageSymbol> = withValidityAssertion {
sequence {
- if (targetPlatform.isJvm()) {
- val javaPackage = JavaPsiFacade.getInstance(project).findPackage(fqName.asString())
- if (javaPackage != null) {
- for (psiPackage in javaPackage.getSubPackages(searchScope)) {
- val fqName = FqName(psiPackage.qualifiedName)
- if (nameFilter(fqName.shortName())) {
- yield(builder.createPackageSymbol(fqName))
- }
- }
- }
- }
- packageProvider.getKotlinSubPackageFqNames(fqName).forEach {
- if (nameFilter(it)) {
- yield(builder.createPackageSymbol(fqName.child(it)))
- }
+ packageProvider.getSubPackageFqNames(fqName, nameFilter).forEach {
+ yield(builder.createPackageSymbol(fqName.child(it)))
}
}
}
diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinPackageProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinPackageProvider.kt
index 42b1f6c..1c4bb2c 100644
--- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinPackageProvider.kt
+++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/KotlinPackageProvider.kt
@@ -22,7 +22,13 @@
* So, a package [FqName] is determined by Kotlin files package directive.
*/
public abstract fun doKotlinPackageExists(packageFqName: FqName): Boolean
- public abstract fun getKotlinSubPackageFqNames(packageFqName: FqName): Set<Name>
+
+ /**
+ * Returns the list of subpackages for a given package, which satisfy [nameFilter].
+ *
+ * Returned list of packages
+ */
+ public abstract fun getSubPackageFqNames(packageFqName: FqName, nameFilter: (Name) -> Boolean): Set<Name>
}
public abstract class KotlinPackageProviderFactory {
diff --git a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticPackageProvider.kt b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticPackageProvider.kt
index 32c9d58..01c22361 100644
--- a/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticPackageProvider.kt
+++ b/analysis/analysis-api-providers/src/org/jetbrains/kotlin/analysis/providers/impl/KotlinStaticPackageProvider.kt
@@ -34,8 +34,8 @@
return packageFqName in packageToSubPackageNames
}
- override fun getKotlinSubPackageFqNames(packageFqName: FqName): Set<Name> {
- return packageToSubPackageNames[packageFqName] ?: emptySet()
+ override fun getSubPackageFqNames(packageFqName: FqName, nameFilter: (Name) -> Boolean): Set<Name> {
+ return packageToSubPackageNames[packageFqName]?.filterTo(mutableSetOf()) { nameFilter(it) } ?: emptySet()
}
}
diff --git a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt
index 75e1bcd..a170759 100644
--- a/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt
+++ b/analysis/symbol-light-classes/src/org/jetbrains/kotlin/light/classes/symbol/SymbolKotlinAsJavaSupport.kt
@@ -83,7 +83,7 @@
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> =
project.createPackageProvider(scope)
- .getKotlinSubPackageFqNames(fqn)
+ .getSubPackageFqNames(fqn, nameFilter = { true })
.map { fqn.child(it) }
override fun createInstanceOfLightScript(script: KtScript): KtLightClass? = error("Should not be called")
diff --git a/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java b/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java
index a98032b..1423ec2 100644
--- a/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java
+++ b/core/compiler.common/src/org/jetbrains/kotlin/name/Name.java
@@ -74,6 +74,11 @@
return true;
}
+ public static @Nullable Name identifierIfValid(@NotNull String name) {
+ if (!isValidIdentifier(name)) return null;
+ return identifier(name);
+ }
+
@NotNull
public static Name special(@NotNull String name) {
if (!name.startsWith("<")) {