Revert "[FIR]: sealed hierarchy processor for IDE"
This reverts commit e6ccdff2
This commit is contained in:
+11
-1
@@ -44,4 +44,14 @@ abstract class FirAbstractPhaseTransformer<D>(
|
||||
"File ${file.name} and transformer ${this::class} have inconsistent sessions"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun FirFile.runResolve(toPhase: FirResolvePhase, fromPhase: FirResolvePhase = FirResolvePhase.RAW_FIR) {
|
||||
val scopeSession = ScopeSession()
|
||||
var currentPhase = fromPhase
|
||||
while (currentPhase < toPhase) {
|
||||
currentPhase = currentPhase.next
|
||||
val phaseProcessor = currentPhase.createTransformerBasedProcessorByPhase(session, scopeSession)
|
||||
phaseProcessor.processFile(this)
|
||||
}
|
||||
}
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2019 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.fir.resolve.transformers
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
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.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
|
||||
/*
|
||||
* This processor is needed only for IDE until there won't be proper IDE implementation
|
||||
* for detecting sealed inheritors in multiple files
|
||||
*/
|
||||
class FirLegacySealedClassInheritorsProcessor(session: FirSession, scopeSession: ScopeSession) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
override val transformer = FirLegacySealedClassInheritorsTransformer()
|
||||
}
|
||||
|
||||
class FirLegacySealedClassInheritorsTransformer : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
throw IllegalStateException("Should not be there")
|
||||
}
|
||||
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
||||
file.accept(FirSealedClassInheritorsProcessor.InheritorsCollector, sealedClassInheritorsMap)
|
||||
if (sealedClassInheritorsMap.isEmpty()) return file.compose()
|
||||
return file.transform(FirSealedClassInheritorsProcessor.InheritorsTransformer(sealedClassInheritorsMap), null)
|
||||
}
|
||||
}
|
||||
+11
-1
@@ -41,7 +41,17 @@ fun createAllCompilerResolveProcessors(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T : FirResolveProcessor> createAllResolveProcessors(
|
||||
fun createAllTransformerBasedResolveProcessors(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession? = null,
|
||||
pluginPhasesEnabled: Boolean = false,
|
||||
): List<FirTransformerBasedResolveProcessor> {
|
||||
return createAllResolveProcessors(scopeSession, pluginPhasesEnabled) {
|
||||
createTransformerBasedProcessorByPhase(session, it)
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun <T : FirResolveProcessor> createAllResolveProcessors(
|
||||
scopeSession: ScopeSession? = null,
|
||||
pluginPhasesEnabled: Boolean,
|
||||
creator: FirResolvePhase.(ScopeSession) -> T
|
||||
|
||||
+23
-1
@@ -40,7 +40,29 @@ fun FirResolvePhase.createCompilerProcessorByPhase(
|
||||
}
|
||||
}
|
||||
|
||||
class FirDummyTransformerBasedProcessor(
|
||||
fun FirResolvePhase.createTransformerBasedProcessorByPhase(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
): FirTransformerBasedResolveProcessor {
|
||||
return when (this) {
|
||||
RAW_FIR -> throw IllegalStateException("Raw FIR building phase does not have a transformer")
|
||||
ANNOTATIONS_FOR_PLUGINS -> FirPluginAnnotationsResolveProcessor(session, scopeSession)
|
||||
CLASS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove
|
||||
IMPORTS -> FirImportResolveProcessor(session, scopeSession)
|
||||
SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
|
||||
SEALED_CLASS_INHERITORS -> FirLegacySealedClassInheritorsProcessor(session, scopeSession)
|
||||
TYPES -> FirTypeResolveProcessor(session, scopeSession)
|
||||
ARGUMENTS_OF_PLUGIN_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
|
||||
EXTENSION_STATUS_UPDATE -> FirTransformerBasedExtensionStatusProcessor(session, scopeSession)
|
||||
STATUS -> FirStatusResolveProcessor(session, scopeSession)
|
||||
CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
|
||||
NEW_MEMBERS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove
|
||||
IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveProcessor(session, scopeSession)
|
||||
BODY_RESOLVE -> FirBodyResolveProcessor(session, scopeSession)
|
||||
}
|
||||
}
|
||||
|
||||
private class FirDummyTransformerBasedProcessor(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
) : FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
|
||||
@@ -79,7 +79,6 @@ import org.jetbrains.kotlin.idea.editor.backspaceHandler.AbstractBackspaceHandle
|
||||
import org.jetbrains.kotlin.idea.editor.quickDoc.AbstractQuickDocProviderTest
|
||||
import org.jetbrains.kotlin.idea.filters.AbstractKotlinExceptionFilterTest
|
||||
import org.jetbrains.kotlin.idea.fir.AbstractKtDeclarationAndFirDeclarationEqualityChecker
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.*
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyDeclarationResolveTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirLazyResolveTest
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.AbstractFirMultiModuleLazyResolveTest
|
||||
@@ -1063,9 +1062,6 @@ fun main(args: Array<String>) {
|
||||
testClass<AbstractFirMultiModuleLazyResolveTest> {
|
||||
model("multiModuleLazyResolve", recursive = false, extension = null)
|
||||
}
|
||||
testClass<AbstractFirSealedInheritorsTest> {
|
||||
model("resolveSealed", recursive = false, extension = null)
|
||||
}
|
||||
testClass<AbstractFirLazyDeclarationResolveTest> {
|
||||
model("lazyResolve")
|
||||
}
|
||||
|
||||
-101
@@ -1,101 +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.openapi.module.Module
|
||||
import com.intellij.psi.JavaDirectoryService
|
||||
import com.intellij.psi.PsiPackage
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.PackageScope
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.fir.FirElement
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirSealedClassInheritorsProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.visitors.CompositeTransformResult
|
||||
import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor
|
||||
import org.jetbrains.kotlin.fir.visitors.FirTransformer
|
||||
import org.jetbrains.kotlin.fir.visitors.compose
|
||||
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.resolve.jvm.KotlinJavaPsiFacade
|
||||
|
||||
|
||||
class FirIdeSealedHierarchyProcessor(session: FirSession, scopeSession: ScopeSession) :
|
||||
FirTransformerBasedResolveProcessor(session, scopeSession) {
|
||||
|
||||
override val transformer: FirTransformer<Nothing?> = SealedClassInheritorsTransformer
|
||||
|
||||
|
||||
private object SealedClassInheritorsTransformer : FirTransformer<Nothing?>() {
|
||||
override fun <E : FirElement> transformElement(element: E, data: Nothing?): CompositeTransformResult<E> {
|
||||
throw IllegalStateException("Should not be there")
|
||||
}
|
||||
|
||||
override fun transformFile(file: FirFile, data: Nothing?): CompositeTransformResult<FirDeclaration> {
|
||||
val sealedClassInheritorsMap = mutableMapOf<FirRegularClass, MutableList<ClassId>>()
|
||||
file.accept(SealedInheritorsCollector, sealedClassInheritorsMap)
|
||||
|
||||
if (sealedClassInheritorsMap.isEmpty()) return file.compose()
|
||||
return file.transform(FirSealedClassInheritorsProcessor.InheritorsTransformer(sealedClassInheritorsMap), null)
|
||||
}
|
||||
}
|
||||
|
||||
private object SealedInheritorsCollector : FirDefaultVisitor<Unit, MutableMap<FirRegularClass, MutableList<ClassId>>>() {
|
||||
|
||||
override fun visitElement(element: FirElement, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {}
|
||||
|
||||
override fun visitFile(file: FirFile, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
|
||||
file.declarations.forEach { it.accept(this, data) }
|
||||
}
|
||||
|
||||
override fun visitRegularClass(regularClass: FirRegularClass, data: MutableMap<FirRegularClass, MutableList<ClassId>>) {
|
||||
if (!regularClass.isSealed) {
|
||||
regularClass.acceptChildren(this, data)
|
||||
return
|
||||
}
|
||||
|
||||
val sealedKtClass = regularClass.psi as? KtClass ?: return
|
||||
val module = sealedKtClass.module ?: return
|
||||
val containingPackage = regularClass.classId.packageFqName
|
||||
|
||||
val psiPackage = KotlinJavaPsiFacade.getInstance(sealedKtClass.project)
|
||||
.findPackage(containingPackage.asString(), GlobalSearchScope.moduleScope(module))
|
||||
?: getPackageViaDirectoryService(sealedKtClass)
|
||||
?: return
|
||||
|
||||
val kotlinAsJavaSupport = KotlinAsJavaSupport.getInstance(sealedKtClass.project)
|
||||
val lightClass = sealedKtClass.toLightClass() ?: kotlinAsJavaSupport.getFakeLightClass(sealedKtClass)
|
||||
|
||||
val searchScope: SearchScope = getSearchScope(module, psiPackage)
|
||||
val searchParameters = ClassInheritorsSearch.SearchParameters(lightClass, searchScope, false, true, false)
|
||||
val subclasses = ClassInheritorsSearch.search(searchParameters)
|
||||
.mapNotNull { it.classIdIfNonLocal() }
|
||||
.toMutableList()
|
||||
|
||||
data[regularClass] = subclasses
|
||||
}
|
||||
|
||||
private fun getSearchScope(module: Module, psiPackage: PsiPackage): GlobalSearchScope {
|
||||
val packageScope = PackageScope(psiPackage, false, false)
|
||||
// MPP multiple common modules are not supported!!
|
||||
return module.moduleScope.intersectWith(packageScope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPackageViaDirectoryService(ktClass: KtClass): PsiPackage? {
|
||||
val directory = ktClass.containingFile.containingDirectory ?: return null
|
||||
return JavaDirectoryService.getInstance().getPackage(directory)
|
||||
}
|
||||
+2
-30
@@ -5,17 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.fir.low.level.api
|
||||
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirImplicitTypeBodyResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.FirContractResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirAnnotationArgumentsResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirPluginAnnotationsResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirTransformerBasedExtensionStatusProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.createTransformerBasedProcessorByPhase
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyBodiesCalculator
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.util.executeWithoutPCE
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
@@ -62,6 +55,7 @@ internal class FirPhaseRunner {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun runPhaseWithoutLock(firFile: FirFile, phase: FirResolvePhase, scopeSession: ScopeSession) {
|
||||
val phaseProcessor = phase.createTransformerBasedProcessorByPhase(firFile.session, scopeSession)
|
||||
executeWithoutPCE {
|
||||
@@ -70,25 +64,3 @@ internal class FirPhaseRunner {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirResolvePhase.createTransformerBasedProcessorByPhase(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession
|
||||
): FirTransformerBasedResolveProcessor {
|
||||
return when (this) {
|
||||
FirResolvePhase.RAW_FIR -> throw IllegalStateException("Raw FIR building phase does not have a transformer")
|
||||
FirResolvePhase.ANNOTATIONS_FOR_PLUGINS -> FirPluginAnnotationsResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.CLASS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove
|
||||
FirResolvePhase.IMPORTS -> FirImportResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.SUPER_TYPES -> FirSupertypeResolverProcessor(session, scopeSession)
|
||||
FirResolvePhase.SEALED_CLASS_INHERITORS -> FirIdeSealedHierarchyProcessor(session, scopeSession)
|
||||
FirResolvePhase.TYPES -> FirTypeResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.ARGUMENTS_OF_PLUGIN_ANNOTATIONS -> FirAnnotationArgumentsResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.EXTENSION_STATUS_UPDATE -> FirTransformerBasedExtensionStatusProcessor(session, scopeSession)
|
||||
FirResolvePhase.STATUS -> FirStatusResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.CONTRACTS -> FirContractResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.NEW_MEMBERS_GENERATION -> FirDummyTransformerBasedProcessor(session, scopeSession) // TODO: remove
|
||||
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE -> FirImplicitTypeBodyResolveProcessor(session, scopeSession)
|
||||
FirResolvePhase.BODY_RESOLVE -> FirBodyResolveProcessor(session, scopeSession)
|
||||
}
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
class ClassAnotherModuleInheritorA: SealedClass()
|
||||
class ClassAnotherModuleInheritorB: SealedClass()
|
||||
|
||||
class InterfaceAnotherModuleInheritorA: SealedInterface
|
||||
class InterfaceAnotherModuleInheritorB: SealedInterface
|
||||
Vendored
-18
@@ -1,18 +0,0 @@
|
||||
ClassSameFileInheritorA
|
||||
ClassSameFileInheritorB
|
||||
ClassSameFileInheritorC
|
||||
ClassSamePackageInheritorA
|
||||
ClassSamePackageInheritorB
|
||||
InterfaceSameFileInheritorA
|
||||
InterfaceSameFileInheritorB
|
||||
InterfaceSameFileInheritorC
|
||||
InterfaceSamePackageInheritorA
|
||||
InterfaceSamePackageInheritorB
|
||||
NonSealedClass.NestedSealedInheritorA
|
||||
NonSealedClass.NestedSealedInheritorB
|
||||
SealedClass.NestedInheritorA
|
||||
SealedClass.NestedInheritorA.NestedNestedInheritorA
|
||||
SealedClass.NestedInheritorA.NestedNestedInheritorB
|
||||
SealedInterface.NestedInheritorA
|
||||
SealedInterface.NestedInheritorA.NestedNestedInheritorA
|
||||
SealedInterface.NestedInheritorA.NestedNestedInheritorB
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
class ClassSamePackageInheritorA: SealedClass()
|
||||
class ClassSamePackageInheritorB: SealedClass()
|
||||
|
||||
class InterfaceSamePackageInheritorA: SealedInterface
|
||||
class InterfaceSamePackageInheritorB: SealedInterface
|
||||
-7
@@ -1,7 +0,0 @@
|
||||
package anotherpackage
|
||||
|
||||
class ClassAnotherPackageInheritorA: SealedClass()
|
||||
class ClassAnotherPackageInheritorB: SealedClass()
|
||||
|
||||
class InterfaceAnotherPackageInheritorA: SealedInterface
|
||||
class InterfaceAnotherPackageInheritorB: SealedInterface
|
||||
Vendored
-29
@@ -1,29 +0,0 @@
|
||||
sealed class SealedClass { // (1): top level sealed class
|
||||
class NestedInheritorA: SealedClass() {
|
||||
class NestedNestedInheritorA: SealedClass()
|
||||
object NestedNestedInheritorB: SealedClass()
|
||||
}
|
||||
}
|
||||
|
||||
class ClassSameFileInheritorA: SealedClass()
|
||||
class ClassSameFileInheritorB: SealedClass()
|
||||
object ClassSameFileInheritorC: SealedClass()
|
||||
|
||||
sealed interface SealedInterface { // (2): top level sealed interface
|
||||
class NestedInheritorA: SealedInterface {
|
||||
interface NestedNestedInheritorA: SealedInterface
|
||||
object NestedNestedInheritorB: SealedInterface
|
||||
}
|
||||
}
|
||||
|
||||
class InterfaceSameFileInheritorA: SealedInterface
|
||||
class InterfaceSameFileInheritorB: SealedInterface
|
||||
object InterfaceSameFileInheritorC: SealedInterface
|
||||
|
||||
|
||||
class NonSealedClass {
|
||||
sealed class NestedSealedClass // (3): nested sealed class
|
||||
sealed interface NestedSealedInterface // (4): nested sealed interface
|
||||
class NestedSealedInheritorA: NestedSealedClass()
|
||||
class NestedSealedInheritorB: NestedSealedInterface
|
||||
}
|
||||
idea/idea-frontend-fir/idea-fir-low-level-api/testdata/resolveSealed/directInheritors/structure.json
Vendored
-7
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"modules" : [
|
||||
{ "name": "main", "dependsOn": ["anotherModule"] },
|
||||
{ "name": "anotherModule"}
|
||||
],
|
||||
"fileToResolve": { "module": "main", "file": "main.kt" }
|
||||
}
|
||||
+3
-10
@@ -9,10 +9,8 @@ import com.google.gson.JsonElement
|
||||
import com.google.gson.JsonObject
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.psi.PsiManager
|
||||
import org.jetbrains.kotlin.executeOnPooledThreadInReadAction
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.idea.fir.low.level.api.api.getOrBuildFirOfType
|
||||
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.jsonUtils.getString
|
||||
import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest
|
||||
@@ -49,9 +47,8 @@ abstract class AbstractFirMultiModuleLazyResolveTest : AbstractMultiModuleTest()
|
||||
val fails = testStructure.fails
|
||||
|
||||
try {
|
||||
val fir = executeOnPooledThreadInReadAction { ktFileToAnalyse.getOrBuildFirOfType<FirFile>(resolveState) }
|
||||
?: throw AssertionError("Can't build FirFile from ${ktFileToAnalyse.virtualFilePath}")
|
||||
checkFirFile(fir, path)
|
||||
val fir = ktFileToAnalyse.getOrBuildFir(resolveState)
|
||||
KotlinTestUtils.assertEqualsToFile(File("$path/expected.txt"), fir.render())
|
||||
} catch (e: Throwable) {
|
||||
if (!fails) throw e
|
||||
return
|
||||
@@ -60,10 +57,6 @@ abstract class AbstractFirMultiModuleLazyResolveTest : AbstractMultiModuleTest()
|
||||
throw AssertionError("Looks like test is passing, please remove `\"fails\": true` from structure.json")
|
||||
}
|
||||
}
|
||||
|
||||
protected open fun checkFirFile(firFile: FirFile, path: String) {
|
||||
KotlinTestUtils.assertEqualsToFile(File("$path/expected.txt"), firFile.render())
|
||||
}
|
||||
}
|
||||
|
||||
private data class FileToResolve(val moduleName: String, val relativeFilePath: String) {
|
||||
|
||||
+2
-13
@@ -11,17 +11,16 @@ import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiManager
|
||||
import com.intellij.psi.search.FileTypeIndex
|
||||
import org.jetbrains.kotlin.fir.FirRenderer
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.builder.RawFirBuilder
|
||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||
import org.jetbrains.kotlin.fir.dependenciesWithoutSelf
|
||||
import org.jetbrains.kotlin.fir.java.*
|
||||
import org.jetbrains.kotlin.fir.psi
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.impl.FirProviderImpl
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.*
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirTransformerBasedResolveProcessor
|
||||
import org.jetbrains.kotlin.fir.resolve.transformers.createAllTransformerBasedResolveProcessors
|
||||
import org.jetbrains.kotlin.fir.session.FirSessionFactory
|
||||
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
@@ -156,15 +155,5 @@ abstract class AbstractFirMultiModuleResolveTest : AbstractMultiModuleTest() {
|
||||
// KotlinTestUtils.assertEqualsToFile(File("$dirPath/extraDump.java.txt"), javaFirDump)
|
||||
// }
|
||||
}
|
||||
|
||||
private fun createAllTransformerBasedResolveProcessors(
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession? = null,
|
||||
pluginPhasesEnabled: Boolean = false,
|
||||
): List<FirTransformerBasedResolveProcessor> {
|
||||
return createAllResolveProcessors(scopeSession, pluginPhasesEnabled) {
|
||||
createTransformerBasedProcessorByPhase(session, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-39
@@ -1,39 +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 org.jetbrains.kotlin.utils.addToStdlib.flatMapToNullable
|
||||
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 { it.sealedInheritors ?: 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()
|
||||
}
|
||||
}
|
||||
-36
@@ -1,36 +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/resolveSealed")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class FirSealedInheritorsTestGenerated extends AbstractFirSealedInheritorsTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInResolveSealed() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/resolveSealed"), Pattern.compile("^([^\\.]+)$"), null, false);
|
||||
}
|
||||
|
||||
@TestMetadata("directInheritors")
|
||||
public void testDirectInheritors() throws Exception {
|
||||
runTest("idea/idea-frontend-fir/idea-fir-low-level-api/testdata/resolveSealed/directInheritors/");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -42,7 +42,7 @@ internal class KtFirTypeProvider(
|
||||
|
||||
override fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType {
|
||||
require(symbol is KtFirClassOrObjectSymbol)
|
||||
val type = symbol.firRef.withFir(FirResolvePhase.SUPER_TYPES) { firClass ->
|
||||
val type = symbol.firRef.withFir(FirResolvePhase.TYPES) { firClass ->
|
||||
ConeClassLikeTypeImpl(
|
||||
firClass.symbol.toLookupTag(),
|
||||
firClass.typeParameters.map { ConeTypeParameterTypeImpl(it.symbol.toLookupTag(), isNullable = false) }.toTypedArray(),
|
||||
|
||||
@@ -5,14 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.util
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement
|
||||
import com.intellij.psi.util.parentOfType
|
||||
import com.intellij.psi.util.parentsOfType
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.cfg.containingDeclarationForPseudocode
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -48,15 +45,3 @@ fun KtClassOrObject.classIdIfNonLocal(): ClassId? {
|
||||
return ClassId(packageName, FqName(classesNames.joinToString(separator = ".")), /*local=*/false)
|
||||
}
|
||||
|
||||
fun PsiClass.classIdIfNonLocal(): ClassId? {
|
||||
if (this is KtLightClass) {
|
||||
return this.kotlinOrigin?.classIdIfNonLocal()
|
||||
}
|
||||
val packageName = (containingFile as? PsiJavaFile)?.packageName ?: return null
|
||||
val packageFqName = FqName(packageName)
|
||||
|
||||
val classesNames = parentsOfType<KtDeclaration>().map { it.name }.toList().asReversed()
|
||||
if (classesNames.any { it == null }) return null
|
||||
return ClassId(packageFqName, FqName(classesNames.joinToString(separator = ".")), false)
|
||||
}
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ The Kotlin FIR plugin provides language support in IntelliJ IDEA and Android Stu
|
||||
<definitionsScopedSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDefinitionsSearcher"/>
|
||||
<methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodReferenceSearcher"/>
|
||||
<methodReferencesSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinPropertyAccessorsReferenceSearcher"/>
|
||||
<directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>
|
||||
<!-- <directClassInheritorsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinDirectInheritorsSearcher"/>-->
|
||||
<!-- <overridingMethodsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinOverridingMethodsWithGenericsSearcher"/>-->
|
||||
<!-- <annotatedElementsSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinAnnotatedElementsSearcher"/>-->
|
||||
<!-- <classesWithAnnotatedMembersSearch implementation="org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinClassesWithAnnotatedMembersSearcher"/>-->
|
||||
|
||||
Reference in New Issue
Block a user