member.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #
  2. # Metrix++, Copyright 2009-2019, Metrix++ Project
  3. # Link: https://github.com/metrixplusplus/metrixplusplus
  4. #
  5. # This file is a part of Metrix++ Tool.
  6. #
  7. import mpp.api
  8. import re
  9. class Plugin(mpp.api.Plugin,
  10. mpp.api.IConfigurable,
  11. mpp.api.Child,
  12. mpp.api.MetricPluginMixin):
  13. def declare_configuration(self, parser):
  14. parser.add_option("--std.code.member.fields", "--scmf",
  15. action="store_true", default=False,
  16. help="Enables collection of number of data members / fields "
  17. "per classes, structs and interfaces [default: %default]")
  18. parser.add_option("--std.code.member.globals", "--scmg",
  19. action="store_true", default=False,
  20. help="Enables collection of number of global variables / fields "
  21. "per global regions and namespaces [default: %default]")
  22. parser.add_option("--std.code.member.classes", "--scmc",
  23. action="store_true", default=False,
  24. help="Enables collection of number of classes defined "
  25. "per any region [default: %default]")
  26. parser.add_option("--std.code.member.structs", "--scms",
  27. action="store_true", default=False,
  28. help="Enables collection of number of structs defined "
  29. "per any region [default: %default]")
  30. parser.add_option("--std.code.member.interfaces", "--scmi",
  31. action="store_true", default=False,
  32. help="Enables collection of number of interfaces defined "
  33. "per any region [default: %default]")
  34. parser.add_option("--std.code.member.types", "--scmt",
  35. action="store_true", default=False,
  36. help="Enables collection of number of types (classes, structs "
  37. "or interface) defined per any region [default: %default]")
  38. parser.add_option("--std.code.member.methods", "--scmm",
  39. action="store_true", default=False,
  40. help="Enables collection of number of methods (functions) defined "
  41. "per any region [default: %default]")
  42. parser.add_option("--std.code.member.namespaces", "--scmnss",
  43. action="store_true", default=False,
  44. help="Enables collection of number of namespaces defined "
  45. "globally and enclosed (sub-namespaces) [default: %default]")
  46. def configure(self, options):
  47. self.is_active_fields = options.__dict__['std.code.member.fields']
  48. self.is_active_globals = options.__dict__['std.code.member.globals']
  49. self.is_active_classes = options.__dict__['std.code.member.classes']
  50. self.is_active_structs = options.__dict__['std.code.member.structs']
  51. self.is_active_interfaces = options.__dict__['std.code.member.interfaces']
  52. self.is_active_types = options.__dict__['std.code.member.types']
  53. self.is_active_methods = options.__dict__['std.code.member.methods']
  54. self.is_active_namespaces = options.__dict__['std.code.member.namespaces']
  55. def initialize(self):
  56. # counts fields and properties with default getter/setter
  57. pattern_to_search_cs = re.compile(
  58. r'''([_a-zA-Z][_a-zA-Z0-9]*\s+[_a-zA-Z][_a-zA-Z0-9])\s*([=;]|'''
  59. r'''[{]\s*(public\s+|private\s+|protected\s+|internal\s+)?(get|set)\s*[;]\s*[a-z \t\r\n]*[}])''')
  60. pattern_to_search_cpp = re.compile(
  61. r'''([_a-zA-Z][_a-zA-Z0-9]*\s+[_a-zA-Z][_a-zA-Z0-9])\s*[=;]''')
  62. pattern_to_search_java = re.compile(
  63. r'''([_$a-zA-Z][_$a-zA-Z0-9]*\s+[_$a-zA-Z][_$a-zA-Z0-9])\s*[=;]''')
  64. self.declare_metric(self.is_active_fields,
  65. self.Field('fields', int, non_zero=True),
  66. {
  67. 'std.code.java': pattern_to_search_java,
  68. 'std.code.cpp': pattern_to_search_cpp,
  69. 'std.code.cs': pattern_to_search_cs,
  70. },
  71. marker_type_mask=mpp.api.Marker.T.CODE,
  72. region_type_mask=mpp.api.Region.T.CLASS |
  73. mpp.api.Region.T.STRUCT | mpp.api.Region.T.INTERFACE)
  74. self.declare_metric(self.is_active_globals,
  75. self.Field('globals', int, non_zero=True),
  76. {
  77. 'std.code.java': pattern_to_search_java,
  78. 'std.code.cpp': pattern_to_search_cpp,
  79. 'std.code.cs': pattern_to_search_cs,
  80. },
  81. marker_type_mask=mpp.api.Marker.T.CODE,
  82. region_type_mask=mpp.api.Region.T.GLOBAL |
  83. mpp.api.Region.T.NAMESPACE)
  84. self.declare_metric(self.is_active_classes,
  85. self.Field('classes', int, non_zero=True),
  86. (None, self.ClassesCounter),
  87. exclude_subregions=False,
  88. merge_markers=True)
  89. self.declare_metric(self.is_active_structs,
  90. self.Field('structs', int, non_zero=True),
  91. (None, self.StructCounter),
  92. exclude_subregions=False,
  93. merge_markers=True)
  94. self.declare_metric(self.is_active_interfaces,
  95. self.Field('interfaces', int, non_zero=True),
  96. (None, self.InterfaceCounter),
  97. exclude_subregions=False,
  98. merge_markers=True)
  99. self.declare_metric(self.is_active_types,
  100. self.Field('types', int, non_zero=True),
  101. (None, self.TypeCounter),
  102. exclude_subregions=False,
  103. merge_markers=True)
  104. self.declare_metric(self.is_active_methods,
  105. self.Field('methods', int, non_zero=True),
  106. (None, self.MethodCounter),
  107. exclude_subregions=False,
  108. merge_markers=True)
  109. self.declare_metric(self.is_active_namespaces,
  110. self.Field('namespaces', int, non_zero=True),
  111. (None, self.NamespaceCounter),
  112. exclude_subregions=False,
  113. merge_markers=True)
  114. super(Plugin, self).initialize(fields=self.get_fields())
  115. if self.is_active() == True:
  116. self.subscribe_by_parents_interface(mpp.api.ICode)
  117. class ClassesCounter(mpp.api.MetricPluginMixin.PlainCounter):
  118. def count(self, marker, pattern_to_search):
  119. self.result = sum(1 for unused in self.data.iterate_regions(
  120. filter_group=mpp.api.Region.T.CLASS, region_id=self.region.get_id()))
  121. class StructCounter(mpp.api.MetricPluginMixin.PlainCounter):
  122. def count(self, marker, pattern_to_search):
  123. self.result = sum(1 for unused in self.data.iterate_regions(
  124. filter_group=mpp.api.Region.T.STRUCT, region_id=self.region.get_id()))
  125. class InterfaceCounter(mpp.api.MetricPluginMixin.PlainCounter):
  126. def count(self, marker, pattern_to_search):
  127. self.result = sum(1 for unused in self.data.iterate_regions(
  128. filter_group=mpp.api.Region.T.INTERFACE, region_id=self.region.get_id()))
  129. class TypeCounter(mpp.api.MetricPluginMixin.PlainCounter):
  130. def count(self, marker, pattern_to_search):
  131. self.result = sum(1 for unused in self.data.iterate_regions(
  132. filter_group=mpp.api.Region.T.CLASS | mpp.api.Region.T.STRUCT |
  133. mpp.api.Region.T.INTERFACE, region_id=self.region.get_id()))
  134. class MethodCounter(mpp.api.MetricPluginMixin.PlainCounter):
  135. def count(self, marker, pattern_to_search):
  136. self.result = sum(1 for unused in self.data.iterate_regions(
  137. filter_group=mpp.api.Region.T.FUNCTION, region_id=self.region.get_id()))
  138. class NamespaceCounter(mpp.api.MetricPluginMixin.PlainCounter):
  139. def count(self, marker, pattern_to_search):
  140. self.result = sum(1 for unused in self.data.iterate_regions(
  141. filter_group=mpp.api.Region.T.NAMESPACE, region_id=self.region.get_id()))