A semantic search engine for source code https://bitshift.benkurtovic.com/
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

149 wiersze
3.8 KiB

  1. require 'socket'
  2. require 'ruby_parser'
  3. require 'sexp_processor'
  4. module Bitshift
  5. class Tuple
  6. attr_accessor :objects
  7. def initialize(arr)
  8. @objects = arr
  9. end
  10. def inspect
  11. s = "("
  12. @objects.each {|o| s += "#{o},"}
  13. s = s[0..-2] + ')'
  14. end
  15. end
  16. class Parser
  17. def initialize(source)
  18. @source = source
  19. end
  20. def parse
  21. parser = RubyParser.new
  22. tree = parser.parse(@source)
  23. offset = tree.line - 1
  24. processor = CachedWalker.new offset, tree
  25. processor.process(tree)
  26. return processor.to_s
  27. end
  28. end
  29. class CachedWalker < SexpProcessor
  30. attr_accessor :symbols
  31. attr_accessor :offset
  32. def initialize(offset, tree)
  33. super()
  34. module_hash = Hash.new {|hash, key| hash[key] = { decls: [], uses: [] }}
  35. class_hash = module_hash.clone
  36. function_hash = module_hash.clone
  37. var_hash = module_hash.clone
  38. @require_empty = false
  39. @offset = offset
  40. @symbols = {
  41. modules: module_hash,
  42. classes: class_hash,
  43. functions: function_hash,
  44. vars: var_hash
  45. }
  46. end
  47. def block_position(exp)
  48. end_ln = (start_ln = exp.line - offset)
  49. cur_exp = exp
  50. while cur_exp.is_a? Sexp
  51. end_ln = cur_exp.line - offset
  52. cur_exp = cur_exp.last
  53. break if cur_exp == nil
  54. end
  55. pos = Tuple.new([start_ln, -1, end_ln, -1])
  56. return pos
  57. end
  58. def statement_position(exp)
  59. pos = Hash.new
  60. end_ln = start_ln = exp.line - offset
  61. pos = Tuple.new([start_ln, -1, end_ln, -1])
  62. return pos
  63. end
  64. def process_module(exp)
  65. pos = block_position(exp)
  66. exp.shift
  67. name = exp.shift
  68. symbols[:modules][name][:decls] << pos
  69. exp.each_sexp {|s| process(s)}
  70. return exp.clear
  71. end
  72. def process_class(exp)
  73. pos = block_position(exp)
  74. exp.shift
  75. name = exp.shift
  76. symbols[:classes][name][:decls] << pos
  77. exp.each_sexp {|s| process(s)}
  78. return exp.clear
  79. end
  80. def process_defn(exp)
  81. pos = block_position(exp)
  82. exp.shift
  83. name = exp.shift
  84. symbols[:functions][name][:decls] << pos
  85. exp.each_sexp {|s| process(s)}
  86. return exp.clear
  87. end
  88. def process_call(exp)
  89. pos = statement_position(exp)
  90. exp.shift
  91. exp.shift
  92. name = exp.shift
  93. symbols[:functions][name][:uses] << pos
  94. exp.each_sexp {|s| process(s)}
  95. return exp.clear
  96. end
  97. def process_iasgn(exp)
  98. pos = statement_position(exp)
  99. exp.shift
  100. name = exp.shift
  101. symbols[:vars][name][:decls] << pos
  102. exp.each_sexp {|s| process(s)}
  103. return exp.clear
  104. end
  105. def process_lasgn(exp)
  106. pos = statement_position(exp)
  107. exp.shift
  108. name = exp.shift
  109. symbols[:vars][name][:decls] << pos
  110. exp.each_sexp {|s| process(s)}
  111. return exp.clear
  112. end
  113. def to_s
  114. new_symbols = Hash.new {|hash, key| hash[key] = []}
  115. symbols.each do |type, sym_list|
  116. sym_list.each do |name, sym|
  117. new_symbols[type.to_s] << Tuple.new(["'#{name}'", sym[:decls], sym[:uses]])
  118. end
  119. end
  120. str = new_symbols.to_s
  121. str = str.gsub(/=>/, ":")
  122. return str
  123. end
  124. end
  125. end