diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt index d9f8051c661..9109fc358ab 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt @@ -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): LightClassConstructionContext { - return getContext() + override fun createLightClassDataHolderForFacade(files: Collection, build: (LightClassConstructionContext) -> LightClassBuilderResult): LightClassDataHolder { + val (stub, _, diagnostics) = build(getContext()) + return LightClassDataHolderImpl(stub, diagnostics) } override fun createTrace(): BindingTraceContext { diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt index 1893d708888..5aee7c7a977 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.kt @@ -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, build: (LightClassConstructionContext) -> LightClassBuilderResult + ): LightClassDataHolder abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection @@ -71,8 +79,6 @@ abstract class LightClassGenerationSupport { abstract fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection - abstract fun getContextForFacade(files: Collection): LightClassConstructionContext - companion object { @JvmStatic fun getInstance(project: Project): LightClassGenerationSupport { return ServiceManager.getService(project, LightClassGenerationSupport::class.java) 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 11dbdd6e766..97f0fb7be7f 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 @@ -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( 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(project) { +) : LightClassDataProvider(project) { override val isLocal: Boolean get() = false abstract val files: Collection 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 { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 0aa06e3eced..8845e8e9475 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -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): LightClassConstructionContext { + override fun createLightClassDataHolderForFacade(files: Collection, build: (LightClassConstructionContext) -> LightClassBuilderResult): LightClassDataHolder { + val (stub, _, diagnostics) = build(getContextForFacade(files)) + return LightClassDataHolderImpl(stub, diagnostics) + } + + fun getContextForFacade(files: Collection): LightClassConstructionContext { assert(!files.isEmpty()) { "No files in facade" } val sortedFiles = files.sortedWith(scopeFileComparator)