KotlinPositionManager: add progress when computing classnames for inline function
This commit is contained in:
@@ -25,8 +25,12 @@ import com.intellij.debugger.engine.PositionManagerEx
|
|||||||
import com.intellij.debugger.engine.evaluation.EvaluationContext
|
import com.intellij.debugger.engine.evaluation.EvaluationContext
|
||||||
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
import com.intellij.debugger.jdi.StackFrameProxyImpl
|
||||||
import com.intellij.debugger.requests.ClassPrepareRequestor
|
import com.intellij.debugger.requests.ClassPrepareRequestor
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
|
import com.intellij.openapi.application.ModalityState
|
||||||
|
import com.intellij.openapi.progress.ProgressManager
|
||||||
import com.intellij.openapi.project.DumbService
|
import com.intellij.openapi.project.DumbService
|
||||||
import com.intellij.openapi.roots.libraries.LibraryUtil
|
import com.intellij.openapi.roots.libraries.LibraryUtil
|
||||||
|
import com.intellij.openapi.ui.MessageType
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiFile
|
import com.intellij.psi.PsiFile
|
||||||
import com.intellij.psi.impl.compiled.ClsFileImpl
|
import com.intellij.psi.impl.compiled.ClsFileImpl
|
||||||
@@ -34,6 +38,7 @@ import com.intellij.psi.search.searches.ReferencesSearch
|
|||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.util.ThreeState
|
import com.intellij.util.ThreeState
|
||||||
import com.intellij.xdebugger.frame.XStackFrame
|
import com.intellij.xdebugger.frame.XStackFrame
|
||||||
|
import com.intellij.xdebugger.impl.XDebugSessionImpl
|
||||||
import com.sun.jdi.AbsentInformationException
|
import com.sun.jdi.AbsentInformationException
|
||||||
import com.sun.jdi.Location
|
import com.sun.jdi.Location
|
||||||
import com.sun.jdi.ReferenceType
|
import com.sun.jdi.ReferenceType
|
||||||
@@ -238,7 +243,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (psiFile is ClsFileImpl) {
|
if (psiFile is ClsFileImpl) {
|
||||||
val decompiledPsiFile = runReadAction { psiFile.decompiledPsiFile }
|
val decompiledPsiFile = psiFile.readAction { it.decompiledPsiFile }
|
||||||
if (decompiledPsiFile is KtClsFile && sourcePosition.line == -1) {
|
if (decompiledPsiFile is KtClsFile && sourcePosition.line == -1) {
|
||||||
val className =
|
val className =
|
||||||
JvmFileClassUtil.getFileClassInfoNoResolve(decompiledPsiFile).fileClassFqName.internalNameWithoutInnerClasses
|
JvmFileClassUtil.getFileClassInfoNoResolve(decompiledPsiFile).fileClassFqName.internalNameWithoutInnerClasses
|
||||||
@@ -254,7 +259,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun classNamesForPosition(sourcePosition: SourcePosition, withInlines: Boolean): List<String> {
|
private fun classNamesForPosition(sourcePosition: SourcePosition, withInlines: Boolean): List<String> {
|
||||||
val element = runReadAction { sourcePosition.elementAt } ?: return emptyList()
|
val element = sourcePosition.readAction { it.elementAt } ?: return emptyList()
|
||||||
val names = classNamesForPosition(element, withInlines)
|
val names = classNamesForPosition(element, withInlines)
|
||||||
|
|
||||||
val lambdas = findLambdas(sourcePosition)
|
val lambdas = findLambdas(sourcePosition)
|
||||||
@@ -265,27 +270,25 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
return names + lambdas
|
return names + lambdas
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun classNamesForPosition(element: PsiElement, withInlines: Boolean): List<String> {
|
private fun classNamesForPosition(element: PsiElement?, withInlines: Boolean): List<String> {
|
||||||
return runReadAction {
|
if (DumbService.getInstance(myDebugProcess.project).isDumb) {
|
||||||
if (DumbService.getInstance(element.project).isDumb) {
|
return emptyList()
|
||||||
emptyList()
|
}
|
||||||
}
|
else {
|
||||||
else {
|
val baseElement = getElementToCalculateClassName(element) ?: return emptyList()
|
||||||
val baseElement = getElementToCalculateClassName(element) ?: return@runReadAction emptyList()
|
return getOrComputeClassNames(baseElement) {
|
||||||
getOrComputeClassNames(baseElement) {
|
element ->
|
||||||
element ->
|
val file = element.readAction { it.containingFile as KtFile }
|
||||||
val file = element.containingFile as KtFile
|
val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null
|
||||||
val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null
|
val typeMapper = KotlinDebuggerCaches.getOrCreateTypeMapper(element)
|
||||||
val typeMapper = KotlinDebuggerCaches.getOrCreateTypeMapper(element)
|
|
||||||
|
|
||||||
getInternalClassNameForElement(element, typeMapper, file, isInLibrary, withInlines)
|
getInternalClassNameForElement(element, typeMapper, file, isInLibrary, withInlines)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findLambdas(sourcePosition: SourcePosition): Collection<String> {
|
private fun findLambdas(sourcePosition: SourcePosition): Collection<String> {
|
||||||
val lambdas = runReadAction { getLambdasAtLineIfAny(sourcePosition) }
|
val lambdas = sourcePosition.readAction { getLambdasAtLineIfAny(it) }
|
||||||
return lambdas.flatMap { classNamesForPosition(it, true) }
|
return lambdas.flatMap { classNamesForPosition(it, true) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -330,12 +333,13 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
isInLibrary: Boolean,
|
isInLibrary: Boolean,
|
||||||
withInlines: Boolean
|
withInlines: Boolean
|
||||||
): KotlinDebuggerCaches.ComputedClassNames {
|
): KotlinDebuggerCaches.ComputedClassNames {
|
||||||
|
val parent = element.readAction { getElementToCalculateClassName(it.parent) }
|
||||||
when (element) {
|
when (element) {
|
||||||
is KtClassOrObject -> return CachedClassNames(getClassNameForClass(element, typeMapper))
|
is KtClassOrObject -> return CachedClassNames(getClassNameForClass(element, typeMapper))
|
||||||
is KtFunction -> {
|
is KtFunction -> {
|
||||||
val descriptor = InlineUtil.getInlineArgumentDescriptor(element, typeMapper.bindingContext)
|
val descriptor = element.readAction { InlineUtil.getInlineArgumentDescriptor(it, typeMapper.bindingContext) }
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
val classNamesForParent = classNamesForPosition(element.parent, withInlines)
|
val classNamesForParent = classNamesForPosition(parent, withInlines)
|
||||||
if (descriptor.isCrossinline) {
|
if (descriptor.isCrossinline) {
|
||||||
return CachedClassNames(classNamesForParent + findCrossInlineArguments(element, descriptor, typeMapper.bindingContext))
|
return CachedClassNames(classNamesForParent + findCrossInlineArguments(element, descriptor, typeMapper.bindingContext))
|
||||||
}
|
}
|
||||||
@@ -344,7 +348,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val crossInlineParameterUsages = element.containsCrossInlineParameterUsages(typeMapper.bindingContext)
|
val crossInlineParameterUsages = element.readAction { it.containsCrossInlineParameterUsages(typeMapper.bindingContext) }
|
||||||
if (crossInlineParameterUsages.isNotEmpty()) {
|
if (crossInlineParameterUsages.isNotEmpty()) {
|
||||||
return CachedClassNames(classNamesForCrossInlineParameters(crossInlineParameterUsages, typeMapper.bindingContext).toList())
|
return CachedClassNames(classNamesForCrossInlineParameters(crossInlineParameterUsages, typeMapper.bindingContext).toList())
|
||||||
}
|
}
|
||||||
@@ -355,38 +359,36 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
return CachedClassNames(asmType.internalName)
|
return CachedClassNames(asmType.internalName)
|
||||||
}
|
}
|
||||||
element is KtAnonymousInitializer -> {
|
element is KtAnonymousInitializer -> {
|
||||||
val parent = getElementToCalculateClassName(element.parent)
|
|
||||||
// Class-object initializer
|
// Class-object initializer
|
||||||
if (parent is KtObjectDeclaration && parent.isCompanion()) {
|
if (parent is KtObjectDeclaration && parent.isCompanion()) {
|
||||||
return CachedClassNames(classNamesForPosition(parent.parent, withInlines))
|
return CachedClassNames(classNamesForPosition(parent.parent, withInlines))
|
||||||
}
|
}
|
||||||
return CachedClassNames(classNamesForPosition(element.parent, withInlines))
|
return CachedClassNames(classNamesForPosition(parent, withInlines))
|
||||||
}
|
}
|
||||||
element is KtPropertyAccessor && (!element.property.isTopLevel || !isInLibrary)-> {
|
element is KtPropertyAccessor && (!element.readAction { it.property.isTopLevel } || !isInLibrary) -> {
|
||||||
val classOrObject = PsiTreeUtil.getParentOfType(element, KtClassOrObject::class.java)
|
val classOrObject = element.readAction { PsiTreeUtil.getParentOfType(it, KtClassOrObject::class.java) }
|
||||||
if (classOrObject != null) {
|
if (classOrObject != null) {
|
||||||
return CachedClassNames(getClassNameForClass(classOrObject, typeMapper))
|
return CachedClassNames(getClassNameForClass(classOrObject, typeMapper))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
element is KtProperty && (!element.isTopLevel || !isInLibrary) -> {
|
element is KtProperty && (!element.readAction { it.isTopLevel } || !isInLibrary) -> {
|
||||||
val descriptor = typeMapper.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
|
val descriptor = typeMapper.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, element)
|
||||||
if (descriptor !is PropertyDescriptor) {
|
if (descriptor !is PropertyDescriptor) {
|
||||||
return CachedClassNames(classNamesForPosition(element.parent, withInlines))
|
return CachedClassNames(classNamesForPosition(parent, withInlines))
|
||||||
}
|
}
|
||||||
|
|
||||||
return CachedClassNames(getJvmInternalNameForPropertyOwner(typeMapper, descriptor))
|
return CachedClassNames(getJvmInternalNameForPropertyOwner(typeMapper, descriptor))
|
||||||
}
|
}
|
||||||
element is KtNamedFunction -> {
|
element is KtNamedFunction -> {
|
||||||
val parent = getElementToCalculateClassName(element.parent)
|
|
||||||
val parentInternalName = if (parent is KtClassOrObject) {
|
val parentInternalName = if (parent is KtClassOrObject) {
|
||||||
getJvmInternalNameForImpl(typeMapper, parent)
|
getClassNameForClass(parent, typeMapper)
|
||||||
}
|
}
|
||||||
else if (parent != null) {
|
else if (parent != null) {
|
||||||
val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.bindingContext, element)
|
val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.bindingContext, element)
|
||||||
asmType.internalName
|
asmType.internalName
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NoResolveFileClassesProvider.getFileClassInternalName(file)
|
getClassNameForFile(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!withInlines) return NonCachedClassNames(parentInternalName)
|
if (!withInlines) return NonCachedClassNames(parentInternalName)
|
||||||
@@ -399,29 +401,34 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return CachedClassNames(NoResolveFileClassesProvider.getFileClassInternalName(file))
|
return CachedClassNames(getClassNameForFile(file))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getClassNameForClass(klass: KtClassOrObject, typeMapper: JetTypeMapper) = getJvmInternalNameForImpl(typeMapper, klass)
|
private fun getClassNameForClass(klass: KtClassOrObject, typeMapper: JetTypeMapper) = klass.readAction { getJvmInternalNameForImpl(typeMapper, it) }
|
||||||
|
private fun getClassNameForFile(file: KtFile) = file.readAction { NoResolveFileClassesProvider.getFileClassInternalName(it) }
|
||||||
|
|
||||||
private val TYPES_TO_CALCULATE_CLASSNAME: Array<Class<out KtElement>> =
|
private val TYPES_TO_CALCULATE_CLASSNAME: Array<Class<out KtElement>> =
|
||||||
arrayOf(KtClassOrObject::class.java,
|
arrayOf(KtClass::class.java,
|
||||||
|
KtObjectDeclaration::class.java,
|
||||||
|
KtEnumEntry::class.java,
|
||||||
KtFunctionLiteral::class.java,
|
KtFunctionLiteral::class.java,
|
||||||
KtNamedFunction::class.java,
|
KtNamedFunction::class.java,
|
||||||
KtPropertyAccessor::class.java,
|
KtPropertyAccessor::class.java,
|
||||||
KtProperty::class.java,
|
KtProperty::class.java,
|
||||||
KtAnonymousInitializer::class.java)
|
KtClassInitializer::class.java)
|
||||||
|
|
||||||
private fun getElementToCalculateClassName(notPositionedElement: PsiElement?): KtElement? {
|
private fun getElementToCalculateClassName(notPositionedElement: PsiElement?): KtElement? {
|
||||||
if (notPositionedElement?.javaClass as Class<*> in TYPES_TO_CALCULATE_CLASSNAME) return notPositionedElement as KtElement
|
if (notPositionedElement?.javaClass as Class<*> in TYPES_TO_CALCULATE_CLASSNAME) return notPositionedElement as KtElement
|
||||||
|
|
||||||
return PsiTreeUtil.getParentOfType(notPositionedElement, *TYPES_TO_CALCULATE_CLASSNAME)
|
return readAction { PsiTreeUtil.getParentOfType(notPositionedElement, *TYPES_TO_CALCULATE_CLASSNAME) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getJvmInternalNameForPropertyOwner(typeMapper: JetTypeMapper, descriptor: PropertyDescriptor): String {
|
fun getJvmInternalNameForPropertyOwner(typeMapper: JetTypeMapper, descriptor: PropertyDescriptor): String {
|
||||||
return typeMapper.mapOwner(
|
return descriptor.readAction {
|
||||||
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(descriptor)) descriptor.containingDeclaration else descriptor
|
typeMapper.mapOwner(
|
||||||
).internalName
|
if (JvmAbi.isPropertyWithBackingFieldInOuterClass(it)) it.containingDeclaration else it
|
||||||
|
).internalName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getJvmInternalNameForImpl(typeMapper: JetTypeMapper, ktClass: KtClassOrObject): String? {
|
private fun getJvmInternalNameForImpl(typeMapper: JetTypeMapper, ktClass: KtClassOrObject): String? {
|
||||||
@@ -439,21 +446,38 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
return emptyList()
|
return emptyList()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return runReadAction {
|
val searchResult = hashSetOf<KtElement>()
|
||||||
val result = hashSetOf<String>()
|
val functionName = function.readAction { it.name }
|
||||||
|
|
||||||
|
val task = Runnable {
|
||||||
ReferencesSearch.search(function, myDebugProcess.searchScope).forEach {
|
ReferencesSearch.search(function, myDebugProcess.searchScope).forEach {
|
||||||
if (!it.isImportUsage()) {
|
if (!it.readAction { it.isImportUsage() }) {
|
||||||
val usage = it.element
|
val usage = (it.element as? KtElement)?.let { getElementToCalculateClassName(it) }
|
||||||
if (usage is KtElement) {
|
if (usage != null) {
|
||||||
//TODO recursive search
|
searchResult.add(usage)
|
||||||
val names = classNamesForPosition(usage, true)
|
|
||||||
result.addAll(names)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.toList()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isSuccess = true
|
||||||
|
ApplicationManager.getApplication().invokeAndWait(
|
||||||
|
{
|
||||||
|
isSuccess = ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||||
|
task,
|
||||||
|
"Compute class names for function $functionName",
|
||||||
|
true,
|
||||||
|
myDebugProcess.project)
|
||||||
|
}, ModalityState.NON_MODAL)
|
||||||
|
|
||||||
|
if (!isSuccess) {
|
||||||
|
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(
|
||||||
|
"Debugger can skip some executions of $functionName method, because the computation of class names was interrupted", MessageType.WARNING
|
||||||
|
).notify(myDebugProcess.project)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO recursive search
|
||||||
|
return searchResult.flatMap { classNamesForPosition(it, true) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,15 +528,17 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
val inlineFunction = parameter.containingDeclaration.source.getPsi() as? KtNamedFunction ?: return emptySet()
|
val inlineFunction = parameter.containingDeclaration.source.getPsi() as? KtNamedFunction ?: return emptySet()
|
||||||
|
|
||||||
ReferencesSearch.search(inlineFunction, myDebugProcess.searchScope).forEach {
|
ReferencesSearch.search(inlineFunction, myDebugProcess.searchScope).forEach {
|
||||||
if (!it.isImportUsage()) {
|
runReadAction {
|
||||||
val call = (it.element as? KtExpression)?.let { KtPsiUtil.getParentCallIfPresent(it) }
|
if (!it.isImportUsage()) {
|
||||||
if (call != null) {
|
val call = (it.element as? KtExpression)?.let { KtPsiUtil.getParentCallIfPresent(it) }
|
||||||
val resolvedCall = call.getResolvedCall(context)
|
if (call != null) {
|
||||||
val argument = resolvedCall?.valueArguments?.entries?.firstOrNull { it.key.original == parameter }?.value
|
val resolvedCall = call.getResolvedCall(context)
|
||||||
if (argument != null) {
|
val argument = resolvedCall?.valueArguments?.entries?.firstOrNull { it.key.original == parameter }?.value
|
||||||
val argumentExpression = getArgumentExpression(argument.arguments.first())
|
if (argument != null) {
|
||||||
if (argumentExpression is KtFunction) {
|
val argumentExpression = getArgumentExpression(argument.arguments.first())
|
||||||
result.add(getCrossInlineArgumentClassName(argumentExpression, inlineFunction.name!!, context))
|
if (argumentExpression is KtFunction) {
|
||||||
|
result.add(getCrossInlineArgumentClassName(argumentExpression, inlineFunction.name!!, context))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -536,3 +562,7 @@ class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiReq
|
|||||||
|
|
||||||
private fun ReferenceType.containsKotlinStrata() = availableStrata().contains("Kotlin")
|
private fun ReferenceType.containsKotlinStrata() = availableStrata().contains("Kotlin")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inline fun <U, V> U.readAction(crossinline f: (U) -> V): V {
|
||||||
|
return runReadAction { f(this) }
|
||||||
|
}
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ class KotlinDebuggerCaches(private val project: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun <T: PsiElement> getOrComputeClassNames(psiElement: T, create: (T) -> ComputedClassNames): List<String> {
|
fun <T: PsiElement> getOrComputeClassNames(psiElement: T, create: (T) -> ComputedClassNames): List<String> {
|
||||||
val cache = getInstance(psiElement.project)
|
val cache = getInstance(runReadAction { psiElement.project })
|
||||||
synchronized(cache.cachedClassNames) {
|
synchronized(cache.cachedClassNames) {
|
||||||
val classNamesCache = cache.cachedClassNames.value
|
val classNamesCache = cache.cachedClassNames.value
|
||||||
|
|
||||||
@@ -112,11 +112,11 @@ class KotlinDebuggerCaches(private val project: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun getOrCreateTypeMapper(psiElement: PsiElement): JetTypeMapper {
|
fun getOrCreateTypeMapper(psiElement: PsiElement): JetTypeMapper {
|
||||||
val cache = getInstance(psiElement.project)
|
val cache = getInstance(runReadAction { psiElement.project })
|
||||||
synchronized(cache.cachedTypeMappers) {
|
synchronized(cache.cachedTypeMappers) {
|
||||||
val typeMappersCache = cache.cachedTypeMappers.value
|
val typeMappersCache = cache.cachedTypeMappers.value
|
||||||
|
|
||||||
val file = psiElement.containingFile as KtFile
|
val file = runReadAction { psiElement.containingFile as KtFile }
|
||||||
val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null
|
val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null
|
||||||
|
|
||||||
if (!isInLibrary) {
|
if (!isInLibrary) {
|
||||||
@@ -142,33 +142,37 @@ class KotlinDebuggerCaches(private val project: Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createTypeMapperForLibraryFile(element: KtElement, file: KtFile): JetTypeMapper {
|
private fun createTypeMapperForLibraryFile(element: KtElement, file: KtFile): JetTypeMapper {
|
||||||
val analysisResult = element.analyzeAndGetResult()
|
return runReadAction {
|
||||||
|
val analysisResult = element.analyzeAndGetResult()
|
||||||
|
|
||||||
val state = GenerationState(
|
val state = GenerationState(
|
||||||
file.project,
|
file.project,
|
||||||
ClassBuilderFactories.THROW_EXCEPTION,
|
ClassBuilderFactories.THROW_EXCEPTION,
|
||||||
analysisResult.moduleDescriptor,
|
analysisResult.moduleDescriptor,
|
||||||
analysisResult.bindingContext,
|
analysisResult.bindingContext,
|
||||||
listOf(file))
|
listOf(file))
|
||||||
state.beforeCompile()
|
state.beforeCompile()
|
||||||
return state.typeMapper
|
state.typeMapper
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getElementToCreateTypeMapperForLibraryFile(element: PsiElement?) =
|
private fun getElementToCreateTypeMapperForLibraryFile(element: PsiElement?) =
|
||||||
if (element is KtElement) element else PsiTreeUtil.getParentOfType(element, KtElement::class.java)!!
|
runReadAction { if (element is KtElement) element else PsiTreeUtil.getParentOfType(element, KtElement::class.java)!! }
|
||||||
|
|
||||||
private fun createTypeMapperForSourceFile(file: KtFile): JetTypeMapper {
|
private fun createTypeMapperForSourceFile(file: KtFile): JetTypeMapper {
|
||||||
val analysisResult = file.analyzeFullyAndGetResult()
|
return runReadAction {
|
||||||
analysisResult.throwIfError()
|
val analysisResult = file.analyzeFullyAndGetResult()
|
||||||
|
analysisResult.throwIfError()
|
||||||
|
|
||||||
val state = GenerationState(
|
val state = GenerationState(
|
||||||
file.project,
|
file.project,
|
||||||
ClassBuilderFactories.THROW_EXCEPTION,
|
ClassBuilderFactories.THROW_EXCEPTION,
|
||||||
analysisResult.moduleDescriptor,
|
analysisResult.moduleDescriptor,
|
||||||
analysisResult.bindingContext,
|
analysisResult.bindingContext,
|
||||||
listOf(file))
|
listOf(file))
|
||||||
state.beforeCompile()
|
state.beforeCompile()
|
||||||
return state.typeMapper
|
state.typeMapper
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestOnly fun addTypeMapper(file: KtFile, typeMapper: JetTypeMapper) {
|
@TestOnly fun addTypeMapper(file: KtFile, typeMapper: JetTypeMapper) {
|
||||||
|
|||||||
Reference in New Issue
Block a user