[Analysis API Standalone] extract test logic for a test against the stdlib to a base classes

It will be reused in a Kotlin/Native resolution test in the following commit

^KT-63126
This commit is contained in:
Ilya Kirillov
2023-11-06 14:47:06 +01:00
committed by Space Team
parent 6aeabc83ea
commit 63c807f7bd
3 changed files with 119 additions and 81 deletions
@@ -0,0 +1,77 @@
/*
* Copyright 2010-2023 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.analysis.api.standalone.fir.test.cases.session.builder
import org.jetbrains.kotlin.analysis.api.KtAnalysisApiInternals
import org.jetbrains.kotlin.analysis.api.analyze
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSourceModule
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import org.junit.jupiter.api.Assertions
import java.nio.file.Path
@OptIn(KtAnalysisApiInternals::class)
abstract class AbstractStandaloneSessionBuilderAgainstStdlibTest {
protected fun doTestKotlinStdLibResolve(
targetPlatform: TargetPlatform, platformStdlibPath: Path,
additionalStdlibRoots: List<Path> = emptyList(),
) {
lateinit var sourceModule: KtSourceModule
val session = buildStandaloneAnalysisAPISession {
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
buildKtModuleProvider {
platform = targetPlatform
val stdlib = addModule(
buildKtLibraryModule {
addBinaryRoot(platformStdlibPath)
addBinaryRoots(additionalStdlibRoots)
platform = targetPlatform
libraryName = "stdlib"
}
)
sourceModule = addModule(
buildKtSourceModule {
addSourceRoot(testDataPath("stdlibFunctionUsage"))
addRegularDependency(stdlib)
platform = targetPlatform
moduleName = "source"
}
)
}
}
val ktFile = session.modulesWithFiles.getValue(sourceModule).single() as KtFile
// call
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
ktCallExpression.assertIsCallOf(CallableId(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, Name.identifier("listOf")))
// builtin type
val typeReference = ktFile.findDescendantOfType<KtNamedFunction>()!!.typeReference!!
typeReference.assertIsReferenceTo(StandardClassIds.Unit)
}
private fun KtTypeReference.assertIsReferenceTo(classId: ClassId) {
analyze(this) {
val actualClassId = getKtType().expandedClassSymbol?.classIdIfNonLocal
Assertions.assertEquals(classId, actualClassId)
}
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2023 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.analysis.api.standalone.fir.test.cases.session.builder
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.utils.PathUtil
import org.junit.Test
import java.nio.file.Paths
class StandaloneSessionBuilderAgainstStdlibTest : AbstractStandaloneSessionBuilderAgainstStdlibTest() {
@Test
fun testKotlinStdlibJvm() {
doTestKotlinStdLibResolve(JvmPlatforms.defaultJvmPlatform, PathUtil.kotlinPathsForDistDirectory.stdlibPath.toPath())
}
@Test
fun testKotlinStdLibCommon() {
doTestKotlinStdLibResolve(CommonPlatforms.defaultCommonPlatform, Paths.get("dist/common/kotlin-stdlib-common.jar"))
}
@Test
fun testKotlinStdLibJs() {
doTestKotlinStdLibResolve(JsPlatforms.defaultJsPlatform, PathUtil.kotlinPathsForDistDirectory.jsStdLibKlibPath.toPath())
}
@Test
fun testKotlinStdLibJsWithInvalidKlib() {
doTestKotlinStdLibResolve(
JsPlatforms.defaultJsPlatform,
PathUtil.kotlinPathsForDistDirectory.jsStdLibKlibPath.toPath(),
additionalStdlibRoots = listOf(
Paths.get(System.getProperty("java.home")), // directory which exists and does not contain KLibs inside
PathUtil.kotlinPathsForDistDirectory.stdlibPath.toPath(), // file which exists and not a KLib
)
)
}
}
@@ -15,30 +15,23 @@ import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.KtAlwaysAccessibleLifetimeTokenProvider
import org.jetbrains.kotlin.analysis.api.standalone.buildStandaloneAnalysisAPISession
import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.analysis.project.structure.KtSourceModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtLibraryModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSdkModule
import org.jetbrains.kotlin.analysis.project.structure.builder.buildKtSourceModule
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.platform.CommonPlatforms
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.js.JsPlatforms
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtTypeReference
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import org.jetbrains.kotlin.utils.PathUtil
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import java.nio.file.Path
import java.nio.file.Paths
@OptIn(KtAnalysisApiInternals::class)
@@ -112,33 +105,6 @@ class StandaloneSessionBuilderTest {
ktCallExpression.assertIsCallOf(CallableId(FqName("commonKLib"), Name.identifier("commonKLibFunction")))
}
@Test
fun testKotlinStdlibJvm() {
doTestKotlinStdLibResolve(JvmPlatforms.defaultJvmPlatform, PathUtil.kotlinPathsForDistDirectory.stdlibPath.toPath())
}
@Test
fun testKotlinStdLibCommon() {
doTestKotlinStdLibResolve(CommonPlatforms.defaultCommonPlatform, Paths.get("dist/common/kotlin-stdlib-common.jar"))
}
@Test
fun testKotlinStdLibJs() {
doTestKotlinStdLibResolve(JsPlatforms.defaultJsPlatform, PathUtil.kotlinPathsForDistDirectory.jsStdLibKlibPath.toPath())
}
@Test
fun testKotlinStdLibJsWithInvalidKlib() {
doTestKotlinStdLibResolve(
JsPlatforms.defaultJsPlatform,
PathUtil.kotlinPathsForDistDirectory.jsStdLibKlibPath.toPath(),
additionalStdlibRoots = listOf(
Paths.get(System.getProperty("java.home")), // directory which exists and does not contain KLibs inside
PathUtil.kotlinPathsForDistDirectory.stdlibPath.toPath(), // file which exists and not a KLib
)
)
}
@Test
fun testKotlinSourceModuleSessionBuilder() {
lateinit var sourceModule: KtSourceModule
@@ -168,51 +134,4 @@ class StandaloneSessionBuilderTest {
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
ktCallExpression.assertIsCallOf(CallableId(FqName.ROOT, Name.identifier("foo")))
}
private fun doTestKotlinStdLibResolve(
targetPlatform: TargetPlatform, platformStdlibPath: Path,
additionalStdlibRoots: List<Path> = emptyList(),
) {
lateinit var sourceModule: KtSourceModule
val session = buildStandaloneAnalysisAPISession {
registerProjectService(KtLifetimeTokenProvider::class.java, KtAlwaysAccessibleLifetimeTokenProvider())
buildKtModuleProvider {
platform = targetPlatform
val stdlib = addModule(
buildKtLibraryModule {
addBinaryRoot(platformStdlibPath)
addBinaryRoots(additionalStdlibRoots)
platform = targetPlatform
libraryName = "stdlib"
}
)
sourceModule = addModule(
buildKtSourceModule {
addSourceRoot(testDataPath("stdlibFunctionUsage"))
addRegularDependency(stdlib)
platform = targetPlatform
moduleName = "source"
}
)
}
}
val ktFile = session.modulesWithFiles.getValue(sourceModule).single() as KtFile
// call
val ktCallExpression = ktFile.findDescendantOfType<KtCallExpression>()!!
ktCallExpression.assertIsCallOf(CallableId(StandardNames.COLLECTIONS_PACKAGE_FQ_NAME, Name.identifier("listOf")))
// builtin type
val typeReference = ktFile.findDescendantOfType<KtNamedFunction>()!!.typeReference!!
typeReference.assertIsReferenceTo(StandardClassIds.Unit)
}
private fun KtTypeReference.assertIsReferenceTo(classId: ClassId) {
analyze(this) {
val actualClassId = getKtType().expandedClassSymbol?.classIdIfNonLocal
Assertions.assertEquals(classId, actualClassId)
}
}
}