Split LightClassGenerationSupport into separate entities
LightClassGenerationSupport:
Includes utilities related to generating light classes
Primary client of this service are KtLight* implementation classes
KotlinAsJavaSupport:
Provides APIs to transform kotlin code into Psi* entities
Primary client of this service is JavaElementFinder
This commit is contained in:
+114
-100
@@ -25,6 +25,7 @@ import com.intellij.util.Function
|
||||
import com.intellij.util.SmartList
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassBuilder
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
|
||||
@@ -63,28 +64,12 @@ import kotlin.properties.Delegates
|
||||
|
||||
* To mitigate this, CliLightClassGenerationSupport hold a trace that is shared between the analyzer and JetLightClasses
|
||||
*/
|
||||
class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSupport(), CodeAnalyzerInitializer {
|
||||
private val psiManager = PsiManager.getInstance(project)
|
||||
private var bindingContext: BindingContext by Delegates.notNull()
|
||||
private var module: ModuleDescriptor by Delegates.notNull()
|
||||
|
||||
|
||||
override fun initialize(trace: BindingTrace, module: ModuleDescriptor, codeAnalyzer: KotlinCodeAnalyzer) {
|
||||
this.bindingContext = trace.bindingContext
|
||||
this.module = module
|
||||
|
||||
if (trace !is CliBindingTrace) {
|
||||
throw IllegalArgumentException("Shared trace is expected to be subclass of ${CliBindingTrace::class.java.simpleName} class")
|
||||
}
|
||||
|
||||
trace.setKotlinCodeAnalyzer(codeAnalyzer)
|
||||
}
|
||||
|
||||
class CliLightClassGenerationSupport(private val traceHolder: CliTraceHolder) : LightClassGenerationSupport() {
|
||||
override fun createDataHolderForClass(
|
||||
classOrObject: KtClassOrObject, builder: LightClassBuilder
|
||||
): LightClassDataHolder.ForClass {
|
||||
//force resolve companion for light class generation
|
||||
bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||
traceHolder.bindingContext.get(BindingContext.CLASS, classOrObject)?.companionObjectDescriptor
|
||||
|
||||
val (stub, bindingContext, diagnostics) = builder(getContext())
|
||||
|
||||
@@ -106,96 +91,33 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
return LightClassDataHolderImpl(stub, diagnostics)
|
||||
}
|
||||
|
||||
private fun getContext(): LightClassConstructionContext = LightClassConstructionContext(bindingContext, module)
|
||||
|
||||
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
return ResolveSessionUtils.getClassDescriptorsByFqName(module, fqName).mapNotNull {
|
||||
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
||||
if (element is KtClassOrObject && PsiSearchScopeUtil.isInScope(searchScope, element)) {
|
||||
element
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
||||
|
||||
override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||
return bindingContext.get(BindingContext.PACKAGE_TO_FILES, fqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(searchScope, it)
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
override fun findClassOrObjectDeclarationsInPackage(
|
||||
packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
val files = findFilesForPackage(packageFqName, searchScope)
|
||||
val result = SmartList<KtClassOrObject>()
|
||||
for (file in files) {
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration is KtClassOrObject) {
|
||||
result.add(declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean {
|
||||
return !module.getPackage(fqName).isEmpty()
|
||||
}
|
||||
|
||||
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> {
|
||||
val packageView = module.getPackage(fqn)
|
||||
val members = packageView.memberScope.getContributedDescriptors(DescriptorKindFilter.PACKAGES, MemberScope.ALL_NAME_FILTER)
|
||||
return ContainerUtil.mapNotNull(members, object : Function<DeclarationDescriptor, FqName> {
|
||||
override fun `fun`(member: DeclarationDescriptor): FqName? {
|
||||
if (member is PackageViewDescriptor) {
|
||||
return member.fqName
|
||||
}
|
||||
return null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
|
||||
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||
private fun getContext(): LightClassConstructionContext = LightClassConstructionContext(traceHolder.bindingContext, traceHolder.module)
|
||||
|
||||
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
||||
return bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||
return traceHolder.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration)
|
||||
}
|
||||
|
||||
override fun analyze(element: KtElement) = bindingContext
|
||||
override fun analyze(element: KtElement) = traceHolder.bindingContext
|
||||
|
||||
override fun analyzeWithContent(element: KtClassOrObject) = bindingContext
|
||||
override fun analyzeWithContent(element: KtClassOrObject) = traceHolder.bindingContext
|
||||
}
|
||||
|
||||
override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
val filesForFacade = findFilesForFacade(facadeFqName, scope)
|
||||
if (filesForFacade.isEmpty()) return emptyList()
|
||||
class CliTraceHolder : CodeAnalyzerInitializer {
|
||||
var bindingContext: BindingContext by Delegates.notNull()
|
||||
private set
|
||||
var module: ModuleDescriptor by Delegates.notNull()
|
||||
private set
|
||||
|
||||
return listOfNotNull<PsiClass>(
|
||||
KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope, filesForFacade))
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
if (scriptFqName.isRoot) {
|
||||
return emptyList()
|
||||
override fun initialize(trace: BindingTrace, module: ModuleDescriptor, codeAnalyzer: KotlinCodeAnalyzer) {
|
||||
this.bindingContext = trace.bindingContext
|
||||
this.module = module
|
||||
|
||||
if (trace !is CliBindingTrace) {
|
||||
throw IllegalArgumentException("Shared trace is expected to be subclass of ${CliBindingTrace::class.java.simpleName} class")
|
||||
}
|
||||
|
||||
return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file ->
|
||||
file.script?.takeIf { it.fqName == scriptFqName }?.let { it -> getLightClassForScript(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
//
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile> {
|
||||
if (facadeFqName.isRoot) return emptyList()
|
||||
|
||||
return bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(scope, it)
|
||||
} ?: emptyList()
|
||||
trace.setKotlinCodeAnalyzer(codeAnalyzer)
|
||||
}
|
||||
|
||||
override fun createTrace(): BindingTraceContext {
|
||||
@@ -245,6 +167,14 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CliKotlinAsJavaSupport(
|
||||
project: Project,
|
||||
private val traceHolder: CliTraceHolder
|
||||
): KotlinAsJavaSupport() {
|
||||
private val psiManager = PsiManager.getInstance(project)
|
||||
|
||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
return findFacadeFilesInPackage(packageFqName, scope)
|
||||
@@ -260,7 +190,91 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup
|
||||
private fun findFacadeFilesInPackage(
|
||||
packageFqName: FqName,
|
||||
scope: GlobalSearchScope
|
||||
) = bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_PACKAGE_NAME, packageFqName)
|
||||
) = traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_PACKAGE_NAME, packageFqName)
|
||||
?.filter { PsiSearchScopeUtil.isInScope(scope, it) }
|
||||
.orEmpty()
|
||||
}
|
||||
|
||||
override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
val filesForFacade = findFilesForFacade(facadeFqName, scope)
|
||||
if (filesForFacade.isEmpty()) return emptyList()
|
||||
|
||||
return listOfNotNull<PsiClass>(
|
||||
KtLightClassForFacade.createForFacade(psiManager, facadeFqName, scope, filesForFacade))
|
||||
}
|
||||
|
||||
override fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
if (scriptFqName.isRoot) {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
return findFilesForPackage(scriptFqName.parent(), scope).mapNotNull { file ->
|
||||
file.script?.takeIf { it.fqName == scriptFqName }?.let { it -> getLightClassForScript(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun getKotlinInternalClasses(fqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
//
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile> {
|
||||
if (facadeFqName.isRoot) return emptyList()
|
||||
|
||||
return traceHolder.bindingContext.get(FilesByFacadeFqNameIndexer.FACADE_FILES_BY_FQ_NAME, facadeFqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(scope, it)
|
||||
} ?: emptyList()
|
||||
}
|
||||
|
||||
|
||||
override fun findClassOrObjectDeclarationsInPackage(
|
||||
packageFqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
val files = findFilesForPackage(packageFqName, searchScope)
|
||||
val result = SmartList<KtClassOrObject>()
|
||||
for (file in files) {
|
||||
for (declaration in file.declarations) {
|
||||
if (declaration is KtClassOrObject) {
|
||||
result.add(declaration)
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean {
|
||||
return !traceHolder.module.getPackage(fqName).isEmpty()
|
||||
}
|
||||
|
||||
override fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName> {
|
||||
val packageView = traceHolder.module.getPackage(fqn)
|
||||
val members = packageView.memberScope.getContributedDescriptors(DescriptorKindFilter.PACKAGES, MemberScope.ALL_NAME_FILTER)
|
||||
return ContainerUtil.mapNotNull(members, object : Function<DeclarationDescriptor, FqName> {
|
||||
override fun `fun`(member: DeclarationDescriptor): FqName? {
|
||||
if (member is PackageViewDescriptor) {
|
||||
return member.fqName
|
||||
}
|
||||
return null
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun getLightClass(classOrObject: KtClassOrObject): KtLightClass? = KtLightClassForSourceDeclaration.create(classOrObject)
|
||||
|
||||
override fun getLightClassForScript(script: KtScript): KtLightClassForScript? = KtLightClassForScript.create(script)
|
||||
|
||||
|
||||
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
return ResolveSessionUtils.getClassDescriptorsByFqName(traceHolder.module, fqName).mapNotNull {
|
||||
val element = DescriptorToSourceUtils.getSourceFromDescriptor(it)
|
||||
if (element is KtClassOrObject && PsiSearchScopeUtil.isInScope(searchScope, element)) {
|
||||
element
|
||||
}
|
||||
else null
|
||||
}
|
||||
}
|
||||
|
||||
override fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile> {
|
||||
return traceHolder.bindingContext.get(BindingContext.PACKAGE_TO_FILES, fqName)?.filter {
|
||||
PsiSearchScopeUtil.isInScope(searchScope, it)
|
||||
} ?: emptyList()
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,7 @@ import com.intellij.psi.util.JavaClassSupers
|
||||
import com.intellij.util.io.URLUtil
|
||||
import com.intellij.util.lang.UrlClassLoader
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
@@ -130,17 +131,20 @@ class KotlinCoreEnvironment private constructor(
|
||||
with (project) {
|
||||
registerService(CoreJavaFileManager::class.java, ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager)
|
||||
|
||||
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(this)
|
||||
val traceHolder = CliTraceHolder()
|
||||
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder)
|
||||
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder)
|
||||
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||
registerService(CodeAnalyzerInitializer::class.java, cliLightClassGenerationSupport)
|
||||
registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport)
|
||||
registerService(CodeAnalyzerInitializer::class.java, traceHolder)
|
||||
|
||||
registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager())
|
||||
registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager())
|
||||
|
||||
val area = Extensions.getArea(this)
|
||||
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, cliLightClassGenerationSupport))
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(JavaElementFinder(this, kotlinAsJavaSupport))
|
||||
area.getExtensionPoint(PsiElementFinder.EP_NAME).registerExtension(
|
||||
PsiElementFinderImpl(this, ServiceManager.getService(this, JavaFileManager::class.java)))
|
||||
}
|
||||
|
||||
+1
-1
@@ -374,7 +374,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
project,
|
||||
sourceFiles,
|
||||
CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
CliTraceHolder.NoScopeRecordCliBindingTrace(),
|
||||
environment.configuration,
|
||||
environment::createPackagePartProvider,
|
||||
sourceModuleSearchScope = scope
|
||||
|
||||
+2
-5
@@ -17,8 +17,8 @@
|
||||
package org.jetbrains.kotlin.cli.jvm.javac
|
||||
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.asJava.findFacadeClass
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.javac.JavacWrapperKotlinResolver
|
||||
import org.jetbrains.kotlin.javac.resolve.MockKotlinField
|
||||
@@ -47,7 +47,7 @@ class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: Li
|
||||
}
|
||||
|
||||
override fun findField(classOrObject: KtClassOrObject, name: String): JavaField? {
|
||||
val lightClass = classOrObject.getLightClass() ?: return null
|
||||
val lightClass = classOrObject.toLightClass() ?: return null
|
||||
|
||||
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
||||
}
|
||||
@@ -57,7 +57,4 @@ class JavacWrapperKotlinResolverImpl(private val lightClassGenerationSupport: Li
|
||||
|
||||
return lightClass.allFields.find { it.name == name}?.let(::MockKotlinField)
|
||||
}
|
||||
|
||||
private fun KtClassOrObject.getLightClass(): KtLightClass? = lightClassGenerationSupport.getLightClass(this)
|
||||
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.cli.common.repl.CompiledReplCodeLine
|
||||
import org.jetbrains.kotlin.cli.common.repl.ILineId
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplCodeLine
|
||||
import org.jetbrains.kotlin.cli.common.repl.ReplHistory
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.container.get
|
||||
@@ -56,7 +56,7 @@ class ReplCodeAnalyzer(environment: KotlinCoreEnvironment) {
|
||||
|
||||
val module: ModuleDescriptorImpl
|
||||
|
||||
val trace: BindingTraceContext = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace()
|
||||
val trace: BindingTraceContext = CliTraceHolder.NoScopeRecordCliBindingTrace()
|
||||
|
||||
init {
|
||||
// Module source scope is empty because all binary classes are in the dependency module, and all source classes are guaranteed
|
||||
|
||||
+40
-29
@@ -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.*
|
||||
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.asJava.classes.KtLightClassForScript
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
@@ -30,31 +32,24 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
typealias LightClassBuilder = (LightClassConstructionContext) -> LightClassBuilderResult
|
||||
|
||||
abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass
|
||||
|
||||
abstract fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade
|
||||
|
||||
abstract fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript
|
||||
|
||||
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||
|
||||
/*
|
||||
* Finds files whose package declaration is exactly {@code fqName}. For example, if a file declares
|
||||
* package a.b.c
|
||||
* it will not be returned for fqName "a.b"
|
||||
*
|
||||
* If the resulting collection is empty, it means that this package has not other declarations than sub-packages
|
||||
*/
|
||||
abstract fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
abstract class KotlinAsJavaSupport {
|
||||
// Returns only immediately declared classes/objects, package classes are not included (they have no declarations)
|
||||
abstract fun findClassOrObjectDeclarationsInPackage(
|
||||
packageFqName: FqName,
|
||||
searchScope: GlobalSearchScope
|
||||
packageFqName: FqName,
|
||||
searchScope: GlobalSearchScope
|
||||
): Collection<KtClassOrObject>
|
||||
|
||||
/*
|
||||
* Finds files whose package declaration is exactly {@code fqName}. For example, if a file declares
|
||||
* package a.b.c
|
||||
* it will not be returned for fqName "a.b"
|
||||
*
|
||||
* If the resulting collection is empty, it means that this package has not other declarations than sub-packages
|
||||
*/
|
||||
abstract fun findFilesForPackage(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
abstract fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject>
|
||||
|
||||
abstract fun packageExists(fqName: FqName, scope: GlobalSearchScope): Boolean
|
||||
|
||||
abstract fun getSubPackages(fqn: FqName, scope: GlobalSearchScope): Collection<FqName>
|
||||
@@ -63,12 +58,6 @@ abstract class LightClassGenerationSupport {
|
||||
|
||||
abstract fun getLightClassForScript(script: KtScript): KtLightClassForScript?
|
||||
|
||||
abstract fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
|
||||
|
||||
abstract fun analyze(element: KtElement): BindingContext
|
||||
|
||||
abstract fun analyzeWithContent(element: KtClassOrObject): BindingContext
|
||||
|
||||
abstract fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
|
||||
abstract fun getScriptClasses(scriptFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass>
|
||||
@@ -82,7 +71,29 @@ abstract class LightClassGenerationSupport {
|
||||
abstract fun findFilesForFacade(facadeFqName: FqName, scope: GlobalSearchScope): Collection<KtFile>
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun getInstance(project: Project): LightClassGenerationSupport {
|
||||
@JvmStatic
|
||||
fun getInstance(project: Project): KotlinAsJavaSupport {
|
||||
return ServiceManager.getService(project, KotlinAsJavaSupport::class.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LightClassGenerationSupport {
|
||||
abstract fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass
|
||||
|
||||
abstract fun createDataHolderForFacade(files: Collection<KtFile>, builder: LightClassBuilder): LightClassDataHolder.ForFacade
|
||||
|
||||
abstract fun createDataHolderForScript(script: KtScript, builder: LightClassBuilder): LightClassDataHolder.ForScript
|
||||
|
||||
abstract fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor?
|
||||
|
||||
abstract fun analyze(element: KtElement): BindingContext
|
||||
|
||||
abstract fun analyzeWithContent(element: KtClassOrObject): BindingContext
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(project: Project): LightClassGenerationSupport {
|
||||
return ServiceManager.getService(project, LightClassGenerationSupport::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -23,6 +23,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.CachedValueProvider
|
||||
import com.intellij.psi.util.PsiModificationTracker
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||
import org.jetbrains.kotlin.codegen.CompilationErrorHandler
|
||||
@@ -114,7 +115,7 @@ sealed class LightClassDataProviderForFileFacade constructor(
|
||||
facadeFqName: FqName,
|
||||
private val searchScope: GlobalSearchScope
|
||||
) : LightClassDataProviderForFileFacade(project, facadeFqName) {
|
||||
override fun findFiles() = LightClassGenerationSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope)
|
||||
override fun findFiles() = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(facadeFqName, searchScope)
|
||||
}
|
||||
|
||||
// create delegate by single file
|
||||
|
||||
+19
-16
@@ -29,11 +29,14 @@ import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport;
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport;
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.name.FqNamesUtilKt;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.KtClass;
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject;
|
||||
import org.jetbrains.kotlin.psi.KtEnumEntry;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.resolve.jvm.KotlinFinderMarker;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -58,15 +61,15 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
|
||||
private final Project project;
|
||||
private final PsiManager psiManager;
|
||||
private final LightClassGenerationSupport lightClassGenerationSupport;
|
||||
private final KotlinAsJavaSupport kotlinAsJavaSupport;
|
||||
|
||||
public JavaElementFinder(
|
||||
@NotNull Project project,
|
||||
@NotNull LightClassGenerationSupport lightClassGenerationSupport
|
||||
@NotNull KotlinAsJavaSupport kotlinAsJavaSupport
|
||||
) {
|
||||
this.project = project;
|
||||
this.psiManager = PsiManager.getInstance(project);
|
||||
this.lightClassGenerationSupport = lightClassGenerationSupport;
|
||||
this.kotlinAsJavaSupport = kotlinAsJavaSupport;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,8 +90,8 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
FqName qualifiedName = new FqName(qualifiedNameString);
|
||||
|
||||
findClassesAndObjects(qualifiedName, scope, answer);
|
||||
answer.addAll(lightClassGenerationSupport.getFacadeClasses(qualifiedName, scope));
|
||||
answer.addAll(lightClassGenerationSupport.getKotlinInternalClasses(qualifiedName, scope));
|
||||
answer.addAll(kotlinAsJavaSupport.getFacadeClasses(qualifiedName, scope));
|
||||
answer.addAll(kotlinAsJavaSupport.getKotlinInternalClasses(qualifiedName, scope));
|
||||
|
||||
return sortByClasspath(answer, scope).toArray(new PsiClass[answer.size()]);
|
||||
}
|
||||
@@ -99,7 +102,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
findInterfaceDefaultImpls(qualifiedName, scope, answer);
|
||||
|
||||
Collection<KtClassOrObject> classOrObjectDeclarations =
|
||||
lightClassGenerationSupport.findClassOrObjectDeclarations(qualifiedName, scope);
|
||||
kotlinAsJavaSupport.findClassOrObjectDeclarations(qualifiedName, scope);
|
||||
|
||||
for (KtClassOrObject declaration : classOrObjectDeclarations) {
|
||||
if (!(declaration instanceof KtEnumEntry)) {
|
||||
@@ -116,7 +119,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
|
||||
if (!qualifiedName.shortName().asString().equals(JvmAbi.DEFAULT_IMPLS_CLASS_NAME)) return;
|
||||
|
||||
for (KtClassOrObject classOrObject : lightClassGenerationSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
|
||||
for (KtClassOrObject classOrObject : kotlinAsJavaSupport.findClassOrObjectDeclarations(qualifiedName.parent(), scope)) {
|
||||
//NOTE: can't filter out more interfaces right away because decompiled declarations do not have member bodies
|
||||
if (classOrObject instanceof KtClass && ((KtClass) classOrObject).isInterface()) {
|
||||
PsiClass interfaceClass = toLightClass(classOrObject);
|
||||
@@ -135,10 +138,10 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
|
||||
|
||||
Collection<KtClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
|
||||
Collection<KtClassOrObject> declarations = kotlinAsJavaSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
|
||||
|
||||
Set<String> answer = Sets.newHashSet();
|
||||
answer.addAll(lightClassGenerationSupport.getFacadeNames(packageFQN, scope));
|
||||
answer.addAll(kotlinAsJavaSupport.getFacadeNames(packageFQN, scope));
|
||||
|
||||
for (KtClassOrObject declaration : declarations) {
|
||||
String name = declaration.getName();
|
||||
@@ -160,7 +163,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
|
||||
// allScope() because the contract says that the whole project
|
||||
GlobalSearchScope allScope = GlobalSearchScope.allScope(project);
|
||||
if (lightClassGenerationSupport.packageExists(fqName, allScope)) {
|
||||
if (kotlinAsJavaSupport.packageExists(fqName, allScope)) {
|
||||
return new KtLightPackage(psiManager, fqName, allScope);
|
||||
}
|
||||
|
||||
@@ -172,7 +175,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
public PsiPackage[] getSubPackages(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
|
||||
|
||||
Collection<FqName> subpackages = lightClassGenerationSupport.getSubPackages(packageFQN, scope);
|
||||
Collection<FqName> subpackages = kotlinAsJavaSupport.getSubPackages(packageFQN, scope);
|
||||
|
||||
Collection<PsiPackage> answer = Collections2.transform(subpackages, input -> new KtLightPackage(psiManager, input, scope));
|
||||
|
||||
@@ -185,9 +188,9 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
List<PsiClass> answer = new SmartList<>();
|
||||
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
|
||||
|
||||
answer.addAll(lightClassGenerationSupport.getFacadeClassesInPackage(packageFQN, scope));
|
||||
answer.addAll(kotlinAsJavaSupport.getFacadeClassesInPackage(packageFQN, scope));
|
||||
|
||||
Collection<KtClassOrObject> declarations = lightClassGenerationSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
|
||||
Collection<KtClassOrObject> declarations = kotlinAsJavaSupport.findClassOrObjectDeclarationsInPackage(packageFQN, scope);
|
||||
for (KtClassOrObject declaration : declarations) {
|
||||
PsiClass aClass = toLightClass(declaration);
|
||||
if (aClass != null) {
|
||||
@@ -203,7 +206,7 @@ public class JavaElementFinder extends PsiElementFinder implements KotlinFinderM
|
||||
public PsiFile[] getPackageFiles(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
|
||||
FqName packageFQN = new FqName(psiPackage.getQualifiedName());
|
||||
// TODO: this does not take into account JvmPackageName annotation
|
||||
Collection<KtFile> result = lightClassGenerationSupport.findFilesForPackage(packageFQN, scope);
|
||||
Collection<KtFile> result = kotlinAsJavaSupport.findFilesForPackage(packageFQN, scope);
|
||||
return result.toArray(new PsiFile[result.size()]);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.impl.file.PsiPackageImpl;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport;
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
|
||||
public class KtLightPackage extends PsiPackageImpl {
|
||||
@@ -43,6 +43,6 @@ public class KtLightPackage extends PsiPackageImpl {
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return LightClassGenerationSupport.getInstance(getProject()).packageExists(fqName, scope);
|
||||
return KotlinAsJavaSupport.getInstance(getProject()).packageExists(fqName, scope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
|
||||
fun KtClassOrObject.toLightClass(): KtLightClass? = LightClassGenerationSupport.getInstance(project).getLightClass(this)
|
||||
fun KtClassOrObject.toLightClass(): KtLightClass? = KotlinAsJavaSupport.getInstance(project).getLightClass(this)
|
||||
|
||||
fun KtClassOrObject.toLightClassWithBuiltinMapping(): PsiClass? {
|
||||
toLightClass()?.let { return it }
|
||||
@@ -48,12 +48,12 @@ fun KtClassOrObject.toLightClassWithBuiltinMapping(): PsiClass? {
|
||||
}
|
||||
|
||||
fun KtFile.findFacadeClass(): KtLightClass? {
|
||||
return LightClassGenerationSupport.getInstance(project)
|
||||
return KotlinAsJavaSupport.getInstance(project)
|
||||
.getFacadeClassesInPackage(packageFqName, this.useScope as? GlobalSearchScope ?: GlobalSearchScope.projectScope(project))
|
||||
.firstOrNull { it is KtLightClassForFacade && this in it.files } as? KtLightClass
|
||||
}
|
||||
|
||||
fun KtScript.toLightClass(): KtLightClassForScript? = LightClassGenerationSupport.getInstance(project).getLightClassForScript(this)
|
||||
fun KtScript.toLightClass(): KtLightClassForScript? = KotlinAsJavaSupport.getInstance(project).getLightClassForScript(this)
|
||||
|
||||
fun KtElement.toLightElements(): List<PsiNamedElement> =
|
||||
when (this) {
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ abstract class AbstractCompilerLightClassTest : KotlinMultiFileTestWithJava<Void
|
||||
fun findLightClass(environment: KotlinCoreEnvironment, fqname: String): PsiClass? {
|
||||
KotlinTestUtils.resolveAllKotlinFiles(environment)
|
||||
|
||||
val lightCLassForScript = LightClassGenerationSupport
|
||||
val lightCLassForScript = KotlinAsJavaSupport
|
||||
.getInstance(environment.project)
|
||||
.getScriptClasses(FqName(fqname), GlobalSearchScope.allScope(environment.project))
|
||||
.firstOrNull()
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.analyzer.common.CommonAnalyzerFacade
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.container.get
|
||||
@@ -104,7 +104,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
||||
|
||||
val separateModules = groupedByModule.size == 1 && groupedByModule.keys.single() == null
|
||||
val result = analyzeModuleContents(
|
||||
moduleContext, ktFiles, CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
moduleContext, ktFiles, CliTraceHolder.NoScopeRecordCliBindingTrace(),
|
||||
languageVersionSettings, separateModules, loadJvmTarget(testFilesInModule)
|
||||
)
|
||||
if (oldModule != result.moduleDescriptor) {
|
||||
|
||||
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.checkers.CheckerTestUtil;
|
||||
import org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys;
|
||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
|
||||
@@ -466,7 +466,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
try {
|
||||
GenerationState generationState = GenerationUtils.compileFiles(
|
||||
myFiles.getPsiFiles(), myEnvironment, getClassBuilderFactory(),
|
||||
new CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace()
|
||||
new CliTraceHolder.NoScopeRecordCliBindingTrace()
|
||||
);
|
||||
classFileFactory = generationState.getFactory();
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||
import org.jetbrains.kotlin.cli.common.output.outputUtils.writeAllTo
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
@@ -48,7 +48,7 @@ object GenerationUtils {
|
||||
files: List<KtFile>,
|
||||
environment: KotlinCoreEnvironment,
|
||||
classBuilderFactory: ClassBuilderFactory = ClassBuilderFactories.TEST,
|
||||
trace: BindingTrace = CliLightClassGenerationSupport.CliBindingTrace()
|
||||
trace: BindingTrace = CliTraceHolder.CliBindingTrace()
|
||||
): GenerationState =
|
||||
compileFiles(files, environment.configuration, classBuilderFactory, environment::createPackagePartProvider, trace)
|
||||
|
||||
@@ -59,7 +59,7 @@ object GenerationUtils {
|
||||
configuration: CompilerConfiguration,
|
||||
classBuilderFactory: ClassBuilderFactory,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
trace: BindingTrace = CliLightClassGenerationSupport.CliBindingTrace()
|
||||
trace: BindingTrace = CliTraceHolder.CliBindingTrace()
|
||||
): GenerationState {
|
||||
val analysisResult =
|
||||
JvmResolveUtil.analyzeAndCheckForErrors(files.first().project, files, configuration, packagePartProvider, trace)
|
||||
|
||||
+2
-2
@@ -21,7 +21,7 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import junit.framework.ComparisonFailure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment;
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM;
|
||||
@@ -189,7 +189,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
KotlinCoreEnvironment.createForTests(getTestRootDisposable(), configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES);
|
||||
registerJavacIfNeeded(environment);
|
||||
AnalysisResult result = TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
environment.getProject(), environment.getSourceFiles(), new CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
environment.getProject(), environment.getSourceFiles(), new CliTraceHolder.NoScopeRecordCliBindingTrace(),
|
||||
configuration, environment::createPackagePartProvider
|
||||
);
|
||||
|
||||
|
||||
+8
-8
@@ -18,7 +18,7 @@ package org.jetbrains.kotlin.renderer
|
||||
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
@@ -58,13 +58,13 @@ abstract class AbstractDescriptorRendererTest : KotlinTestWithEnvironment() {
|
||||
val context = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(project, environment.configuration)
|
||||
|
||||
val container = createContainerForLazyResolve(
|
||||
context,
|
||||
FileBasedDeclarationProviderFactory(context.storageManager, listOf(psiFile)),
|
||||
CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
JvmPlatform,
|
||||
JvmTarget.JVM_1_6,
|
||||
targetEnvironment,
|
||||
LanguageVersionSettingsImpl.DEFAULT
|
||||
context,
|
||||
FileBasedDeclarationProviderFactory(context.storageManager, listOf(psiFile)),
|
||||
CliTraceHolder.NoScopeRecordCliBindingTrace(),
|
||||
JvmPlatform,
|
||||
JvmTarget.JVM_1_6,
|
||||
targetEnvironment,
|
||||
LanguageVersionSettingsImpl.DEFAULT
|
||||
)
|
||||
|
||||
val resolveSession = container.get<ResolveSession>()
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.resolve.lazy
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.CliTraceHolder
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
@@ -35,7 +35,7 @@ object JvmResolveUtil {
|
||||
@JvmOverloads
|
||||
fun createContainer(environment: KotlinCoreEnvironment, files: Collection<KtFile> = emptyList()): ComponentProvider =
|
||||
TopDownAnalyzerFacadeForJVM.createContainer(
|
||||
environment.project, files, CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace(),
|
||||
environment.project, files, CliTraceHolder.NoScopeRecordCliBindingTrace(),
|
||||
environment.configuration, { PackagePartProvider.Empty }, ::FileBasedDeclarationProviderFactory
|
||||
)
|
||||
|
||||
@@ -53,7 +53,7 @@ object JvmResolveUtil {
|
||||
files: Collection<KtFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
packagePartProvider: (GlobalSearchScope) -> PackagePartProvider,
|
||||
trace: BindingTrace = CliLightClassGenerationSupport.CliBindingTrace()
|
||||
trace: BindingTrace = CliTraceHolder.CliBindingTrace()
|
||||
): AnalysisResult {
|
||||
for (file in files) {
|
||||
AnalyzingUtils.checkForSyntacticErrors(file)
|
||||
@@ -85,7 +85,7 @@ object JvmResolveUtil {
|
||||
files: Collection<KtFile>,
|
||||
configuration: CompilerConfiguration,
|
||||
packagePartProviderFactory: (GlobalSearchScope) -> PackagePartProvider,
|
||||
trace: BindingTrace = CliLightClassGenerationSupport.CliBindingTrace()
|
||||
trace: BindingTrace = CliTraceHolder.CliBindingTrace()
|
||||
): AnalysisResult {
|
||||
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
project, files, trace, configuration, packagePartProviderFactory
|
||||
|
||||
+48
-41
@@ -23,6 +23,7 @@ import com.intellij.psi.impl.compiled.ClsClassImpl
|
||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||
import org.jetbrains.kotlin.asJava.LightClassBuilder
|
||||
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||
import org.jetbrains.kotlin.asJava.builder.ClsWrapperStubPsiFactory
|
||||
@@ -30,13 +31,14 @@ import org.jetbrains.kotlin.asJava.builder.InvalidLightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.builder.LightClassDataHolder
|
||||
import org.jetbrains.kotlin.asJava.classes.*
|
||||
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||
import org.jetbrains.kotlin.asJava.toLightClass
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.*
|
||||
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.caches.project.getModuleInfo
|
||||
import org.jetbrains.kotlin.idea.caches.lightClasses.*
|
||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile
|
||||
import org.jetbrains.kotlin.idea.decompiler.navigation.SourceNavigationHelper
|
||||
import org.jetbrains.kotlin.idea.stubindex.*
|
||||
@@ -51,9 +53,8 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import java.util.*
|
||||
|
||||
class IDELightClassGenerationSupport(private val project: Project) : LightClassGenerationSupport() {
|
||||
class IDELightClassGenerationSupport(project: Project) : LightClassGenerationSupport() {
|
||||
private val scopeFileComparator = JavaElementFinder.byClasspathComparator(GlobalSearchScope.allScope(project))
|
||||
private val psiManager: PsiManager = PsiManager.getInstance(project)
|
||||
|
||||
override fun createDataHolderForClass(classOrObject: KtClassOrObject, builder: LightClassBuilder): LightClassDataHolder.ForClass {
|
||||
return when {
|
||||
@@ -98,6 +99,45 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
||||
try {
|
||||
return declaration.resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
||||
} catch (e: NoDescriptorForDeclarationException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun analyze(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
override fun analyzeWithContent(element: KtClassOrObject) = element.analyzeWithContent()
|
||||
}
|
||||
|
||||
class IDEKotlinAsJavaSupport(private val project: Project): KotlinAsJavaSupport() {
|
||||
private val psiManager: PsiManager = PsiManager.getInstance(project)
|
||||
|
||||
override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String> {
|
||||
val facadeFilesInPackage = runReadAction {
|
||||
KotlinFileFacadeClassByPackageIndex.getInstance().get(packageFqName.asString(), project, scope)
|
||||
}
|
||||
return facadeFilesInPackage.map { it.javaFileFacadeFqName.shortName().asString() }
|
||||
}
|
||||
|
||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
val facadeFilesInPackage = runReadAction {
|
||||
KotlinFileFacadeClassByPackageIndex.getInstance().get(packageFqName.asString(), project, scope)
|
||||
}
|
||||
val groupedByFqNameAndModuleInfo = facadeFilesInPackage.groupBy {
|
||||
Pair(it.javaFileFacadeFqName, it.getModuleInfo())
|
||||
}
|
||||
|
||||
return groupedByFqNameAndModuleInfo.flatMap {
|
||||
val (key, files) = it
|
||||
val (fqName, moduleInfo) = key
|
||||
createLightClassForFileFacade(fqName, files, moduleInfo)
|
||||
}
|
||||
}
|
||||
|
||||
override fun findClassOrObjectDeclarations(fqName: FqName, searchScope: GlobalSearchScope): Collection<KtClassOrObject> {
|
||||
return runReadAction {
|
||||
KotlinFullClassNameIndex.getInstance().get(fqName.asString(), project, sourceAndClassFiles(searchScope, project))
|
||||
@@ -230,40 +270,6 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
}
|
||||
}
|
||||
|
||||
override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? {
|
||||
try {
|
||||
return declaration.resolveToDescriptorIfAny(BodyResolveMode.FULL)
|
||||
} catch (e: NoDescriptorForDeclarationException) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
override fun analyze(element: KtElement) = element.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
override fun analyzeWithContent(element: KtClassOrObject) = element.analyzeWithContent()
|
||||
|
||||
override fun getFacadeNames(packageFqName: FqName, scope: GlobalSearchScope): Collection<String> {
|
||||
val facadeFilesInPackage = runReadAction {
|
||||
KotlinFileFacadeClassByPackageIndex.getInstance().get(packageFqName.asString(), project, scope)
|
||||
}
|
||||
return facadeFilesInPackage.map { it.javaFileFacadeFqName.shortName().asString() }
|
||||
}
|
||||
|
||||
override fun getFacadeClassesInPackage(packageFqName: FqName, scope: GlobalSearchScope): Collection<PsiClass> {
|
||||
val facadeFilesInPackage = runReadAction {
|
||||
KotlinFileFacadeClassByPackageIndex.getInstance().get(packageFqName.asString(), project, scope)
|
||||
}
|
||||
val groupedByFqNameAndModuleInfo = facadeFilesInPackage.groupBy {
|
||||
Pair(it.javaFileFacadeFqName, it.getModuleInfo())
|
||||
}
|
||||
|
||||
return groupedByFqNameAndModuleInfo.flatMap {
|
||||
val (key, files) = it
|
||||
val (fqName, moduleInfo) = key
|
||||
createLightClassForFileFacade(fqName, files, moduleInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getLightClassForDecompiledClassOrObject(decompiledClassOrObject: KtClassOrObject): KtLightClassForDecompiledDeclaration? {
|
||||
if (decompiledClassOrObject is KtEnumEntry) {
|
||||
return null
|
||||
@@ -343,7 +349,8 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG
|
||||
}
|
||||
}
|
||||
|
||||
class KtFileClassProviderImpl(val lightClassGenerationSupport: LightClassGenerationSupport) : KtFileClassProvider {
|
||||
|
||||
class KtFileClassProviderImpl(val kotlinAsJavaSupport: KotlinAsJavaSupport) : KtFileClassProvider {
|
||||
override fun getFileClasses(file: KtFile): Array<PsiClass> {
|
||||
// TODO We don't currently support finding light classes for scripts
|
||||
if (file.isCompiled || file.isScript()) {
|
||||
@@ -351,7 +358,7 @@ class KtFileClassProviderImpl(val lightClassGenerationSupport: LightClassGenerat
|
||||
}
|
||||
|
||||
val result = arrayListOf<PsiClass>()
|
||||
file.declarations.filterIsInstance<KtClassOrObject>().map { lightClassGenerationSupport.getLightClass(it) }.filterNotNullTo(result)
|
||||
file.declarations.filterIsInstance<KtClassOrObject>().map { it.toLightClass() }.filterNotNullTo(result)
|
||||
|
||||
val moduleInfo = file.getModuleInfo()
|
||||
val jvmClassInfo = JvmFileClassUtil.getFileClassInfoNoResolve(file)
|
||||
@@ -362,10 +369,10 @@ class KtFileClassProviderImpl(val lightClassGenerationSupport: LightClassGenerat
|
||||
listOf(KtLightClassForFacade.createForSyntheticFile(PsiManager.getInstance(file.project), fileClassFqName, file))
|
||||
|
||||
jvmClassInfo.withJvmMultifileClass ->
|
||||
lightClassGenerationSupport.getFacadeClasses(fileClassFqName, moduleInfo.contentScope())
|
||||
kotlinAsJavaSupport.getFacadeClasses(fileClassFqName, moduleInfo.contentScope())
|
||||
|
||||
file.hasTopLevelCallables() ->
|
||||
(lightClassGenerationSupport as IDELightClassGenerationSupport).createLightClassForFileFacade(
|
||||
(kotlinAsJavaSupport as IDEKotlinAsJavaSupport).createLightClassForFileFacade(
|
||||
fileClassFqName, listOf(file), moduleInfo
|
||||
)
|
||||
|
||||
|
||||
@@ -257,6 +257,9 @@
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.asJava.LightClassGenerationSupport"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.IDELightClassGenerationSupport"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.asJava.KotlinAsJavaSupport"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.IDEKotlinAsJavaSupport"/>
|
||||
|
||||
<projectService serviceInterface="org.jetbrains.kotlin.psi.KtFileClassProvider"
|
||||
serviceImplementation="org.jetbrains.kotlin.idea.caches.resolve.KtFileClassProviderImpl"/>
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ class KotlinLightClassInheritorTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
private fun doTestInheritorByText(text: String, superQName: String, checkDeep: Boolean) {
|
||||
val file = myFixture.configureByText("A.kt", text) as KtFile
|
||||
val jetClass = file.declarations.filterIsInstance<KtClass>().single()
|
||||
val psiClass = LightClassGenerationSupport.getInstance(project).getLightClass(jetClass)!!
|
||||
val psiClass = KotlinAsJavaSupport.getInstance(project).getLightClass(jetClass)!!
|
||||
val baseClass = JavaPsiFacade.getInstance(project).findClass(superQName, GlobalSearchScope.allScope(project))!!
|
||||
Assert.assertTrue(psiClass.isInheritor(baseClass, checkDeep))
|
||||
}
|
||||
|
||||
@@ -58,14 +58,14 @@ class KtFileLightClassTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
fun testNoFacadeForScript() {
|
||||
val file = myFixture.configureByText("foo.kts", "package foo") as KtFile
|
||||
assertEquals(0, file.classes.size)
|
||||
val facadeFiles = LightClassGenerationSupport.getInstance(project).findFilesForFacade(FqName("foo.FooKt"), GlobalSearchScope.allScope(project))
|
||||
val facadeFiles = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(FqName("foo.FooKt"), GlobalSearchScope.allScope(project))
|
||||
assertEquals(0, facadeFiles.size)
|
||||
}
|
||||
|
||||
fun testNoFacadeForHeaderClass() {
|
||||
val file = myFixture.configureByText("foo.kt", "header fun foo(): Int") as KtFile
|
||||
assertEquals(0, file.classes.size)
|
||||
val facadeFiles = LightClassGenerationSupport.getInstance(project).findFilesForFacade(FqName("foo.FooKt"), GlobalSearchScope.allScope(project))
|
||||
val facadeFiles = KotlinAsJavaSupport.getInstance(project).findFilesForFacade(FqName("foo.FooKt"), GlobalSearchScope.allScope(project))
|
||||
assertEquals(0, facadeFiles.size)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user