Refactor light classes: Delegate LightClassDataHolder construction to LightClassGenerationSupport
This commit is contained in:
+14
-5
@@ -26,7 +26,7 @@ import com.intellij.util.SmartList
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
|
||||
import org.jetbrains.kotlin.asJava.builder.*
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForSourceDeclaration
|
||||
@@ -75,10 +75,18 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
trace.setKotlinCodeAnalyzer(codeAnalyzer)
|
||||
}
|
||||
|
||||
override fun getContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
|
||||
override fun createLightClassDataHolderForClassOrObject(classOrObject: KtClassOrObject, builder: (LightClassConstructionContext) -> LightClassBuilderResult): LightClassDataHolder {
|
||||
//force resolve companion for light class generation
|
||||
bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||
return LightClassConstructionContext(bindingContext, module)
|
||||
|
||||
val (stub, bindingContext, diagnostics) = builder(getContext())
|
||||
|
||||
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassDataHolder
|
||||
|
||||
return LightClassDataHolderImpl(
|
||||
stub,
|
||||
diagnostics
|
||||
)
|
||||
}
|
||||
|
||||
private fun getContext(): LightClassConstructionContext {
|
||||
@@ -163,8 +171,9 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContextForFacade(files: Collection<KtFile>): LightClassConstructionContext {
|
||||
return getContext()
|
||||
override fun createLightClassDataHolderForFacade(files: Collection<KtFile>, build: (LightClassConstructionContext) -> LightClassBuilderResult): LightClassDataHolder {
|
||||
val (stub, _, diagnostics) = build(getContext())
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
override fun createTrace(): BindingTraceContext {
|
||||
|
||||
+9
-3
@@ -20,7 +20,9 @@ import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassBuilderResult
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -32,7 +34,13 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun getContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext
|
||||
abstract fun createLightClassDataHolderForClassOrObject(
|
||||
classOrObject: KtClassOrObject, builder: (LightClassConstructionContext) -> LightClassBuilderResult
|
||||
): LightClassDataHolder
|
||||
|
||||
abstract fun createLightClassDataHolderForFacade(
|
||||
files: Collection<KtFile>, build: (LightClassConstructionContext) -> LightClassBuilderResult
|
||||
): LightClassDataHolder
|
||||
|
||||
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||
|
||||
@@ -71,8 +79,6 @@ abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
abstract fun getContextForFacade(files: Collection<KtFile>): LightClassConstructionContext
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun getInstance(project: Project): LightClassGenerationSupport {
|
||||
return ServiceManager.getService(project, LightClassGenerationSupport::class.java)
|
||||
|
||||
+29
-36
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.KtScript
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
abstract class LightClassDataProvider<T : LightClassDataHolder>(
|
||||
private val project: Project
|
||||
@@ -116,24 +115,17 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
|
||||
}
|
||||
}
|
||||
|
||||
val classConstructionContext = LightClassGenerationSupport.getInstance(classOrObject.project).getContextForClassOrObject(classOrObject)
|
||||
|
||||
val (stub, bindingContext, diagnostics) = buildLightClass(classOrObject.project, packageFqName, listOf(file), generateClassFilter, classConstructionContext) {
|
||||
state, files ->
|
||||
val packageCodegen = state.factory.forPackage(packageFqName, files)
|
||||
val packagePartType = state.fileClassesProvider.getFileClassType(file)
|
||||
val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file)
|
||||
packageCodegen.generateClassOrObject(getOutermostClassOrObject(classOrObject), context)
|
||||
state.factory.asList()
|
||||
return LightClassGenerationSupport.getInstance(classOrObject.project).createLightClassDataHolderForClassOrObject(classOrObject) {
|
||||
constructionContext ->
|
||||
buildLightClass(classOrObject.project, packageFqName, listOf(file), generateClassFilter, constructionContext) {
|
||||
state, files ->
|
||||
val packageCodegen = state.factory.forPackage(packageFqName, files)
|
||||
val packagePartType = state.fileClassesProvider.getFileClassType(file)
|
||||
val context = state.rootContext.intoPackagePart(packageCodegen.packageFragment, packagePartType, file)
|
||||
packageCodegen.generateClassOrObject(getOutermostClassOrObject(classOrObject), context)
|
||||
state.factory.asList()
|
||||
}
|
||||
}
|
||||
|
||||
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassDataHolder
|
||||
|
||||
|
||||
return LightClassDataHolderImpl(
|
||||
stub,
|
||||
diagnostics
|
||||
)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
@@ -143,14 +135,14 @@ class LightClassDataProviderForClassOrObject(private val classOrObject: KtClassO
|
||||
|
||||
sealed class LightClassDataProviderForFileFacade constructor(
|
||||
protected val project: Project, protected val facadeFqName: FqName
|
||||
) : LightClassDataProvider<LightClassDataHolderImpl>(project) {
|
||||
) : LightClassDataProvider<LightClassDataHolder>(project) {
|
||||
override val isLocal: Boolean get() = false
|
||||
abstract val files: Collection<KtFile>
|
||||
|
||||
override val valueAbsent: Boolean
|
||||
get() = files.isEmpty()
|
||||
|
||||
override fun computeLightClassData(): LightClassDataHolderImpl {
|
||||
override fun computeLightClassData(): LightClassDataHolder {
|
||||
val generateClassFilter = object : GenerationState.GenerateClassFilter() {
|
||||
override fun shouldAnnotateClass(processingClassOrObject: KtClassOrObject): Boolean {
|
||||
return shouldGenerateClass(processingClassOrObject)
|
||||
@@ -171,25 +163,26 @@ sealed class LightClassDataProviderForFileFacade constructor(
|
||||
|
||||
val packageFqName = facadeFqName.parent()
|
||||
|
||||
val (stub, _, diagnostics) = buildLightClass(project, packageFqName, files, generateClassFilter, LightClassGenerationSupport.getInstance(project).getContextForFacade(files)) 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
|
||||
return LightClassGenerationSupport.getInstance(project).createLightClassDataHolderForFacade(files) {
|
||||
constructionContext ->
|
||||
buildLightClass(project, packageFqName, files, generateClassFilter, 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 codegen = state.factory.forMultifileClass(facadeFqName, files)
|
||||
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION)
|
||||
state.factory.asList()
|
||||
}
|
||||
|
||||
val codegen = state.factory.forMultifileClass(facadeFqName, files)
|
||||
codegen.generate(CompilationErrorHandler.THROW_EXCEPTION)
|
||||
state.factory.asList()
|
||||
}
|
||||
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
|
||||
+18
-4
@@ -28,8 +28,7 @@ import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassConstructionContext
|
||||
import org.jetbrains.kotlin.asJava.builder.*
|
||||
import org.jetbrains.kotlin.asJava.classes.FakeLightClassForFileOfPackage
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
@@ -65,7 +64,17 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project))
|
||||
private val psiManager: PsiManager = PsiManager.getInstance(project)
|
||||
|
||||
override fun getContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
|
||||
override fun createLightClassDataHolderForClassOrObject(classOrObject: KtClassOrObject, build: (LightClassConstructionContext) -> LightClassBuilderResult): LightClassDataHolder {
|
||||
val (stub, bindingContext, diagnostics) = build(getContextForClassOrObject(classOrObject))
|
||||
bindingContext.get(BindingContext.CLASS, classOrObject) ?: return InvalidLightClassDataHolder
|
||||
|
||||
return LightClassDataHolderImpl(
|
||||
stub,
|
||||
diagnostics
|
||||
)
|
||||
}
|
||||
|
||||
fun getContextForClassOrObject(classOrObject: KtClassOrObject): LightClassConstructionContext {
|
||||
if (classOrObject.isLocal) {
|
||||
return getContextForLocalClassOrObject(classOrObject)
|
||||
}
|
||||
@@ -108,7 +117,12 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
return LightClassConstructionContext(bindingContext, resolutionFacade.moduleDescriptor)
|
||||
}
|
||||
|
||||
override fun getContextForFacade(files: Collection<KtFile>): LightClassConstructionContext {
|
||||
override fun createLightClassDataHolderForFacade(files: Collection<KtFile>, build: (LightClassConstructionContext) -> LightClassBuilderResult): LightClassDataHolder {
|
||||
val (stub, _, diagnostics) = build(getContextForFacade(files))
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
fun getContextForFacade(files: Collection<KtFile>): LightClassConstructionContext {
|
||||
assert(!files.isEmpty()) { "No files in facade" }
|
||||
|
||||
val sortedFiles = files.sortedWith(scopeFileComparator)
|
||||
|
||||
Reference in New Issue
Block a user