From df7d9eb8b68b50dff900d7a6ece45a2a12e3c67b Mon Sep 17 00:00:00 2001
From: hjk <hjk121@nokiamail.com>
Date: Mon, 13 Jan 2014 18:23:22 +0100
Subject: [PATCH] Debugger: Add some convenience to display "paired" data

The switch between compact/full display was so far part of the
individual dumpers, there's some potential for code-reuse here.

Change-Id: I47e3308cfd2209948adbf70fca617908e793c0fc
Reviewed-by: hjk <hjk121@nokiamail.com>
---
 share/qtcreator/debugger/dumper.py   | 52 ++++++++++++++++++++++++++++
 share/qtcreator/debugger/stdtypes.py | 38 +++-----------------
 2 files changed, 57 insertions(+), 33 deletions(-)

diff --git a/share/qtcreator/debugger/dumper.py b/share/qtcreator/debugger/dumper.py
index 0a319b5a409..a70c42165fa 100644
--- a/share/qtcreator/debugger/dumper.py
+++ b/share/qtcreator/debugger/dumper.py
@@ -181,6 +181,34 @@ class Children:
         self.d.put('],')
         return True
 
+class PairedChildrenData:
+    def __init__(self, d, pairType):
+        self.pairType = pairType
+        self.keyType = d.templateArgument(pairType, 0).unqualified()
+        self.valueType = d.templateArgument(pairType, 1)
+        self.isCompact = d.isMapCompact(self.keyType, self.valueType)
+        self.childNumChild = None if self.isCompact else 2
+        self.childType = self.valueType if self.isCompact else self.pairType
+        ns = d.qtNamespace()
+        self.keyIsQString = str(self.keyType) == ns + "QString"
+        self.keyIsQByteArray = str(self.keyType) == ns + "QByteArray"
+
+class PairedChildren:
+    def __init__(self, d, numChild, pairType, maxNumChild = None):
+        self.d = d
+        d.pairData = PairedChildrenData(d, pairType)
+        Children.__init__(self, d, numChild,
+            d.pairData.childType, d.pairData.childNumChild,
+            maxNumChild, addrBase = None, addrStep = None)
+
+    def __enter__(self):
+        self.savedPairData = self.d.pairData if hasattr(self.d, "pairData") else None
+        Children.__enter__(self)
+
+    def __exit__(self, exType, exValue, exTraceBack):
+        Children.__exit__(self, exType, exValue, exTraceBack)
+        self.d.pairData = self.savedPairData if self.savedPairData else None
+
 
 class SubItem:
     def __init__(self, d, component):
@@ -424,6 +452,30 @@ class DumperBase:
             else:
                 self.put('key="[%d] %s",' % (index, val))
 
+    def putPair(self, pair, index = -1):
+        key = pair["first"]
+        value = pair["second"]
+        if self.pairData.isCompact:
+            if self.pairData.keyIsQString:
+                self.put('key="%s",' % self.encodeString(key))
+                self.put('keyencoded="%s",' % Hex4EncodedLittleEndian)
+            elif self.pairData.keyIsQByteArray:
+                self.put('key="%s",' % self.encodeByteArray(key))
+                self.put('keyencoded="%s",' % Hex2EncodedLatin1)
+            else:
+                name = str(key.GetValue()) if self.isLldb else str(key)
+                if index == -1:
+                    self.put('name="%s",' % name)
+                else:
+                    self.put('key="[%d] %s",' % (index, name))
+            self.putItem(value)
+        else:
+            self.putEmptyValue()
+            if self.isExpanded():
+                with Children(self, 2):
+                    self.putSubItem("first", key)
+                    self.putSubItem("second", value)
+
     def isMapCompact(self, keyType, valueType):
         format = self.currentItemFormat()
         if format == 2:
diff --git a/share/qtcreator/debugger/stdtypes.py b/share/qtcreator/debugger/stdtypes.py
index fafe88ec101..7b109a759e6 100644
--- a/share/qtcreator/debugger/stdtypes.py
+++ b/share/qtcreator/debugger/stdtypes.py
@@ -192,42 +192,14 @@ def qdump__std__map(d, value):
     d.putNumChild(size)
 
     if d.isExpanded():
-        keyType = d.templateArgument(value.type, 0)
-        valueType = d.templateArgument(value.type, 1)
-        try:
-            # Does not work on gcc 4.4, the allocator type (fourth template
-            # argument) seems not to be available.
-            pairType = d.templateArgument(d.templateArgument(value.type, 3), 0)
-            pairPointer = pairType.pointer()
-        except:
-            # So use this as workaround:
-            pairType = d.templateArgument(impl.type, 1)
-            pairPointer = pairType.pointer()
-        isCompact = d.isMapCompact(keyType, valueType)
-        innerType = pairType
-        if isCompact:
-            innerType = valueType
-        node = impl["_M_header"]["_M_left"]
-        childType = innerType
-        if size == 0:
-            childType = pairType
-        childNumChild = 2
-        if isCompact:
-            childNumChild = None
-        with Children(d, size, maxNumChild=1000,
-                childType=childType, childNumChild=childNumChild):
+        pairType = d.templateArgument(d.templateArgument(value.type, 3), 0)
+        pairPointer = pairType.pointer()
+        with PairedChildren(d, size, pairType, maxNumChild=1000):
+            node = impl["_M_header"]["_M_left"]
             for i in d.childRange():
                 with SubItem(d, i):
                     pair = (node + 1).cast(pairPointer).dereference()
-                    if isCompact:
-                        d.putMapName(pair["first"])
-                        d.putItem(pair["second"])
-                    else:
-                        d.putEmptyValue()
-                        if d.isExpanded():
-                            with Children(d, 2):
-                                d.putSubItem("first", pair["first"])
-                                d.putSubItem("second", pair["second"])
+                    d.putPair(pair)
                 if d.isNull(node["_M_right"]):
                     parent = node["_M_parent"]
                     while node == parent["_M_right"]:
-- 
GitLab