FIR IDE: fix constructor symbol building for type alias constructors
This commit is contained in:
@@ -1022,6 +1022,11 @@ fun main(args: Array<String>) {
|
|||||||
model("symbolsByFqName", extension = "txt")
|
model("symbolsByFqName", extension = "txt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
testClass<AbstractSymbolByReferenceTest> {
|
||||||
|
model("symbolByReference")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractMemberScopeByFqNameTest> {
|
testClass<AbstractMemberScopeByFqNameTest> {
|
||||||
model("memberScopeByFqName", extension = "txt")
|
model("memberScopeByFqName", extension = "txt")
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.FirElement
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.originalConstructorIfTypeAlias
|
||||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
import org.jetbrains.kotlin.fir.resolve.getSymbolByLookupTag
|
||||||
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
|
import org.jetbrains.kotlin.fir.resolve.inference.isFunctionalType
|
||||||
@@ -134,7 +135,10 @@ internal class KtSymbolByFirBuilder private constructor(
|
|||||||
KtFirFunctionSymbol(fir, resolveState, token, this)
|
KtFirFunctionSymbol(fir, resolveState, token, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildConstructorSymbol(fir: FirConstructor) = symbolsCache.cache(fir) { KtFirConstructorSymbol(fir, resolveState, token, this) }
|
fun buildConstructorSymbol(fir: FirConstructor): KtFirConstructorSymbol {
|
||||||
|
val originalFir = fir.originalConstructorIfTypeAlias ?: fir
|
||||||
|
return symbolsCache.cache(originalFir) { KtFirConstructorSymbol(originalFir, resolveState, token, this) }
|
||||||
|
}
|
||||||
fun buildTypeParameterSymbol(fir: FirTypeParameter) =
|
fun buildTypeParameterSymbol(fir: FirTypeParameter) =
|
||||||
symbolsCache.cache(fir) { KtFirTypeParameterSymbol(fir, resolveState, token, this) }
|
symbolsCache.cache(fir) { KtFirTypeParameterSymbol(fir, resolveState, token, this) }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun x() {
|
||||||
|
val a = <caret>ArrayList(listOf(1))
|
||||||
|
}
|
||||||
|
// RESULT
|
||||||
|
|
||||||
|
/*
|
||||||
|
KtFirConstructorSymbol:
|
||||||
|
annotatedType: [] java/util/ArrayList<E>
|
||||||
|
annotationClassIds: []
|
||||||
|
annotations: []
|
||||||
|
containingClassIdIfNonLocal: java/util/ArrayList
|
||||||
|
dispatchType: java/util/ArrayList<E>
|
||||||
|
isPrimary: false
|
||||||
|
origin: JAVA
|
||||||
|
symbolKind: MEMBER
|
||||||
|
typeParameters: [KtFirTypeParameterSymbol(E)]
|
||||||
|
valueParameters: [KtFirConstructorValueParameterSymbol(c)]
|
||||||
|
visibility: PUBLIC
|
||||||
|
*/
|
||||||
|
|
||||||
+1
-6
@@ -24,7 +24,7 @@ abstract class AbstractOverriddenDeclarationProviderTest : AbstractKtIdeaTest()
|
|||||||
override fun doTestByFileStructure(fileStructure: TestFileStructure) {
|
override fun doTestByFileStructure(fileStructure: TestFileStructure) {
|
||||||
val signatures = executeOnPooledThreadInReadAction {
|
val signatures = executeOnPooledThreadInReadAction {
|
||||||
analyze(fileStructure.mainKtFile) {
|
analyze(fileStructure.mainKtFile) {
|
||||||
val symbol = getDeclarationAtCaret().getSymbol() as KtCallableSymbol
|
val symbol = getElementOfTypeAtCaret<KtDeclaration>().getSymbol() as KtCallableSymbol
|
||||||
val allOverriddenSymbols = symbol.getAllOverriddenSymbols().map { renderSignature(it) }
|
val allOverriddenSymbols = symbol.getAllOverriddenSymbols().map { renderSignature(it) }
|
||||||
val directlyOverriddenSymbols = symbol.getDirectlyOverriddenSymbols().map { renderSignature(it) }
|
val directlyOverriddenSymbols = symbol.getDirectlyOverriddenSymbols().map { renderSignature(it) }
|
||||||
listOf(
|
listOf(
|
||||||
@@ -67,9 +67,4 @@ abstract class AbstractOverriddenDeclarationProviderTest : AbstractKtIdeaTest()
|
|||||||
.joinToString(separator = ".")
|
.joinToString(separator = ".")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDeclarationAtCaret(): KtDeclaration =
|
|
||||||
file.findElementAt(myFixture.caretOffset)
|
|
||||||
?.parentOfType()
|
|
||||||
?: error("No KtDeclaration found at caret with position ${myFixture.caretOffset}")
|
|
||||||
}
|
}
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* 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 org.jetbrains.kotlin.idea.analyseOnPooledThreadInReadAction
|
||||||
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
|
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.KtNameReferenceExpression
|
||||||
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
|
|
||||||
|
abstract class AbstractSymbolByReferenceTest : AbstractKtIdeaTest() {
|
||||||
|
override fun doTestByFileStructure(fileStructure: TestFileStructure) {
|
||||||
|
val referenceExpression = getElementOfTypeAtCaret<KtNameReferenceExpression>()
|
||||||
|
val reference = referenceExpression.mainReference
|
||||||
|
val renderedSymbol = analyseOnPooledThreadInReadAction(fileStructure.mainKtFile) {
|
||||||
|
val symbol = reference.resolveToSymbol()
|
||||||
|
?: error("${referenceExpression.text} was not resolved to anything")
|
||||||
|
DebugSymbolRenderer.render(symbol)
|
||||||
|
}
|
||||||
|
|
||||||
|
val actual = TestStructureRenderer.render(
|
||||||
|
fileStructure,
|
||||||
|
TestStructureExpectedDataBlock(renderedSymbol)
|
||||||
|
)
|
||||||
|
KotlinTestUtils.assertEqualsToFile(fileStructure.filePath.toFile(), actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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 SymbolByReferenceTestGenerated extends AbstractSymbolByReferenceTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -9,6 +9,7 @@ import com.intellij.openapi.util.io.FileUtil
|
|||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.util.parentOfType
|
import com.intellij.psi.util.parentOfType
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||||
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@@ -64,6 +65,11 @@ abstract class AbstractKtIdeaTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected inline fun <reified P : PsiElement> getElementOfTypeAtCaret(): P =
|
||||||
|
file.findElementAt(myFixture.caretOffset)
|
||||||
|
?.parentOfType<P>()
|
||||||
|
?: error("No ${P::class.simpleName} found at caret with position ${myFixture.caretOffset}")
|
||||||
|
|
||||||
abstract fun doTestByFileStructure(fileStructure: TestFileStructure)
|
abstract fun doTestByFileStructure(fileStructure: TestFileStructure)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -59,7 +59,16 @@ object TestStructureRenderer {
|
|||||||
private fun StringBuilder.renderExpectedDataBlock(block: TestStructureExpectedDataBlock) {
|
private fun StringBuilder.renderExpectedDataBlock(block: TestStructureExpectedDataBlock) {
|
||||||
block.name?.let { name -> appendLine("// $name") }
|
block.name?.let { name -> appendLine("// $name") }
|
||||||
block.values.forEach { value ->
|
block.values.forEach { value ->
|
||||||
appendLine("// $value")
|
if (value.lines().size > 1) {
|
||||||
|
appendLine(
|
||||||
|
"""|/*
|
||||||
|
|${value.trim()}
|
||||||
|
|*/
|
||||||
|
""".trimMargin()
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
appendLine("// $value")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,20 @@ import com.intellij.testFramework.LightPlatformTestCase
|
|||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.DuplicatedFirSourceElementsException
|
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.DuplicatedFirSourceElementsException
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
||||||
|
import org.jetbrains.kotlin.psi.KtElement
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
fun <R> executeOnPooledThreadInReadAction(action: () -> R): R =
|
fun <R> executeOnPooledThreadInReadAction(action: () -> R): R =
|
||||||
ApplicationManager.getApplication().executeOnPooledThread<R> { runReadAction(action) }.get()
|
ApplicationManager.getApplication().executeOnPooledThread<R> { runReadAction(action) }.get()
|
||||||
|
|
||||||
|
inline fun <R> analyseOnPooledThreadInReadAction(context: KtElement, crossinline action: KtAnalysisSession.() -> R): R =
|
||||||
|
executeOnPooledThreadInReadAction {
|
||||||
|
analyze(context) { action() }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun addExternalTestFiles(testDataFilePath: String) {
|
fun addExternalTestFiles(testDataFilePath: String) {
|
||||||
File(testDataFilePath).getExternalFiles().forEach(::addFile)
|
File(testDataFilePath).getExternalFiles().forEach(::addFile)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user