[LL API] Handle 'KtScript' consistently in file-based provider

This commit is contained in:
Yan Zhulanow
2023-03-16 00:29:26 +09:00
committed by Space Team
parent 8f4c6eae2f
commit c66f1a12cb
4 changed files with 47 additions and 13 deletions
@@ -16,6 +16,19 @@ import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.yieldIfNotNull import org.jetbrains.kotlin.utils.yieldIfNotNull
internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile) : KotlinDeclarationProvider() { internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile) : KotlinDeclarationProvider() {
private val topLevelDeclarations: Sequence<KtDeclaration>
get() {
return sequence {
for (child in kotlinFile.declarations) {
if (child is KtScript) {
yieldAll(child.declarations)
} else {
yield(child)
}
}
}
}
override fun getClassLikeDeclarationByClassId(classId: ClassId): KtClassLikeDeclaration? { override fun getClassLikeDeclarationByClassId(classId: ClassId): KtClassLikeDeclaration? {
return getClassLikeDeclarationsByClassId(classId).firstOrNull() return getClassLikeDeclarationsByClassId(classId).firstOrNull()
} }
@@ -39,7 +52,7 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile
val tasks = ArrayDeque<Task>() val tasks = ArrayDeque<Task>()
val startingChunks = classId.relativeClassName.pathSegments() val startingChunks = classId.relativeClassName.pathSegments()
for (declaration in kotlinFile.declarations) { for (declaration in topLevelDeclarations) {
tasks.addLast(Task(startingChunks, declaration)) tasks.addLast(Task(startingChunks, declaration))
} }
@@ -49,13 +62,6 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile
val (chunks, element) = tasks.removeFirst() val (chunks, element) = tasks.removeFirst()
assert(chunks.isNotEmpty()) assert(chunks.isNotEmpty())
if (element is KtScript) {
for (child in element.declarations) {
tasks.addLast(Task(chunks, child))
}
continue
}
if (element !is KtNamedDeclaration || element.nameAsName != chunks[0]) { if (element !is KtNamedDeclaration || element.nameAsName != chunks[0]) {
continue continue
} }
@@ -113,7 +119,7 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile
override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> { override fun findFilesForFacade(facadeFqName: FqName): Collection<KtFile> {
if (kotlinFile.javaFileFacadeFqName != facadeFqName) return emptyList() if (kotlinFile.javaFileFacadeFqName != facadeFqName) return emptyList()
for (declaration in kotlinFile.declarations) { for (declaration in topLevelDeclarations) {
if (declaration !is KtClassLikeDeclaration) { if (declaration !is KtClassLikeDeclaration) {
return listOf(kotlinFile) return listOf(kotlinFile)
} }
@@ -135,7 +141,7 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile
} }
return buildList { return buildList {
for (declaration in kotlinFile.declarations) { for (declaration in topLevelDeclarations) {
if (declaration is T && declaration.nameAsName == name) { if (declaration is T && declaration.nameAsName == name) {
add(declaration) add(declaration)
} }
@@ -149,7 +155,7 @@ internal class FileBasedKotlinDeclarationProvider(private val kotlinFile: KtFile
} }
return buildSet { return buildSet {
for (declaration in kotlinFile.declarations) { for (declaration in topLevelDeclarations) {
if (declaration is T) { if (declaration is T) {
addIfNotNull(declaration.nameAsName) addIfNotNull(declaration.nameAsName)
} }
@@ -0,0 +1,22 @@
// CLASS: test/app/Foo
// CLASS: test/app/Foo.Bar
// CLASS: test/app/Foo.Bar.Baz
// TYPE_ALIAS: test/app/MyString
// FUNCTION: test/app/#foo
// PROPERTY: test/app/#bar
package test.app
interface Foo {
class Bar {
object Baz
}
fun nested() {}
}
typealias MyString = String
fun foo() {}
val bar: String = "bar"
@@ -21,7 +21,7 @@ import java.util.regex.Pattern;
public class FileBasedKotlinDeclarationProviderTestGenerated extends AbstractFileBasedKotlinDeclarationProviderTest { public class FileBasedKotlinDeclarationProviderTestGenerated extends AbstractFileBasedKotlinDeclarationProviderTest {
@Test @Test
public void testAllFilesPresentInFileBasedDeclarationProvider() throws Exception { public void testAllFilesPresentInFileBasedDeclarationProvider() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/fileBasedDeclarationProvider"), Pattern.compile("^(.+)\\.kt$"), null, true); KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/low-level-api-fir/testdata/fileBasedDeclarationProvider"), Pattern.compile("^(.+)\\.(kt|kts)$"), null, true);
} }
@Test @Test
@@ -48,6 +48,12 @@ public class FileBasedKotlinDeclarationProviderTestGenerated extends AbstractFil
runTest("analysis/low-level-api-fir/testdata/fileBasedDeclarationProvider/sameNames.kt"); runTest("analysis/low-level-api-fir/testdata/fileBasedDeclarationProvider/sameNames.kt");
} }
@Test
@TestMetadata("script.kts")
public void testScript() throws Exception {
runTest("analysis/low-level-api-fir/testdata/fileBasedDeclarationProvider/script.kts");
}
@Test @Test
@TestMetadata("simple.kt") @TestMetadata("simple.kt")
public void testSimple() throws Exception { public void testSimple() throws Exception {
@@ -88,7 +88,7 @@ internal fun TestGroupSuite.generateFirLowLevelApiTests() {
} }
testClass<AbstractFileBasedKotlinDeclarationProviderTest> { testClass<AbstractFileBasedKotlinDeclarationProviderTest> {
model("fileBasedDeclarationProvider") model("fileBasedDeclarationProvider", pattern = TestGeneratorUtil.KT_OR_KTS)
} }
} }