FIR IDE: add property support for incremental analysis

This commit is contained in:
Ilya Kirillov
2020-11-26 13:46:58 +01:00
parent 953dba808b
commit 76c0dc7dba
21 changed files with 290 additions and 69 deletions
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataC
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.fir.low.level.api.sessions.FirIdeSourcesSession
import org.jetbrains.kotlin.idea.fir.low.level.api.util.ktDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
@@ -8,10 +8,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.element.builder
import com.intellij.psi.PsiElement
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
import org.jetbrains.kotlin.idea.fir.low.level.api.annotations.ThreadSafe
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.fir.low.level.api.file.structure.FileStructureCache
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
@@ -104,6 +101,9 @@ internal fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDec
getNonLocalContainingOrThisDeclaration { declaration ->
when (declaration) {
is KtNamedFunction -> declaration.bodyExpression?.isAncestor(this) == true
is KtProperty -> declaration.initializer?.isAncestor(this) == true ||
declaration.getter?.isAncestor(this) == true ||
declaration.setter?.isAncestor(this) == true
else -> false
}
}
@@ -7,9 +7,11 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.KtProperty
internal object FileElementFactory {
/**
@@ -20,13 +22,19 @@ internal object FileElementFactory {
ktDeclaration: KtDeclaration,
firFile: FirFile,
): FileStructureElement = when {
ktDeclaration is KtNamedFunction && ktDeclaration.name != null && ktDeclaration.hasExplicitTypeOrUnit ->
ReanalyzableFunctionStructureElement(
firFile,
ktDeclaration,
(firDeclaration as FirSimpleFunction).symbol,
ktDeclaration.modificationStamp
)
ktDeclaration is KtNamedFunction && ktDeclaration.isReanalyzableContainer() -> ReanalyzableFunctionStructureElement(
firFile,
ktDeclaration,
(firDeclaration as FirSimpleFunction).symbol,
ktDeclaration.modificationStamp
)
ktDeclaration is KtProperty && ktDeclaration.isReanalyzableContainer() -> ReanalyzablePropertyStructureElement(
firFile,
ktDeclaration,
(firDeclaration as FirProperty).symbol,
ktDeclaration.modificationStamp
)
else -> NonReanalyzableDeclarationStructureElement(
firFile,
@@ -40,11 +48,18 @@ internal object FileElementFactory {
*/
fun isReanalyzableContainer(
ktDeclaration: KtDeclaration,
): Boolean = when {
ktDeclaration is KtNamedFunction && ktDeclaration.name != null && ktDeclaration.hasExplicitTypeOrUnit -> true
): Boolean = when (ktDeclaration) {
is KtNamedFunction -> ktDeclaration.isReanalyzableContainer()
is KtProperty -> ktDeclaration.isReanalyzableContainer()
else -> false
}
private fun KtNamedFunction.isReanalyzableContainer() =
name != null && hasExplicitTypeOrUnit
private fun KtProperty.isReanalyzableContainer() =
name != null && typeReference != null
private val KtNamedFunction.hasExplicitTypeOrUnit
get() = hasBlockBody() || typeReference != null
}
@@ -36,11 +36,12 @@ internal class FileStructure(
}
private fun getStructureElementForDeclaration(declaration: KtAnnotated): FileStructureElement {
@Suppress("CANNOT_CHECK_FOR_ERASED")
val structureElement = structureElements.compute(declaration) { _, structureElement ->
when {
structureElement == null -> createStructureElement(declaration)
structureElement is ReanalyzableStructureElement<*> && !structureElement.isUpToDate() -> {
structureElement.reanalyze(declaration as KtNamedFunction, moduleFileCache, firLazyDeclarationResolver, firIdeProvider)
structureElement is ReanalyzableStructureElement<KtDeclaration> && !structureElement.isUpToDate() -> {
structureElement.reanalyze(declaration as KtDeclaration, moduleFileCache, firLazyDeclarationResolver, firIdeProvider)
}
else -> structureElement
}
@@ -11,10 +11,10 @@ import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorDeclarati
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.realPsi
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
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.diagnostics.FirIdeStructureElementDiagnosticsCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
@@ -40,16 +40,16 @@ internal sealed class FileStructureElement {
}
internal sealed class ReanalyzableStructureElement<KT : KtDeclaration> : FileStructureElement() {
abstract override val psi: KT
abstract override val psi: KtDeclaration
abstract val firSymbol: AbstractFirBasedSymbol<*>
abstract val timestamp: Long
/**
* Creates new declaration by [newKtDeclaration] which will serve as replacement of [firSymbol]
* Also, modify [firFile] & replace old version of declaration to a new one
* Also, modify [firFile] & replace old version of declaration with a new one
*/
abstract fun reanalyze(
newKtDeclaration: KtNamedFunction,
newKtDeclaration: KT,
cache: ModuleFileCache,
firLazyDeclarationResolver: FirLazyDeclarationResolver,
firIdeProvider: FirIdeProvider,
@@ -75,18 +75,6 @@ internal class ReanalyzableFunctionStructureElement(
override val mappings: Map<KtElement, FirElement> =
FirElementsRecorder.recordElementsFrom(firSymbol.fir, recorder)
private fun replaceFunction(from: FirSimpleFunction, to: FirSimpleFunction) {
val declarations = if (from.symbol.callableId.className == null) {
firFile.declarations as MutableList<FirDeclaration>
} else {
val classLikeLookupTag = from.containingClass()
?: error("Class name should not be null for non-top-level & non-local declarations")
val containingClass = classLikeLookupTag.toSymbol(firFile.session)?.fir as FirRegularClass
containingClass.declarations as MutableList<FirDeclaration>
}
declarations.replaceFirst(from, to)
}
override fun reanalyze(
newKtDeclaration: KtNamedFunction,
cache: ModuleFileCache,
@@ -96,12 +84,7 @@ internal class ReanalyzableFunctionStructureElement(
val newFunction = firIdeProvider.buildFunctionWithBody(newKtDeclaration) as FirSimpleFunction
val originalFunction = firSymbol.fir as FirSimpleFunction
cache.firFileLockProvider.withWriteLock(firFile) {
replaceFunction(originalFunction, newFunction)
}
//todo remap symbol under firFile write lock
try {
return FileStructureUtil.withDeclarationReplaced(firFile, cache, originalFunction, newFunction) {
firLazyDeclarationResolver.lazyResolveDeclaration(
newFunction,
cache,
@@ -109,7 +92,7 @@ internal class ReanalyzableFunctionStructureElement(
checkPCE = true,
reresolveFile = true,
)
return cache.firFileLockProvider.withReadLock(firFile) {
cache.firFileLockProvider.withReadLock(firFile) {
ReanalyzableFunctionStructureElement(
firFile,
newKtDeclaration,
@@ -117,11 +100,44 @@ internal class ReanalyzableFunctionStructureElement(
newKtDeclaration.modificationStamp,
)
}
} catch (e: Throwable) {
cache.firFileLockProvider.withWriteLock(firFile) {
replaceFunction(newFunction, originalFunction)
}
}
}
internal class ReanalyzablePropertyStructureElement(
override val firFile: FirFile,
override val psi: KtProperty,
override val firSymbol: FirPropertySymbol,
override val timestamp: Long
) : ReanalyzableStructureElement<KtProperty>() {
override val mappings: Map<KtElement, FirElement> =
FirElementsRecorder.recordElementsFrom(firSymbol.fir, recorder)
override fun reanalyze(
newKtDeclaration: KtProperty,
cache: ModuleFileCache,
firLazyDeclarationResolver: FirLazyDeclarationResolver,
firIdeProvider: FirIdeProvider,
): ReanalyzablePropertyStructureElement {
val newProperty = firIdeProvider.buildPropertyWithBody(newKtDeclaration)
val originalProperty = firSymbol.fir
return FileStructureUtil.withDeclarationReplaced(firFile, cache, originalProperty, newProperty) {
firLazyDeclarationResolver.lazyResolveDeclaration(
newProperty,
cache,
FirResolvePhase.BODY_RESOLVE,
checkPCE = true,
reresolveFile = true,
)
cache.firFileLockProvider.withReadLock(firFile) {
ReanalyzablePropertyStructureElement(
firFile,
newKtDeclaration,
newProperty.symbol,
newKtDeclaration.modificationStamp,
)
}
throw e
}
}
}
@@ -5,6 +5,14 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.util.replaceFirst
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
@@ -15,4 +23,32 @@ internal object FileStructureUtil {
ktDeclaration.containingClassOrObject is KtEnumEntry -> false
else -> !KtPsiUtil.isLocal(ktDeclaration)
}
fun replaceDeclaration(firFile: FirFile, from: FirCallableDeclaration<*>, to: FirCallableDeclaration<*>) {
val declarations = if (from.symbol.callableId.className == null) {
firFile.declarations as MutableList<FirDeclaration>
} else {
val classLikeLookupTag = from.containingClass()
?: error("Class name should not be null for non-top-level & non-local declarations")
val containingClass = classLikeLookupTag.toSymbol(firFile.session)?.fir as FirRegularClass
containingClass.declarations as MutableList<FirDeclaration>
}
declarations.replaceFirst(from, to)
}
inline fun <R> withDeclarationReplaced(
firFile: FirFile,
cache: ModuleFileCache,
from: FirCallableDeclaration<*>,
to: FirCallableDeclaration<*>,
action: () -> R,
): R {
cache.firFileLockProvider.withWriteLock(firFile) { replaceDeclaration(firFile, from, to) }
return try {
action()
} catch (e: Throwable) {
cache.firFileLockProvider.withWriteLock(firFile) { replaceDeclaration(firFile, to, from) }
throw e
}
}
}
@@ -0,0 +1,11 @@
class X {/* NonReanalyzableDeclarationStructureElement */
var x: Int/* ReanalyzablePropertyStructureElement */
get() = field
set(value) {
field = value
}
val y = 42/* NonReanalyzableDeclarationStructureElement */
var z: Int = 15/* ReanalyzablePropertyStructureElement */
}
@@ -0,0 +1,15 @@
fun foo() {/* ReanalyzableFunctionStructureElement */
var x: Int
}
class A {/* NonReanalyzableDeclarationStructureElement */
fun q() {/* ReanalyzableFunctionStructureElement */
val y = 42
}
}
class B {/* NonReanalyzableDeclarationStructureElement */
class C {/* NonReanalyzableDeclarationStructureElement */
fun u() {/* ReanalyzableFunctionStructureElement */
var z: Int = 15
}
}
}
@@ -0,0 +1,9 @@
var x: Int/* ReanalyzablePropertyStructureElement */
get() = field
set(value) {
field = value
}
val y = 42/* NonReanalyzableDeclarationStructureElement */
var z: Int = 15/* ReanalyzablePropertyStructureElement */
@@ -0,0 +1,3 @@
val x: Int get() = y<caret>
// OUT_OF_BLOCK: false
@@ -0,0 +1,4 @@
val x: Int
get() = y<caret>
// OUT_OF_BLOCK: false
@@ -0,0 +1,3 @@
val x: Int = y<caret>
// OUT_OF_BLOCK: false
@@ -0,0 +1,4 @@
val x: Int
set(value) = y<caret>
// OUT_OF_BLOCK: false
@@ -0,0 +1,3 @@
val x get() = y<caret>
// OUT_OF_BLOCK: true
@@ -0,0 +1,3 @@
val x = y<caret>
// OUT_OF_BLOCK: true
@@ -0,0 +1,8 @@
val x
get() = 1
set(value) {
<caret>
}
// OUT_OF_BLOCK: true
// TODO should not be out of block
@@ -7,6 +7,7 @@ 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 junit.framework.Assert
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveStateImpl
@@ -53,8 +54,13 @@ abstract class AbstractFileStructureAndOutOfBlockModificationTrackerConsistencyT
)
}
private fun KtFile.findElementAtCaret(): KtElement =
findElementAt(myFixture.caretOffset)!!.parentOfType()!!
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): Triple<FileStructureElement, FileStructure, FirModuleResolveState> {
val moduleResolveState = element.getResolveState() as FirModuleResolveStateImpl
@@ -8,20 +8,12 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import com.intellij.openapi.application.runUndoTransparentWriteAction
import com.intellij.openapi.util.io.FileUtil
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.util.collectDescendantsOfType
import com.intellij.psi.util.forEachDescendantOfType
import com.intellij.psi.util.parentOfType
import junit.framework.Assert
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.fir.low.level.api.FirModuleResolveStateImpl
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getResolveState
import org.jetbrains.kotlin.idea.search.getKotlinFqName
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.callUtil.isFakeElement
import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.KotlinTestUtils
import java.io.File
@@ -40,23 +32,31 @@ abstract class AbstractFileStructureTest : KotlinLightCodeInsightFixtureTestCase
ktFile.forEachDescendantOfType<KtDeclaration> { ktDeclaration ->
val structureElement = declarationToStructureElement[ktDeclaration] ?: return@forEachDescendantOfType
val comment = structureElement.createComment()
when (ktDeclaration) {
is KtClassOrObject -> {
val lBrace = ktDeclaration.body?.lBrace
if (lBrace != null) {
ktDeclaration.body!!.addAfter(comment, lBrace)
} else {
ktDeclaration.parent.addAfter(comment, ktDeclaration)
}
}
is KtFunction -> {
val lBrace = ktDeclaration.bodyBlockExpression?.lBrace
if (lBrace != null) {
ktDeclaration.bodyBlockExpression!!.addAfter(comment, lBrace)
} else {
ktDeclaration.parent.addAfter(comment, ktDeclaration)
}
}
when (ktDeclaration) {
is KtClassOrObject -> {
val lBrace = ktDeclaration.body?.lBrace
if (lBrace != null) {
ktDeclaration.body!!.addAfter(comment, lBrace)
} else {
ktDeclaration.parent.addAfter(comment, ktDeclaration)
}
}
is KtFunction -> {
val lBrace = ktDeclaration.bodyBlockExpression?.lBrace
if (lBrace != null) {
ktDeclaration.bodyBlockExpression!!.addAfter(comment, lBrace)
} else {
ktDeclaration.parent.addAfter(comment, ktDeclaration)
}
}
is KtProperty -> {
val initializerOrTypeReference = ktDeclaration.initializer ?: ktDeclaration.typeReference
if (initializerOrTypeReference != null) {
ktDeclaration.addAfter(comment, initializerOrTypeReference)
} else {
ktDeclaration.parent.addAfter(comment, ktDeclaration)
}
}
else -> error("Unsupported declaration $ktDeclaration")
}
}
@@ -53,6 +53,41 @@ public class FileStructureAndOutOfBlockModificationTrackerConsistencyTestGenerat
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topLevelUnitFun.kt");
}
@TestMetadata("topPropertyWithTypeInGetter.kt")
public void testTopPropertyWithTypeInGetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInGetter.kt");
}
@TestMetadata("topPropertyWithTypeInGetterOnNextLine.kt")
public void testTopPropertyWithTypeInGetterOnNextLine() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInGetterOnNextLine.kt");
}
@TestMetadata("topPropertyWithTypeInInititalzer.kt")
public void testTopPropertyWithTypeInInititalzer() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInInititalzer.kt");
}
@TestMetadata("topPropertyWithTypeInSetter.kt")
public void testTopPropertyWithTypeInSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInSetter.kt");
}
@TestMetadata("topPropertyWithoutTypeInGetter.kt")
public void testTopPropertyWithoutTypeInGetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithoutTypeInGetter.kt");
}
@TestMetadata("topPropertyWithoutTypeInInititalzer.kt")
public void testTopPropertyWithoutTypeInInititalzer() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithoutTypeInInititalzer.kt");
}
@TestMetadata("topPropertyWithoutTypeInSetter.kt")
public void testTopPropertyWithoutTypeInSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithoutTypeInSetter.kt");
}
@TestMetadata("typeInFunctionAnnotation.kt")
public void testTypeInFunctionAnnotation() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/typeInFunctionAnnotation.kt");
@@ -33,6 +33,11 @@ public class FileStructureTestGenerated extends AbstractFileStructureTest {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/class.kt");
}
@TestMetadata("classMemberProperty.kt")
public void testClassMemberProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/classMemberProperty.kt");
}
@TestMetadata("localClass.kt")
public void testLocalClass() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/localClass.kt");
@@ -43,6 +48,11 @@ public class FileStructureTestGenerated extends AbstractFileStructureTest {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/localFun.kt");
}
@TestMetadata("localProperty.kt")
public void testLocalProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/localProperty.kt");
}
@TestMetadata("nestedClasses.kt")
public void testNestedClasses() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/nestedClasses.kt");
@@ -63,6 +73,11 @@ public class FileStructureTestGenerated extends AbstractFileStructureTest {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/topLevelFunWithType.kt");
}
@TestMetadata("topLevelProperty.kt")
public void testTopLevelProperty() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/topLevelProperty.kt");
}
@TestMetadata("topLevelUnitFun.kt")
public void testTopLevelUnitFun() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/fileStructure/topLevelUnitFun.kt");
@@ -53,6 +53,41 @@ public class ProjectWideOutOfBlockKotlinModificationTrackerTestGenerated extends
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topLevelUnitFun.kt");
}
@TestMetadata("topPropertyWithTypeInGetter.kt")
public void testTopPropertyWithTypeInGetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInGetter.kt");
}
@TestMetadata("topPropertyWithTypeInGetterOnNextLine.kt")
public void testTopPropertyWithTypeInGetterOnNextLine() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInGetterOnNextLine.kt");
}
@TestMetadata("topPropertyWithTypeInInititalzer.kt")
public void testTopPropertyWithTypeInInititalzer() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInInititalzer.kt");
}
@TestMetadata("topPropertyWithTypeInSetter.kt")
public void testTopPropertyWithTypeInSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithTypeInSetter.kt");
}
@TestMetadata("topPropertyWithoutTypeInGetter.kt")
public void testTopPropertyWithoutTypeInGetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithoutTypeInGetter.kt");
}
@TestMetadata("topPropertyWithoutTypeInInititalzer.kt")
public void testTopPropertyWithoutTypeInInititalzer() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithoutTypeInInititalzer.kt");
}
@TestMetadata("topPropertyWithoutTypeInSetter.kt")
public void testTopPropertyWithoutTypeInSetter() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/topPropertyWithoutTypeInSetter.kt");
}
@TestMetadata("typeInFunctionAnnotation.kt")
public void testTypeInFunctionAnnotation() throws Exception {
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/outOfBlockProjectWide/typeInFunctionAnnotation.kt");