FIR IDE: introduce AbstractSymbolByReferencePointerRestoreTest
This commit is contained in:
@@ -1040,7 +1040,11 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
|
||||
testClass<AbstractSymbolFromLibraryPointerRestoreTest> {
|
||||
model("resoreSymbolFromLibrary", extension = "txt")
|
||||
model("resoreSymbolFromLibrary")
|
||||
}
|
||||
|
||||
testClass<AbstractSymbolByReferencePointerRestoreTest> {
|
||||
model("symbolByReference")
|
||||
}
|
||||
|
||||
testClass<AbstractMemoryLeakInSymbolsTest> {
|
||||
|
||||
+1
-2
@@ -2,8 +2,7 @@ fun test(s: String) {
|
||||
var i: Int = 0
|
||||
<expr>i</expr> = s.length
|
||||
}
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: i
|
||||
// type: kotlin.Int
|
||||
|
||||
|
||||
+1
-2
@@ -1,6 +1,5 @@
|
||||
val x = <expr>1 + 2</expr>
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: 1 + 2
|
||||
// type: kotlin.Int
|
||||
|
||||
|
||||
+1
-2
@@ -3,8 +3,7 @@ fun x(): Int {
|
||||
<expr>break</expr>
|
||||
}
|
||||
}
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: break
|
||||
// type: kotlin.Nothing
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
fun x(): Int {
|
||||
<expr>for(i in 1..2) {}</expr>
|
||||
}
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: for(i in 1..2) {}
|
||||
// type: kotlin.Unit
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
val a = 12
|
||||
val x = <expr>12.toByte()</expr>
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: 12.toByte()
|
||||
// type: kotlin.Byte
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
val x = <expr>(1 + 2)</expr> + 3
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: (1 + 2)
|
||||
// type: kotlin.Int
|
||||
|
||||
|
||||
+1
-2
@@ -1,7 +1,6 @@
|
||||
val a = 10
|
||||
val x = "abc${<expr>a</expr>}defg"
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: a
|
||||
// type: kotlin.Int
|
||||
|
||||
|
||||
Vendored
+1
-2
@@ -1,7 +1,6 @@
|
||||
val a = 10
|
||||
val x = "abc${<expr>a</expr> + 20}defg"
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: a
|
||||
// type: kotlin.Int
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
val x = <expr>1</expr>
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: 1
|
||||
// type: kotlin.Int
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
val a = 10
|
||||
<expr>val x = 1</expr>
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: val x = 1
|
||||
// type: kotlin.Unit
|
||||
|
||||
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
fun x(): Int {
|
||||
<expr>return 1</expr>
|
||||
}
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: return 1
|
||||
// type: kotlin.Nothing
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
val x = <expr>"abc"</expr>
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: "abc"
|
||||
// type: kotlin.String
|
||||
|
||||
|
||||
+1
-2
@@ -1,8 +1,7 @@
|
||||
fun x(): Int {
|
||||
<expr>while(true) {}</expr>
|
||||
}
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// expression: while(true) {}
|
||||
// type: kotlin.Unit
|
||||
|
||||
|
||||
+1
-2
@@ -9,11 +9,10 @@ abstract class B {
|
||||
abstract fun foo(x: String): Int
|
||||
}
|
||||
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// ALL:
|
||||
// B.foo(x: Int): Int
|
||||
|
||||
// DIRECT:
|
||||
// B.foo(x: Int): Int
|
||||
|
||||
|
||||
+1
-2
@@ -22,8 +22,8 @@ interface D {
|
||||
fun foo(x: String)
|
||||
}
|
||||
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// ALL:
|
||||
// C.foo(x: String): Unit
|
||||
// D.foo(x: String): Unit
|
||||
@@ -31,4 +31,3 @@ interface D {
|
||||
// DIRECT:
|
||||
// C.foo(x: String): Unit
|
||||
// D.foo(x: String): Unit
|
||||
|
||||
|
||||
+1
-2
@@ -22,8 +22,8 @@ interface D {
|
||||
fun foo(x: String)
|
||||
}
|
||||
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// ALL:
|
||||
// C.foo(x: String): Unit
|
||||
// D.foo(x: String): Unit
|
||||
@@ -31,4 +31,3 @@ interface D {
|
||||
// DIRECT:
|
||||
// C.foo(x: String): Unit
|
||||
// D.foo(x: String): Unit
|
||||
|
||||
|
||||
+1
-2
@@ -16,12 +16,11 @@ abstract class C {
|
||||
abstract val x: Int
|
||||
}
|
||||
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// ALL:
|
||||
// B.x: Int
|
||||
// C.x: Int
|
||||
|
||||
// DIRECT:
|
||||
// B.x: Int
|
||||
|
||||
|
||||
+1
-2
@@ -25,8 +25,8 @@ interface D {
|
||||
fun foo(x: String)
|
||||
}
|
||||
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// ALL:
|
||||
// B.foo(x: String): Unit
|
||||
// C.foo(x: String): Unit
|
||||
@@ -36,4 +36,3 @@ interface D {
|
||||
// B.foo(x: String): Unit
|
||||
// C.foo(x: String): Unit
|
||||
// D.foo(x: String): Unit
|
||||
|
||||
|
||||
+1
-2
@@ -18,8 +18,8 @@ open class D {
|
||||
open fun foo(x: Int) {}
|
||||
}
|
||||
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
// ALL:
|
||||
// B.foo(x: Int): Unit
|
||||
// C.foo(x: Int): Unit
|
||||
@@ -27,4 +27,3 @@ open class D {
|
||||
|
||||
// DIRECT:
|
||||
// B.foo(x: Int): Unit
|
||||
|
||||
|
||||
+4
-2
@@ -1,8 +1,9 @@
|
||||
// RUNTIME
|
||||
|
||||
class: kotlin/Lazy
|
||||
// class: kotlin/Lazy
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirNamedClassOrObjectSymbol:
|
||||
annotationClassIds: []
|
||||
annotations: []
|
||||
@@ -21,3 +22,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: [KtFirTypeParameterSymbol(T)]
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
+4
-2
@@ -1,8 +1,9 @@
|
||||
// RUNTIME
|
||||
|
||||
class: java/lang/String
|
||||
// class: java/lang/String
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirNamedClassOrObjectSymbol:
|
||||
annotationClassIds: []
|
||||
annotations: []
|
||||
@@ -21,3 +22,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
+4
-2
@@ -1,11 +1,13 @@
|
||||
// RUNTIME
|
||||
|
||||
callable: kotlin/LazyThreadSafetyMode.SYNCHRONIZED
|
||||
// callable: kotlin/LazyThreadSafetyMode.SYNCHRONIZED
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirEnumEntrySymbol:
|
||||
annotatedType: [] kotlin/LazyThreadSafetyMode
|
||||
containingEnumClassIdIfNonLocal: kotlin/LazyThreadSafetyMode
|
||||
name: SYNCHRONIZED
|
||||
origin: LIBRARY
|
||||
symbolKind: MEMBER
|
||||
*/
|
||||
+4
-2
@@ -1,6 +1,7 @@
|
||||
callable: kotlin/collections/List.get
|
||||
// callable: kotlin/collections/List.get
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirFunctionSymbol:
|
||||
annotatedType: [] E
|
||||
annotationClassIds: []
|
||||
@@ -21,3 +22,4 @@ KtFirFunctionSymbol:
|
||||
typeParameters: []
|
||||
valueParameters: [KtFirFunctionValueParameterSymbol(index)]
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
+4
-2
@@ -1,6 +1,7 @@
|
||||
callable: kotlin/collections/List.listIterator
|
||||
// callable: kotlin/collections/List.listIterator
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirFunctionSymbol:
|
||||
annotatedType: [] kotlin/collections/ListIterator<E>
|
||||
annotationClassIds: []
|
||||
@@ -42,3 +43,4 @@ KtFirFunctionSymbol:
|
||||
typeParameters: []
|
||||
valueParameters: [KtFirFunctionValueParameterSymbol(index)]
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
+4
-2
@@ -1,6 +1,7 @@
|
||||
class: kotlin/collections/MutableMap.MutableEntry
|
||||
// class: kotlin/collections/MutableMap.MutableEntry
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirNamedClassOrObjectSymbol:
|
||||
annotationClassIds: []
|
||||
annotations: []
|
||||
@@ -19,3 +20,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: MEMBER
|
||||
typeParameters: [KtFirTypeParameterSymbol(K), KtFirTypeParameterSymbol(V)]
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
@@ -2,4 +2,14 @@ var x: Int = 0
|
||||
get() = <caret>field
|
||||
set(value) {
|
||||
field = value
|
||||
}
|
||||
}
|
||||
|
||||
// RESULT
|
||||
/*
|
||||
KtFirBackingFieldSymbol:
|
||||
annotatedType: [] kotlin/Int
|
||||
name: field
|
||||
origin: PROPERTY_BACKING_FIELD
|
||||
owningProperty: KtFirKotlinPropertySymbol(x)
|
||||
symbolKind: LOCAL
|
||||
*/
|
||||
|
||||
+1
-2
@@ -3,8 +3,8 @@
|
||||
fun x() {
|
||||
val a = <caret>ArrayList(listOf(1))
|
||||
}
|
||||
// RESULT
|
||||
|
||||
// RESULT
|
||||
/*
|
||||
KtFirConstructorSymbol:
|
||||
annotatedType: [] java/util/ArrayList<E>
|
||||
@@ -19,4 +19,3 @@ KtFirConstructorSymbol:
|
||||
valueParameters: [KtFirConstructorValueParameterSymbol(c)]
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
|
||||
+3
-1
@@ -1,7 +1,8 @@
|
||||
class A {
|
||||
}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirNamedClassOrObjectSymbol:
|
||||
annotationClassIds: []
|
||||
annotations: []
|
||||
@@ -20,3 +21,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
class A() {
|
||||
}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirConstructorSymbol:
|
||||
annotatedType: [] A
|
||||
annotationClassIds: []
|
||||
@@ -33,3 +34,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
+3
-1
@@ -3,7 +3,8 @@ class A() {
|
||||
constructor(y: Int, z: String) : this(y)
|
||||
}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirConstructorSymbol:
|
||||
annotatedType: [] A
|
||||
annotationClassIds: []
|
||||
@@ -91,3 +92,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
+3
-1
@@ -2,7 +2,8 @@ enum class X {
|
||||
Y, Z;
|
||||
}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirEnumEntrySymbol:
|
||||
annotatedType: [] X
|
||||
containingEnumClassIdIfNonLocal: X
|
||||
@@ -35,3 +36,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,8 @@ class A {
|
||||
fun y()
|
||||
}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirFunctionSymbol:
|
||||
annotatedType: [] kotlin/Int
|
||||
annotationClassIds: []
|
||||
@@ -64,3 +65,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
@@ -3,7 +3,8 @@ class A {
|
||||
val Int.y get() = this
|
||||
}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirKotlinPropertySymbol:
|
||||
annotatedType: [] kotlin/Int
|
||||
annotationClassIds: []
|
||||
@@ -84,3 +85,4 @@ KtFirNamedClassOrObjectSymbol:
|
||||
symbolKind: TOP_LEVEL
|
||||
typeParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
fun x(): Int = 10
|
||||
fun y() {}
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirFunctionSymbol:
|
||||
annotatedType: [] kotlin/Int
|
||||
annotationClassIds: []
|
||||
@@ -43,3 +44,4 @@ KtFirFunctionSymbol:
|
||||
typeParameters: []
|
||||
valueParameters: []
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
val x: Int = 10
|
||||
val Int.y get() = this
|
||||
|
||||
// SYMBOLS:
|
||||
// RESULT
|
||||
/*
|
||||
KtFirKotlinPropertySymbol:
|
||||
annotatedType: [] kotlin/Int
|
||||
annotationClassIds: []
|
||||
@@ -63,3 +64,4 @@ KtFirKotlinPropertySymbol:
|
||||
setter: null
|
||||
symbolKind: TOP_LEVEL
|
||||
visibility: PUBLIC
|
||||
*/
|
||||
|
||||
+2
-1
@@ -14,12 +14,13 @@ import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescrip
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
abstract class AbstractSymbolByFqNameTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
protected fun doTest(path: String) {
|
||||
val fakeKtFile = myFixture.configureByText("file.kt", "fun a() {}") as KtFile
|
||||
|
||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(path)
|
||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(Paths.get(path))
|
||||
|
||||
val renderedSymbols = executeOnPooledThreadInReadAction {
|
||||
analyze(fakeKtFile) {
|
||||
|
||||
+9
-4
@@ -13,12 +13,17 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
||||
object SymbolByFqName {
|
||||
fun getSymbolDataFromFile(filePath: String): SymbolData {
|
||||
val testFileText = FileUtil.loadFile(File(filePath))
|
||||
val identifier = testFileText.lineSequence().first { line -> SymbolData.identifiers.any { line.startsWith(it) } }
|
||||
return SymbolData.create(identifier)
|
||||
fun getSymbolDataFromFile(filePath: Path): SymbolData {
|
||||
val testFileText = FileUtil.loadFile(filePath.toFile())
|
||||
val identifier = testFileText.lineSequence().first { line ->
|
||||
SymbolData.identifiers.any { identifier ->
|
||||
line.startsWith(identifier) || line.startsWith("// $identifier")
|
||||
}
|
||||
}
|
||||
return SymbolData.create(identifier.removePrefix("// "))
|
||||
}
|
||||
|
||||
fun textWithRenderedSymbolData(filePath: String, rendered: String): String = buildString {
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.frontend.api.symbols
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.idea.test.framework.TestFileStructure
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
|
||||
abstract class AbstractSymbolByReferencePointerRestoreTest : AbstractSymbolPointerRestoreTest() {
|
||||
override fun KtAnalysisSession.collectSymbols(fileStructure: TestFileStructure): List<KtSymbol> {
|
||||
val referenceExpression = getElementOfTypeAtCaret<KtNameReferenceExpression>()
|
||||
return listOfNotNull(referenceExpression.mainReference.resolveToSymbol())
|
||||
}
|
||||
}
|
||||
+2
-1
@@ -27,7 +27,8 @@ abstract class AbstractSymbolByReferenceTest : AbstractKtIdeaTest() {
|
||||
|
||||
val actual = TestStructureRenderer.render(
|
||||
fileStructure,
|
||||
TestStructureExpectedDataBlock(renderedSymbol)
|
||||
TestStructureExpectedDataBlock(renderedSymbol),
|
||||
renderingMode = TestStructureRenderer.RenderingMode.ALL_BLOCKS_IN_MULTI_LINE_COMMENT,
|
||||
)
|
||||
KotlinTestUtils.assertEqualsToFile(fileStructure.filePath.toFile(), actual)
|
||||
}
|
||||
|
||||
+3
-2
@@ -7,11 +7,12 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.SymbolByFqName
|
||||
import org.jetbrains.kotlin.idea.test.framework.TestFileStructure
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
abstract class AbstractSymbolFromLibraryPointerRestoreTest : AbstractSymbolPointerRestoreTest() {
|
||||
override fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List<KtSymbol> {
|
||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(filePath)
|
||||
override fun KtAnalysisSession.collectSymbols(fileStructure: TestFileStructure): List<KtSymbol> {
|
||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(fileStructure.filePath)
|
||||
return with(symbolData) { toSymbols() }
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -6,13 +6,14 @@
|
||||
package org.jetbrains.kotlin.idea.frontend.api.symbols
|
||||
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.test.framework.TestFileStructure
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||
|
||||
abstract class AbstractSymbolFromSourcePointerRestoreTest : AbstractSymbolPointerRestoreTest() {
|
||||
override fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List<KtSymbol> =
|
||||
ktFile.collectDescendantsOfType<KtDeclaration>().map { declaration ->
|
||||
override fun KtAnalysisSession.collectSymbols(fileStructure: TestFileStructure): List<KtSymbol> =
|
||||
fileStructure.mainKtFile.collectDescendantsOfType<KtDeclaration>().map { declaration ->
|
||||
declaration.getSymbol()
|
||||
}
|
||||
}
|
||||
+55
-48
@@ -7,74 +7,81 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols
|
||||
|
||||
import com.intellij.openapi.application.runWriteAction
|
||||
import com.intellij.openapi.command.CommandProcessor
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.editor.Document
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction
|
||||
import org.jetbrains.kotlin.idea.analyseOnPooledThreadInReadAction
|
||||
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||
import org.jetbrains.kotlin.idea.frontend.api.SymbolByFqName
|
||||
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.framework.AbstractKtIdeaTest
|
||||
import org.jetbrains.kotlin.idea.test.framework.TestFileStructure
|
||||
import org.jetbrains.kotlin.idea.test.framework.TestStructureExpectedDataBlock
|
||||
import org.jetbrains.kotlin.idea.test.framework.TestStructureRenderer
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||
import org.jetbrains.kotlin.util.suffixIfNot
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
|
||||
abstract class AbstractSymbolPointerRestoreTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
abstract fun KtAnalysisSession.collectSymbols(filePath: String, ktFile: KtFile): List<KtSymbol>
|
||||
abstract class AbstractSymbolPointerRestoreTest : AbstractKtIdeaTest() {
|
||||
abstract fun KtAnalysisSession.collectSymbols(fileStructure: TestFileStructure): List<KtSymbol>
|
||||
|
||||
protected fun doTest(path: String) {
|
||||
val file = File(path)
|
||||
val ktFile = myFixture.configureByText(file.name.suffixIfNot(".kt"), FileUtil.loadFile(file)) as KtFile
|
||||
|
||||
val pointersWithRendered = executeOnPooledThreadInReadAction {
|
||||
analyze(ktFile) {
|
||||
collectSymbols(path, ktFile).map { symbol ->
|
||||
PointerWithRenderedSymbol(
|
||||
symbol.createPointer(),
|
||||
DebugSymbolRenderer.render(symbol)
|
||||
)
|
||||
}
|
||||
override fun doTestByFileStructure(fileStructure: TestFileStructure) {
|
||||
val pointersWithRendered = analyseOnPooledThreadInReadAction(fileStructure.mainKtFile) {
|
||||
collectSymbols(fileStructure).map { symbol ->
|
||||
PointerWithRenderedSymbol(
|
||||
symbol.createPointer(),
|
||||
DebugSymbolRenderer.render(symbol)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val actual = SymbolByFqName.textWithRenderedSymbolData(
|
||||
path,
|
||||
pointersWithRendered.joinToString(separator = "\n") { it.rendered },
|
||||
val actual = TestStructureRenderer.render(
|
||||
fileStructure,
|
||||
TestStructureExpectedDataBlock(values = pointersWithRendered.map { it.rendered }),
|
||||
renderingMode = TestStructureRenderer.RenderingMode.ALL_BLOCKS_IN_MULTI_LINE_COMMENT,
|
||||
)
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(File(path), actual)
|
||||
KotlinTestUtils.assertEqualsToFile(fileStructure.filePath.toFile(), actual)
|
||||
|
||||
doOutOfBlockModification(fileStructure.mainKtFile)
|
||||
|
||||
restoreSymbolsInOtherReadActionAndCompareResults(fileStructure, pointersWithRendered)
|
||||
}
|
||||
|
||||
private fun restoreSymbolsInOtherReadActionAndCompareResults(
|
||||
fileStructure: TestFileStructure,
|
||||
pointersWithRendered: List<PointerWithRenderedSymbol>
|
||||
) {
|
||||
val restored = analyseOnPooledThreadInReadAction(fileStructure.mainKtFile) {
|
||||
pointersWithRendered.map { (pointer, expectedRender) ->
|
||||
val restored = pointer.restoreSymbol() ?: error("Symbol $expectedRender was not not restored correctly")
|
||||
DebugSymbolRenderer.render(restored)
|
||||
}
|
||||
}
|
||||
val actualRestored = TestStructureRenderer.render(
|
||||
fileStructure,
|
||||
TestStructureExpectedDataBlock(values = restored),
|
||||
renderingMode = TestStructureRenderer.RenderingMode.ALL_BLOCKS_IN_MULTI_LINE_COMMENT,
|
||||
)
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(fileStructure.filePath.toFile(), actualRestored)
|
||||
}
|
||||
|
||||
private fun doOutOfBlockModification(ktFile: KtFile) {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction {
|
||||
runWriteAction {
|
||||
KtPsiFactory(ktFile).apply {
|
||||
ktFile.add(createNewLine(lineBreaks = 2))
|
||||
ktFile.add(createProperty("val aaaaaa: Int = 10"))
|
||||
}
|
||||
PsiDocumentManager.getInstance(project).apply {
|
||||
commitDocument(getDocument(ktFile) ?: error("Cannot find document for ktFile"))
|
||||
}
|
||||
val document = PsiDocumentManager.getInstance(project).getDocument(ktFile) ?: error("Cannot find document for ktFile")
|
||||
val initialText = ktFile.text
|
||||
val ktPsiFactory = KtPsiFactory(ktFile)
|
||||
ktFile.add(ktPsiFactory.createNewLine(lineBreaks = 2))
|
||||
ktFile.add(ktPsiFactory.createProperty("val aaaaaa: Int = 10"))
|
||||
commitDocument(document)
|
||||
document.setText(initialText)
|
||||
commitDocument(document)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// another read action
|
||||
executeOnPooledThreadInReadAction {
|
||||
analyze(ktFile) {
|
||||
val restored = pointersWithRendered.map { (pointer, expectedRender) ->
|
||||
val restored = pointer.restoreSymbol() ?: error("Symbol $expectedRender was not not restored correctly")
|
||||
DebugSymbolRenderer.render(restored)
|
||||
}
|
||||
val actualRestored = SymbolByFqName.textWithRenderedSymbolData(
|
||||
path,
|
||||
restored.joinToString(separator = "\n"),
|
||||
)
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(File(path), actualRestored)
|
||||
}
|
||||
}
|
||||
private fun commitDocument(document: Document) {
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.frontend.api.symbols;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.JUnit3RunnerWithInners;
|
||||
import org.jetbrains.kotlin.test.KotlinTestUtils;
|
||||
import org.jetbrains.kotlin.test.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/testData/symbolByReference")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class SymbolByReferencePointerRestoreTestGenerated extends AbstractSymbolByReferencePointerRestoreTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
@TestMetadata("accessorField.kt")
|
||||
public void testAccessorField() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/symbolByReference/accessorField.kt");
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInSymbolByReference() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/symbolByReference"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constructorViaTypeAlias.kt")
|
||||
public void testConstructorViaTypeAlias() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/symbolByReference/constructorViaTypeAlias.kt");
|
||||
}
|
||||
}
|
||||
+13
-13
@@ -26,36 +26,36 @@ public class SymbolFromLibraryPointerRestoreTestGenerated extends AbstractSymbol
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInResoreSymbolFromLibrary() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary"), Pattern.compile("^(.+)\\.txt$"), null, true);
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@TestMetadata("class.txt")
|
||||
@TestMetadata("class.kt")
|
||||
public void testClass() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/class.txt");
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/class.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("classFromJdk.txt")
|
||||
@TestMetadata("classFromJdk.kt")
|
||||
public void testClassFromJdk() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.txt");
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/classFromJdk.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("enumEntry.txt")
|
||||
@TestMetadata("enumEntry.kt")
|
||||
public void testEnumEntry() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/enumEntry.txt");
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/enumEntry.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberFunction.txt")
|
||||
@TestMetadata("memberFunction.kt")
|
||||
public void testMemberFunction() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/memberFunction.txt");
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/memberFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("memberFunctionWithOverloads.txt")
|
||||
@TestMetadata("memberFunctionWithOverloads.kt")
|
||||
public void testMemberFunctionWithOverloads() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/memberFunctionWithOverloads.txt");
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/memberFunctionWithOverloads.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedClass.txt")
|
||||
@TestMetadata("nestedClass.kt")
|
||||
public void testNestedClass() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/nestedClass.txt");
|
||||
runTest("idea/idea-frontend-fir/testData/resoreSymbolFromLibrary/nestedClass.kt");
|
||||
}
|
||||
}
|
||||
|
||||
+41
-26
@@ -8,19 +8,25 @@ package org.jetbrains.kotlin.idea.test.framework
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStartOffsetIn
|
||||
|
||||
object TestStructureRenderer {
|
||||
fun render(testStructure: TestFileStructure, vararg expectedData: TestStructureExpectedDataBlock): String = buildString {
|
||||
fun render(
|
||||
testStructure: TestFileStructure,
|
||||
vararg expectedData: TestStructureExpectedDataBlock,
|
||||
renderingMode: RenderingMode = RenderingMode.EVERY_LINE_WITH_SINGLE_LINE_COMMENT,
|
||||
): String =
|
||||
render(testStructure, expectedData.toList(), renderingMode)
|
||||
|
||||
fun render(
|
||||
testStructure: TestFileStructure,
|
||||
expectedData: List<TestStructureExpectedDataBlock>,
|
||||
renderingMode: RenderingMode = RenderingMode.EVERY_LINE_WITH_SINGLE_LINE_COMMENT
|
||||
): String = buildString {
|
||||
renderFiles(testStructure)
|
||||
renderExpectedData(expectedData.toList())
|
||||
appendLine()
|
||||
renderExpectedData(expectedData, renderingMode)
|
||||
renderCaretSymbol(testStructure)
|
||||
renderExpressionTag(testStructure)
|
||||
}
|
||||
|
||||
fun render(testStructure: TestFileStructure, expectedData: List<TestStructureExpectedDataBlock>): String = buildString {
|
||||
renderFiles(testStructure)
|
||||
renderExpectedData(expectedData)
|
||||
renderCaretSymbol(testStructure)
|
||||
}
|
||||
|
||||
private fun StringBuilder.renderCaretSymbol(testStructure: TestFileStructure) {
|
||||
testStructure.caretPosition?.let { position ->
|
||||
insert(position, KtTest.CARET_SYMBOL)
|
||||
@@ -45,29 +51,33 @@ object TestStructureRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
private fun StringBuilder.renderExpectedData(expectedData: List<TestStructureExpectedDataBlock>) {
|
||||
if (expectedData.isNotEmpty()) {
|
||||
appendLine(KtTest.RESULT_DIRECTIVE)
|
||||
appendLine()
|
||||
expectedData.forEach { block ->
|
||||
renderExpectedDataBlock(block)
|
||||
private fun StringBuilder.renderExpectedData(expectedData: List<TestStructureExpectedDataBlock>, renderingMode: RenderingMode) {
|
||||
if (expectedData.isEmpty()) return
|
||||
appendLine(KtTest.RESULT_DIRECTIVE)
|
||||
if (renderingMode == RenderingMode.ALL_BLOCKS_IN_MULTI_LINE_COMMENT) {
|
||||
appendLine("/*")
|
||||
}
|
||||
expectedData.forEachIndexed { index, block ->
|
||||
renderExpectedDataBlock(
|
||||
block,
|
||||
asSingleLineComment = renderingMode == RenderingMode.EVERY_LINE_WITH_SINGLE_LINE_COMMENT
|
||||
)
|
||||
if (index != expectedData.lastIndex) {
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
if (renderingMode == RenderingMode.ALL_BLOCKS_IN_MULTI_LINE_COMMENT) {
|
||||
appendLine("*/")
|
||||
}
|
||||
}
|
||||
|
||||
private fun StringBuilder.renderExpectedDataBlock(block: TestStructureExpectedDataBlock) {
|
||||
block.name?.let { name -> appendLine("// $name") }
|
||||
block.values.forEach { value ->
|
||||
if (value.lines().size > 1) {
|
||||
appendLine(
|
||||
"""|/*
|
||||
|${value.trim()}
|
||||
|*/
|
||||
""".trimMargin()
|
||||
)
|
||||
} else {
|
||||
appendLine("// $value")
|
||||
private fun StringBuilder.renderExpectedDataBlock(block: TestStructureExpectedDataBlock, asSingleLineComment: Boolean) {
|
||||
val singleLineCommentPrefix = if (asSingleLineComment) "// " else ""
|
||||
block.name?.let { name -> appendLine("$singleLineCommentPrefix$name") }
|
||||
block.values.forEachIndexed { index, value ->
|
||||
appendLine("$singleLineCommentPrefix${value.trim()}")
|
||||
if (index != block.values.lastIndex && !asSingleLineComment) {
|
||||
appendLine()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -77,4 +87,9 @@ object TestStructureRenderer {
|
||||
appendLine(file.psiFile.text)
|
||||
appendLine()
|
||||
}
|
||||
|
||||
enum class RenderingMode {
|
||||
EVERY_LINE_WITH_SINGLE_LINE_COMMENT,
|
||||
ALL_BLOCKS_IN_MULTI_LINE_COMMENT
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user