From b70405b25feecaa57ae02d757f853b653bfcca4b Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Sat, 26 Mar 2016 17:47:15 +0100 Subject: [PATCH] WEB-20340 JavaScript debugger doesn't show "this" reference with ES6 fat arrows --- .../src/MemberFilterWithNameMappings.kt | 12 ++------ .../debugger-ui/src/ScopeVariablesGroup.kt | 30 ++++++++++++++++--- .../javascript/debugger/NameMapper.kt | 12 +++++--- .../util/resources/misc/registry.properties | 1 + 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/platform/script-debugger/debugger-ui/src/MemberFilterWithNameMappings.kt b/platform/script-debugger/debugger-ui/src/MemberFilterWithNameMappings.kt index b1f0cb06b10d..a84a0c654255 100644 --- a/platform/script-debugger/debugger-ui/src/MemberFilterWithNameMappings.kt +++ b/platform/script-debugger/debugger-ui/src/MemberFilterWithNameMappings.kt @@ -15,12 +15,8 @@ */ package org.jetbrains.debugger -open class MemberFilterWithNameMappings(rawNameToSource: Map?) : MemberFilter { - protected val rawNameToSource = rawNameToSource ?: emptyMap() - - override fun hasNameMappings(): Boolean { - return !rawNameToSource.isEmpty() - } +open class MemberFilterWithNameMappings(protected val rawNameToSource: Map = emptyMap()) : MemberFilter { + override fun hasNameMappings() = !rawNameToSource.isEmpty() override fun rawNameToSource(variable: Variable): String { val name = variable.name @@ -28,9 +24,7 @@ open class MemberFilterWithNameMappings(rawNameToSource: Map?) : return sourceName ?: normalizeMemberName(name) } - protected open fun normalizeMemberName(name: String): String { - return name - } + protected open fun normalizeMemberName(name: String) = name override fun sourceNameToRaw(name: String): String? { if (!hasNameMappings()) { diff --git a/platform/script-debugger/debugger-ui/src/ScopeVariablesGroup.kt b/platform/script-debugger/debugger-ui/src/ScopeVariablesGroup.kt index b08b9af9d9d8..7a467539df0a 100644 --- a/platform/script-debugger/debugger-ui/src/ScopeVariablesGroup.kt +++ b/platform/script-debugger/debugger-ui/src/ScopeVariablesGroup.kt @@ -19,8 +19,10 @@ import com.intellij.xdebugger.XDebuggerBundle import com.intellij.xdebugger.frame.XCompositeNode import com.intellij.xdebugger.frame.XValueChildrenList import com.intellij.xdebugger.frame.XValueGroup +import org.jetbrains.concurrency.Promise import org.jetbrains.concurrency.done import org.jetbrains.concurrency.rejected +import org.jetbrains.concurrency.thenAsyncAccept class ScopeVariablesGroup(val scope: Scope, parentContext: VariableContext, callFrame: CallFrame?) : XValueGroup(scope.createScopeNodeName()) { private val context = createVariableContext(scope, parentContext, callFrame) @@ -42,15 +44,35 @@ class ScopeVariablesGroup(val scope: Scope, parentContext: VariableContext, call promise .done(node) { - callFrame.receiverVariable - .done(node) { - node.addChildren(if (it == null) XValueChildrenList.EMPTY else XValueChildrenList.singleton(VariableView(it, context)), true) + context.memberFilter + .thenAsyncAccept(node) { memberFilter -> + if (memberFilter.hasNameMappings()) { + memberFilter.sourceNameToRaw(RECEIVER_NAME)?.let { + return@thenAsyncAccept callFrame.evaluateContext.evaluate(it) + .done(node) { + VariableImpl(RECEIVER_NAME, it.value, null) + node.addChildren(XValueChildrenList.singleton(VariableView(VariableImpl(RECEIVER_NAME, it.value, null), context)), true) + } + } + } + + computeReceiverVariable(callFrame, node) } .rejected(node) { - node.addChildren(XValueChildrenList.EMPTY, true) + computeReceiverVariable(callFrame, node) } } } + + private fun computeReceiverVariable(callFrame: CallFrame, node: XCompositeNode): Promise<*> { + return callFrame.receiverVariable + .done(node) { + node.addChildren(if (it == null) XValueChildrenList.EMPTY else XValueChildrenList.singleton(VariableView(it, context)), true) + } + .rejected(node) { + node.addChildren(XValueChildrenList.EMPTY, true) + } + } } fun createAndAddScopeList(node: XCompositeNode, scopes: List, context: VariableContext, callFrame: CallFrame?) { diff --git a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt index 31c4f8e6415a..556969cf0425 100644 --- a/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt +++ b/platform/script-debugger/debugger-ui/src/com/jetbrains/javascript/debugger/NameMapper.kt @@ -34,13 +34,13 @@ private val OPERATOR_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1)) val NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:")) // generateVirtualFile only for debug purposes -open class NameMapper(private val document: Document, private val transpiledDocument: Document, private val sourceMappings: MappingList, private val sourceMap: SourceMap, private val transpiledFile: VirtualFile? = null) { +open class NameMapper(private val document: Document, private val transpiledDocument: Document, private val sourceMappings: MappingList, protected val sourceMap: SourceMap, private val transpiledFile: VirtualFile? = null) { var rawNameToSource: MutableMap? = null private set // PsiNamedElement, JSVariable for example // returns generated name - fun map(identifierOrNamedElement: PsiElement): String? { + open fun map(identifierOrNamedElement: PsiElement): String? { val offset = identifierOrNamedElement.textOffset val line = document.getLineNumber(offset) @@ -67,15 +67,19 @@ open class NameMapper(private val document: Document, private val transpiledDocu } var sourceName = sourceEntry.name - if (sourceName == null || Registry.`is`("js.debugger.name.mappings.by.source.code", false)) { + if (sourceName == null || (Registry.`is`("js.debugger.name.mappings.by.source.code", false) || Registry.`is`("js.debugger.map.this.by.source.code", false))) { sourceName = (identifierOrNamedElement as? PsiNamedElement)?.name ?: identifierOrNamedElement.text ?: sourceName ?: return null } + addMapping(generatedName, sourceName) + return generatedName + } + + fun addMapping(generatedName: String, sourceName: String) { if (rawNameToSource == null) { rawNameToSource = THashMap() } rawNameToSource!!.put(generatedName, sourceName) - return generatedName } protected open fun extractName(rawGeneratedName: CharSequence) = NAME_TRIMMER.trimFrom(rawGeneratedName) diff --git a/platform/util/resources/misc/registry.properties b/platform/util/resources/misc/registry.properties index c1995d98390e..29d788713149 100644 --- a/platform/util/resources/misc/registry.properties +++ b/platform/util/resources/misc/registry.properties @@ -554,6 +554,7 @@ js.debugger.v8.use.any.breakpoint=true js.debugger.chrome.use.any.breakpoint=true nodejs.debugger.use.jb.support=true js.debugger.name.mappings.by.source.code=false +js.debugger.map.this.by.source.code=false js.debugger.v8.log= js.debugger.wip.log= js.debugger.fix.jspm.source.maps=false