db.py 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. import re
  2. import checksymbolslib.br as br
  3. choice = 'part of a choice'
  4. definition = 'definition'
  5. helper = 'possible config helper'
  6. legacy_definition = 'legacy definition'
  7. legacy_note = 'legacy note'
  8. legacy_usage = 'legacy usage'
  9. select = 'selected'
  10. usage = 'normal usage'
  11. usage_in_legacy = 'usage inside legacy'
  12. virtual = 'virtual'
  13. class DB:
  14. def __init__(self):
  15. self.all_symbols = {}
  16. def __str__(self):
  17. return str(self.all_symbols)
  18. def add_symbol_entry(self, symbol, filename, lineno, entry_type):
  19. if symbol not in self.all_symbols:
  20. self.all_symbols[symbol] = {}
  21. if entry_type not in self.all_symbols[symbol]:
  22. self.all_symbols[symbol][entry_type] = {}
  23. if filename not in self.all_symbols[symbol][entry_type]:
  24. self.all_symbols[symbol][entry_type][filename] = []
  25. self.all_symbols[symbol][entry_type][filename].append(lineno)
  26. def add_symbol_choice(self, symbol, filename, lineno):
  27. self.add_symbol_entry(symbol, filename, lineno, choice)
  28. def add_symbol_definition(self, symbol, filename, lineno):
  29. self.add_symbol_entry(symbol, filename, lineno, definition)
  30. def add_symbol_helper(self, symbol, filename, lineno):
  31. self.add_symbol_entry(symbol, filename, lineno, helper)
  32. def add_symbol_legacy_definition(self, symbol, filename, lineno):
  33. self.add_symbol_entry(symbol, filename, lineno, legacy_definition)
  34. def add_symbol_legacy_note(self, symbol, filename, lineno):
  35. self.add_symbol_entry(symbol, filename, lineno, legacy_note)
  36. def add_symbol_legacy_usage(self, symbol, filename, lineno):
  37. self.add_symbol_entry(symbol, filename, lineno, legacy_usage)
  38. def add_symbol_select(self, symbol, filename, lineno):
  39. self.add_symbol_entry(symbol, filename, lineno, select)
  40. def add_symbol_usage(self, symbol, filename, lineno):
  41. self.add_symbol_entry(symbol, filename, lineno, usage)
  42. def add_symbol_usage_in_legacy(self, symbol, filename, lineno):
  43. self.add_symbol_entry(symbol, filename, lineno, usage_in_legacy)
  44. def add_symbol_virtual(self, symbol, filename, lineno):
  45. self.add_symbol_entry(symbol, filename, lineno, virtual)
  46. def get_symbols_with_pattern(self, pattern):
  47. re_pattern = re.compile(r'{}'.format(pattern))
  48. found_symbols = {}
  49. for symbol, entries in self.all_symbols.items():
  50. if not re_pattern.search(symbol):
  51. continue
  52. found_symbols[symbol] = entries
  53. return found_symbols
  54. def get_warnings_for_choices_selected(self):
  55. warnings = []
  56. for symbol, entries in self.all_symbols.items():
  57. if choice not in entries:
  58. continue
  59. if select not in entries:
  60. continue
  61. all_items = []
  62. all_items += entries.get(select, {}).items()
  63. for filename, linenos in all_items:
  64. for lineno in linenos:
  65. msg = '{} is part of a "choice" and should not be "select"ed'.format(symbol)
  66. warnings.append((filename, lineno, msg))
  67. return warnings
  68. def get_warnings_for_legacy_symbols_being_used(self):
  69. warnings = []
  70. for symbol, entries in self.all_symbols.items():
  71. if legacy_definition not in entries:
  72. continue
  73. if usage not in entries:
  74. continue
  75. all_items = []
  76. all_items += entries.get(usage, {}).items()
  77. for filename, linenos in all_items:
  78. for lineno in linenos:
  79. msg = '{} is a legacy symbol and should not be referenced'.format(symbol)
  80. warnings.append((filename, lineno, msg))
  81. return warnings
  82. def get_warnings_for_legacy_symbols_being_defined(self):
  83. warnings = []
  84. for symbol, entries in self.all_symbols.items():
  85. if legacy_definition not in entries:
  86. continue
  87. if definition not in entries:
  88. continue
  89. all_items = []
  90. all_items += entries.get(definition, {}).items()
  91. for filename, linenos in all_items:
  92. for lineno in linenos:
  93. msg = '{} is a legacy symbol and should not be redefined'.format(symbol)
  94. warnings.append((filename, lineno, msg))
  95. return warnings
  96. def get_warnings_for_symbols_without_definition(self):
  97. warnings = []
  98. for symbol, entries in self.all_symbols.items():
  99. if definition in entries:
  100. continue
  101. if legacy_definition in entries:
  102. continue
  103. if br.re_host_symbol.search(symbol):
  104. continue
  105. if br.is_an_optional_symbol_for_a_roofts(symbol):
  106. continue
  107. if symbol in br.symbols_defined_only_at_command_line:
  108. continue
  109. if symbol in br.symbols_defined_only_when_using_br2_external:
  110. continue
  111. if symbol in br.symbols_defined_only_for_barebox_variant:
  112. continue
  113. if symbol in br.symbols_not_defined_for_fake_virtual_packages:
  114. continue
  115. if virtual in entries:
  116. continue
  117. all_items = []
  118. all_items += entries.get(usage, {}).items()
  119. all_items += entries.get(legacy_usage, {}).items()
  120. all_items += entries.get(usage_in_legacy, {}).items()
  121. for filename, linenos in all_items:
  122. for lineno in linenos:
  123. msg = '{} referenced but not defined'.format(symbol)
  124. warnings.append((filename, lineno, msg))
  125. return warnings
  126. def get_warnings_for_symbols_without_usage(self):
  127. warnings = []
  128. for symbol, entries in self.all_symbols.items():
  129. if usage in entries:
  130. continue
  131. if usage_in_legacy in entries:
  132. continue
  133. if legacy_usage in entries:
  134. continue
  135. if symbol in br.symbols_used_only_in_source_code:
  136. continue
  137. if symbol in br.symbols_used_only_for_host_variant:
  138. continue
  139. if helper in entries:
  140. continue
  141. if choice in entries:
  142. continue
  143. all_items = []
  144. all_items += entries.get(definition, {}).items()
  145. all_items += entries.get(legacy_definition, {}).items()
  146. for filename, linenos in all_items:
  147. for lineno in linenos:
  148. msg = '{} defined but not referenced'.format(symbol)
  149. warnings.append((filename, lineno, msg))
  150. return warnings
  151. def get_warnings_for_symbols_with_legacy_note_and_no_comment_on_usage(self):
  152. warnings = []
  153. for symbol, entries in self.all_symbols.items():
  154. if legacy_note not in entries:
  155. continue
  156. if legacy_usage in entries:
  157. continue
  158. all_items = []
  159. all_items += entries.get(usage, {}).items()
  160. for filename, linenos in all_items:
  161. for lineno in linenos:
  162. msg = '{} missing "# legacy"'.format(symbol)
  163. warnings.append((filename, lineno, msg))
  164. return warnings
  165. def get_warnings_for_symbols_with_legacy_note_and_no_usage(self):
  166. warnings = []
  167. for symbol, entries in self.all_symbols.items():
  168. if legacy_note not in entries:
  169. continue
  170. if legacy_usage in entries:
  171. continue
  172. if usage in entries:
  173. continue
  174. all_items = []
  175. all_items += entries.get(legacy_note, {}).items()
  176. for filename, linenos in all_items:
  177. for lineno in linenos:
  178. msg = '{} not referenced but has a comment stating it is'.format(symbol)
  179. warnings.append((filename, lineno, msg))
  180. return warnings