From c3512933945509cd9598ddcc745256a52106c25c Mon Sep 17 00:00:00 2001 From: Natalia Ukhorskaya Date: Sat, 26 Dec 2015 01:03:09 +0300 Subject: [PATCH] KotlinPositionManager: drop PositionElement, classNameForPosition now returns collection of names --- .../kotlin/idea/ExtraSteppingFilter.kt | 16 ++-- .../idea/debugger/KotlinPositionManager.kt | 95 ++++++++----------- 2 files changed, 50 insertions(+), 61 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt b/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt index 5da57850bb3..8988de949ca 100644 --- a/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt +++ b/idea/src/org/jetbrains/kotlin/idea/ExtraSteppingFilter.kt @@ -56,14 +56,16 @@ public class ExtraSteppingFilter : com.intellij.debugger.engine.ExtraSteppingFil if (sourcePosition == null) return false - val className = positionManager.classNameForPosition(sourcePosition)?.replace('/', '.') ?: return false + val classNames = positionManager.classNamesForPosition(sourcePosition).map { it.replace('/', '.') } - val settings = DebuggerSettings.getInstance() - if (settings.TRACING_FILTERS_ENABLED) { - for (filter in settings.getSteppingFilters()) { - if (filter.isEnabled()) { - if (filter.matches(className)) { - return true; + classNames.forEach { className -> + val settings = DebuggerSettings.getInstance() + if (settings.TRACING_FILTERS_ENABLED) { + for (filter in settings.steppingFilters) { + if (filter.isEnabled) { + if (filter.matches(className)) { + return true + } } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinPositionManager.kt b/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinPositionManager.kt index 3bc535872ce..bd0e5782203 100644 --- a/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinPositionManager.kt +++ b/idea/src/org/jetbrains/kotlin/idea/debugger/KotlinPositionManager.kt @@ -70,8 +70,6 @@ import org.jetbrains.kotlin.utils.toReadOnlyList import java.util.* import com.intellij.debugger.engine.DebuggerUtils as JDebuggerUtils -class PositionedElement(val className: String?, val element: PsiElement?) - public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : MultiRequestPositionManager, PositionManagerEx() { private val myTypeMappers = WeakHashMap>() @@ -177,8 +175,8 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M continue } - val internalClassName = getInternalClassNameForElement(literal.firstChild, typeMapper, file, isInLibrary).className - if (internalClassName == currentLocationClassName) { + val internalClassNames = getInternalClassNameForElement(literal.firstChild, typeMapper, file, isInLibrary) + if (internalClassNames.any { it == currentLocationClassName }) { return literal } } @@ -233,7 +231,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M if (!ProjectRootsUtil.isInProjectOrLibSource(psiFile)) return result - val names = classNameForPositionAndInlinedOnes(sourcePosition) + val names = classNamesForPositionAndInlinedOnes(sourcePosition) for (name in names) { result.addAll(myDebugProcess.virtualMachineProxy.classesByName(name)) } @@ -252,14 +250,10 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M throw NoDataException.INSTANCE } - private fun classNameForPositionAndInlinedOnes(sourcePosition: SourcePosition): List { + private fun classNamesForPositionAndInlinedOnes(sourcePosition: SourcePosition): List { val result = hashSetOf() - val name = classNameForPosition(sourcePosition) - if (name != null) { - result.add(name) - } - val list = findInlinedCalls(sourcePosition.elementAt, sourcePosition.file) - result.addAll(list) + val names = classNamesForPosition(sourcePosition) + result.addAll(names) val lambdas = findLambdas(sourcePosition) result.addAll(lambdas) @@ -267,33 +261,33 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M return result.toReadOnlyList(); } - private fun findLambdas(sourcePosition: SourcePosition): List { + private fun findLambdas(sourcePosition: SourcePosition): Collection { return runReadAction { val lambdas = getLambdasAtLineIfAny(sourcePosition) val file = sourcePosition.file.containingFile as KtFile val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null - lambdas.mapNotNull { + lambdas.flatMap { val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(it, file) - getInternalClassNameForElement(it, typeMapper, file, isInLibrary).className + getInternalClassNameForElement(it, typeMapper, file, isInLibrary) } } } - public fun classNameForPosition(sourcePosition: SourcePosition): String? { - val psiElement = runReadAction { sourcePosition.elementAt } ?: return null - return classNameForPosition(psiElement) + public fun classNamesForPosition(sourcePosition: SourcePosition): Collection { + val psiElement = runReadAction { sourcePosition.elementAt } ?: return emptyList() + return classNamesForPosition(psiElement) } - private fun classNameForPosition(element: PsiElement): String? { + private fun classNamesForPosition(element: PsiElement): Collection { return runReadAction { if (DumbService.getInstance(element.project).isDumb) { - null + emptySet() } else { val file = element.containingFile as KtFile val isInLibrary = LibraryUtil.findLibraryEntry(file.virtualFile, file.project) != null val typeMapper = if (!isInLibrary) prepareTypeMapper(file) else createTypeMapperForLibraryFile(element, file) - getInternalClassNameForElement(element, typeMapper, file, isInLibrary).className + getInternalClassNameForElement(element, typeMapper, file, isInLibrary) } } } @@ -335,11 +329,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M @Deprecated("Since Idea 14.0.3 use createPrepareRequests fun") override fun createPrepareRequest(classPrepareRequestor: ClassPrepareRequestor, sourcePosition: SourcePosition): ClassPrepareRequest? { - if (sourcePosition.file !is KtFile) { - throw NoDataException.INSTANCE - } - val className = classNameForPosition(sourcePosition) ?: return null - return myDebugProcess.requestsManager.createClassPrepareRequest(classPrepareRequestor, className.replace('/', '.')) + return createPrepareRequests(classPrepareRequestor, sourcePosition).firstOrNull() } override fun createPrepareRequests(requestor: ClassPrepareRequestor, position: SourcePosition): List { @@ -347,7 +337,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M throw NoDataException.INSTANCE } - return classNameForPositionAndInlinedOnes(position).mapNotNull { + return classNamesForPositionAndInlinedOnes(position).mapNotNull { className -> myDebugProcess.requestsManager.createClassPrepareRequest(requestor, className.replace('/', '.')) } } @@ -360,24 +350,24 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M myTypeMappers.put(key, value) } - private fun getInternalClassNameForElement(notPositionedElement: PsiElement?, typeMapper: JetTypeMapper, file: KtFile, isInLibrary: Boolean): PositionedElement { + private fun getInternalClassNameForElement(notPositionedElement: PsiElement?, typeMapper: JetTypeMapper, file: KtFile, isInLibrary: Boolean): Collection { val element = getElementToCalculateClassName(notPositionedElement) when { - element is KtClassOrObject -> return PositionedElement(getJvmInternalNameForImpl(typeMapper, element), element) + element is KtClassOrObject -> return getJvmInternalNameForImpl(typeMapper, element).toCollection() element is KtFunctionLiteral -> { if (isInlinedLambda(element, typeMapper.bindingContext)) { return getInternalClassNameForElement(element.parent, typeMapper, file, isInLibrary) } else { val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.bindingContext, element) - return PositionedElement(asmType.internalName, element) + return asmType.internalName.toCollection() } } element is KtAnonymousInitializer -> { val parent = getElementToCalculateClassName(element.parent) // Class-object initializer if (parent is KtObjectDeclaration && parent.isCompanion()) { - return PositionedElement(getInternalClassNameForElement(parent.parent, typeMapper, file, isInLibrary).className, parent) + return getInternalClassNameForElement(parent.parent, typeMapper, file, isInLibrary) } return getInternalClassNameForElement(element.parent, typeMapper, file, isInLibrary) } @@ -385,7 +375,7 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M if (isInPropertyAccessor(notPositionedElement)) { val classOrObject = PsiTreeUtil.getParentOfType(element, KtClassOrObject::class.java) if (classOrObject != null) { - return PositionedElement(getJvmInternalNameForImpl(typeMapper, classOrObject), element) + return getJvmInternalNameForImpl(typeMapper, classOrObject).toCollection() } } @@ -394,25 +384,31 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M return getInternalClassNameForElement(element.parent, typeMapper, file, isInLibrary) } - return PositionedElement(getJvmInternalNameForPropertyOwner(typeMapper, descriptor), element) + return getJvmInternalNameForPropertyOwner(typeMapper, descriptor).toCollection() } element is KtNamedFunction -> { if (isInlinedLambda(element, typeMapper.bindingContext)) { return getInternalClassNameForElement(element.parent, typeMapper, file, isInLibrary) } + val inlinedCalls = findInlinedCalls(element, typeMapper.bindingContext) val parent = getElementToCalculateClassName(element.parent) - if (parent is KtClassOrObject) { - return PositionedElement(getJvmInternalNameForImpl(typeMapper, parent), element) + val parentInternalName = if (parent is KtClassOrObject) { + getJvmInternalNameForImpl(typeMapper, parent) } else if (parent != null) { val asmType = CodegenBinding.asmTypeForAnonymousClass(typeMapper.bindingContext, element) - return PositionedElement(asmType.internalName, element) + asmType.internalName } + else { + NoResolveFileClassesProvider.getFileClassInternalName(file) + } + + return (inlinedCalls + parentInternalName.toCollection()).toSet() } } - return PositionedElement(NoResolveFileClassesProvider.getFileClassInternalName(file), element) + return NoResolveFileClassesProvider.getFileClassInternalName(file).toCollection() } private val TYPES_TO_CALCULATE_CLASSNAME: Array> = @@ -468,29 +464,18 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M private fun createKeyForTypeMapper(file: KtFile) = NoResolveFileClassesProvider.getFileClassInternalName(file) - private fun findInlinedCalls(element: PsiElement?, jetFile: PsiFile?): List { - if (element == null || jetFile !is KtFile) { - return emptyList() - } - + private fun findInlinedCalls(function: KtNamedFunction, context: BindingContext): Collection { return runReadAction { - val result = arrayListOf() - val isInLibrary = LibraryUtil.findLibraryEntry(jetFile.virtualFile, jetFile.project) != null - val typeMapper = if (!isInLibrary) prepareTypeMapper(jetFile) else createTypeMapperForLibraryFile(element, jetFile) - val psiElement = getInternalClassNameForElement(element, typeMapper, jetFile, isInLibrary).element; + val result = hashSetOf() - if (psiElement is KtNamedFunction && - InlineUtil.isInline(typeMapper.bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement)) - ) { - ReferencesSearch.search(psiElement).forEach { + if (InlineUtil.isInline(context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, function))) { + ReferencesSearch.search(function).forEach { if (!it.isImportUsage()) { val usage = it.element if (usage is KtElement) { //TODO recursive search - val name = classNameForPosition(usage) - if (name != null) { - result.add(name) - } + val names = classNamesForPosition(usage) + result.addAll(names) } } true @@ -502,6 +487,8 @@ public class KotlinPositionManager(private val myDebugProcess: DebugProcess) : M private fun ReferenceType.containsKotlinStrata() = availableStrata().contains("Kotlin") + private fun String?.toCollection() = if (this == null) emptySet() else setOf(this) + companion object { public fun createTypeMapper(file: KtFile): JetTypeMapper { val project = file.project