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