simplify.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. """A module to ease code analysis
  2. This module is here to help source code analysis.
  3. """
  4. import re
  5. from rope.base import codeanalyze, utils
  6. @utils.cached(7)
  7. def real_code(source):
  8. """Simplify `source` for analysis
  9. It replaces:
  10. * comments with spaces
  11. * strs with a new str filled with spaces
  12. * implicit and explicit continuations with spaces
  13. * tabs and semicolons with spaces
  14. The resulting code is a lot easier to analyze if we are interested
  15. only in offsets.
  16. """
  17. collector = codeanalyze.ChangeCollector(source)
  18. for start, end in ignored_regions(source):
  19. if source[start] == '#':
  20. replacement = ' ' * (end - start)
  21. else:
  22. replacement = '"%s"' % (' ' * (end - start - 2))
  23. collector.add_change(start, end, replacement)
  24. source = collector.get_changed() or source
  25. collector = codeanalyze.ChangeCollector(source)
  26. parens = 0
  27. for match in _parens.finditer(source):
  28. i = match.start()
  29. c = match.group()
  30. if c in '({[':
  31. parens += 1
  32. if c in ')}]':
  33. parens -= 1
  34. if c == '\n' and parens > 0:
  35. collector.add_change(i, i + 1, ' ')
  36. source = collector.get_changed() or source
  37. return source.replace('\\\n', ' ').replace('\t', ' ').replace(';', '\n')
  38. @utils.cached(7)
  39. def ignored_regions(source):
  40. """Return ignored regions like strings and comments in `source` """
  41. return [(match.start(), match.end()) for match in _str.finditer(source)]
  42. _str = re.compile('%s|%s' % (codeanalyze.get_comment_pattern(),
  43. codeanalyze.get_string_pattern()))
  44. _parens = re.compile(r'[\({\[\]}\)\n]')