Debugger: Navigate to the right file in MPP projects (#KT-25152, #KT-25147)
This commit is contained in:
+68
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||
* that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.org.objectweb.asm.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
|
||||
class OriginCollectingClassBuilderFactory(private val builderMode: ClassBuilderMode) : ClassBuilderFactory {
|
||||
val compiledClasses = mutableListOf<ClassNode>()
|
||||
val origins = mutableMapOf<Any, JvmDeclarationOrigin>()
|
||||
|
||||
override fun getClassBuilderMode(): ClassBuilderMode = builderMode
|
||||
|
||||
override fun newClassBuilder(origin: JvmDeclarationOrigin): AbstractClassBuilder.Concrete {
|
||||
val classNode = ClassNode()
|
||||
compiledClasses += classNode
|
||||
origins[classNode] = origin
|
||||
return OriginCollectingClassBuilder(classNode)
|
||||
}
|
||||
|
||||
private inner class OriginCollectingClassBuilder(val classNode: ClassNode) : AbstractClassBuilder.Concrete(classNode) {
|
||||
override fun newField(
|
||||
origin: JvmDeclarationOrigin,
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String,
|
||||
signature: String?,
|
||||
value: Any?
|
||||
): FieldVisitor {
|
||||
val fieldNode = super.newField(origin, access, name, desc, signature, value) as FieldNode
|
||||
origins[fieldNode] = origin
|
||||
return fieldNode
|
||||
}
|
||||
|
||||
override fun newMethod(
|
||||
origin: JvmDeclarationOrigin,
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String,
|
||||
signature: String?,
|
||||
exceptions: Array<out String>?
|
||||
): MethodVisitor {
|
||||
val methodNode = super.newMethod(origin, access, name, desc, signature, exceptions) as MethodNode
|
||||
origins[methodNode] = origin
|
||||
|
||||
// ASM doesn't read information about local variables for the `abstract` methods so we need to get it manually
|
||||
if ((access and Opcodes.ACC_ABSTRACT) != 0 && methodNode.localVariables == null) {
|
||||
methodNode.localVariables = mutableListOf<LocalVariableNode>()
|
||||
}
|
||||
|
||||
return methodNode
|
||||
}
|
||||
}
|
||||
|
||||
override fun asBytes(builder: ClassBuilder): ByteArray {
|
||||
val classWriter = ClassWriter(0)
|
||||
(builder as OriginCollectingClassBuilder).classNode.accept(classWriter)
|
||||
return classWriter.toByteArray()
|
||||
}
|
||||
|
||||
override fun asText(builder: ClassBuilder) = throw UnsupportedOperationException()
|
||||
|
||||
override fun close() {}
|
||||
}
|
||||
@@ -94,6 +94,10 @@ fun PsiElement.nextLeaf(filter: (PsiElement) -> Boolean): PsiElement? {
|
||||
return leaf
|
||||
}
|
||||
|
||||
fun <T : PsiElement> PsiElement.getParentOfTypes(strict: Boolean = false, vararg parentClasses: Class<out T>): T? {
|
||||
return getParentOfTypesAndPredicate(strict, *parentClasses) { true }
|
||||
}
|
||||
|
||||
fun <T : PsiElement> PsiElement.getParentOfTypesAndPredicate(
|
||||
strict: Boolean = false, vararg parentClasses: Class<out T>, predicate: (T) -> Boolean
|
||||
): T? {
|
||||
@@ -121,6 +125,14 @@ inline fun <reified T : PsiElement> PsiElement.getParentOfType(strict: Boolean):
|
||||
return PsiTreeUtil.getParentOfType(this, T::class.java, strict)
|
||||
}
|
||||
|
||||
inline fun <reified T : PsiElement, reified V : PsiElement> PsiElement.getParentOfTypes2(): PsiElement? {
|
||||
return PsiTreeUtil.getParentOfType(this, T::class.java, V::class.java)
|
||||
}
|
||||
|
||||
inline fun <reified T : PsiElement, reified V : PsiElement, reified U : PsiElement> PsiElement.getParentOfTypes3(): PsiElement? {
|
||||
return PsiTreeUtil.getParentOfType(this, T::class.java, V::class.java, U::class.java)
|
||||
}
|
||||
|
||||
inline fun <reified T : PsiElement> PsiElement.getStrictParentOfType(): T? {
|
||||
return PsiTreeUtil.getParentOfType(this, T::class.java, true)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user