From c73e58516b5ee873309910959ec454c4bf421af2 Mon Sep 17 00:00:00 2001 From: "Pavel V. Talanov" Date: Tue, 14 Mar 2017 16:01:15 +0300 Subject: [PATCH] Refactor LightClassDataProvider: drop LightClassDataProvider class Move code to inheritors Improve api to avoid getting empty file lists in random places --- .../asJava/builder/LightClassBuilder.kt | 9 +-- .../asJava/builder/LightClassDataProvider.kt | 80 ++++++++----------- 2 files changed, 37 insertions(+), 52 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassBuilder.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassBuilder.kt index a731b16408e..a0358f9eb35 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassBuilder.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassBuilder.kt @@ -40,14 +40,13 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics data class LightClassBuilderResult(val stub: PsiJavaFileStub, val bindingContext: BindingContext, val diagnostics: Diagnostics) fun buildLightClass( - project: Project, packageFqName: FqName, files: Collection, generateClassFilter: GenerationState.GenerateClassFilter, context: LightClassConstructionContext, generate: (state: GenerationState, files: Collection) -> Unit ): LightClassBuilderResult { - + val project = files.first().project val javaFileStub = createJavaFileStub(project, packageFqName, files) val bindingContext: BindingContext @@ -64,7 +63,7 @@ fun buildLightClass( KotlinLightClassBuilderFactory(stubStack), context.module, context.bindingContext, - files.toMutableList(), + files.toList(), CompilerConfiguration.EMPTY, generateClassFilter, wantsDiagnostics = false @@ -93,7 +92,7 @@ fun buildLightClass( } private fun createJavaFileStub(project: Project, packageFqName: FqName, files: Collection): PsiJavaFileStub { - val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), true) + val javaFileStub = PsiJavaFileStubImpl(packageFqName.asString(), /*compiled = */true) javaFileStub.psiFactory = ClsWrapperStubPsiFactory.INSTANCE 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) \ No newline at end of file +private val LOG = Logger.getInstance(LightClassBuilderResult::class.java) \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt index cc0fe64eccc..40c066606cc 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/builder/LightClassDataProvider.kt @@ -36,37 +36,14 @@ import org.jetbrains.kotlin.psi.KtPsiUtil import org.jetbrains.kotlin.psi.KtScript import org.jetbrains.kotlin.psi.psiUtil.isAncestor -abstract class LightClassDataProvider( - private val project: Project -) : CachedValueProvider { - abstract val isLocal: Boolean +class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassOrObject) : CachedValueProvider { - open val valueAbsent: Boolean = false - - override fun compute(): CachedValueProvider.Result? { - 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(classOrObject.project) { - - override val isLocal: Boolean get() = classOrObject.isLocal - - - override fun computeLightClassData(): LightClassDataHolder { + private fun computeLightClassData(): LightClassDataHolder { val file = classOrObject.containingKtFile val packageFqName = file.packageFqName return LightClassGenerationSupport.getInstance(classOrObject.project).createLightClassDataHolderForClassOrObject(classOrObject) { constructionContext -> - buildLightClass(classOrObject.project, packageFqName, listOf(file), ClassFilterForClassOrObject(classOrObject), constructionContext) { + buildLightClass(packageFqName, listOf(file), ClassFilterForClassOrObject(classOrObject), constructionContext) { state, files -> val packageCodegen = state.factory.forPackage(packageFqName, files) val packagePartType = state.fileClassesProvider.getFileClassType(file) @@ -77,6 +54,13 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO } } + override fun compute(): CachedValueProvider.Result? { + return CachedValueProvider.Result.create( + computeLightClassData(), + if (classOrObject.isLocal()) PsiModificationTracker.MODIFICATION_COUNT else PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT + ) + } + override fun toString(): String { return this::class.java.name + " for " + classOrObject.name } @@ -84,27 +68,21 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO sealed class LightClassDataProviderForFileFacade constructor( protected val project: Project, protected val facadeFqName: FqName -) : LightClassDataProvider(project) { - override val isLocal: Boolean get() = false - abstract val files: Collection +) : CachedValueProvider { + abstract fun findFiles(): Collection - override val valueAbsent: Boolean - get() = files.isEmpty() - - override fun computeLightClassData(): LightClassDataHolder { + private fun computeLightClassData(files: Collection): LightClassDataHolder { return LightClassGenerationSupport.getInstance(project).createLightClassDataHolderForFacade(files) { constructionContext -> - buildLightClass(project, facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@ { + buildLightClass(facadeFqName.parent(), files, ClassFilterForFacade, constructionContext) generate@ { state, files -> - if (!files.isEmpty()) { - val representativeFile = files.iterator().next() - val fileClassInfo = NoResolveFileClassesProvider.getFileClassInfo(representativeFile) - if (!fileClassInfo.withJvmMultifileClass) { - val codegen = state.factory.forPackage(representativeFile.packageFqName, files) - codegen.generate(CompilationErrorHandler.THROW_EXCEPTION) - state.factory.asList() - return@generate - } + val representativeFile = files.first() + val fileClassInfo = NoResolveFileClassesProvider.getFileClassInfo(representativeFile) + if (!fileClassInfo.withJvmMultifileClass) { + val codegen = state.factory.forPackage(representativeFile.packageFqName, files) + codegen.generate(CompilationErrorHandler.THROW_EXCEPTION) + state.factory.asList() + return@generate } val codegen = state.factory.forMultifileClass(facadeFqName, files) @@ -114,6 +92,16 @@ sealed class LightClassDataProviderForFileFacade constructor( } } + override fun compute(): CachedValueProvider.Result? { + 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 { return this::class.java.name + " for $facadeFqName" } @@ -124,8 +112,7 @@ sealed class LightClassDataProviderForFileFacade constructor( facadeFqName: FqName, private val searchScope: GlobalSearchScope ) : LightClassDataProviderForFileFacade(project, facadeFqName) { - override val files: Collection - get() = LightClassGenerationSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope) + override fun findFiles() = LightClassGenerationSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope) } // create delegate by single file @@ -134,8 +121,7 @@ sealed class LightClassDataProviderForFileFacade constructor( facadeFqName: FqName, private val file: KtFile ) : LightClassDataProviderForFileFacade(project, facadeFqName) { - override val files: Collection - get() = listOf(file) + override fun findFiles() = listOf(file) } }