FIR IDE: abstract low-level-api from dependency on idea

This commit is contained in:
Ilya Kirillov
2021-06-18 17:02:25 +02:00
parent a483098303
commit 75331b3448
140 changed files with 10894 additions and 6709 deletions
+1
View File
@@ -880,6 +880,7 @@ tasks {
":idea:idea-frontend-api:test",
":idea:idea-frontend-fir:test",
":idea:idea-frontend-fir:idea-fir-low-level-api:test",
":idea:idea-frontend-fir:idea-fir-low-level-api:test-ide-impl",
":plugins:uast-kotlin-fir:test",
":idea:idea-fir-fe10-binding:test"
)
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// FILE: foo/Some.java
package foo;
@@ -0,0 +1,10 @@
/*
* Copyright 2010-2021 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.analyzer
interface ModuleSourceInfoBase: ModuleInfo
interface SdkInfoBase: ModuleInfo
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// FIR_IDENTICAL
// Error: name should present
enum class<!SYNTAX!><!>(val rgb : Int) {
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// FIR_IDE_IGNORE
enum class<!SYNTAX!><!> {
}
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// SKIP_JAVAC
// FILE: JavaClass.java
public class JavaClass {
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// SKIP_JAVAC
// FILE: A.java
public class A {
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// FIR_IDENTICAL
// FILE: a/b.java
package a;
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// FIR_IDENTICAL
// FILE: foo/a/b.java
package foo.a;
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// FIR_IDENTICAL
// FILE: a/b/c.java
package a.b;
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// FIR_IDENTICAL
// FILE: a/b.java
package a;
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// WITH_RUNTIME
// FULL_JDK
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// WITH_RUNTIME
// FULL_JDK
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// WITH_RUNTIME
// FULL_JDK
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// WITH_RUNTIME
// FULL_JDK
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// WITH_RUNTIME
// FULL_JDK
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// WITH_RUNTIME
// FULL_JDK
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// JAVAC_EXPECTED_FILE
// FILE: KotlinFile.kt
fun foo(javaClass: JavaClass<String>): String {
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// JAVAC_EXPECTED_FILE
// FILE: KotlinFile.kt
fun foo(javaClass: JavaClass): String {
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// JAVAC_EXPECTED_FILE
// FILE: KotlinFile.kt
fun foo(javaClass: JavaClass<Int>) {
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// !JDK_KIND: MODIFIED_MOCK_JDK
abstract class A : Throwable(1.0) {}
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// !API_VERSION: 1.5
// !LANGUAGE: -JvmRecordSupport
// SKIP_TXT
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// !API_VERSION: 1.5
// !LANGUAGE: +JvmRecordSupport
// FILE: MyRecord.java
@@ -106,14 +106,14 @@ class FirFrontendFacade(
return FirOutputArtifactImpl(session, filesMap, firAnalyzerFacade)
}
}
private fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
return when {
isJvm() -> JvmPlatformAnalyzerServices
isJs() -> JsPlatformAnalyzerServices
isNative() -> NativePlatformAnalyzerServices
isCommon() -> CommonPlatformAnalyzerServices
else -> error("Unknown target platform: $this")
}
fun TargetPlatform.getAnalyzerServices(): PlatformDependentAnalyzerServices {
return when {
isJvm() -> JvmPlatformAnalyzerServices
isJs() -> JsPlatformAnalyzerServices
isNative() -> NativePlatformAnalyzerServices
isCommon() -> CommonPlatformAnalyzerServices
else -> error("Unknown target platform: $this")
}
}
@@ -49,7 +49,7 @@ abstract class AbstractKotlinCompilerTest {
}
}
private val configuration: TestConfigurationBuilder.() -> Unit = {
protected val configuration: TestConfigurationBuilder.() -> Unit = {
assertions = JUnit5Assertions
defaultConfiguration()
configure(this)
@@ -60,6 +60,7 @@ import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -272,6 +273,10 @@ public class KotlinTestUtils {
assertEqualsToFile(expectedFile, afterText);
}
public static void assertEqualsToFile(@NotNull Path expectedFile, @NotNull String actual) {
assertEqualsToFile(expectedFile.toFile(), actual);
}
public static void assertEqualsToFile(@NotNull File expectedFile, @NotNull String actual) {
assertEqualsToFile(expectedFile, actual, s -> s);
}
@@ -1,4 +1,3 @@
// FIR_IDE_IGNORE
// SKIP_TXT
// FILE: functions.kt
+1
View File
@@ -81,6 +81,7 @@ val generateTests by generator("org.jetbrains.kotlin.generators.tests.GenerateTe
if (kotlinBuildProperties.getOrNull("attachedIntellijVersion") == null) {
dependsOn(":generators:idea-generator:generateIdeaTests")
}
dependsOn(":generators:frontend-api-generator:generateFrontendApiTests")
}
val generateProtoBuf by generator("org.jetbrains.kotlin.generators.protobuf.GenerateProtoBufKt", protobufSourceSet)
@@ -0,0 +1,24 @@
plugins {
kotlin("jvm")
id("jps-compatible")
}
sourceSets {
"main" { java.srcDirs("main") }
"test" { projectDefault() }
}
dependencies {
compile(kotlinStdlib("jdk8"))
testCompile(projectTests(":generators:test-generator"))
testCompile(projectTests(":plugins:parcelize:parcelize-ide"))
testCompile(projectTests(":kotlinx-serialization-ide-plugin"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":compiler:tests-spec"))
testCompile(projectTests(":idea:idea-frontend-fir:idea-fir-low-level-api"))
testCompile(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) }
testApiJUnit5()
}
val generateFrontendApiTests by generator("org.jetbrains.kotlin.generators.tests.frontend.api.GenerateTestsKt")
@@ -0,0 +1,98 @@
/*
* Copyright 2010-2021 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.generators.tests.frontend.api
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyBodiesCalculatorTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyDeclarationResolveTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirOnAirResolveTest
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractPartialRawFirBuilderTestCase
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractDiagnosticTraversalCounterTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractFirContextCollectionTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based.AbstractDiagnosisCompilerTestDataSpecTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based.AbstractDiagnosisCompilerTestDataTest
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.AbstractFileStructureTest
import org.jetbrains.kotlin.spec.utils.GeneralConfiguration
import org.jetbrains.kotlin.spec.utils.tasks.detectDirsWithTestsMapFileOnly
import org.jetbrains.kotlin.test.generators.generateTestGroupSuiteWithJUnit5
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
val excludedFirTestdataPattern = "^(.+)\\.fir\\.kts?\$"
generateTestGroupSuiteWithJUnit5(args) {
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "compiler/fir/raw-fir/psi2fir/testData") {
testClass<AbstractFirLazyBodiesCalculatorTest> {
model("rawBuilder", testMethod = "doTest")
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "idea/idea-frontend-fir/idea-fir-low-level-api/testdata") {
testClass<AbstractFirOnAirResolveTest> {
model("onAirResolve")
}
testClass<AbstractFirLazyDeclarationResolveTest> {
model("lazyResolve")
}
testClass<AbstractFileStructureTest> {
model("fileStructure")
}
testClass<AbstractFirContextCollectionTest> {
model("fileStructure")
}
testClass<AbstractDiagnosticTraversalCounterTest> {
model("diagnosticTraversalCounter")
}
testClass<AbstractPartialRawFirBuilderTestCase> {
model("partialRawBuilder", testMethod = "doRawFirTest")
}
}
testGroup(
"idea/idea-frontend-fir/idea-fir-low-level-api/tests",
"compiler/fir/analysis-tests/testData",
) {
testClass<AbstractDiagnosisCompilerTestDataTest>(suiteTestClassName = "DiagnosisCompilerFirTestdataTestGenerated") {
model("resolve", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
model("resolveWithStdlib", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
}
}
testGroup(
"idea/idea-frontend-fir/idea-fir-low-level-api/tests",
"compiler/testData",
) {
testClass<AbstractDiagnosisCompilerTestDataTest>(suiteTestClassName = "DiagnosisCompilerTestFE10TestdataTestGenerated") {
model(
"diagnostics/tests",
excludedPattern = excludedFirTestdataPattern,
)
model(
"diagnostics/testsWithStdLib",
excludedPattern = excludedFirTestdataPattern,
excludeDirs = listOf("native")
)
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", testDataRoot = GeneralConfiguration.SPEC_TESTDATA_PATH) {
testClass<AbstractDiagnosisCompilerTestDataSpecTest>(suiteTestClassName = "FirIdeSpecTest") {
model(
"diagnostics",
excludeDirs = listOf("helpers") + detectDirsWithTestsMapFileOnly("diagnostics"),
excludedPattern = excludedFirTestdataPattern,
)
}
}
}
}
@@ -15,6 +15,7 @@ dependencies {
testCompile(projectTests(":idea:idea-fir-performance-tests"))
testCompile(projectTests(":idea:idea-frontend-fir"))
testCompile(projectTests(":idea:idea-frontend-fir:idea-fir-low-level-api"))
testCompile(projectTests(":idea:idea-frontend-fir:fir-low-level-api-ide-impl"))
testCompile(projectTests(":idea:idea-fir-fe10-binding"))
testCompile(projectTests(":j2k"))
testCompile(projectTests(":nj2k"))
@@ -35,6 +36,7 @@ dependencies {
testCompile(projectTests(":kotlinx-serialization-ide-plugin"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":compiler:tests-spec"))
testApiJUnit5()
}
val generateIdeaTests by generator("org.jetbrains.kotlin.generators.tests.idea.GenerateTestsKt")
@@ -87,11 +87,8 @@ import org.jetbrains.kotlin.idea.fir.inspections.AbstractHLInspectionTest
import org.jetbrains.kotlin.idea.fir.inspections.AbstractHLLocalInspectionTest
import org.jetbrains.kotlin.idea.fir.intentions.AbstractHLIntentionTest
import org.jetbrains.kotlin.idea.fir.low.level.api.*
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractDiagnosticTraversalCounterTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractFirContextCollectionTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based.AbstractDiagnosisCompilerTestDataSpecTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.compiler.based.AbstractDiagnosisCompilerTestDataTest
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyTest
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.AbstractFileStructureTest
import org.jetbrains.kotlin.idea.fir.low.level.api.resolve.AbstractInnerDeclarationsResolvePhaseTest
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.AbstractSessionsInvalidationTest
@@ -109,6 +106,9 @@ import org.jetbrains.kotlin.idea.fir.frontend.api.symbols.AbstractSymbolByFqName
import org.jetbrains.kotlin.idea.fir.frontend.api.symbols.AbstractSymbolByPsiTest
import org.jetbrains.kotlin.idea.fir.frontend.api.symbols.AbstractSymbolByReferenceTest
import org.jetbrains.kotlin.idea.fir.inspections.AbstractFe10BindingIntentionTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractDiagnosticTraversalCounterTest
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostic.AbstractFirContextCollectionTest
//import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyTest
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyTest
import org.jetbrains.kotlin.idea.hierarchy.AbstractHierarchyWithLibTest
import org.jetbrains.kotlin.idea.highlighter.*
@@ -183,9 +183,11 @@ import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationPluginIdeDi
import org.jetbrains.kotlinx.serialization.idea.AbstractSerializationQuickFixTest
import org.jetbrains.uast.test.kotlin.*
import org.jetbrains.kotlin.spec.utils.tasks.detectDirsWithTestsMapFileOnly
import org.jetbrains.kotlin.test.generators.generateTestGroupSuiteWithJUnit5
fun main(args: Array<String>) {
System.setProperty("java.awt.headless", "true")
generateTestGroupSuite(args) {
val excludedFirTestdataPattern = "^(.+)\\.fir\\.kts?\$"
@@ -1047,100 +1049,21 @@ fun main(args: Array<String>) {
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "idea/testData") {
testClass<AbstractFirLazyResolveTest> {
model("fir/lazyResolve", extension = "test", singleClass = true, filenameStartsLowerCase = true)
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "compiler/fir/raw-fir/psi2fir/testData") {
testClass<AbstractFirLazyBodiesCalculatorTest> {
model("rawBuilder", testMethod = "doTest")
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", "idea/idea-frontend-fir/idea-fir-low-level-api/testdata") {
testClass<AbstractFirMultiModuleLazyResolveTest> {
model("multiModuleLazyResolve", recursive = false, extension = null)
}
testClass<AbstractFirSealedInheritorsTest> {
model("resolveSealed", recursive = false, extension = null)
}
testClass<AbstractFirOnAirResolveTest> {
model("onAirResolve")
}
testClass<AbstractFirLazyDeclarationResolveTest> {
model("lazyResolve")
}
testClass<AbstractFirLibraryModuleDeclarationResolveTest> {
model("libraryModuleResolve", recursive = false)
}
testGroup("idea/idea-frontend-fir/fir-low-level-api-ide-impl/tests", "idea/idea-frontend-fir/idea-fir-low-level-api/testdata") {
testClass<AbstractProjectWideOutOfBlockKotlinModificationTrackerTest> {
model("outOfBlockProjectWide")
}
testClass<AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyTest> {
model("outOfBlockProjectWide")
}
testClass<AbstractFileStructureTest> {
model("fileStructure")
}
testClass<AbstractFirContextCollectionTest> {
model("fileStructure")
}
testClass<AbstractDiagnosticTraversalCounterTest> {
model("diagnosticTraversalCounter")
}
//
// testClass<AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyTest> {
// model("outOfBlockProjectWide")
// }
testClass<AbstractSessionsInvalidationTest> {
model("sessionInvalidation", recursive = false, extension = null)
}
testClass<AbstractInnerDeclarationsResolvePhaseTest> {
model("innerDeclarationsResolve")
}
testClass<AbstractPartialRawFirBuilderTestCase> {
model("partialRawBuilder", testMethod = "doRawFirTest")
}
}
testGroup(
"idea/idea-frontend-fir/idea-fir-low-level-api/tests",
"compiler/fir/analysis-tests/testData",
) {
testClass<AbstractDiagnosisCompilerTestDataTest>(suiteTestClassName = "DiagnosisCompilerFirTestdataTestGenerated") {
model("resolve", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME)
model("resolveWithStdlib", pattern = TestGeneratorUtil.KT_WITHOUT_DOTS_IN_NAME, )
}
}
testGroup(
"idea/idea-frontend-fir/idea-fir-low-level-api/tests",
"compiler/testData",
) {
testClass<AbstractDiagnosisCompilerTestDataTest>(suiteTestClassName = "DiagnosisCompilerTestFE10TestdataTestGenerated") {
model(
"diagnostics/tests",
excludedPattern = excludedFirTestdataPattern,
)
model(
"diagnostics/testsWithStdLib",
excludedPattern = excludedFirTestdataPattern,
excludeDirs = listOf("native")
)
}
}
testGroup("idea/idea-frontend-fir/idea-fir-low-level-api/tests", testDataRoot = GeneralConfiguration.SPEC_TESTDATA_PATH
) {
testClass<AbstractDiagnosisCompilerTestDataSpecTest>(suiteTestClassName = "FirIdeSpecTest") {
model(
"diagnostics",
excludeDirs = listOf("helpers") + detectDirsWithTestsMapFileOnly("diagnostics"),
excludedPattern = excludedFirTestdataPattern,
)
}
}
testGroup("idea/idea-fir/tests", "idea") {
testClass<AbstractFirHighlightingTest> {
model("testData/highlighter")
@@ -41,7 +41,11 @@ open class SimpleTestMethodModel(
val found = matcher.find()
assert(found) { file.name + " isn't matched by regex " + filenamePattern.pattern() }
assert(matcher.groupCount() >= 1) { filenamePattern.pattern() }
val extractedName = matcher.group(1) ?: error("extractedName should not be null: " + filenamePattern.pattern())
val extractedName = try {
matcher.group(1) ?: error("extractedName should not be null: " + filenamePattern.pattern())
} catch (e: Throwable) {
throw IllegalStateException("Error generating test ${file.name}", e)
}
val unescapedName = if (rootDir == file.parentFile) {
extractedName
} else {
@@ -191,7 +191,7 @@ internal fun TargetPlatform.canDependOn(other: IdeaModuleInfo, isHmppEnabled: Bo
}
}
interface ModuleSourceInfo : IdeaModuleInfo, TrackableModuleInfo {
interface ModuleSourceInfo : IdeaModuleInfo, TrackableModuleInfo, ModuleSourceInfoBase {
val module: Module
override val expectedBy: List<ModuleSourceInfo>
@@ -418,7 +418,7 @@ data class LibrarySourceInfo(override val project: Project, val library: Library
}
//TODO: (module refactoring) there should be separate SdkSourceInfo but there are no kotlin source in existing sdks for now :)
data class SdkInfo(override val project: Project, val sdk: Sdk) : IdeaModuleInfo {
data class SdkInfo(override val project: Project, val sdk: Sdk) : IdeaModuleInfo, SdkInfoBase {
override val moduleOrigin: ModuleOrigin
get() = ModuleOrigin.LIBRARY
@@ -442,8 +442,8 @@ data class SdkInfo(override val project: Project, val sdk: Sdk) : IdeaModuleInfo
override val capabilities: Map<ModuleCapability<*>, Any?>
get() = when (this.sdk.sdkType) {
is JavaSdk -> super.capabilities + mapOf(JDK_CAPABILITY to true)
else -> super.capabilities
is JavaSdk -> super<IdeaModuleInfo>.capabilities + mapOf(JDK_CAPABILITY to true)
else -> super<IdeaModuleInfo>.capabilities
}
}
@@ -1,20 +0,0 @@
/*
* 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.trackers
import com.intellij.openapi.module.Module
import com.intellij.openapi.util.ModificationTracker
class KotlinFE10OutOfBlockModificationTracker : KotlinOutOfBlockModificationTrackerFactory() {
override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker =
throwUnsupportedError()
override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: Module): ModificationTracker =
throwUnsupportedError()
private fun throwUnsupportedError(): Nothing =
error("Supported only for FIR plugin now, sorry, consider using KotlinModificationTrackerService instead")
}
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.fir.fe10.*
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EntityWasGarbageCollectedException
@@ -26,7 +27,6 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
import java.lang.ref.WeakReference
interface FE10BindingContext {
@@ -17,11 +17,12 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiModificationTracker
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.fir.HLIndexHelper
import org.jetbrains.kotlin.idea.fir.api.fixes.diagnosticFixFactory
import org.jetbrains.kotlin.idea.fir.low.level.api.util.createScopeForModuleLibraries
import org.jetbrains.kotlin.idea.fir.low.level.api.api.stateConfigurator
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
import org.jetbrains.kotlin.idea.frontend.api.fir.diagnostics.KtFirDiagnostic
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.addImportToFile
@@ -149,8 +150,11 @@ internal class ImportQuickFix(
}
private fun createSearchScope(element: PsiElement): GlobalSearchScope {
val contentScope = element.getModuleInfo().contentScope()
val librariesScope = element.module?.let(::createScopeForModuleLibraries)
val moduleInfo = element.getModuleInfo()
val contentScope = moduleInfo.contentScope()
//todo do not use internal stateConfigurator here
val librariesScope = element.module?.project?.stateConfigurator
?.createScopeForModuleLibraries(moduleInfo as ModuleSourceInfoBase)
?: GlobalSearchScope.EMPTY_SCOPE
return contentScope.uniteWith(librariesScope)
+2
View File
@@ -11,6 +11,8 @@ dependencies {
compileOnly(project(":core:compiler.common"))
compileOnly(project(":core:compiler.common.jvm"))
compileOnly(project(":idea:idea-frontend-independent"))
compileOnly(project(":idea:idea-frontend-fir:idea-fir-low-level-api"))
compileOnly(project(":idea:idea-frontend-independent"))
compileOnly(intellijCoreDep())
compileOnly(intellijDep())
compileOnly(intellijPluginDep("java")) { includeJars("java-api", "java-impl") }
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.idea.frontend.api.tokens
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createProjectWideOutOfBlockModificationTracker
import kotlin.reflect.KClass
class AlwaysAccessibleValidityToken(project: Project) : ValidityToken() {
@@ -7,8 +7,8 @@ package org.jetbrains.kotlin.idea.frontend.api.tokens
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.frontend.api.*
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
import kotlin.reflect.KClass
class ReadActionConfinementValidityToken(project: Project) : ValidityToken() {
+1
View File
@@ -18,6 +18,7 @@ dependencies {
compile(project(":compiler:fir:java"))
compile(project(":compiler:fir:jvm"))
compile(project(":idea:idea-frontend-fir:idea-fir-low-level-api"))
compile(project(":idea:idea-frontend-fir:fir-low-level-api-ide-impl"))
compile(intellijDep())
compile(intellijCoreDep())
@@ -0,0 +1,66 @@
plugins {
kotlin("jvm")
id("jps-compatible")
}
dependencies {
compile(project(":compiler:psi"))
compile(project( ":idea:idea-frontend-fir:idea-fir-low-level-api"))
compile(project(":idea:idea-frontend-independent"))
compile(project(":idea:idea-frontend-api"))
compile(project(":idea:idea-core"))
compile(project(":compiler:fir:fir2ir"))
compile(project(":compiler:fir:fir2ir:jvm-backend"))
compile(project(":compiler:ir.serialization.common"))
compile(project(":compiler:fir:resolve"))
compile(project(":compiler:fir:checkers"))
compile(project(":compiler:fir:checkers:checkers.jvm"))
compile(project(":compiler:fir:java"))
compile(project(":compiler:fir:jvm"))
implementation(project(":compiler:ir.psi2ir"))
implementation(project(":compiler:fir:entrypoint"))
compile(intellijDep())
compile(intellijCoreDep())
// <temp>
compile(project(":idea:idea-core"))
// </temp>
// <neededFor>`AbstractFirLazyResolveTest` uses fir implementation of references which are not in classpath otherwise
testRuntimeOnly(project(":idea:idea-frontend-fir"))
// </neededFor>
testCompile(projectTests(":compiler:test-infrastructure-utils"))
testCompile(projectTests(":compiler:test-infrastructure"))
testCompile(projectTests(":compiler:tests-common-new"))
testImplementation("org.opentest4j:opentest4j:1.2.0")
testCompile(toolsJar())
testCompile(projectTests(":idea"))
testCompile(project(":idea:idea-fir"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":compiler:fir:analysis-tests:legacy-fir-tests"))
testCompile(projectTests(":idea:idea-test-framework"))
testCompile(project(":kotlin-test:kotlin-test-junit"))
testCompile(commonDep("junit:junit"))
compile(intellijPluginDep("java"))
}
sourceSets {
"main" { projectDefault() }
"test" { projectDefault() }
}
projectTest(parallel = true ) {
dependsOn(":dist")
workingDir = rootDir
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
doFirst {
if (!useFirIdeaPlugin) {
error("Test task in the module should be executed with -Pidea.fir.plugin=true")
}
}
}
testsJar()
@@ -1,15 +1,16 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 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.fir.low.level.api
package org.jetbrains.kotlin.idea.fir.low.level.api.ide
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.stubs.StubIndex
import com.intellij.psi.stubs.StubIndexKey
import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProvider
import org.jetbrains.kotlin.idea.stubindex.*
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
@@ -0,0 +1,108 @@
/*
* Copyright 2010-2021 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.fir.low.level.api.ide
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.LibraryModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.analyzer.SdkInfoBase
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.DependencyListForCliModule
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.idea.caches.project.ModuleProductionSourceScope
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.caches.project.SdkInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceChecker
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveStateConfigurator
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.psi.KtElement
import java.nio.file.Path
import java.nio.file.Paths
class FirModuleResolveStateConfiguratorIdeImpl(private val project: Project) : FirModuleResolveStateConfigurator() {
override fun createDeclarationProvider(scope: GlobalSearchScope): DeclarationProvider =
DeclarationProviderByIndexesImpl(project, scope)
override fun createPackageExistingCheckerForModule(moduleInfo: ModuleInfo): PackageExistenceChecker =
PackageExistenceCheckerIdeImpl(project, moduleInfo)
override fun createPackagePartsProvider(scope: GlobalSearchScope): PackagePartProvider =
IDEPackagePartProvider(scope)
override fun createModuleDataProvider(moduleInfo: ModuleSourceInfoBase): ModuleDataProvider {
return DependencyListForCliModule.build(
moduleInfo.name,
moduleInfo.platform,
moduleInfo.analyzerServices
) {
dependencies(moduleInfo.dependenciesWithoutSelf().extractLibraryPaths(project))
friendDependencies(moduleInfo.modulesWhoseInternalsAreVisible().extractLibraryPaths(project))
dependsOnDependencies(moduleInfo.expectedBy.extractLibraryPaths(project))
}.moduleDataProvider
}
private fun Sequence<ModuleInfo>.extractLibraryPaths(project: Project): List<Path> {
return fold(mutableListOf()) { acc, moduleInfo ->
moduleInfo.extractLibraryPaths(acc)
acc
}
}
private fun Iterable<ModuleInfo>.extractLibraryPaths(project: Project): List<Path> {
return fold(mutableListOf()) { acc, moduleInfo ->
moduleInfo.extractLibraryPaths(acc)
acc
}
}
private fun ModuleInfo.extractLibraryPaths(destination: MutableList<Path>) {
when (this) {
is SdkInfoBase -> {
val sdk = (this as SdkInfo).sdk
sdk.rootProvider.getFiles(OrderRootType.CLASSES).mapNotNullTo(destination) {
Paths.get(it.fileSystem.extractPresentableUrl(it.path)).normalize()
}
}
is LibraryModuleInfo -> {
getLibraryRoots().mapTo(destination) {
Paths.get(it).normalize()
}
}
}
}
override fun getLanguageVersionSettings(moduleInfo: ModuleSourceInfoBase): LanguageVersionSettings {
require(moduleInfo is ModuleSourceInfo)
return moduleInfo.module.languageVersionSettings
}
override fun getModuleSourceScope(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope {
require(moduleInfo is ModuleSourceInfo)
return ModuleProductionSourceScope(moduleInfo.module)
}
override fun createScopeForModuleLibraries(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope {
require(moduleInfo is ModuleSourceInfo)
return ModuleLibrariesSearchScope(moduleInfo.module)
}
override fun createSealedInheritorsProvider(): SealedClassInheritorsProvider {
return SealedClassInheritorsProviderIdeImpl()
}
override fun getModuleInfoFor(element: KtElement): ModuleInfo {
return element.getModuleInfo()
}
}
@@ -1,9 +1,9 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 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.fir.low.level.api.util
package org.jetbrains.kotlin.idea.fir.low.level.api.ide
import com.intellij.openapi.module.Module
import com.intellij.openapi.roots.JdkOrderEntry
@@ -14,7 +14,8 @@ import com.intellij.openapi.util.Comparing
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.search.GlobalSearchScope
private class ModuleLibrariesSearchScope(module: Module) : GlobalSearchScope(module.project) {
internal class ModuleLibrariesSearchScope(module: Module) : GlobalSearchScope(module.project) {
private val projectFileIndex = ProjectRootManager.getInstance(module.project).fileIndex
private val moduleFileIndex = ModuleRootManager.getInstance(module).fileIndex
@@ -33,6 +34,4 @@ private class ModuleLibrariesSearchScope(module: Module) : GlobalSearchScope(mod
override fun isSearchInModuleContent(aModule: Module): Boolean = false
override fun isSearchInLibraries(): Boolean = true
}
fun createScopeForModuleLibraries(module: Module): GlobalSearchScope = ModuleLibrariesSearchScope(module)
}
@@ -0,0 +1,17 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.ide
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.idea.caches.resolve.IdePackageOracleFactory
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceChecker
import org.jetbrains.kotlin.name.FqName
internal class PackageExistenceCheckerIdeImpl(
project: Project,
module: ModuleInfo
) : PackageExistenceChecker() {
private val oracle = project.service<IdePackageOracleFactory>().createOracle(module)
override fun isPackageExists(packageFqName: FqName): Boolean = oracle.packageExists(packageFqName)
}
@@ -3,7 +3,7 @@
* 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.fir.low.level.api
package org.jetbrains.kotlin.idea.fir.low.level.api.ide
import com.intellij.openapi.module.Module
import com.intellij.psi.JavaDirectoryService
@@ -16,14 +16,16 @@ import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.idea.core.util.toPsiFile
import org.jetbrains.kotlin.idea.util.classIdIfNonLocal
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.psi.KtClass
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
import java.util.concurrent.ConcurrentHashMap
class SealedClassInheritorsProviderIdeImpl : SealedClassInheritorsProvider() {
internal class SealedClassInheritorsProviderIdeImpl : SealedClassInheritorsProvider() {
val cache = ConcurrentHashMap<ClassId, List<ClassId>>()
@OptIn(SealedClassInheritorsProviderInternals::class)
@@ -23,7 +23,7 @@ import com.intellij.psi.impl.source.tree.FileElement
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingInBodyDeclarationWith
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileElementFactory
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.isReanalyzableContainer
import org.jetbrains.kotlin.idea.util.module
internal class KotlinFirModificationTrackerService(project: Project) : Disposable {
@@ -140,7 +140,7 @@ internal class KotlinFirModificationTrackerService(project: Project) : Disposabl
return true
}
val container = psi.getNonLocalContainingInBodyDeclarationWith() ?: return true
return !FileElementFactory.isReanalyzableContainer(container)
return !isReanalyzableContainer(container)
}
}
}
@@ -10,14 +10,23 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.ModificationTracker
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.trackers.KotlinOutOfBlockModificationTrackerFactory
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.api.KotlinOutOfBlockModificationTrackerFactory
class KotlinFirOutOfBlockModificationTrackerFactory(private val project: Project) : KotlinOutOfBlockModificationTrackerFactory() {
override fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker =
KotlinFirOutOfBlockModificationTracker(project)
override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(module: Module): ModificationTracker =
KotlinFirOutOfBlockModuleModificationTracker(module)
override fun createModuleWithoutDependenciesOutOfBlockModificationTracker(moduleInfo: ModuleSourceInfoBase): ModificationTracker {
require(moduleInfo is ModuleSourceInfo)
return KotlinFirOutOfBlockModuleModificationTracker(moduleInfo.module)
}
override fun createLibraryOutOfBlockModificationTracker(): ModificationTracker {
return LibraryModificationTracker.getInstance(project)
}
@TestOnly
fun incrementModificationsCount() {
@@ -0,0 +1,111 @@
///*
// * Copyright 2010-2021 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.fir.low.level.api.file.structure
//
//import com.intellij.openapi.util.io.FileUtil
//import com.intellij.psi.PsiDocumentManager
//import com.intellij.psi.PsiWhiteSpace
//import com.intellij.psi.util.parentOfType
//import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveStateImpl
//import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
//import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
//import org.jetbrains.kotlin.idea.fir.low.level.api.trackers.AbstractProjectWideOutOfBlockKotlinModificationTrackerTest
//import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
//import org.jetbrains.kotlin.psi.KtElement
//import org.jetbrains.kotlin.psi.KtFile
//import org.jetbrains.kotlin.test.InTextDirectivesUtils
//import java.io.File
//
//abstract class AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyTest : KotlinLightCodeInsightFixtureTestCase() {
// override fun isFirPlugin(): Boolean = true
//
// fun doTest(path: String) {
// val testDataFile = File(path)
// val fileText = FileUtil.loadFile(testDataFile)
// val ktFile = myFixture.configureByText(testDataFile.name, fileText) as KtFile
// val textToType = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// TYPE:")
// ?: AbstractProjectWideOutOfBlockKotlinModificationTrackerTest.DEFAULT_TEXT_TO_TYPE
// val outOfBlock = InTextDirectivesUtils.getPrefixedBoolean(fileText, "// OUT_OF_BLOCK:")
// ?: error("Please, specify should out of block change happen or not by `// OUT_OF_BLOCK:` directive")
//
// val elementAtCaret = ktFile.findElementAtCaret()
//
// var fileStructureWithResolveState = getStructureElementForKtElement(elementAtCaret)
// for (i in 0..REPETITIONS_COUNT) {
// fileStructureWithResolveState = typeAndCheck(ktFile, fileStructureWithResolveState, textToType, outOfBlock)
// }
// }
//
// private fun typeAndCheck(
// ktFile: KtFile,
// fileStructureWithResolveStateBeforeTyping: FileStructureWithResolveState,
// textToType: String,
// outOfBlock: Boolean,
// ): FileStructureWithResolveState {
// val newFileStructureWithResolveState = getStateAfterTyping(textToType, ktFile)
// checkIsCorrect(newFileStructureWithResolveState, fileStructureWithResolveStateBeforeTyping, outOfBlock)
// return newFileStructureWithResolveState
// }
//
// private fun getStateAfterTyping(
// textToType: String,
// ktFile: KtFile
// ): FileStructureWithResolveState {
// myFixture.type(textToType)
// PsiDocumentManager.getInstance(project).commitAllDocuments()
//
// val newElementAtCaret = ktFile.findElementAtCaret()
// return getStructureElementForKtElement(newElementAtCaret)
// }
//
// private fun checkIsCorrect(
// newFileStructureWithResolveState: FileStructureWithResolveState,
// fileStructureWithResolveStateBeforeTyping: FileStructureWithResolveState,
// outOfBlock: Boolean
// ) {
// assertTrue(
// "Structure elements should be different after typing",
// newFileStructureWithResolveState.element !== fileStructureWithResolveStateBeforeTyping.element
// )
//
// assertEquals(
// "FirModuleResolveState should change only on out of block modification",
// outOfBlock,
// newFileStructureWithResolveState.resolveState !== fileStructureWithResolveStateBeforeTyping.resolveState
// )
// assertEquals(
// "FileStructure state should change only on out of block modification",
// outOfBlock,
// newFileStructureWithResolveState.fileStructure !== fileStructureWithResolveStateBeforeTyping.fileStructure
// )
// }
//
// private fun KtFile.findElementAtCaret(): KtElement {
// val element = when (val elementAtOffset = findElementAt(myFixture.caretOffset)) {
// is PsiWhiteSpace -> findElementAt((myFixture.caretOffset - 1).coerceAtLeast(0))
// else -> elementAtOffset
// }
// return element!!.parentOfType()!!
// }
//
// private fun getStructureElementForKtElement(element: KtElement): FileStructureWithResolveState {
// val moduleResolveState = element.getResolveState() as FirModuleResolveStateImpl
// val fileStructure =
// moduleResolveState.fileStructureCache.getFileStructure(element.containingKtFile, moduleResolveState.rootModuleSession.cache)
// val fileStructureElement = fileStructure.getStructureElementFor(element)
// return FileStructureWithResolveState(fileStructureElement, fileStructure, moduleResolveState)
// }
//
// private data class FileStructureWithResolveState(
// val element: FileStructureElement,
// val fileStructure: FileStructure,
// val resolveState: FirModuleResolveState
// )
//
// companion object {
// private const val REPETITIONS_COUNT = 3
// }
//}
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Copyright 2010-2021 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.
*/
@@ -58,7 +58,10 @@ abstract class AbstractSessionsInvalidationTest : AbstractMultiModuleTest() {
val sessionsAfterOOBM = storage.getFirSessions(rootModuleSourceInfo)
val changedSessions = Sets.symmetricDifference(initialSessions, sessionsAfterOOBM)
val changedSessionsModulesNamesSorted = changedSessions.map { it.moduleData.moduleSourceInfo.module.name }.distinct().sorted()
val changedSessionsModulesNamesSorted = changedSessions
.map { (it.moduleData.moduleSourceInfo as ModuleSourceInfo).module.name }
.distinct()
.sorted()
Assert.assertEquals(testStructure.expectedInvalidatedModules, changedSessionsModulesNamesSorted)
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2021 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.fir.low.level.api
import com.intellij.openapi.components.service
import com.intellij.openapi.module.Module
import org.jetbrains.kotlin.idea.fir.low.level.api.trackers.KotlinFirModificationTrackerService
internal fun Module.incModificationTracker() {
project.service<KotlinFirModificationTrackerService>().increaseModificationCountForModule(this)
}
@@ -8,9 +8,9 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.trackers
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiDocumentManager
import junit.framework.Assert
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
import java.io.File
abstract class AbstractProjectWideOutOfBlockKotlinModificationTrackerTest : KotlinLightCodeInsightFixtureTestCase() {
@@ -15,6 +15,10 @@ import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiManager
import com.intellij.testFramework.PsiTestUtil
import junit.framework.Assert
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.caches.project.productionSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createModuleWithoutDependenciesOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.idea.util.sourceRoots
@@ -22,9 +26,6 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.trackers.KotlinOutOfBlockModificationTrackerFactory
import org.jetbrains.kotlin.trackers.createModuleWithoutDependenciesOutOfBlockModificationTracker
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
import java.nio.file.Files
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.writeText
@@ -167,7 +168,7 @@ class KotlinModuleOutOfBlockTrackerTest : AbstractMultiModuleTest() {
}
private class ModuleWithModificationTracker(module: Module) : WithModificationTracker(
module.createModuleWithoutDependenciesOutOfBlockModificationTracker()
module.productionSourceInfo()!!.createModuleWithoutDependenciesOutOfBlockModificationTracker(module.project)
)
private class ProjectWithModificationTracker(project: Project) : WithModificationTracker(
@@ -5,9 +5,6 @@ plugins {
dependencies {
compile(project(":compiler:psi"))
compile(project(":idea:idea-frontend-independent"))
compile(project(":idea:idea-frontend-api"))
compile(project(":idea:idea-core"))
compile(project(":compiler:fir:fir2ir"))
compile(project(":compiler:fir:fir2ir:jvm-backend"))
compile(project(":compiler:ir.serialization.common"))
@@ -16,33 +13,24 @@ dependencies {
compile(project(":compiler:fir:checkers:checkers.jvm"))
compile(project(":compiler:fir:java"))
compile(project(":compiler:fir:jvm"))
compile(project(":compiler:backend.common.jvm"))
implementation(project(":compiler:ir.psi2ir"))
implementation(project(":compiler:fir:entrypoint"))
compile(intellijDep())
compile(intellijCoreDep())
// <temp>
compile(project(":idea:idea-core"))
// </temp>
// <neededFor>`AbstractFirLazyResolveTest` uses fir implementation of references which are not in classpath otherwise
testRuntimeOnly(project(":idea:idea-frontend-fir"))
// </neededFor>
compile(intellijCoreDep()) { includeJars("intellij-core", "guava", rootProject = rootProject) }
testCompile(projectTests(":compiler:test-infrastructure-utils"))
testCompile(projectTests(":compiler:test-infrastructure"))
testCompile(projectTests(":compiler:tests-common-new"))
testImplementation("org.opentest4j:opentest4j:1.2.0")
testCompile(toolsJar())
testCompile(projectTests(":idea"))
testCompile(project(":idea:idea-fir"))
testCompile(projectTests(":compiler:tests-common"))
testCompile(projectTests(":compiler:fir:analysis-tests:legacy-fir-tests"))
testCompile(projectTests(":idea:idea-test-framework"))
testCompile(project(":kotlin-test:kotlin-test-junit"))
testCompile(commonDep("junit:junit"))
compile(intellijPluginDep("java"))
testApiJUnit5()
}
sourceSets {
@@ -50,15 +38,10 @@ sourceSets {
"test" { projectDefault() }
}
projectTest(parallel = true ) {
projectTest(jUnit5Enabled = true) {
dependsOn(":dist")
workingDir = rootDir
val useFirIdeaPlugin = kotlinBuildProperties.useFirIdeaPlugin
doFirst {
if (!useFirIdeaPlugin) {
error("Test task in the module should be executed with -Pidea.fir.plugin=true")
}
}
useJUnitPlatform()
}
testsJar()
@@ -9,15 +9,15 @@ import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootModificationTracker
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSession
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProviderStorage
import org.jetbrains.kotlin.idea.util.cachedValue
import org.jetbrains.kotlin.idea.util.getValue
import org.jetbrains.kotlin.trackers.createProjectWideOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
import java.util.concurrent.ConcurrentHashMap
internal class FirIdeResolveStateService(project: Project) {
@@ -28,10 +28,10 @@ internal class FirIdeResolveStateService(project: Project) {
project.createProjectWideOutOfBlockModificationTracker(),
ProjectRootModificationTracker.getInstance(project),
) {
ConcurrentHashMap<IdeaModuleInfo, FirModuleResolveStateImpl>()
ConcurrentHashMap<ModuleInfo, FirModuleResolveStateImpl>()
}
fun getResolveState(moduleInfo: IdeaModuleInfo): FirModuleResolveStateImpl =
fun getResolveState(moduleInfo: ModuleInfo): FirModuleResolveStateImpl =
stateCache.computeIfAbsent(moduleInfo) { createResolveStateFor(moduleInfo, sessionProviderStorage) }
companion object {
@@ -39,17 +39,17 @@ internal class FirIdeResolveStateService(project: Project) {
ServiceManager.getService(project, FirIdeResolveStateService::class.java)
internal fun createResolveStateFor(
moduleInfo: IdeaModuleInfo,
moduleInfo: ModuleInfo,
sessionProviderStorage: FirIdeSessionProviderStorage,
configureSession: (FirIdeSession.() -> Unit)? = null,
): FirModuleResolveStateImpl {
if (moduleInfo !is ModuleSourceInfo) {
if (moduleInfo !is ModuleSourceInfoBase) {
error("Creating FirModuleResolveState is not yet supported for $moduleInfo")
}
val sessionProvider = sessionProviderStorage.getSessionProvider(moduleInfo, configureSession)
val firFileBuilder = sessionProvider.rootModuleSession.firFileBuilder
return FirModuleResolveStateImpl(
moduleInfo.project,
sessionProviderStorage.project,
moduleInfo,
sessionProvider,
firFileBuilder,
@@ -61,12 +61,13 @@ internal class FirIdeResolveStateService(project: Project) {
@TestOnly
fun createResolveStateForNoCaching(
moduleInfo: IdeaModuleInfo,
moduleInfo: ModuleInfo,
project: Project,
configureSession: (FirIdeSession.() -> Unit)? = null,
): FirModuleResolveState =
FirIdeResolveStateService.createResolveStateFor(
moduleInfo = moduleInfo,
sessionProviderStorage = FirIdeSessionProviderStorage(moduleInfo.project!!),
sessionProviderStorage = FirIdeSessionProviderStorage(project),
configureSession = configureSession
)
@@ -6,13 +6,13 @@
package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.InternalForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
@@ -34,11 +34,11 @@ internal class FirModuleResolveStateDepended(
) : FirModuleResolveState() {
override val project: Project get() = originalState.project
override val moduleInfo: IdeaModuleInfo get() = originalState.moduleInfo
override val moduleInfo: ModuleInfo get() = originalState.moduleInfo
override val rootModuleSession get() = originalState.rootModuleSession
private val fileStructureCache get() = originalState.fileStructureCache
override fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession =
override fun getSessionFor(moduleInfo: ModuleInfo): FirSession =
originalState.getSessionFor(moduleInfo)
override fun getOrBuildFirFor(element: KtElement): FirElement {
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.InternalForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DiagnosticCheckerFilter
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.DiagnosticsCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirElementBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration
@@ -33,12 +36,11 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSessionProvide
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
internal class FirModuleResolveStateImpl(
override val project: Project,
override val moduleInfo: IdeaModuleInfo,
override val moduleInfo: ModuleInfo,
private val sessionProvider: FirIdeSessionProvider,
val firFileBuilder: FirFileBuilder,
val firLazyDeclarationResolver: FirLazyDeclarationResolver,
@@ -55,7 +57,7 @@ internal class FirModuleResolveStateImpl(
val elementBuilder = FirElementBuilder()
private val diagnosticsCollector = DiagnosticsCollector(fileStructureCache, rootModuleSession.cache)
override fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession =
override fun getSessionFor(moduleInfo: ModuleInfo): FirSession =
sessionProvider.getSession(moduleInfo)!!
override fun getOrBuildFirFor(element: KtElement): FirElement =
@@ -92,7 +94,7 @@ internal class FirModuleResolveStateImpl(
* [ktDeclaration] should be either [KtDeclaration] or [KtLambdaExpression]
*/
private fun findSourceFirDeclarationByExpression(ktDeclaration: KtExpression): FirDeclaration {
require(ktDeclaration.getModuleInfo() is ModuleSourceInfo) {
require(ktDeclaration.getModuleInfo() is ModuleSourceInfoBase) {
"Declaration should have ModuleSourceInfo, instead it had ${ktDeclaration.getModuleInfo()}"
}
@@ -102,7 +104,7 @@ internal class FirModuleResolveStateImpl(
val nonLocalFirForNamedDeclaration = nonLocalNamedDeclaration.findSourceNonLocalFirDeclaration(
firFileBuilder,
rootModuleSession.firIdeProvider.symbolProvider,
sessionProvider.getModuleCache(ktDeclaration.getModuleInfo() as ModuleSourceInfo)
sessionProvider.getModuleCache(ktDeclaration.getModuleInfo() as ModuleSourceInfoBase)
)
if (ktDeclaration == nonLocalNamedDeclaration) return nonLocalFirForNamedDeclaration
@@ -5,35 +5,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.openapi.components.service
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.PackageOracleFactory
import org.jetbrains.kotlin.idea.caches.resolve.IdePackageOracleFactory
import org.jetbrains.kotlin.name.FqName
internal sealed class PackageExistenceChecker {
abstract class PackageExistenceChecker {
abstract fun isPackageExists(packageFqName: FqName): Boolean
}
internal class PackageExistenceCheckerForSingleModule(
project: Project,
module: ModuleInfo
) : PackageExistenceChecker() {
private val oracle =
project.service<IdePackageOracleFactory>().createOracle(module)
override fun isPackageExists(packageFqName: FqName): Boolean = oracle.packageExists(packageFqName)
}
internal class PackageExistenceCheckerForMultipleModules(
project: Project,
modules: List<ModuleInfo>
) : PackageExistenceChecker() {
private val oracles = run {
val factory = project.service<IdePackageOracleFactory>()
modules.map { factory.createOracle(it) }
}
override fun isPackageExists(packageFqName: FqName): Boolean =
oracles.any { oracle -> oracle.packageExists(packageFqName) }
}
@@ -6,15 +6,15 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.api
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.InternalForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.ResolveType
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
abstract class FirModuleResolveState {
@@ -22,9 +22,9 @@ abstract class FirModuleResolveState {
abstract val rootModuleSession: FirSession
abstract val moduleInfo: IdeaModuleInfo
abstract val moduleInfo: ModuleInfo
internal abstract fun getSessionFor(moduleInfo: IdeaModuleInfo): FirSession
internal abstract fun getSessionFor(moduleInfo: ModuleInfo): FirSession
/**
* Build fully resolved FIR node for requested element.
@@ -5,9 +5,39 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.api
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.analyzer.SdkInfoBase
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.declarations.SealedClassInheritorsProvider
import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.PackageExistenceChecker
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.psi.KtElement
import java.nio.file.Path
abstract class FirModuleResolveStateConfigurator {
abstract fun createDeclarationProvider(scope: GlobalSearchScope): DeclarationProvider
}
abstract fun createPackageExistingCheckerForModule(moduleInfo: ModuleInfo): PackageExistenceChecker
abstract fun createPackagePartsProvider(scope: GlobalSearchScope): PackagePartProvider
abstract fun createModuleDataProvider(moduleInfo: ModuleSourceInfoBase): ModuleDataProvider
abstract fun getLanguageVersionSettings(moduleInfo: ModuleSourceInfoBase): LanguageVersionSettings
abstract fun getModuleSourceScope(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope
abstract fun createScopeForModuleLibraries(moduleInfo: ModuleSourceInfoBase): GlobalSearchScope
abstract fun createSealedInheritorsProvider(): SealedClassInheritorsProvider
abstract fun getModuleInfoFor(element: KtElement): ModuleInfo
}
val Project.stateConfigurator: FirModuleResolveStateConfigurator
get() = ServiceManager.getService(this, FirModuleResolveStateConfigurator::class.java)
internal fun KtElement.getModuleInfo(): ModuleInfo =
project.stateConfigurator.getModuleInfoFor(this)
@@ -1,16 +0,0 @@
/*
* Copyright 2010-2021 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.fir.low.level.api.api
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProviderByIndexesImpl
class FirModuleResolveStateConfiguratorIdeImpl(private val project: Project) : FirModuleResolveStateConfigurator() {
override fun createDeclarationProvider(scope: GlobalSearchScope): DeclarationProvider =
DeclarationProviderByIndexesImpl(project, scope)
}
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2021 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.fir.low.level.api.api
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.ModificationTracker
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
abstract class KotlinOutOfBlockModificationTrackerFactory {
abstract fun createProjectWideOutOfBlockModificationTracker(): ModificationTracker
abstract fun createModuleWithoutDependenciesOutOfBlockModificationTracker(moduleInfo: ModuleSourceInfoBase): ModificationTracker
abstract fun createLibraryOutOfBlockModificationTracker(): ModificationTracker
}
fun Project.createProjectWideOutOfBlockModificationTracker() =
ServiceManager.getService(this, KotlinOutOfBlockModificationTrackerFactory::class.java).createProjectWideOutOfBlockModificationTracker()
fun Project.createLibraryOutOfBlockModificationTracker() =
ServiceManager.getService(this, KotlinOutOfBlockModificationTrackerFactory::class.java).createLibraryOutOfBlockModificationTracker()
fun ModuleSourceInfoBase.createModuleWithoutDependenciesOutOfBlockModificationTracker(project: Project) =
ServiceManager.getService(project, KotlinOutOfBlockModificationTrackerFactory::class.java)
.createModuleWithoutDependenciesOutOfBlockModificationTracker(this)
@@ -5,12 +5,11 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.api
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirPsiDiagnostic
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.renderWithType
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.FirIdeResolveStateService
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.InternalForInline
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.ResolveType
@@ -24,13 +23,13 @@ import kotlin.reflect.KClass
* Returns [FirModuleResolveState] which corresponds to containing module
*/
fun KtElement.getResolveState(): FirModuleResolveState =
getModuleInfo().getResolveState()
getModuleInfo().getResolveState(project)
/**
* Returns [FirModuleResolveState] which corresponds to containing module
*/
fun IdeaModuleInfo.getResolveState(): FirModuleResolveState =
FirIdeResolveStateService.getInstance(project!!).getResolveState(this)
fun ModuleInfo.getResolveState(project: Project): FirModuleResolveState =
FirIdeResolveStateService.getInstance(project).getResolveState(this)
/**
@@ -6,8 +6,7 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.api
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.parentOfType
import com.intellij.psi.util.parentsOfType
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
@@ -20,7 +19,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirTowerDataCo
import org.jetbrains.kotlin.fir.scopes.createImportingScopes
import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveStateDepended
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveStateImpl
import org.jetbrains.kotlin.idea.fir.low.level.api.api.DeclarationCopyBuilder.withBodyFrom
@@ -36,9 +34,12 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.buildFileFirAnno
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.buildFirUserTypeRef
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.sessions.FirIdeSourcesSession
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getElementTextInContext
import org.jetbrains.kotlin.idea.fir.low.level.api.util.originalDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.idea.util.ifTrue
import org.jetbrains.kotlin.idea.fir.low.level.api.util.parentOfType
import org.jetbrains.kotlin.idea.fir.low.level.api.util.parentsOfType
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2021 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.fir.low.level.api.api
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.psi.KtElement
abstract class ModuleInfoProvider {
companion object {
fun getInstance(project: Project): ModuleInfoProvider = ServiceManager.getService(project, ModuleInfoProvider::class.java)
}
}
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.element.builder
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getElementTextInContext
import org.jetbrains.kotlin.psi.KtElement
class DuplicatedFirSourceElementsException(
@@ -18,9 +18,9 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getElementTextInContext
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.declarationCanBeLazilyResolved
import org.jetbrains.kotlin.idea.fir.low.level.api.util.isNonAnonymousClassOrObject
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
@@ -124,7 +124,7 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate:
return null
}
internal fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? =
fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? =
getNonLocalContainingOrThisDeclaration { declaration ->
when (declaration) {
is KtNamedFunction -> declaration.bodyExpression?.isAncestor(this) == true
@@ -47,24 +47,25 @@ internal object FileElementFactory {
firFileLockProvider,
)
}
}
/**
* should be consistent with [createFileStructureElement]
*/
fun isReanalyzableContainer(
ktDeclaration: KtDeclaration,
): Boolean = when (ktDeclaration) {
is KtNamedFunction -> ktDeclaration.isReanalyzableContainer()
is KtProperty -> ktDeclaration.isReanalyzableContainer()
else -> false
}
/**
* should be consistent with [createFileStructureElement]
*/
//TODO make internal
fun isReanalyzableContainer(
ktDeclaration: KtDeclaration,
): Boolean = when (ktDeclaration) {
is KtNamedFunction -> ktDeclaration.isReanalyzableContainer()
is KtProperty -> ktDeclaration.isReanalyzableContainer()
else -> false
}
private fun KtNamedFunction.isReanalyzableContainer() =
name != null && hasExplicitTypeOrUnit
private fun KtNamedFunction.isReanalyzableContainer() =
name != null && hasExplicitTypeOrUnit
private fun KtProperty.isReanalyzableContainer() =
name != null && typeReference != null
private fun KtProperty.isReanalyzableContainer() =
name != null && typeReference != null
private val KtNamedFunction.hasExplicitTypeOrUnit
get() = hasBlockBody() || typeReference != null
}
private val KtNamedFunction.hasExplicitTypeOrUnit
get() = hasBlockBody() || typeReference != null
@@ -17,7 +17,7 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.idea.fir.low.level.api.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import java.util.concurrent.ConcurrentHashMap
@@ -235,14 +235,14 @@ internal class NonReanalyzableDeclarationStructureElement(
private val recorder = object : FirElementsRecorder() {
override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) {
val psi = property.psi as? KtProperty ?: return super.visitProperty(property, data)
if (!FileElementFactory.isReanalyzableContainer(psi) || !declarationCanBeLazilyResolved(psi)) {
if (!isReanalyzableContainer(psi) || !declarationCanBeLazilyResolved(psi)) {
super.visitProperty(property, data)
}
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) {
val psi = simpleFunction.psi as? KtNamedFunction ?: return super.visitSimpleFunction(simpleFunction, data)
if (!FileElementFactory.isReanalyzableContainer(psi) || !declarationCanBeLazilyResolved(psi)) {
if (!isReanalyzableContainer(psi) || !declarationCanBeLazilyResolved(psi)) {
super.visitSimpleFunction(simpleFunction, data)
}
}
@@ -0,0 +1,7 @@
/*
* Copyright 2010-2021 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.fir.low.level.api.ide
@@ -0,0 +1,7 @@
/*
* Copyright 2010-2021 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.fir.low.level.api.ide
@@ -27,6 +27,10 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
import org.jetbrains.kotlin.idea.fir.low.level.api.util.ensurePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.idea.util.ifTrue
import org.jetbrains.kotlin.idea.fir.low.level.api.transformers.*
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBuilder) {
/**
@@ -305,13 +309,13 @@ internal class FirLazyDeclarationResolver(private val firFileBuilder: FirFileBui
val scopeSession = ScopeSession()
var currentPhase = maxOf(designation.declaration.resolvePhase, FirResolvePhase.IMPORTS)
val firProviderInterceptor = onAirCreatedDeclaration.ifTrue {
val firProviderInterceptor = if(onAirCreatedDeclaration) {
FirProviderInterceptorForIDE.createForFirElement(
session = designation.firFile.moduleData.session,
firFile = designation.firFile,
element = designation.declaration
)
}
} else null
while (currentPhase < FirResolvePhase.BODY_RESOLVE) {
currentPhase = currentPhase.next
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.providers
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.NoMutableState
import org.jetbrains.kotlin.fir.ThreadSafeMutableState
@@ -19,7 +20,6 @@ import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProvider
import org.jetbrains.kotlin.fir.resolve.providers.FirSymbolProviderInternals
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.DeclarationProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveStateConfigurator
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
@@ -32,7 +32,7 @@ import org.jetbrains.kotlin.name.Name
internal class FirIdeProvider(
project: Project,
val session: FirSession,
moduleInfo: ModuleSourceInfo,
moduleInfo: ModuleSourceInfoBase,
val kotlinScopeProvider: FirKotlinScopeProvider,
firFileBuilder: FirFileBuilder,
val cache: ModuleFileCache,
@@ -6,8 +6,10 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.OrderRootType
import org.jetbrains.kotlin.analyzer.LibraryModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.analyzer.SdkInfoBase
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.*
@@ -27,12 +29,11 @@ import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseCheckingPhaseManage
import org.jetbrains.kotlin.fir.resolve.transformers.FirPhaseManager
import org.jetbrains.kotlin.fir.scopes.FirKotlinScopeProvider
import org.jetbrains.kotlin.fir.session.*
import org.jetbrains.kotlin.idea.caches.project.*
import org.jetbrains.kotlin.idea.caches.resolve.IDEPackagePartProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.*
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
import org.jetbrains.kotlin.idea.fir.low.level.api.IdeFirPhaseManager
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveStateConfigurator
import org.jetbrains.kotlin.idea.fir.low.level.api.api.stateConfigurator
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCacheImpl
import org.jetbrains.kotlin.idea.fir.low.level.api.fir.caches.FirThreadSafeCachesFactory
@@ -44,8 +45,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirModuleWithDependenciesSymbolProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirThreadSafeSymbolProviderWrapper
import org.jetbrains.kotlin.idea.fir.low.level.api.util.checkCanceled
import org.jetbrains.kotlin.idea.fir.low.level.api.util.createScopeForModuleLibraries
import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
import org.jetbrains.kotlin.name.Name
@@ -59,23 +58,23 @@ internal object FirIdeSessionFactory {
fun createSourcesSession(
project: Project,
configurator: FirModuleResolveStateConfigurator,
moduleInfo: ModuleSourceInfo,
moduleInfo: ModuleSourceInfoBase,
builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession,
firPhaseRunner: FirPhaseRunner,
sessionInvalidator: FirSessionInvalidator,
builtinTypes: BuiltinTypes,
sessionsCache: MutableMap<ModuleSourceInfo, FirIdeSourcesSession>,
sessionsCache: MutableMap<ModuleSourceInfoBase, FirIdeSourcesSession>,
isRootModule: Boolean,
librariesCache: LibrariesCache,
configureSession: (FirIdeSession.() -> Unit)? = null
): FirIdeSourcesSession {
sessionsCache[moduleInfo]?.let { return it }
val languageVersionSettings = moduleInfo.module.languageVersionSettings
val languageVersionSettings = project.stateConfigurator.getLanguageVersionSettings(moduleInfo)
val scopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
val firBuilder = FirFileBuilder(scopeProvider, firPhaseRunner)
val searchScope = ModuleProductionSourceScope(moduleInfo.module)
val searchScope = project.stateConfigurator.getModuleSourceScope(moduleInfo)
val dependentModules = moduleInfo.dependenciesWithoutSelf()
.filterIsInstanceTo<ModuleSourceInfo, MutableList<ModuleSourceInfo>>(mutableListOf())
.filterIsInstanceTo<ModuleSourceInfoBase, MutableList<ModuleSourceInfoBase>>(mutableListOf())
val session = FirIdeSourcesSession(dependentModules, project, searchScope, firBuilder, builtinTypes)
sessionsCache[moduleInfo] = session
@@ -87,7 +86,7 @@ internal object FirIdeSessionFactory {
val cache = ModuleFileCacheImpl(this)
val firPhaseManager = IdeFirPhaseManager(FirLazyDeclarationResolver(firFileBuilder), cache, sessionInvalidator)
registerIdeComponents()
registerIdeComponents(project)
registerCommonComponents(languageVersionSettings)
registerResolveComponents()
@@ -161,7 +160,7 @@ internal object FirIdeSessionFactory {
}
fun createLibrarySession(
mainModuleInfo: ModuleSourceInfo,
mainModuleInfo: ModuleSourceInfoBase,
project: Project,
builtinsAndCloneableSession: FirIdeBuiltinsAndCloneableSession,
builtinTypes: BuiltinTypes,
@@ -170,18 +169,18 @@ internal object FirIdeSessionFactory {
configureSession: (FirIdeSession.() -> Unit)?,
): FirIdeLibrariesSession = librariesCache.cached(mainModuleInfo) {
checkCanceled()
val searchScope = createScopeForModuleLibraries(mainModuleInfo.module)
val searchScope = project.stateConfigurator.createScopeForModuleLibraries(mainModuleInfo)
val javaClassFinder = JavaClassFinderImpl().apply {
setProjectInstance(project)
setScope(searchScope)
}
val packagePartProvider = IDEPackagePartProvider(searchScope)
val packagePartProvider = project.stateConfigurator.createPackagePartsProvider(searchScope)
val kotlinClassFinder = VirtualFileFinderFactory.getInstance(project).create(searchScope)
FirIdeLibrariesSession(project, searchScope, builtinTypes).apply session@{
val mainModuleData = FirModuleInfoBasedModuleData(mainModuleInfo).apply { bindSession(this@session) }
registerIdeComponents()
registerIdeComponents(project)
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
registerCommonComponents(languageVersionSettings)
registerJavaSpecificResolveComponents()
@@ -190,15 +189,7 @@ internal object FirIdeSessionFactory {
val kotlinScopeProvider = FirKotlinScopeProvider(::wrapScopeWithJvmMapped)
val moduleDataProvider = DependencyListForCliModule.build(
mainModuleInfo.name,
mainModuleInfo.platform,
mainModuleInfo.analyzerServices
) {
dependencies(mainModuleInfo.dependenciesWithoutSelf().extractLibraryPaths())
friendDependencies(mainModuleInfo.modulesWhoseInternalsAreVisible().extractLibraryPaths())
dependsOnDependencies(mainModuleInfo.expectedBy.extractLibraryPaths())
}.moduleDataProvider
val moduleDataProvider = project.stateConfigurator.createModuleDataProvider(mainModuleInfo)
moduleDataProvider.allModuleData.forEach { it.bindSession(this@session) }
@@ -230,35 +221,6 @@ internal object FirIdeSessionFactory {
}
}
private fun Sequence<ModuleInfo>.extractLibraryPaths(): List<Path> {
return fold(mutableListOf()) { acc, moduleInfo ->
moduleInfo.extractLibraryPaths(acc)
acc
}
}
private fun Iterable<ModuleInfo>.extractLibraryPaths(): List<Path> {
return fold(mutableListOf()) { acc, moduleInfo ->
moduleInfo.extractLibraryPaths(acc)
acc
}
}
private fun ModuleInfo.extractLibraryPaths(destination: MutableList<Path>) {
when (this) {
is SdkInfo -> {
sdk.rootProvider.getFiles(OrderRootType.CLASSES).mapNotNullTo(destination) {
Paths.get(it.fileSystem.extractPresentableUrl(it.path)).normalize()
}
}
is LibraryInfo -> {
getLibraryRoots().mapTo(destination) {
Paths.get(it).normalize()
}
}
}
}
fun createBuiltinsAndCloneableSession(
project: Project,
@@ -277,7 +239,7 @@ internal object FirIdeSessionFactory {
).apply {
bindSession(this@session)
}
registerIdeComponents()
registerIdeComponents(project)
register(FirPhaseManager::class, FirPhaseCheckingPhaseManager)
registerCommonComponents(languageVersionSettings)
@@ -296,10 +258,10 @@ internal object FirIdeSessionFactory {
}
}
private fun FirIdeSession.registerIdeComponents() {
private fun FirIdeSession.registerIdeComponents(project: Project) {
register(IdeSessionComponents::class, IdeSessionComponents.create(this))
register(FirCachesFactory::class, FirThreadSafeCachesFactory)
register(SealedClassInheritorsProvider::class, SealedClassInheritorsProviderIdeImpl())
register(SealedClassInheritorsProvider::class, project.stateConfigurator.createSealedInheritorsProvider())
}
}
@@ -7,28 +7,25 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSessionProvider
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.caches.project.isLibraryClasses
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.Immutable
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.ThreadSafe
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
@Immutable
class FirIdeSessionProvider internal constructor(
val project: Project,
internal val rootModuleSession: FirIdeSourcesSession,
val sessions: Map<ModuleSourceInfo, FirIdeSession>
val sessions: Map<ModuleSourceInfoBase, FirIdeSession>
) : FirSessionProvider() {
override fun getSession(moduleData: FirModuleData): FirSession? =
sessions[moduleData.moduleSourceInfo]
fun getSession(moduleInfo: IdeaModuleInfo): FirSession? =
fun getSession(moduleInfo: ModuleInfo): FirSession? =
sessions[moduleInfo]
internal fun getModuleCache(moduleSourceInfo: ModuleSourceInfo): ModuleFileCache =
internal fun getModuleCache(moduleSourceInfo: ModuleSourceInfoBase): ModuleFileCache =
(sessions.getValue(moduleSourceInfo) as FirIdeSourcesSession).cache
}
@@ -11,28 +11,28 @@ import kotlinx.collections.immutable.PersistentMap
import kotlinx.collections.immutable.persistentMapOf
import kotlinx.collections.immutable.toPersistentMap
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.FirModuleData
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.session.FirModuleInfoBasedModuleData
import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveStateConfigurator
import org.jetbrains.kotlin.idea.fir.low.level.api.FirPhaseRunner
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createLibraryOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.api.createModuleWithoutDependenciesOutOfBlockModificationTracker
import org.jetbrains.kotlin.idea.fir.low.level.api.util.addValueFor
import org.jetbrains.kotlin.idea.fir.low.level.api.util.*
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.trackers.createModuleWithoutDependenciesOutOfBlockModificationTracker
import java.util.concurrent.ConcurrentHashMap
internal class FirIdeSessionProviderStorage(private val project: Project) {
private val sessionsCache = ConcurrentHashMap<ModuleSourceInfo, FromModuleViewSessionCache>()
class FirIdeSessionProviderStorage(val project: Project) {
private val sessionsCache = ConcurrentHashMap<ModuleSourceInfoBase, FromModuleViewSessionCache>()
private val configurator = ServiceManager.getService(project, FirModuleResolveStateConfigurator::class.java)
private val librariesCache by cachedValue(project, LibraryModificationTracker.getInstance(project)) { LibrariesCache() }
private val librariesCache by cachedValue(project, project.createLibraryOutOfBlockModificationTracker()) { LibrariesCache() }
fun getSessionProvider(
rootModule: ModuleSourceInfo,
rootModule: ModuleSourceInfoBase,
configureSession: (FirIdeSession.() -> Unit)? = null
): FirIdeSessionProvider {
val firPhaseRunner = FirPhaseRunner()
@@ -40,8 +40,8 @@ internal class FirIdeSessionProviderStorage(private val project: Project) {
val builtinTypes = BuiltinTypes()
val builtinsAndCloneableSession = FirIdeSessionFactory.createBuiltinsAndCloneableSession(project, builtinTypes)
val cache = sessionsCache.getOrPut(rootModule) { FromModuleViewSessionCache(rootModule) }
val (sessions, session) = cache.withMappings { mappings ->
val sessions = mutableMapOf<ModuleSourceInfo, FirIdeSourcesSession>().apply { putAll(mappings) }
val (sessions, session) = cache.withMappings(project) { mappings ->
val sessions = mutableMapOf<ModuleSourceInfoBase, FirIdeSourcesSession>().apply { putAll(mappings) }
val session = executeWithoutPCE {
FirIdeSessionFactory.createSourcesSession(
project,
@@ -65,10 +65,10 @@ internal class FirIdeSessionProviderStorage(private val project: Project) {
}
private class FromModuleViewSessionCache(
val root: ModuleSourceInfo,
val root: ModuleSourceInfoBase,
) {
@Volatile
private var mappings: PersistentMap<ModuleSourceInfo, FirSessionWithModificationTracker> = persistentMapOf()
private var mappings: PersistentMap<ModuleSourceInfoBase, FirSessionWithModificationTracker> = persistentMapOf()
val sessionInvalidator: FirSessionInvalidator = FirSessionInvalidator { session ->
mappings[session.moduleData.moduleSourceInfo]?.invalidate()
@@ -76,15 +76,16 @@ private class FromModuleViewSessionCache(
inline fun <R> withMappings(
action: (Map<ModuleSourceInfo, FirIdeSourcesSession>) -> Pair<Map<ModuleSourceInfo, FirIdeSourcesSession>, R>
): Pair<Map<ModuleSourceInfo, FirIdeSourcesSession>, R> {
project: Project,
action: (Map<ModuleSourceInfoBase, FirIdeSourcesSession>) -> Pair<Map<ModuleSourceInfoBase, FirIdeSourcesSession>, R>
): Pair<Map<ModuleSourceInfoBase, FirIdeSourcesSession>, R> {
val (newMappings, result) = action(getSessions().mapValues { it.value })
mappings = newMappings.mapValues { FirSessionWithModificationTracker(it.value) }.toPersistentMap()
mappings = newMappings.mapValues { FirSessionWithModificationTracker(project, it.value) }.toPersistentMap()
return newMappings to result
}
@OptIn(ExperimentalStdlibApi::class)
private fun getSessions(): Map<ModuleSourceInfo, FirIdeSourcesSession> = buildMap {
private fun getSessions(): Map<ModuleSourceInfoBase, FirIdeSourcesSession> = buildMap {
val sessions = mappings.values
val wasSessionInvalidated = sessions.associateWithTo(hashMapOf()) { false }
@@ -125,10 +126,11 @@ private class FromModuleViewSessionCache(
}
private class FirSessionWithModificationTracker(
project: Project,
val firSession: FirIdeSourcesSession,
) {
private val modificationTracker =
firSession.moduleData.moduleSourceInfo.module.createModuleWithoutDependenciesOutOfBlockModificationTracker()
firSession.moduleData.moduleSourceInfo.createModuleWithoutDependenciesOutOfBlockModificationTracker(project)
private val timeStamp = modificationTracker.modificationCount
@@ -142,7 +144,7 @@ private class FirSessionWithModificationTracker(
val isValid: Boolean get() = !isInvalidated && modificationTracker.modificationCount == timeStamp
}
val FirModuleData.moduleSourceInfo: ModuleSourceInfo
val FirModuleData.moduleSourceInfo: ModuleSourceInfoBase
get() = moduleInfoUnsafe()
inline fun <reified T : ModuleInfo> FirModuleData.moduleInfoUnsafe(): T = (this as FirModuleInfoBasedModuleData).moduleInfo as T
@@ -7,15 +7,15 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
import com.intellij.openapi.project.Project
import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import org.jetbrains.kotlin.fir.BuiltinTypes
import org.jetbrains.kotlin.fir.PrivateSessionConstructor
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
@OptIn(PrivateSessionConstructor::class)
internal class FirIdeSourcesSession @PrivateSessionConstructor constructor(
val dependencies: List<ModuleSourceInfo>,
val dependencies: List<ModuleSourceInfoBase>,
override val project: Project,
override val scope: GlobalSearchScope,
val firFileBuilder: FirFileBuilder,
@@ -5,10 +5,10 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.sessions
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
import org.jetbrains.kotlin.analyzer.ModuleSourceInfoBase
import java.util.concurrent.ConcurrentHashMap
internal inline class LibrariesCache(private val cache: ConcurrentHashMap<ModuleSourceInfo, FirIdeLibrariesSession> = ConcurrentHashMap()) {
fun cached(moduleSourceInfo: ModuleSourceInfo, create: (ModuleSourceInfo) -> FirIdeLibrariesSession): FirIdeLibrariesSession =
internal inline class LibrariesCache(private val cache: ConcurrentHashMap<ModuleSourceInfoBase, FirIdeLibrariesSession> = ConcurrentHashMap()) {
fun cached(moduleSourceInfo: ModuleSourceInfoBase, create: (ModuleSourceInfoBase) -> FirIdeLibrariesSession): FirIdeLibrariesSession =
cache.computeIfAbsent(moduleSourceInfo, create)
}
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.api.KtDeclarationAndFirDeclarationEqualityChecker
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.api.InvalidFirElementTypeExce
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -7,18 +7,25 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.util
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.util.parentsOfType
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.*
import org.jetbrains.kotlin.analyzer.ModuleInfo
import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.Lock
import kotlin.reflect.KProperty
internal inline fun <T> executeOrReturnDefaultValueOnPCE(defaultValue: T, action: () -> T): T =
@@ -82,9 +89,9 @@ internal val FirDeclaration.containingKtFileIfAny: KtFile?
get() = psi?.containingFile as? KtFile
internal fun IdeaModuleInfo.collectTransitiveDependenciesWithSelf(): List<IdeaModuleInfo> {
val result = mutableSetOf<IdeaModuleInfo>()
fun collect(module: IdeaModuleInfo) {
internal fun ModuleInfo.collectTransitiveDependenciesWithSelf(): List<ModuleInfo> {
val result = mutableSetOf<ModuleInfo>()
fun collect(module: ModuleInfo) {
if (module in result) return
result += module
module.dependencies().forEach(::collect)
@@ -97,3 +104,57 @@ internal fun KtDeclaration.isNonAnonymousClassOrObject() =
this is KtClassOrObject
&& !this.isObjectLiteral()
&& this !is KtEnumEntry
@Suppress("NOTHING_TO_INLINE")
internal inline operator fun <T> CachedValue<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value
internal inline fun <T> cachedValue(project: Project, vararg dependencies: Any, crossinline createValue: () -> T) =
CachedValuesManager.getManager(project).createCachedValue {
CachedValueProvider.Result(
createValue(),
dependencies
)
}
/**
* Creates a value which will be cached until until any physical PSI change happens
*
* @see com.intellij.psi.util.CachedValue
* @see com.intellij.psi.util.PsiModificationTracker.MODIFICATION_COUNT
*/
internal fun <T> psiModificationTrackerBasedCachedValue(project: Project, createValue: () -> T) =
cachedValue(project, PsiModificationTracker.MODIFICATION_COUNT, createValue = createValue)
internal fun KtElement.getElementTextInContext(): String {
val context = parentOfType<KtImportDirective>()
?: parentOfType<KtPackageDirective>()
?: containingDeclarationForPseudocode
?: containingKtFile
val builder = StringBuilder()
context.accept(object : PsiElementVisitor() {
override fun visitElement(element: PsiElement) {
if (element === this@getElementTextInContext) builder.append("<$ELEMENT_TAG>")
if (element is LeafPsiElement) {
builder.append(element.text)
} else {
element.acceptChildren(this)
}
if (element === this@getElementTextInContext) builder.append("</$ELEMENT_TAG>")
}
})
return builder.toString().trimIndent().trim()
}
private const val ELEMENT_TAG = "ELEMENT"
internal inline fun <reified T : PsiElement> PsiElement.parentOfType(withSelf: Boolean = false): T? {
return PsiTreeUtil.getParentOfType(this, T::class.java, !withSelf)
}
internal fun <T : PsiElement> PsiElement.parentsOfType(clazz: Class<out T>, withSelf: Boolean = true): Sequence<T> {
return (if (withSelf) parentsWithSelf else parents).filterIsInstance(clazz)
}
internal inline fun <reified T : PsiElement> PsiElement.parentsOfType(withSelf: Boolean = true): Sequence<T> =
parentsOfType(T::class.java, withSelf)
@@ -10,30 +10,28 @@ import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
import org.jetbrains.kotlin.fir.builder.RawFirBuilderMode
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyBodiesCalculator
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
abstract class AbstractFirLazyBodiesCalculatorTest : KotlinLightCodeInsightFixtureTestCase() {
abstract class AbstractFirLazyBodiesCalculatorTest : FrontendApiSingleTestDataFileTest() {
override fun isFirPlugin(): Boolean = true
protected fun doTest(filePath: String) {
val file = myFixture.configureByFile(fileName()) as KtFile
val resolveState = file.getResolveState()
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
val session = resolveState.rootModuleSession
val provider = session.firIdeProvider.kotlinScopeProvider
val laziedFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.LAZY_BODIES).buildFirFile(file)
val laziedFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.LAZY_BODIES).buildFirFile(ktFile)
FirLazyBodiesCalculator.calculateLazyBodies(laziedFirFile)
val fullFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.NORMAL).buildFirFile(file)
val fullFirFile = RawFirBuilder(session, provider, RawFirBuilderMode.NORMAL).buildFirFile(ktFile)
val laziedFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(laziedFirFile) }.toString()
val fullFirFileDump = StringBuilder().also { FirRenderer(it).visitFile(fullFirFile) }.toString()
TestCase.assertEquals(laziedFirFileDump, fullFirFileDump)
}
}
@@ -1,114 +0,0 @@
/*
* 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.fir.low.level.api
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.search.FileTypeIndex
import com.intellij.testFramework.LightProjectDescriptor
import junit.framework.TestCase
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirResolvedImport
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.KotlinFileType
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.caches.project.productionSourceInfo
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFir
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.jsonUtils.getString
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.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractFirLazyResolveTest : KotlinLightCodeInsightFixtureTestCase() {
override fun isFirPlugin(): Boolean = true
override fun getProjectDescriptor(): LightProjectDescriptor {
if (KotlinTestUtils.isAllFilesPresentTest(getTestName(false))) return super.getProjectDescriptor()
val testFile = File(testDataPath, fileName())
val config = JsonParser().parse(FileUtil.loadFile(testFile, true)) as JsonObject
val withRuntime = config["withRuntime"]?.asBoolean ?: false
return if (withRuntime)
KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
else
KotlinLightProjectDescriptor.INSTANCE
}
fun doTest(path: String) {
val testFile = File(path)
val config = JsonParser().parse(FileUtil.loadFile(testFile, true)) as JsonObject
val mainFilePath = config.getString("mainFile")
val mainFile = File(testFile.parent, mainFilePath)
val mainFileText = FileUtil.loadFile(mainFile, true)
TestCase.assertTrue("\"<caret>\" is missing in file \"$mainFilePath\"", mainFileText.contains("<caret>"))
val projectDir = path.removePrefix(testDataPath).substringBeforeLast('/')
myFixture.copyDirectoryToProject(projectDir, "")
PsiDocumentManager.getInstance(myFixture.project).commitAllDocuments()
myFixture.configureFromTempProjectFile(mainFilePath)
val referenceToResolve = myFixture.getReferenceAtCaretPositionWithAssertion(mainFilePath)
val elementToResolve = referenceToResolve.element
val expressionToResolve = when {
elementToResolve.parent is KtCallExpression -> elementToResolve.parent
else -> elementToResolve
} as KtExpression
val resolveState = expressionToResolve.getResolveState()
val resultsDump = when (val firElement = expressionToResolve.getOrBuildFir(resolveState)) {
is FirResolvedImport -> buildString {
append("import ")
append(firElement.packageFqName)
val className = firElement.relativeClassName
if (className != null) {
append("/")
append(className)
}
val name = firElement.importedName
if (name != null) {
append(".")
append(name)
}
}
else -> firElement.render(FirRenderer.RenderMode.WithResolvePhases)
}
KotlinTestUtils.assertEqualsToFile(File(testFile.parent, "results.txt"), resultsDump)
fun expectedTxtPath(virtualFile: VirtualFile): String {
val virtualPath = virtualFile.path.substringAfter("/src/")
var result: String? = null
val root = File(path).parentFile
for (file in root.walkTopDown()) {
if (!file.isDirectory && virtualPath in file.absolutePath.replace("\\", "/")) {
result = file.absolutePath.replace(".kt", ".txt")
}
}
return result!!
}
val moduleInfo = project.allModules().single().productionSourceInfo() as IdeaModuleInfo
val contentScope = moduleInfo.contentScope()
val files = FileTypeIndex.getFiles(KotlinFileType.INSTANCE, contentScope)
for (file in files) {
val psiFile = psiManager.findFile(file) as KtFile
val session = resolveState.rootModuleSession
val firProvider = session.firIdeProvider
val firFile = firProvider.cache.getCachedFirFile(psiFile) ?: continue
KotlinTestUtils.assertEqualsToFile(File(expectedTxtPath(file)), firFile.render(FirRenderer.RenderMode.WithResolvePhases))
}
}
}
@@ -1,59 +0,0 @@
/*
* Copyright 2010-2021 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.fir.low.level.api
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.fir.low.level.api.api.withFirDeclaration
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.SdkAndMockLibraryProjectDescriptor
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
abstract class AbstractFirLibraryModuleDeclarationResolveTest : KotlinLightCodeInsightFixtureTestCase() {
override fun isFirPlugin(): Boolean = true
override fun getProjectDescriptor(): LightProjectDescriptor {
val pathToLibraryFiles = File(testDataPath).resolve("_library")
assertExists(pathToLibraryFiles)
return SdkAndMockLibraryProjectDescriptor(pathToLibraryFiles.toString(), true)
}
/**
* We want to check that resolving 'compiled' PSI-elements (i.e. elements from libraries)
* works as expected.
*
* Compiled PSI-elements might come from indices, for example, and we need to be able to work with them
* and to resolve them to FIR declarations.
*/
fun doTest(path: String) {
val testDataFile = File(path)
val expectedFile = File(path.removeSuffix(".kt") + ".txt")
val ktFile = myFixture.configureByFile(testDataFile.name) as KtFile
val caretResolutionTarget = myFixture.elementAtCaret
require(caretResolutionTarget is KtDeclaration) {
"Element at caret should be referencing some declaration, but referenced ${caretResolutionTarget::class} instead"
}
// We intentionally use ktFile here as a context element, because resolving
// from compiled PSI-elements (e.g. caretResolutionTarget) is not yet supported
resolveWithClearCaches(ktFile) { resolveState ->
val renderedDeclaration = caretResolutionTarget.withFirDeclaration(resolveState, FirResolvePhase.RAW_FIR) { firDeclaration ->
firDeclaration.render(FirRenderer.RenderMode.WithResolvePhases)
}
KotlinTestUtils.assertEqualsToFile(expectedFile, renderedDeclaration)
}
}
}
@@ -5,28 +5,23 @@
package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.LightProjectDescriptor
import org.jetbrains.kotlin.fir.FirRenderer
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.api.LowLevelFirApiFacadeForResolveOnAir
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtFileAnnotationList
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.util.findElementByCommentPrefix
import java.io.File
abstract class AbstractFirOnAirResolveTest : KotlinLightCodeInsightFixtureTestCase() {
override fun isFirPlugin(): Boolean = true
abstract class AbstractFirOnAirResolveTest : FrontendApiSingleTestDataFileTest() {
fun doTest(path: String) {
val testDataFile = File(path)
val ktFile = myFixture.configureByText(testDataFile.name, FileUtil.loadFile(testDataFile)) as KtFile
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
fun fixUpAnnotations(element: KtElement): KtElement = when (element) {
is KtAnnotated -> element.annotationEntries.firstOrNull() ?: element
@@ -39,14 +34,9 @@ abstract class AbstractFirOnAirResolveTest : KotlinLightCodeInsightFixtureTestCa
check(place::class == onAir::class)
resolveWithClearCaches(ktFile) { firModuleResolveState ->
check(firModuleResolveState is FirModuleResolveStateImpl)
val firElement = LowLevelFirApiFacadeForResolveOnAir.onAirResolveElement(firModuleResolveState, place, onAir)
val rendered = firElement.render(FirRenderer.RenderMode.WithResolvePhases)
val expectedFileName = testDataFile.name.replace(".kt", ".txt")
KotlinTestUtils.assertEqualsToFile(testDataFile.parentFile.resolve(expectedFileName), rendered)
}
check(resolveState is FirModuleResolveStateImpl)
val firElement = LowLevelFirApiFacadeForResolveOnAir.onAirResolveElement(resolveState, place, onAir)
val rendered = firElement.render(FirRenderer.RenderMode.WithResolvePhases)
KotlinTestUtils.assertEqualsToFile(testDataFileSibling(".txt"), rendered)
}
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
}
@@ -1,44 +0,0 @@
/*
* 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.fir.low.level.api
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.util.KtTestUtil
import org.jetbrains.kotlin.types.typeUtil.closure
import java.io.File
/**
* The idea behind this test is to check that [FirIdeSealedHierarchyProcessor] finds all direct inheritors of sealed classes and interfaces.
* We use the fact that [SealedClassInheritorsKt#getSealedInheritors] property gets its value thanks to the class activity.
*
* Inheritors are collected for every sealed declaration of the 'fileToResolve' (see test data 'structure.json'). Resulting collection is
* compared with 'expected.txt'.
*/
abstract class AbstractFirSealedInheritorsTest : AbstractFirMultiModuleLazyResolveTest() {
override fun getTestDataPath(): String =
"${KtTestUtil.getHomeDirectory()}/idea/idea-frontend-fir/idea-fir-low-level-api/testdata/resolveSealed/"
override fun checkFirFile(firFile: FirFile, path: String) {
val allClasses = firFile.listNestedClasses().closure { it.listNestedClasses() }
val inheritorNames = allClasses.flatMap { firClass ->
if (firClass.isSealed) {
firClass.getSealedClassInheritors(firFile.moduleData.session)
} else {
emptyList()
}
}.map { it.asString() }.sorted()
KotlinTestUtils.assertEqualsToFile(File("$path/expected.txt"), inheritorNames.joinToString("\n"))
}
}
private fun FirDeclaration.listNestedClasses(): List<FirRegularClass> {
return when (this) {
is FirFile -> declarations.filterIsInstance<FirRegularClass>()
is FirRegularClass -> declarations.filterIsInstance<FirRegularClass>()
else -> emptyList()
}
}
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.idea.fir.low.level.api
import com.intellij.openapi.util.io.FileUtilRt
import com.intellij.util.PathUtil
import junit.framework.TestCase
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
@@ -18,43 +16,43 @@ import org.jetbrains.kotlin.fir.scopes.FirTypeScope
import org.jetbrains.kotlin.fir.session.FirSessionFactory
import org.jetbrains.kotlin.fir.visitors.FirVisitorVoid
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirDeclarationUntypedDesignation
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
import org.jetbrains.kotlin.idea.fir.low.level.api.compiler.based.FrontendApiSingleTestDataFileTest
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.RawFirNonLocalDeclarationBuilder
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.test.testFramework.KtParsingTestCase
import java.io.File
import org.jetbrains.kotlin.test.model.TestModule
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.assertions
import kotlin.io.path.readText
abstract class AbstractPartialRawFirBuilderTestCase : KtParsingTestCase(
"",
"kt",
KotlinParserDefinition()
) {
abstract class AbstractPartialRawFirBuilderTestCase : FrontendApiSingleTestDataFileTest() {
fun doRawFirTest(filePath: String) {
val fileText = File(filePath).readText()
override fun doTest(ktFile: KtFile, module: TestModule, resolveState: FirModuleResolveState, testServices: TestServices) {
val fileText = testDataPath.readText()
val functionName = InTextDirectivesUtils.findStringWithPrefixes(fileText, FUNCTION_DIRECTIVE)
val propertyName = InTextDirectivesUtils.findStringWithPrefixes(fileText, PROPERTY_DIRECTIVE)
when {
functionName != null -> testFunctionPartialBuilding(filePath, functionName)
propertyName != null -> testPropertyPartialBuilding(filePath, propertyName)
else -> fail("No '$FUNCTION_DIRECTIVE' or '$PROPERTY_DIRECTIVE' directives found!")
functionName != null -> testFunctionPartialBuilding(ktFile, functionName)
propertyName != null -> testPropertyPartialBuilding(ktFile, propertyName)
else -> testServices.assertions.fail { "No '$FUNCTION_DIRECTIVE' or '$PROPERTY_DIRECTIVE' directives found!" }
}
}
private fun testFunctionPartialBuilding(filePath: String, nameToFind: String) {
private fun testFunctionPartialBuilding(ktFile: KtFile, nameToFind: String) {
testPartialBuilding(
filePath
ktFile
) { file -> file.findDescendantOfType<KtNamedFunction> { it.name == nameToFind }!! }
}
private fun testPropertyPartialBuilding(filePath: String, nameToFind: String) {
private fun testPropertyPartialBuilding(ktFile: KtFile, nameToFind: String) {
testPartialBuilding(
filePath
ktFile
) { file -> file.findDescendantOfType<KtProperty> { it.name == nameToFind }!! }
}
@@ -88,23 +86,11 @@ abstract class AbstractPartialRawFirBuilderTestCase : KtParsingTestCase(
}
}
private fun createKtFile(filePath: String): KtFile {
val name = PathUtil.getFileName(filePath)
val extension = FileUtilRt.getExtension(name)
val fileDirectory = PathUtil.getParentPath(filePath)
myFileExt = extension
val fileText = loadFileDefault(fileDirectory, name)
val ktFile = createPsiFile(name, fileText) as KtFile
myFile = ktFile
return ktFile
}
private fun <T : KtElement> testPartialBuilding(
filePath: String,
file: KtFile,
findPsiElement: (KtFile) -> T
) {
val file = createKtFile(filePath)
val elementToBuild = findPsiElement(file) as KtDeclaration
val scopeProvider = object : FirScopeProvider() {
@@ -140,8 +126,7 @@ abstract class AbstractPartialRawFirBuilderTestCase : KtParsingTestCase(
)
val firDump = firElement.render(FirRenderer.RenderMode.WithFqNames)
val expectedPath = filePath.replace(".kt", ".txt")
KotlinTestUtils.assertEqualsToFile(File(expectedPath), firDump)
KotlinTestUtils.assertEqualsToFile(testDataFileSibling(".txt"), firDump)
}
companion object {
@@ -6,248 +6,266 @@
package org.jetbrains.kotlin.idea.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
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 */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/rawBuilder")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class FirLazyBodiesCalculatorTestGenerated extends AbstractFirLazyBodiesCalculatorTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@Test
public void testAllFilesPresentInRawBuilder() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/rawBuilder"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Nested
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Declarations extends AbstractFirLazyBodiesCalculatorTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public class Declarations {
@Test
public void testAllFilesPresentInDeclarations() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotation.kt")
public void testAnnotation() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotation.kt");
}
@Test
@TestMetadata("annotationsOnNullableParenthesizedTypes.kt")
public void testAnnotationsOnNullableParenthesizedTypes() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnNullableParenthesizedTypes.kt");
}
@Test
@TestMetadata("annotationsOnParenthesizedTypes.kt")
public void testAnnotationsOnParenthesizedTypes() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/annotationsOnParenthesizedTypes.kt");
}
@Test
@TestMetadata("complexTypes.kt")
public void testComplexTypes() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/complexTypes.kt");
}
@Test
@TestMetadata("constructorInObject.kt")
public void testConstructorInObject() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorInObject.kt");
}
@Test
@TestMetadata("constructorOfAnonymousObject.kt")
public void testConstructorOfAnonymousObject() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/constructorOfAnonymousObject.kt");
}
@Test
@TestMetadata("delegates.kt")
public void testDelegates() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/delegates.kt");
}
@Test
@TestMetadata("derivedClass.kt")
public void testDerivedClass() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/derivedClass.kt");
}
@Test
@TestMetadata("emptyAnonymousObject.kt")
public void testEmptyAnonymousObject() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/emptyAnonymousObject.kt");
}
@Test
@TestMetadata("enums.kt")
public void testEnums() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums.kt");
}
@Test
@TestMetadata("enums2.kt")
public void testEnums2() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/enums2.kt");
}
@Test
@TestMetadata("expectActual.kt")
public void testExpectActual() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/expectActual.kt");
}
@Test
@TestMetadata("external.kt")
public void testExternal() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/external.kt");
}
@Test
@TestMetadata("F.kt")
public void testF() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/F.kt");
}
@Test
@TestMetadata("functionTypes.kt")
public void testFunctionTypes() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/functionTypes.kt");
}
@Test
@TestMetadata("genericFunctions.kt")
public void testGenericFunctions() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/genericFunctions.kt");
}
@Test
@TestMetadata("genericProperty.kt")
public void testGenericProperty() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/genericProperty.kt");
}
@Test
@TestMetadata("initBlockWithDeclarations.kt")
public void testInitBlockWithDeclarations() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/initBlockWithDeclarations.kt");
}
@Test
@TestMetadata("nestedClass.kt")
public void testNestedClass() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/nestedClass.kt");
}
@Test
@TestMetadata("NestedOfAliasedType.kt")
public void testNestedOfAliasedType() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/NestedOfAliasedType.kt");
}
@Test
@TestMetadata("NestedSuperType.kt")
public void testNestedSuperType() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/NestedSuperType.kt");
}
@Test
@TestMetadata("noPrimaryConstructor.kt")
public void testNoPrimaryConstructor() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/noPrimaryConstructor.kt");
}
@Test
@TestMetadata("simpleClass.kt")
public void testSimpleClass() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/simpleClass.kt");
}
@Test
@TestMetadata("simpleFun.kt")
public void testSimpleFun() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/simpleFun.kt");
}
@Test
@TestMetadata("simpleTypeAlias.kt")
public void testSimpleTypeAlias() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/simpleTypeAlias.kt");
}
@Test
@TestMetadata("splitModifierList.kt")
public void testSplitModifierList() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/splitModifierList.kt");
}
@Test
@TestMetadata("suspendFunctionTypes.kt")
public void testSuspendFunctionTypes() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/suspendFunctionTypes.kt");
}
@Test
@TestMetadata("typeAliasWithGeneric.kt")
public void testTypeAliasWithGeneric() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/typeAliasWithGeneric.kt");
}
@Test
@TestMetadata("typeParameterVsNested.kt")
public void testTypeParameterVsNested() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/typeParameterVsNested.kt");
}
@Test
@TestMetadata("typeParameters.kt")
public void testTypeParameters() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/typeParameters.kt");
}
@Test
@TestMetadata("where.kt")
public void testWhere() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/where.kt");
}
@Nested
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Contracts extends AbstractFirLazyBodiesCalculatorTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public class Contracts {
@Test
public void testAllFilesPresentInContracts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Nested
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class NewSyntax extends AbstractFirLazyBodiesCalculatorTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public class NewSyntax {
@Test
public void testAllFilesPresentInNewSyntax() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("functionWithBothOldAndNewSyntaxContractDescription.kt")
public void testFunctionWithBothOldAndNewSyntaxContractDescription() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/functionWithBothOldAndNewSyntaxContractDescription.kt");
}
@Test
@TestMetadata("propertyAccessorsContractDescription.kt")
public void testPropertyAccessorsContractDescription() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/propertyAccessorsContractDescription.kt");
}
@Test
@TestMetadata("simpleFunctionsContractDescription.kt")
public void testSimpleFunctionsContractDescription() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/newSyntax/simpleFunctionsContractDescription.kt");
}
}
@Nested
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/oldSyntax")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class OldSyntax extends AbstractFirLazyBodiesCalculatorTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public class OldSyntax {
@Test
public void testAllFilesPresentInOldSyntax() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/oldSyntax"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("contractDescription.kt")
public void testContractDescription() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/declarations/contracts/oldSyntax/contractDescription.kt");
@@ -256,163 +274,190 @@ public class FirLazyBodiesCalculatorTestGenerated extends AbstractFirLazyBodiesC
}
}
@Nested
@TestMetadata("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Expressions extends AbstractFirLazyBodiesCalculatorTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public class Expressions {
@Test
public void testAllFilesPresentInExpressions() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("annotated.kt")
public void testAnnotated() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/annotated.kt");
}
@Test
@TestMetadata("arrayAccess.kt")
public void testArrayAccess() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAccess.kt");
}
@Test
@TestMetadata("arrayAssignment.kt")
public void testArrayAssignment() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/arrayAssignment.kt");
}
@Test
@TestMetadata("branches.kt")
public void testBranches() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/branches.kt");
}
@Test
@TestMetadata("callableReferences.kt")
public void testCallableReferences() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/callableReferences.kt");
}
@Test
@TestMetadata("calls.kt")
public void testCalls() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/calls.kt");
}
@Test
@TestMetadata("classReference.kt")
public void testClassReference() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/classReference.kt");
}
@Test
@TestMetadata("collectionLiterals.kt")
public void testCollectionLiterals() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/collectionLiterals.kt");
}
@Test
@TestMetadata("destructuring.kt")
public void testDestructuring() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/destructuring.kt");
}
@Test
@TestMetadata("for.kt")
public void testFor() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/for.kt");
}
@Test
@TestMetadata("genericCalls.kt")
public void testGenericCalls() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/genericCalls.kt");
}
@Test
@TestMetadata("in.kt")
public void testIn() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/in.kt");
}
@Test
@TestMetadata("inBrackets.kt")
public void testInBrackets() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/inBrackets.kt");
}
@Test
@TestMetadata("init.kt")
public void testInit() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/init.kt");
}
@Test
@TestMetadata("labelForInfix.kt")
public void testLabelForInfix() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/labelForInfix.kt");
}
@Test
@TestMetadata("lambda.kt")
public void testLambda() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambda.kt");
}
@Test
@TestMetadata("lambdaAndAnonymousFunction.kt")
public void testLambdaAndAnonymousFunction() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/lambdaAndAnonymousFunction.kt");
}
@Test
@TestMetadata("locals.kt")
public void testLocals() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/locals.kt");
}
@Test
@TestMetadata("modifications.kt")
public void testModifications() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/modifications.kt");
}
@Test
@TestMetadata("namedArgument.kt")
public void testNamedArgument() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/namedArgument.kt");
}
@Test
@TestMetadata("nullability.kt")
public void testNullability() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/nullability.kt");
}
@Test
@TestMetadata("qualifierWithTypeArguments.kt")
public void testQualifierWithTypeArguments() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/qualifierWithTypeArguments.kt");
}
@Test
@TestMetadata("simpleReturns.kt")
public void testSimpleReturns() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/simpleReturns.kt");
}
@Test
@TestMetadata("super.kt")
public void testSuper() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/super.kt");
}
@Test
@TestMetadata("these.kt")
public void testThese() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/these.kt");
}
@Test
@TestMetadata("try.kt")
public void testTry() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/try.kt");
}
@Test
@TestMetadata("typeOperators.kt")
public void testTypeOperators() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/typeOperators.kt");
}
@Test
@TestMetadata("unary.kt")
public void testUnary() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/unary.kt");
}
@Test
@TestMetadata("variables.kt")
public void testVariables() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/variables.kt");
}
@Test
@TestMetadata("while.kt")
public void testWhile() throws Exception {
runTest("compiler/fir/raw-fir/psi2fir/testData/rawBuilder/expressions/while.kt");
@@ -6,126 +6,75 @@
package org.jetbrains.kotlin.idea.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
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 */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class FirLazyDeclarationResolveTestGenerated extends AbstractFirLazyDeclarationResolveTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@Test
public void testAllFilesPresentInLazyResolve() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@TestMetadata("annotations.kt")
public void testAnnotations() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/annotations.kt");
}
@Test
@TestMetadata("classMembers.kt")
public void testClassMembers() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/classMembers.kt");
}
@Test
@TestMetadata("delegates.kt")
public void testDelegates() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/delegates.kt");
}
@TestMetadata("localDeclaration.kt")
public void testLocalDeclaration() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/localDeclaration.kt");
}
@TestMetadata("localFunction.kt")
public void testLocalFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/localFunction.kt");
}
@TestMetadata("parameterOfLocalSetter.kt")
public void testParameterOfLocalSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/parameterOfLocalSetter.kt");
}
@TestMetadata("parameterOfNonLocalSetter.kt")
public void testParameterOfNonLocalSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/parameterOfNonLocalSetter.kt");
}
@Test
@TestMetadata("propertyWithGetter.kt")
public void testPropertyWithGetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/propertyWithGetter.kt");
}
@Test
@TestMetadata("propertyWithGetterAndSetter.kt")
public void testPropertyWithGetterAndSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/propertyWithGetterAndSetter.kt");
}
@Test
@TestMetadata("propertyWithInitializer.kt")
public void testPropertyWithInitializer() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/propertyWithInitializer.kt");
}
@Test
@TestMetadata("secondaryConstructor.kt")
public void testSecondaryConstructor() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/secondaryConstructor.kt");
}
@TestMetadata("superTypes.kt")
public void testSuperTypes() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/superTypes.kt");
}
@TestMetadata("superTypesLoop.kt")
public void testSuperTypesLoop() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/superTypesLoop.kt");
}
@Test
@TestMetadata("topLevelFunctions.kt")
public void testTopLevelFunctions() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/topLevelFunctions.kt");
}
@Test
@TestMetadata("topLevelFunctionsWithExpressionBodyAndExplicitType.kt")
public void testTopLevelFunctionsWithExpressionBodyAndExplicitType() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/topLevelFunctionsWithExpressionBodyAndExplicitType.kt");
}
@Test
@TestMetadata("topLevelFunctionsWithImplicitType.kt")
public void testTopLevelFunctionsWithImplicitType() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/topLevelFunctionsWithImplicitType.kt");
}
@TestMetadata("typeParameterOfLocalFunction.kt")
public void testTypeParameterOfLocalFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/typeParameterOfLocalFunction.kt");
}
@TestMetadata("typeParameterOfNonLocalFunction.kt")
public void testTypeParameterOfNonLocalFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/typeParameterOfNonLocalFunction.kt");
}
@TestMetadata("typeParameterOfTopFunction.kt")
public void testTypeParameterOfTopFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/typeParameterOfTopFunction.kt");
}
@TestMetadata("typeParameterOfTopSetter.kt")
public void testTypeParameterOfTopSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/lazyResolve/typeParameterOfTopSetter.kt");
}
}
@@ -1,71 +0,0 @@
/*
* Copyright 2010-2021 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.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
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/testData/fir/lazyResolve")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class FirLazyResolveTestGenerated extends AbstractFirLazyResolveTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInLazyResolve() throws Exception {
KtTestUtil.assertAllTestsPresentInSingleGeneratedClassWithExcluded(this.getClass(), new File("idea/testData/fir/lazyResolve"), Pattern.compile("^(.+)\\.test$"), null);
}
@TestMetadata("elvis/elvis.test")
public void testElvis_Elvis() throws Exception {
runTest("idea/testData/fir/lazyResolve/elvis/elvis.test");
}
@TestMetadata("import/import.test")
public void testImport_Import() throws Exception {
runTest("idea/testData/fir/lazyResolve/import/import.test");
}
@TestMetadata("inInit/inInit.test")
public void testInInit_InInit() throws Exception {
runTest("idea/testData/fir/lazyResolve/inInit/inInit.test");
}
@TestMetadata("inLocal/inLocal.test")
public void testInLocal_InLocal() throws Exception {
runTest("idea/testData/fir/lazyResolve/inLocal/inLocal.test");
}
@TestMetadata("inSecondary/inSecondary.test")
public void testInSecondary_InSecondary() throws Exception {
runTest("idea/testData/fir/lazyResolve/inSecondary/inSecondary.test");
}
@TestMetadata("secondary/secondary.test")
public void testSecondary_Secondary() throws Exception {
runTest("idea/testData/fir/lazyResolve/secondary/secondary.test");
}
@TestMetadata("simple/simple.test")
public void testSimple_Simple() throws Exception {
runTest("idea/testData/fir/lazyResolve/simple/simple.test");
}
@TestMetadata("simpleProperty/simpleProperty.test")
public void testSimpleProperty_SimpleProperty() throws Exception {
runTest("idea/testData/fir/lazyResolve/simpleProperty/simpleProperty.test");
}
}
@@ -1,76 +0,0 @@
/*
* Copyright 2010-2021 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.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
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/idea-fir-low-level-api/testdata/libraryModuleResolve")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class FirLibraryModuleDeclarationResolveTestGenerated extends AbstractFirLibraryModuleDeclarationResolveTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInLibraryModuleResolve() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve"), Pattern.compile("^(.+)\\.kt$"), null, false);
}
@TestMetadata("memberFunctionNoArgs.kt")
public void testMemberFunctionNoArgs() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/memberFunctionNoArgs.kt");
}
@TestMetadata("memberFunctionWithArgs.kt")
public void testMemberFunctionWithArgs() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/memberFunctionWithArgs.kt");
}
@TestMetadata("memberProperty.kt")
public void testMemberProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/memberProperty.kt");
}
@TestMetadata("topLevelClass.kt")
public void testTopLevelClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/topLevelClass.kt");
}
@TestMetadata("topLevelClassPrimaryConstructor.kt")
public void testTopLevelClassPrimaryConstructor() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/topLevelClassPrimaryConstructor.kt");
}
@TestMetadata("topLevelClassSecondaryConstructor.kt")
public void testTopLevelClassSecondaryConstructor() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/topLevelClassSecondaryConstructor.kt");
}
@TestMetadata("topLevelFunctionNoArgs.kt")
public void testTopLevelFunctionNoArgs() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/topLevelFunctionNoArgs.kt");
}
@TestMetadata("topLevelFunctionWithArgs.kt")
public void testTopLevelFunctionWithArgs() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/topLevelFunctionWithArgs.kt");
}
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/libraryModuleResolve/topLevelProperty.kt");
}
}
@@ -1,41 +0,0 @@
/*
* Copyright 2010-2021 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.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
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/idea-fir-low-level-api/testdata/multiModuleLazyResolve")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class FirMultiModuleLazyResolveTestGenerated extends AbstractFirMultiModuleLazyResolveTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
public void testAllFilesPresentInMultiModuleLazyResolve() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/multiModuleLazyResolve"), Pattern.compile("^([^\\.]+)$"), null, false);
}
@TestMetadata("javaExtendsKotlinExtendsJava")
public void testJavaExtendsKotlinExtendsJava() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/multiModuleLazyResolve/javaExtendsKotlinExtendsJava/");
}
@TestMetadata("whenWithHeiarchy")
public void testWhenWithHeiarchy() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/multiModuleLazyResolve/whenWithHeiarchy/");
}
}
@@ -6,109 +6,121 @@
package org.jetbrains.kotlin.idea.fir.low.level.api;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
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 */
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public class FirOnAirResolveTestGenerated extends AbstractFirOnAirResolveTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}
@Test
public void testAllFilesPresentInOnAirResolve() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("classInClass.kt")
public void testClassInClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/classInClass.kt");
}
@Test
@TestMetadata("fileAnnotation.kt")
public void testFileAnnotation() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/fileAnnotation.kt");
}
@Test
@TestMetadata("identifierInContext.kt")
public void testIdentifierInContext() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/identifierInContext.kt");
}
@Test
@TestMetadata("inParameter.kt")
public void testInParameter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/inParameter.kt");
}
@Test
@TestMetadata("incompleteIdentifier.kt")
public void testIncompleteIdentifier() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/incompleteIdentifier.kt");
}
@Test
@TestMetadata("localClass.kt")
public void testLocalClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/localClass.kt");
}
@Test
@TestMetadata("localFunction.kt")
public void testLocalFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/localFunction.kt");
}
@Test
@TestMetadata("loopConstruction.kt")
public void testLoopConstruction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/loopConstruction.kt");
}
@Test
@TestMetadata("memberInClass.kt")
public void testMemberInClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/memberInClass.kt");
}
@Test
@TestMetadata("memberPropertyInClass.kt")
public void testMemberPropertyInClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/memberPropertyInClass.kt");
}
@Test
@TestMetadata("memberWithOverride.kt")
public void testMemberWithOverride() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/memberWithOverride.kt");
}
@Test
@TestMetadata("onAirTypesResolve.kt")
public void testOnAirTypesResolve() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/onAirTypesResolve.kt");
}
@Test
@TestMetadata("replacementInHeader.kt")
public void testReplacementInHeader() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/replacementInHeader.kt");
}
@Test
@TestMetadata("replacementInsidePropertyBody.kt")
public void testReplacementInsidePropertyBody() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/replacementInsidePropertyBody.kt");
}
@Test
@TestMetadata("replacementInsidePropertyBody2.kt")
public void testReplacementInsidePropertyBody2() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/replacementInsidePropertyBody2.kt");
}
@Test
@TestMetadata("topLevelFunction.kt")
public void testTopLevelFunction() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/topLevelFunction.kt");
}
@Test
@TestMetadata("typeAlias.kt")
public void testTypeAlias() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/onAirResolve/typeAlias.kt");

Some files were not shown because too many files have changed in this diff Show More