Jelajahi Sumber

api improvement

avkonst 11 tahun lalu
induk
melakukan
5b6e3e18a2

+ 9 - 24
mainline/ext/std/code/complexity.py

@@ -48,18 +48,18 @@ class Plugin(mpp.api.Plugin, mpp.api.MetricPluginMixin, mpp.api.Child, mpp.api.I
         self.declare_metric(self.is_active_cyclomatic,
                             self.Field('cyclomatic', int),
                             {
-                                'cpp': self.pattern_cpp,
-                                'cs': self.pattern_cs,
-                                'java': self.pattern_java
+                                'std.code.cpp': self.pattern_cpp,
+                                'std.code.cs': self.pattern_cs,
+                                'std.code.java': self.pattern_java
                             },
                             marker_type_mask=mpp.api.Marker.T.CODE,
                             region_type_mask=mpp.api.Region.T.FUNCTION)
         self.declare_metric(self.is_active_maxindent,
                             self.Field('maxindent', int),
                             {
-                                'cpp': self.pattern_indent,
-                                'cs': self.pattern_indent,
-                                'java': self.pattern_indent,
+                                'std.code.cpp': self.pattern_indent,
+                                'std.code.cs': self.pattern_indent,
+                                'std.code.java': self.pattern_indent,
                             },
                             marker_type_mask=mpp.api.Marker.T.CODE,
                             # TODO shall scan all regions?, it is likely actual to functions
@@ -68,24 +68,9 @@ class Plugin(mpp.api.Plugin, mpp.api.MetricPluginMixin, mpp.api.Child, mpp.api.I
         super(Plugin, self).initialize(fields=self.get_fields())
         
         if self.is_active() == True:
-            self.subscribe_by_parents_name('std.code.cpp', 'callback_cpp')
-            self.subscribe_by_parents_name('std.code.cs', 'callback_cs')
-            self.subscribe_by_parents_name('std.code.java', 'callback_java')
-
-    def callback_cpp(self, parent, data, is_updated):
-        self.callback_common(parent, data, is_updated, 'cpp')
-
-    def callback_cs(self, parent, data, is_updated):
-        self.callback_common(parent, data, is_updated, 'cs')
-
-    def callback_java(self, parent, data, is_updated):
-        self.callback_common(parent, data, is_updated, 'java')
-
-    def callback_common(self, parent, data, is_updated, alias):
-        is_updated = is_updated or self.is_updated
-        if is_updated == True:
-            self.count_if_active('cyclomatic', data, alias=alias)
-            self.count_if_active('maxindent', data, alias=alias)
+            self.subscribe_by_parents_name('std.code.cpp')
+            self.subscribe_by_parents_name('std.code.cs')
+            self.subscribe_by_parents_name('std.code.java')
 
     def _maxindent_count_initialize(self, data, alias, region):
         return (0, {'cur_level': 0})

+ 1 - 9
mainline/ext/std/code/lines.py

@@ -71,12 +71,4 @@ class Plugin(mpp.api.Plugin, mpp.api.MetricPluginMixin, mpp.api.Child, mpp.api.I
         super(Plugin, self).initialize(fields=self.get_fields())
 
         if self.is_active() == True:
-            self.subscribe_by_parents_interface(mpp.api.ICode, 'callback')
-
-    def callback(self, parent, data, is_updated):
-        is_updated = is_updated or self.is_updated
-        if is_updated == True:
-            self.count_if_active('code', data)
-            self.count_if_active('preprocessor', data)
-            self.count_if_active('comments', data)
-            self.count_if_active('total', data)
+            self.subscribe_by_parents_interface(mpp.api.ICode)

+ 57 - 42
mainline/mpp/api.py

@@ -546,27 +546,27 @@ class DiffData(Data):
 # Loader
 ####################################
 
-class NamespaceError(Exception):
-    def __init__(self, namespace, reason):
-        Exception.__init__(self, "Namespace '"
-                        + namespace 
+class Namespace(object):
+    
+    class NamespaceError(Exception):
+        def __init__(self, namespace, reason):
+            Exception.__init__(self, "Namespace '"
+                            + namespace 
+                            + "': '"
+                            + reason
+                            + "'")
+    
+    class FieldError(Exception):
+        def __init__(self, field, reason):
+            Exception.__init__(self, "Field '"
+                        + field 
                         + "': '"
                         + reason
                         + "'")
 
-class FieldError(Exception):
-    def __init__(self, field, reason):
-        Exception.__init__(self, "Field '"
-                    + field 
-                    + "': '"
-                    + reason
-                    + "'")
-
-class Namespace(object):
-    
     def __init__(self, db_handle, name, support_regions = False, version='1.0'):
         if not isinstance(name, str):
-            raise NamespaceError(name, "name not a string")
+            raise Namespace.NamespaceError(name, "name not a string")
         self.name = name
         self.support_regions = support_regions
         self.fields = {}
@@ -588,10 +588,10 @@ class Namespace(object):
     
     def add_field(self, field_name, python_type, non_zero=False):
         if not isinstance(field_name, str):
-            raise FieldError(field_name, "field_name not a string")
+            raise Namespace.FieldError(field_name, "field_name not a string")
         packager = mpp.internal.api_impl.PackagerFactory().create(python_type, non_zero)
         if field_name in self.fields.keys():
-            raise FieldError(field_name, "double used")
+            raise Namespace.FieldError(field_name, "double used")
         self.fields[field_name] = packager
         
         if self.db.check_column(self.get_name(), field_name) == False:        
@@ -615,20 +615,20 @@ class Namespace(object):
         try:
             return self._get_field_packager(field_name).get_sql_type()
         except mpp.internal.api_impl.PackagerError:
-            raise FieldError(field_name, 'does not exist')
+            raise Namespace.FieldError(field_name, 'does not exist')
 
     def get_field_python_type(self, field_name):
         try:
             return self._get_field_packager(field_name).get_python_type()
         except mpp.internal.api_impl.PackagerError:
-            raise FieldError(field_name, 'does not exist')
+            raise Namespace.FieldError(field_name, 'does not exist')
 
 
     def is_field_non_zero(self, field_name):
         try:
             return self._get_field_packager(field_name).is_non_zero()
         except mpp.internal.api_impl.PackagerError:
-            raise FieldError(field_name, 'does not exist')
+            raise Namespace.FieldError(field_name, 'does not exist')
 
     def _get_field_packager(self, field_name):
         if field_name in self.fields.keys():
@@ -636,20 +636,6 @@ class Namespace(object):
         else:
             raise mpp.internal.api_impl.PackagerError("unknown field " + field_name + " requested")
     
-class DataNotPackable(Exception):
-    def __init__(self, namespace, field, value, packager, extra_message):
-        Exception.__init__(self, "Data '"
-                           + str(value)
-                           + "' of type "
-                           + str(value.__class__) 
-                           + " referred by '"
-                           + namespace
-                           + "=>"
-                           + field
-                           + "' is not packable by registered packager '"
-                           + str(packager.__class__)
-                           + "': " + extra_message)
-
 class Loader(object):
     
     def __init__(self):
@@ -699,7 +685,7 @@ class Loader(object):
             return None
         
         if name in self.namespaces.keys():
-            raise NamespaceError(name, "double used")
+            raise Namespace.NamespaceError(name, "double used")
         new_namespace = Namespace(self.db, name, support_regions, version)
         self.namespaces[name] = new_namespace
         return new_namespace
@@ -738,6 +724,20 @@ class Loader(object):
         self.last_file_data = result
         return result
 
+    class DataNotPackable(Exception):
+        def __init__(self, namespace, field, value, packager, extra_message):
+            Exception.__init__(self, "Data '"
+                               + str(value)
+                               + "' of type "
+                               + str(value.__class__) 
+                               + " referred by '"
+                               + namespace
+                               + "=>"
+                               + field
+                               + "' is not packable by registered packager '"
+                               + str(packager.__class__)
+                               + "': " + extra_message)
+
     def save_file_data(self, file_data):
         if self.db == None:
             return None
@@ -748,22 +748,22 @@ class Loader(object):
                 for each in data.iterate_fields(namespace):
                     space = self.loader.get_namespace(namespace)
                     if space == None:
-                        raise DataNotPackable(namespace, each[0], each[1], None, "The namespace has not been found")
+                        raise Loader.DataNotPackable(namespace, each[0], each[1], None, "The namespace has not been found")
                     
                     try:
                         packager = space._get_field_packager(each[0])
                     except mpp.internal.api_impl.PackagerError:
-                        raise DataNotPackable(namespace, each[0], each[1], None, "The field has not been found")
+                        raise Loader.DataNotPackable(namespace, each[0], each[1], None, "The field has not been found")
         
                     if space.support_regions != support_regions:
-                        raise DataNotPackable(namespace, each[0], each[1], packager, "Incompatible support for regions")
+                        raise Loader.DataNotPackable(namespace, each[0], each[1], packager, "Incompatible support for regions")
                     
                     try:
                         packed_data = packager.pack(each[1])
                         if packed_data == None:
                             continue
                     except mpp.internal.api_impl.PackagerError:
-                        raise DataNotPackable(namespace, each[0], each[1], packager, "Packager raised exception")
+                        raise Loader.DataNotPackable(namespace, each[0], each[1], packager, "Packager raised exception")
                     
                     yield (each[0], packed_data)
             
@@ -995,7 +995,7 @@ class MetricPluginMixin(object):
         if isinstance(pattern_to_search_or_map_of_patterns, dict):
             map_of_patterns = pattern_to_search_or_map_of_patterns
         else:
-            map_of_patterns = {'default': pattern_to_search_or_map_of_patterns}
+            map_of_patterns = {'*': pattern_to_search_or_map_of_patterns}
 
         if is_active == True:
             self._fields[field.name] = (field,
@@ -1016,7 +1016,19 @@ class MetricPluginMixin(object):
             result.append(self._fields[key][0])
         return result
     
-    def count_if_active(self, metric_name, data, namespace=None, alias='default'):
+    def callback(self, parent, data, is_updated):
+        # count if metric is enabled, 
+        # and (optimization for the case of iterative rescan:)
+        # if file is updated or this plugin's settings are updated
+        is_updated = is_updated or self.is_updated
+        if is_updated == True:
+            for field in self.get_fields():
+                self.count_if_active(field.name, data, alias=parent.get_name())
+        # if parent, notify children
+        if isinstance(self, Parent):
+            self.notify_children(data, is_updated)
+
+    def count_if_active(self, metric_name, data, namespace=None, alias='*'):
         if self.is_active(metric_name) == False:
             return
         
@@ -1027,7 +1039,10 @@ class MetricPluginMixin(object):
         text = data.get_content()
         
         if alias not in field_data[4].keys():
-            raise self.AliasError(alias)
+            if '*' not in field_data[4].keys():
+                raise self.AliasError(alias)
+            else:
+                alias = '*'
         pattern_to_search = field_data[4][alias]
         
         if hasattr(self, '_' + metric_name + '_count'):

+ 2 - 9
mainline/tests/system/test_api_tutorial/ext/step4/myext/magic.py

@@ -42,12 +42,5 @@ class Plugin(mpp.api.Plugin, mpp.api.IConfigurable, mpp.api.Child, mpp.api.Metri
         
         # subscribe to all code parsers if at least one metric is active
         if self.is_active() == True:
-            self.subscribe_by_parents_interface(mpp.api.ICode, 'callback')
-    
-    def callback(self, parent, data, is_updated):
-        # count if metric is enabled, 
-        # and (optimization for the case of iterative rescan:)
-        # if file is updated or this plugin's settings are updated
-        if is_updated or self.is_updated:
-            self.count_if_active('numbers', data)
-        
+            self.subscribe_by_parents_interface(mpp.api.ICode)
+           

+ 2 - 9
mainline/tests/system/test_api_tutorial/ext/step5/myext/magic.py

@@ -43,15 +43,8 @@ class Plugin(mpp.api.Plugin, mpp.api.IConfigurable, mpp.api.Child, mpp.api.Metri
         
         # subscribe to all code parsers if at least one metric is active
         if self.is_active() == True:
-            self.subscribe_by_parents_interface(mpp.api.ICode, 'callback')
-    
-    def callback(self, parent, data, is_updated):
-        # count if metric is enabled, 
-        # and (optimization for the case of iterative rescan:)
-        # if file is updated or this plugin's settings are updated
-        if is_updated or self.is_updated:
-            self.count_if_active('numbers', data)
-        
+            self.subscribe_by_parents_interface(mpp.api.ICode)
+            
     def _numbers_count(self, data, alias, text, begin, end, m, count, counter_data, region, marker):
         if m.group(0).startswith('const'):
             return count