diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index fa7f9d55a91..a8ddffc4880 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -88,6 +88,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirMultiModuleResolve import org.jetbrains.kotlin.idea.fir.AbstractKtDeclarationAndFirDeclarationEqualityChecker import org.jetbrains.kotlin.idea.folding.AbstractKotlinFoldingTest import org.jetbrains.kotlin.idea.frontend.api.fir.AbstractResolveCallTest +import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractStdlibSymbolsBuildingTest import org.jetbrains.kotlin.idea.frontend.api.symbols.AbstractSymbolsByPsiBuildingTest import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest @@ -947,6 +948,10 @@ fun main(args: Array) { testClass { model("symbolsByPsi") } + + testClass { + model("stdLibSymbols", extension = "txt") + } } testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "idea/testData") { diff --git a/idea/idea-frontend-fir/testData/stdLibSymbols/fileWalkDirectionEnum.txt b/idea/idea-frontend-fir/testData/stdLibSymbols/fileWalkDirectionEnum.txt new file mode 100644 index 00000000000..68bfc0c108e --- /dev/null +++ b/idea/idea-frontend-fir/testData/stdLibSymbols/fileWalkDirectionEnum.txt @@ -0,0 +1,41 @@ +callable: kotlin/collections/listOf + +// SYMBOLS: +KtFirFunctionSymbol: + fqName: kotlin.collections.listOf + isExtension: false + isOperator: false + isSuspend: false + modality: FINAL + name: listOf + origin: LIBRARY + symbolKind: TOP_LEVEL + type: kotlin/collections/List + typeParameters: [KtFirTypeParameterSymbol(T)] + valueParameters: [KtFirFunctionValueParameterSymbol(element)] + +KtFirFunctionSymbol: + fqName: kotlin.collections.listOf + isExtension: false + isOperator: false + isSuspend: false + modality: FINAL + name: listOf + origin: LIBRARY + symbolKind: TOP_LEVEL + type: kotlin/collections/List + typeParameters: [KtFirTypeParameterSymbol(T)] + valueParameters: [] + +KtFirFunctionSymbol: + fqName: kotlin.collections.listOf + isExtension: false + isOperator: false + isSuspend: false + modality: FINAL + name: listOf + origin: LIBRARY + symbolKind: TOP_LEVEL + type: kotlin/collections/List + typeParameters: [KtFirTypeParameterSymbol(T)] + valueParameters: [KtFirFunctionValueParameterSymbol(elements)] diff --git a/idea/idea-frontend-fir/testData/stdLibSymbols/iterator.txt b/idea/idea-frontend-fir/testData/stdLibSymbols/iterator.txt new file mode 100644 index 00000000000..4db8f93f130 --- /dev/null +++ b/idea/idea-frontend-fir/testData/stdLibSymbols/iterator.txt @@ -0,0 +1,11 @@ +class: kotlin/collections/Iterator + +// SYMBOLS: +KtFirClassOrObjectSymbol: + classId: kotlin/collections/Iterator + classKind: INTERFACE + modality: ABSTRACT + name: Iterator + origin: LIBRARY + symbolKind: TOP_LEVEL + typeParameters: [KtFirTypeParameterSymbol(T)] diff --git a/idea/idea-frontend-fir/testData/stdLibSymbols/listOf.txt b/idea/idea-frontend-fir/testData/stdLibSymbols/listOf.txt new file mode 100644 index 00000000000..cc656a0ca7a --- /dev/null +++ b/idea/idea-frontend-fir/testData/stdLibSymbols/listOf.txt @@ -0,0 +1,11 @@ +class: kotlin/io/FileWalkDirection + +// SYMBOLS: +KtFirClassOrObjectSymbol: + classId: kotlin/io/FileWalkDirection + classKind: ENUM_CLASS + modality: FINAL + name: FileWalkDirection + origin: LIBRARY + symbolKind: TOP_LEVEL + typeParameters: [] diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt new file mode 100644 index 00000000000..978834ecfa2 --- /dev/null +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.frontend.api.symbols + +import com.intellij.openapi.util.io.FileUtil +import org.jetbrains.kotlin.idea.addExternalTestFiles +import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase +import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor +import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtPsiFactory +import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType +import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File + +abstract class AbstractStdlibSymbolsBuildingTest : KotlinLightCodeInsightFixtureTestCase() { + protected fun doTest(path: String) { + val fakeKtFile = myFixture.configureByText("file.kt", "fun a() {}") as KtFile + + val testDataFile = File(path) + val testFileText = FileUtil.loadFile(testDataFile) + + val identifier = testFileText.substringBeforeLast(SYMBOLS_TAG).trim() + + val symbolData = SymbolData.create(identifier) + + val renderedSymbols = executeOnPooledThreadInReadAction { + val analysisSession = KtFirAnalysisSession(fakeKtFile) + val symbols = symbolData.toSymbols(analysisSession) + symbols.map { DebugSymbolRenderer.render(it) } + } + + val actual = buildString { + val actualSymbolsData = renderedSymbols.joinToString(separator = "\n") + val fileTextWithoutSymbolsData = testFileText.substringBeforeLast(SYMBOLS_TAG).trimEnd() + appendLine(fileTextWithoutSymbolsData) + appendLine() + appendLine(SYMBOLS_TAG) + append(actualSymbolsData) + } + KotlinTestUtils.assertEqualsToFile(testDataFile, actual) + + } + + override fun getDefaultProjectDescriptor(): KotlinLightProjectDescriptor = + KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE + + companion object { + private const val SYMBOLS_TAG = "// SYMBOLS:" + } +} + +private sealed class SymbolData { + abstract fun toSymbols(analysisSession: KtAnalysisSession): List + + data class ClassData(val classId: ClassId) : SymbolData() { + override fun toSymbols(analysisSession: KtAnalysisSession): List { + val symbol = analysisSession.symbolProvider.getClassOrObjectSymbolByClassId(classId) ?: error("Class $classId is not found") + return listOf(symbol) + } + } + + data class CallableData(val packageName: FqName, val name: Name) : SymbolData() { + override fun toSymbols(analysisSession: KtAnalysisSession): List { + val symbols = analysisSession.symbolProvider.getTopLevelCallableSymbols(packageName, name).toList() + if (symbols.isEmpty()) { + error("No callable with fqName ${packageName}/${name} found") + } + return symbols + } + } + + companion object { + fun create(data: String): SymbolData = when { + data.startsWith("class:") -> ClassData(ClassId.fromString(data.removePrefix("class:").trim())) + data.startsWith("callable:") -> { + val fullName = data.removePrefix("callable:").trim() + val name = Name.identifier(fullName.substringAfterLast("/")) + val fqName = FqName(fullName.substringBeforeLast("/").replace('/', '.')) + CallableData(fqName, name) + } + else -> error("Invalid symbol") + } + } +} diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java new file mode 100644 index 00000000000..3bc22f8a6f4 --- /dev/null +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.frontend.api.symbols; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/idea-frontend-fir/testData/stdLibSymbols") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class StdlibSymbolsBuildingTestGenerated extends AbstractStdlibSymbolsBuildingTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInStdLibSymbols() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/stdLibSymbols"), Pattern.compile("^(.+)\\.txt$"), null, true); + } + + @TestMetadata("fileWalkDirectionEnum.txt") + public void testFileWalkDirectionEnum() throws Exception { + runTest("idea/idea-frontend-fir/testData/stdLibSymbols/fileWalkDirectionEnum.txt"); + } + + @TestMetadata("iterator.txt") + public void testIterator() throws Exception { + runTest("idea/idea-frontend-fir/testData/stdLibSymbols/iterator.txt"); + } + + @TestMetadata("listOf.txt") + public void testListOf() throws Exception { + runTest("idea/idea-frontend-fir/testData/stdLibSymbols/listOf.txt"); + } +} diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/testUtils.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/testUtils.kt new file mode 100644 index 00000000000..62197bc0007 --- /dev/null +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/testUtils.kt @@ -0,0 +1,8 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.frontend.api.symbols + +