diff paraspace/dex_deptracker.py @ 40:0c0a659187c2

Use _objs_asso to define association between two set of items. Derivation of _objs_asso define a rule to assocate elements from first set to another element in second set.
author Thinker K.F. Li <thinker@codemud.net>
date Sat, 18 Jun 2011 23:59:37 +0800
parents b0cc5da28141
children c5cfc796af8b
line wrap: on
line diff
--- a/paraspace/dex_deptracker.py	Thu Jun 16 08:03:50 2011 +0800
+++ b/paraspace/dex_deptracker.py	Sat Jun 18 23:59:37 2011 +0800
@@ -157,15 +157,21 @@
 
 
 def _dex_tree_get_child(obj, child_name):
-    if isinstance(obj, list):
-        idx = int(child_name)
-        return obj[idx]
-
-    if isinstance(obj, dexfile.switch):
-        assert obj.map[eval(child_name)] == obj.child_type
-        return obj.value
-
-    return getattr(obj, child_name)
+    child_parts = child_name.split('.')
+    for child_part in child_parts:
+        if isinstance(obj, list):
+            idx = int(child_part)
+            obj = obj[idx]
+            continue
+        
+        if isinstance(obj, dexfile.switch):
+            assert obj.map[eval(child_part)] == obj.child_type
+            obj = obj.value
+            continue
+        
+        obj = getattr(obj, child_part)
+        pass
+    return obj
 
 
 def _dex_tree_set_child(obj, child_name, value):
@@ -330,17 +336,26 @@
 
     @staticmethod
     def find_depon(name_path, parents):
+        name_parts = name_path.split('.')
+        dex_types = _all_dex_types()
+        comp_type_name = name_parts[0]
+        comp_type = dex_types[comp_type_name]
+        
         rev_parents = list(parents)
         rev_parents.reverse()
         
         for parent in rev_parents:
+            if isinstance(parent, comp_type):
+                attr_name = '.'.join(name_parts[1:])
+                depon = _dex_tree_get_child(parent, attr_name)
+                return depon
+
             try:
                 rel_marker_info = parent.rel_marker_info
             except:
                 continue
             if name_path in rel_marker_info:
                 depons = rel_marker_info[name_path]
-                print parent, depons
                 assert len(depons) == 1
                 depon = depons[0]
                 return depon
@@ -361,12 +376,24 @@
         return array
     
     def link_prepare(self, obj, name_path, parents, markers_info):
+        try:
+            id_item_map = markers_info[name_path]
+        except KeyError:
+            id_item_map = []
+            markers_info[name_path] = id_item_map
+            pass
+        for idx, item in enumerate(obj.items):
+            id_item_map[idx] = item
+            pass
         pass
     pass
 
 
 def _install_offset_marker(name_path):
     obj, parent = _resolve_name_path(name_path)
+    while isinstance(parent, dexfile.ref):
+        obj, parent = _resolve_name_path(parent.target_path)
+        pass
     marker = _offset_marker(obj, name_path)
     name = name_path.split('.')[-1]
     _dex_tree_set_child(parent, name, marker)
@@ -375,6 +402,9 @@
 
 def _install_rel_offset_marker(name_path):
     obj, parent = _resolve_name_path(name_path)
+    while isinstance(parent, dexfile.ref):
+        obj, parent = _resolve_name_path(parent.target_path)
+        pass
     marker = _rel_offset_marker(obj, name_path)
     name = name_path.split('.')[-1]
     _dex_tree_set_child(parent, name, marker)
@@ -383,6 +413,9 @@
 
 def _install_uid_marker(name_path):
     obj, parent = _resolve_name_path(name_path)
+    while isinstance(parent, dexfile.ref):
+        obj, parent = _resolve_name_path(parent.target_path)
+        pass
     marker = _uid_marker(obj, name_path)
     name = name_path.split('.')[-1]
     _dex_tree_set_child(parent, name, marker)
@@ -391,6 +424,9 @@
 
 def _install_idx_marker(name_path):
     obj, parent = _resolve_name_path(name_path)
+    while isinstance(parent, dexfile.ref):
+        obj, parent = _resolve_name_path(parent.target_path)
+        pass
     marker = _idx_marker(obj, name_path)
     name = name_path.split('.')[-1]
     _dex_tree_set_child(parent, name, marker)
@@ -479,6 +515,23 @@
     pass
 
 
+def _build_associations(root_obj):
+    for obj, parents, name_path in \
+            _travel_dex_relocatable(root_obj):
+        if isinstance(obj, dexfile._objs_asso):
+            for parent in parents:
+                if isinstance(parent, dexfile.composite):
+                    break
+                pass
+            
+            left_elts = _dex_tree_get_child(parent, obj.left)
+            right_elts = _dex_tree_get_child(parent, obj.right)
+            obj.build_associations()
+            pass
+        pass
+    pass
+
+
 def _link_dependencies(root_obj, all_dep_decls):
     markers_info = {}
     depon_src_map = {}
@@ -520,13 +573,13 @@
             _dex_tree_set_child(parent, name, (depon1, depon2))
         elif dep_type == dexfile.depend_off:
             depon_name_path = dep[1]
-            depon = markers_info[depon_name_path]
+            depon = markers_info[depon_name_path][obj]
             parent = parents[-1]
             name = name_path.split('.')[-1]
             _dex_tree_set_child(parent, name, depon)
         elif dep_type == dexfile.depend_idx:
             depon_name_path = dep[1]
-            depon = markers_info[depon_name_path]
+            depon = markers_info[depon_name_path][obj]
             parent = parents[-1]
             name = name_path.split('.')[-1]
             _dex_tree_set_child(parent, name, depon)