Refactor LightClassDataProvider: drop LightClassDataProvider class
Move code to inheritors Improve api to avoid getting empty file lists in random places
This commit is contained in:
@@ -40,14 +40,13 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
|||||||
data class LightClassBuilderResult(val stub: PsiJavaFileStub, val bindingContext: BindingContext, val diagnostics: Diagnostics)
|
data class LightClassBuilderResult(val stub: PsiJavaFileStub, val bindingContext: BindingContext, val diagnostics: Diagnostics)
|
||||||
|
|
||||||
fun buildLightClass(
|
fun buildLightClass(
|
||||||
project: Project,
|
|
||||||
packageFqName: FqName,
|
packageFqName: FqName,
|
||||||
files: Collection<KtFile>,
|
files: Collection<KtFile>,
|
||||||
generateClassFilter: GenerationState.GenerateClassFilter,
|
generateClassFilter: GenerationState.GenerateClassFilter,
|
||||||
context: LightClassConstructionContext,
|
context: LightClassConstructionContext,
|
||||||
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit
|
generate: (state: GenerationState, files: Collection<KtFile>) -> Unit
|
||||||
): LightClassBuilderResult {
|
): LightClassBuilderResult {
|
||||||
|
val project = files.first().project
|
||||||
val javaFileStub = createJavaFileStub(project, packageFqName, files)
|
val javaFileStub = createJavaFileStub(project, packageFqName, files)
|
||||||
val bindingContext: BindingContext
|
val bindingContext: BindingContext
|
||||||
|
|
||||||
@@ -64,7 +63,7 @@ fun buildLightClass(
|
|||||||
KotlinLightClassBuilderFactory(stubStack),
|
KotlinLightClassBuilderFactory(stubStack),
|
||||||
context.module,
|
context.module,
|
||||||
context.bindingContext,
|
context.bindingContext,
|
||||||
files.toMutableList(),
|
files.toList(),
|
||||||
CompilerConfiguration.EMPTY,
|
CompilerConfiguration.EMPTY,
|
||||||
generateClassFilter,
|
generateClassFilter,
|
||||||
wantsDiagnostics = false
|
wantsDiagnostics = false
|
||||||
@@ -93,7 +92,7 @@ fun buildLightClass(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createJavaFileStub(project: Project, packageFqName: FqName, files: Collection<KtFile>): PsiJavaFileStub {
|
private fun createJavaFileStub(project: Project, packageFqName: FqName, files: Collection<KtFile>): PsiJavaFileStub {
|
||||||
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), true)
|
val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /*compiled = */true)
|
||||||
javaFileStub.psiFactory = ClsWrapperStubPsiFactory.INSTANCE
|
javaFileStub.psiFactory = ClsWrapperStubPsiFactory.INSTANCE
|
||||||
|
|
||||||
val manager = PsiManager.getInstance(project)
|
val manager = PsiManager.getInstance(project)
|
||||||
@@ -124,4 +123,4 @@ private fun logErrorWithOSInfo(cause: Throwable?, fqName: FqName, virtualFile: V
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val LOG = Logger.getInstance(LightClassDataProvider::class.java)
|
private val LOG = Logger.getInstance(LightClassBuilderResult::class.java)
|
||||||
+33
-47
@@ -36,37 +36,14 @@ import org.jetbrains.kotlin.psi.KtPsiUtil
|
|||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
|
|
||||||
abstract class LightClassDataProvider<T : LightClassDataHolder>(
|
class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassOrObject) : CachedValueProvider<LightClassDataHolder> {
|
||||||
private val project: Project
|
|
||||||
) : CachedValueProvider<T> {
|
|
||||||
abstract val isLocal: Boolean
|
|
||||||
|
|
||||||
open val valueAbsent: Boolean = false
|
private fun computeLightClassData(): LightClassDataHolder {
|
||||||
|
|
||||||
override fun compute(): CachedValueProvider.Result<T>? {
|
|
||||||
if (valueAbsent) return null
|
|
||||||
|
|
||||||
return CachedValueProvider.Result.create(
|
|
||||||
computeLightClassData(),
|
|
||||||
if (isLocal) PsiModificationTracker.MODIFICATION_COUNT else PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun computeLightClassData(): T
|
|
||||||
}
|
|
||||||
|
|
||||||
class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassOrObject) :
|
|
||||||
LightClassDataProvider<LightClassDataHolder>(classOrObject.project) {
|
|
||||||
|
|
||||||
override val isLocal: Boolean get() = classOrObject.isLocal
|
|
||||||
|
|
||||||
|
|
||||||
override fun computeLightClassData(): LightClassDataHolder {
|
|
||||||
val file = classOrObject.containingKtFile
|
val file = classOrObject.containingKtFile
|
||||||
val packageFqName = file.packageFqName
|
val packageFqName = file.packageFqName
|
||||||
return LightClassGenerationSupport.getInstance(classOrObject.project).createLightClassDataHolderForClassOrObject(classOrObject) {
|
return LightClassGenerationSupport.getInstance(classOrObject.project).createLightClassDataHolderForClassOrObject(classOrObject) {
|
||||||
constructionContext ->
|
constructionContext ->
|
||||||
buildLightClass(classOrObject.project, packageFqName, listOf(file), ClassFilterForClassOrObject(classOrObject), constructionContext) {
|
buildLightClass(packageFqName, listOf(file), ClassFilterForClassOrObject(classOrObject), constructionContext) {
|
||||||
state, files ->
|
state, files ->
|
||||||
val packageCodegen = state.factory.forPackage(packageFqName, files)
|
val packageCodegen = state.factory.forPackage(packageFqName, files)
|
||||||
val packagePartType = state.fileClassesProvider.getFileClassType(file)
|
val packagePartType = state.fileClassesProvider.getFileClassType(file)
|
||||||
@@ -77,6 +54,13 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun compute(): CachedValueProvider.Result<LightClassDataHolder>? {
|
||||||
|
return CachedValueProvider.Result.create(
|
||||||
|
computeLightClassData(),
|
||||||
|
if (classOrObject.isLocal()) PsiModificationTracker.MODIFICATION_COUNT else PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return this::class.java.name + " for " + classOrObject.name
|
return this::class.java.name + " for " + classOrObject.name
|
||||||
}
|
}
|
||||||
@@ -84,27 +68,21 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
|
|||||||
|
|
||||||
sealed class LightClassDataProviderForFileFacade constructor(
|
sealed class LightClassDataProviderForFileFacade constructor(
|
||||||
protected val project: Project, protected val facadeFqName: FqName
|
protected val project: Project, protected val facadeFqName: FqName
|
||||||
) : LightClassDataProvider<LightClassDataHolder>(project) {
|
) : CachedValueProvider<LightClassDataHolder> {
|
||||||
override val isLocal: Boolean get() = false
|
abstract fun findFiles(): Collection<KtFile>
|
||||||
abstract val files: Collection<KtFile>
|
|
||||||
|
|
||||||
override val valueAbsent: Boolean
|
private fun computeLightClassData(files: Collection<KtFile>): LightClassDataHolder {
|
||||||
get() = files.isEmpty()
|
|
||||||
|
|
||||||
override fun computeLightClassData(): LightClassDataHolder {
|
|
||||||
return LightClassGenerationSupport.getInstance(project).createLightClassDataHolderForFacade(files) {
|
return LightClassGenerationSupport.getInstance(project).createLightClassDataHolderForFacade(files) {
|
||||||
constructionContext ->
|
constructionContext ->
|
||||||
buildLightClass(project, facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@ {
|
buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@ {
|
||||||
state, files ->
|
state, files ->
|
||||||
if (!files.isEmpty()) {
|
val representativeFile = files.first()
|
||||||
val representativeFile = files.iterator().next()
|
val fileClassInfo = NoResolveFileClassesProvider.getFileClassInfo(representativeFile)
|
||||||
val fileClassInfo = NoResolveFileClassesProvider.getFileClassInfo(representativeFile)
|
if (!fileClassInfo.withJvmMultifileClass) {
|
||||||
if (!fileClassInfo.withJvmMultifileClass) {
|
val codegen = state.factory.forPackage(representativeFile.packageFqName, files)
|
||||||
val codegen = state.factory.forPackage(representativeFile.packageFqName, files)
|
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION)
|
||||||
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION)
|
state.factory.asList()
|
||||||
state.factory.asList()
|
return@generate
|
||||||
return@generate
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val codegen = state.factory.forMultifileClass(facadeFqName, files)
|
val codegen = state.factory.forMultifileClass(facadeFqName, files)
|
||||||
@@ -114,6 +92,16 @@ sealed class LightClassDataProviderForFileFacade constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun compute(): CachedValueProvider.Result<LightClassDataHolder>? {
|
||||||
|
val files = findFiles()
|
||||||
|
if (files.isEmpty()) return null
|
||||||
|
|
||||||
|
return CachedValueProvider.Result.create(
|
||||||
|
computeLightClassData(files),
|
||||||
|
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return this::class.java.name + " for $facadeFqName"
|
return this::class.java.name + " for $facadeFqName"
|
||||||
}
|
}
|
||||||
@@ -124,8 +112,7 @@ sealed class LightClassDataProviderForFileFacade constructor(
|
|||||||
facadeFqName: FqName,
|
facadeFqName: FqName,
|
||||||
private val searchScope: GlobalSearchScope
|
private val searchScope: GlobalSearchScope
|
||||||
) : LightClassDataProviderForFileFacade(project, facadeFqName) {
|
) : LightClassDataProviderForFileFacade(project, facadeFqName) {
|
||||||
override val files: Collection<KtFile>
|
override fun findFiles() = LightClassGenerationSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope)
|
||||||
get() = LightClassGenerationSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create delegate by single file
|
// create delegate by single file
|
||||||
@@ -134,8 +121,7 @@ sealed class LightClassDataProviderForFileFacade constructor(
|
|||||||
facadeFqName: FqName,
|
facadeFqName: FqName,
|
||||||
private val file: KtFile
|
private val file: KtFile
|
||||||
) : LightClassDataProviderForFileFacade(project, facadeFqName) {
|
) : LightClassDataProviderForFileFacade(project, facadeFqName) {
|
||||||
override val files: Collection<KtFile>
|
override fun findFiles() = listOf(file)
|
||||||
get() = listOf(file)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user