diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/KotlinFirPsiChecker.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/KotlinFirPsiChecker.kt index 9ca4d16a447..804f1f6ec18 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/KotlinFirPsiChecker.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/KotlinFirPsiChecker.kt @@ -12,6 +12,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.idea.fir.highlighter.visitors.FirAfterResolveHighlightingVisitor import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.analyze import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.idea.highlighter.AbstractKotlinPsiChecker import org.jetbrains.kotlin.idea.highlighter.Diagnostic2Annotation @@ -29,13 +30,13 @@ class KotlinFirPsiChecker : AbstractKotlinPsiChecker() { if (ApplicationManager.getApplication().isDispatchThread) { throw ProcessCanceledException() } - val analysisSession = KtFirAnalysisSession(element) + analyze(element) { + highlightDiagnostics(element, this, holder) - highlightDiagnostics(element, analysisSession, holder) - - FirAfterResolveHighlightingVisitor - .createListOfVisitors(analysisSession, holder) - .forEach(element::accept) + FirAfterResolveHighlightingVisitor + .createListOfVisitors(this, holder) + .forEach(element::accept) + } } private fun highlightDiagnostics(element: KtElement, analysisSession: KtAnalysisSession, holder: AnnotationHolder) { diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSessionProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSessionProvider.kt new file mode 100644 index 00000000000..fe104557812 --- /dev/null +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSessionProvider.kt @@ -0,0 +1,27 @@ +/* + * 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 + +import com.intellij.openapi.components.service +import org.jetbrains.kotlin.idea.util.application.runReadAction +import org.jetbrains.kotlin.psi.KtElement + +abstract class KtAnalysisSessionProvider { + abstract fun getAnalysisSessionFor(contextElement: KtElement): KtAnalysisSession +} + +fun getAnalysisSessionFor(contextElement: KtElement): KtAnalysisSession = + service().getAnalysisSessionFor(contextElement) + +inline fun analyze(contextElement: KtElement, action: KtAnalysisSession.() -> R): R = + getAnalysisSessionFor(contextElement).action() + +inline fun analyzeWithReadAction( + contextElement: KtElement, + crossinline action: KtAnalysisSession.() -> R +): R = runReadAction { + analyze(contextElement, action) +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt index 9a44a9e8fc8..fcdbf4da73d 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSession.kt @@ -33,7 +33,9 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* -class KtFirAnalysisSession( +class KtFirAnalysisSession +@Deprecated("Please use org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProviderKt.analyze") +constructor( private val element: KtElement ) : KtAnalysisSession(element.project) { internal val token get() = validityToken diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt new file mode 100644 index 00000000000..f7ad3ea74e9 --- /dev/null +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/KtFirAnalysisSessionProvider.kt @@ -0,0 +1,16 @@ +/* + * 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.fir + +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSessionProvider +import org.jetbrains.kotlin.psi.KtElement + +class KtFirAnalysisSessionProvider : KtAnalysisSessionProvider() { + @Suppress("DEPRECATION") + override fun getAnalysisSessionFor(contextElement: KtElement): KtAnalysisSession = + KtFirAnalysisSession(contextElement) +} \ No newline at end of file diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReferenceResolver.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReferenceResolver.kt index b63774a0872..5479f32c156 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReferenceResolver.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/KtFirReferenceResolver.kt @@ -11,7 +11,9 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiElementResolveResult import com.intellij.psi.ResolveResult import com.intellij.psi.impl.source.resolve.ResolveCache +import org.jetbrains.kotlin.idea.frontend.api.analyze import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.getAnalysisSessionFor object KtFirReferenceResolver : ResolveCache.PolyVariantResolver { class KotlinResolveResult(element: PsiElement) : PsiElementResolveResult(element) @@ -22,8 +24,7 @@ object KtFirReferenceResolver : ResolveCache.PolyVariantResolver { if (ApplicationManager.getApplication().isDispatchThread) { throw ProcessCanceledException() } - val analysisSession = KtFirAnalysisSession(ref.expression) - val resolveToPsiElements = ref.getResolvedToPsi(analysisSession) + val resolveToPsiElements = analyze(ref.expression) { ref.getResolvedToPsi(this) } return resolveToPsiElements.map { KotlinResolveResult(it) }.toTypedArray() } } \ No newline at end of file diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt index 9c5d13b5b39..caeab15f481 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/fir/AbstractResolveCallTest.kt @@ -11,6 +11,7 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.addExternalTestFiles import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.idea.frontend.api.CallInfo +import org.jetbrains.kotlin.idea.frontend.api.analyze import org.jetbrains.kotlin.idea.frontend.api.types.KtType import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol @@ -39,12 +40,13 @@ abstract class AbstractResolveCallTest : @Suppress("DEPRECATION") KotlinLightCod } val actualText = executeOnPooledThreadInReadAction { - val analysisSession = KtFirAnalysisSession(file as KtFile) - val callInfos = elements.map { element -> - when (element) { - is KtCallExpression -> analysisSession.resolveCall(element) - is KtBinaryExpression -> analysisSession.resolveCall(element) - else -> error("Selected should be either KtCallExpression or KtBinaryExpression but was $element") + val callInfos = analyze(file as KtFile) { + elements.map { element -> + when (element) { + is KtCallExpression -> resolveCall(element) + is KtBinaryExpression -> resolveCall(element) + else -> error("Selected should be either KtCallExpression or KtBinaryExpression but was $element") + } } } diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/scopes/MemberScopeByFqNameTestGenerated.java b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/scopes/MemberScopeByFqNameTestGenerated.java new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt index 978834ecfa2..531eea35748 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractStdlibSymbolsBuildingTest.kt @@ -35,9 +35,10 @@ abstract class AbstractStdlibSymbolsBuildingTest : KotlinLightCodeInsightFixture val symbolData = SymbolData.create(identifier) val renderedSymbols = executeOnPooledThreadInReadAction { - val analysisSession = KtFirAnalysisSession(fakeKtFile) - val symbols = symbolData.toSymbols(analysisSession) - symbols.map { DebugSymbolRenderer.render(it) } + analyze(fakeKtFile) { + val symbols = symbolData.toSymbols(this) + symbols.map { DebugSymbolRenderer.render(it) } + } } val actual = buildString { @@ -49,6 +50,7 @@ abstract class AbstractStdlibSymbolsBuildingTest : KotlinLightCodeInsightFixture append(actualSymbolsData) } KotlinTestUtils.assertEqualsToFile(testDataFile, actual) + } } diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerTest.kt index 2645f0a9ab5..d4db2c6af0c 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolPointerTest.kt @@ -10,7 +10,9 @@ import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.addExternalTestFiles import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction import org.jetbrains.kotlin.idea.frontend.api.KtAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.analyze import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.getAnalysisSessionFor import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinLightProjectDescriptor import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor @@ -31,19 +33,21 @@ abstract class AbstractSymbolPointerTest : KotlinLightCodeInsightFixtureTestCase val ktFile = myFixture.configureByText(file.name, FileUtil.loadFile(file)) as KtFile val pointers = executeOnPooledThreadInReadAction { - val analysisSession = KtFirAnalysisSession(ktFile) - val declarationSymbols = ktFile.collectDescendantsOfType().map { declaration -> - analysisSession.symbolProvider.getSymbol(declaration) + analyze(ktFile) { + val declarationSymbols = ktFile.collectDescendantsOfType().map { declaration -> + symbolProvider.getSymbol(declaration) + } + declarationSymbols.map { PointerWithPsi(it.createPointer(), it.psi!!) } } - declarationSymbols.map { PointerWithPsi(it.createPointer(), it.psi!!) } } // another read action executeOnPooledThreadInReadAction { - val analysisSession = KtFirAnalysisSession(ktFile) - pointers.forEach { (pointer, psi) -> - val restored = pointer.restoreSymbol(analysisSession) ?: error("Symbol $psi was not not restored correctly") - Assert.assertEquals(restored.psi!!, psi) + analyze(ktFile) { + pointers.forEach { (pointer, psi) -> + val restored = pointer.restoreSymbol(this) ?: error("Symbol $psi was not not restored correctly") + Assert.assertEquals(restored.psi!!, psi) + } } } } diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt index a9a35b079b4..01fd0bac070 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/AbstractSymbolsByPsiBuildingTest.kt @@ -8,7 +8,9 @@ package org.jetbrains.kotlin.idea.frontend.api.symbols import com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.idea.addExternalTestFiles import org.jetbrains.kotlin.idea.executeOnPooledThreadInReadAction +import org.jetbrains.kotlin.idea.frontend.api.analyze import org.jetbrains.kotlin.idea.frontend.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.idea.frontend.api.getAnalysisSessionFor import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtFile @@ -23,11 +25,12 @@ abstract class AbstractSymbolsByPsiBuildingTest : KotlinLightCodeInsightFixtureT val ktFile = myFixture.configureByText(file.name, FileUtil.loadFile(file)) as KtFile val renderedSymbols = executeOnPooledThreadInReadAction { - val analysisSession = KtFirAnalysisSession(ktFile) - val declarationSymbols = ktFile.collectDescendantsOfType().map { declaration -> - analysisSession.symbolProvider.getSymbol(declaration) + analyze(ktFile) { + val declarationSymbols = ktFile.collectDescendantsOfType().map { declaration -> + symbolProvider.getSymbol(declaration) + } + declarationSymbols.map(DebugSymbolRenderer::render) } - declarationSymbols.map(DebugSymbolRenderer::render) } val actual = buildString { diff --git a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java index 3bc22f8a6f4..eb2392303b6 100644 --- a/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java +++ b/idea/idea-frontend-fir/tests/org/jetbrains/kotlin/idea/frontend/api/symbols/StdlibSymbolsBuildingTestGenerated.java @@ -16,7 +16,7 @@ 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/stdLibSymbols") +@TestMetadata("idea/idea-frontend-fir/testData/symbolsByFqName") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public class StdlibSymbolsBuildingTestGenerated extends AbstractStdlibSymbolsBuildingTest { @@ -24,22 +24,22 @@ public class StdlibSymbolsBuildingTestGenerated extends AbstractStdlibSymbolsBui KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } - public void testAllFilesPresentInStdLibSymbols() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/stdLibSymbols"), Pattern.compile("^(.+)\\.txt$"), null, true); + public void testAllFilesPresentInSymbolsByFqName() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/testData/symbolsByFqName"), Pattern.compile("^(.+)\\.txt$"), null, true); } @TestMetadata("fileWalkDirectionEnum.txt") public void testFileWalkDirectionEnum() throws Exception { - runTest("idea/idea-frontend-fir/testData/stdLibSymbols/fileWalkDirectionEnum.txt"); + runTest("idea/idea-frontend-fir/testData/symbolsByFqName/fileWalkDirectionEnum.txt"); } @TestMetadata("iterator.txt") public void testIterator() throws Exception { - runTest("idea/idea-frontend-fir/testData/stdLibSymbols/iterator.txt"); + runTest("idea/idea-frontend-fir/testData/symbolsByFqName/iterator.txt"); } @TestMetadata("listOf.txt") public void testListOf() throws Exception { - runTest("idea/idea-frontend-fir/testData/stdLibSymbols/listOf.txt"); + runTest("idea/idea-frontend-fir/testData/symbolsByFqName/listOf.txt"); } } diff --git a/idea/resources-fir/META-INF/plugin.xml b/idea/resources-fir/META-INF/plugin.xml index d68424599ad..0cd46317e94 100644 --- a/idea/resources-fir/META-INF/plugin.xml +++ b/idea/resources-fir/META-INF/plugin.xml @@ -81,6 +81,8 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu +