diff paraspace/dex_deptracker.py @ 23:fff40aabefab

Move collect_dependencies() to dex_deptracker.py
author Thinker K.F. Li <thinker@codemud.net>
date Thu, 02 Jun 2011 16:53:12 +0800
parents
children a57ec6a76fe3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paraspace/dex_deptracker.py	Thu Jun 02 16:53:12 2011 +0800
@@ -0,0 +1,94 @@
+from paraspace import dexfile
+
+
+_nest_types = (dexfile.array,
+               dexfile.cond,
+               dexfile.switch)
+
+
+def _dig_clazz(name_path, clazz, dex_types):
+    deps = {}
+
+    for attr in dir(clazz):
+        namelist = [name_path, attr]
+        
+        digged_flag = False
+        
+        value_type = getattr(clazz, attr)
+        while isinstance(value_type, _nest_types) or \
+                (type(value_type) == type and
+                 issubclass(value_type, _nest_types)):
+            if isinstance(value_type, dexfile.array):
+                namelist.append('items')
+                value_type = value_type.child_type
+            elif isinstance(value_type, dexfile.cond):
+                namelist.append('value')
+                value_type = value_type.child_type
+            elif isinstance(value_type, dexfile.switch):
+                for key, child_type in value_type.map.items():
+                    if child_type in dex_types.values():
+                        continue
+                    child_name_path = '.'.join(namelist) + '.' + repr(key)
+                    child_deps = \
+                        _dig_clazz(child_name_path, child_type, dex_types)
+                    deps.update(child_deps)
+                    pass
+                digged_flag = True
+                break
+            pass
+
+        if digged_flag:
+            continue
+        
+        if isinstance(value_type, dexfile.depend):
+            from_name = '.'.join(namelist)
+            if isinstance(value_type, dexfile.depend_off):
+                depend_name = value_type.depend_on
+                deps[from_name] = (dexfile.depend_off, depend_name)
+            elif isinstance(value_type, dexfile.depend_off_rel):
+                depend_name = value_type.depend_on
+                relative_to = value_type.relative_to
+                deps[from_name] = (dexfile.depend_off_rel,
+                                   depend_name,
+                                   relative_to)
+            elif isinstance(value_type, dexfile.depend_idx):
+                depend_name = value_type.depend_on
+                deps[from_name] = (dexfile.depend_idx, depend_name)
+                pass
+            pass
+        pass
+    return deps
+
+
+def all_dex_types():
+    dex_types = dict([(name, value)
+                       for name, value in dexfile.__dict__.items()
+                       if name.startswith('_DEX_')])
+    dex_types['DEXFile'] = dexfile.DEXFile
+    return dex_types
+
+
+def collect_dependencies():
+    dex_types = all_dex_types()
+
+    all_deps = {}
+    for name_path, clazz in dex_types.items():
+        deps = _dig_clazz(name_path, clazz, dex_types)
+        all_deps.update(deps)
+        pass
+    
+    return all_deps
+
+
+
+def _install_offset_keepers():
+    
+    pass
+
+if __name__ == '__main__':
+    dex = dexfile.DEXFile.open('../data/testdata1.dex')
+    
+    import pprint
+    print
+    print 'Dependencies'
+    pprint.pprint(collect_dependencies())