A semantic search engine for source code https://bitshift.benkurtovic.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
пре 10 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. require 'ripper'
  2. def parse
  3. source = STDIN.read
  4. walker = TreeWalker.new(source)
  5. walker.parse
  6. puts walker.to_s
  7. end
  8. class TreeWalker < Ripper::SexpBuilder
  9. attr_accessor :symbols
  10. def initialize(source)
  11. ns_hash = Hash.new {
  12. |hash, key|
  13. hash[key] = {
  14. :assignments => [], :uses => []
  15. }
  16. }
  17. class_hash = ns_hash.clone
  18. function_hash = ns_hash.clone
  19. var_hash = ns_hash.clone
  20. @symbols = {
  21. :namespaces => ns_hash,
  22. :classes => class_hash,
  23. :functions => function_hash,
  24. :vars => var_hash
  25. }
  26. super(source)
  27. end
  28. def block_position(node)
  29. last_node = node[0]
  30. while last_node.is_a? Array
  31. sp = last_node
  32. while not (last_el = last_node[last_node.count - 1]) or
  33. (last_el.is_a? Array and last_el[last_el.count - 1].nil?)
  34. last_node = last_node[0..last_node.count - 2]
  35. end
  36. last_node = last_el
  37. end
  38. last_node = node[0]
  39. while last_node.is_a? Array
  40. ep = last_node
  41. while not (last_el = last_node[last_node.count - 1]) or
  42. (last_el.is_a? Array and last_el[last_el.count - 1].nil?)
  43. last_node = last_node[0..last_node.count - 2]
  44. end
  45. last_node = last_el
  46. end
  47. if sp == ep
  48. return sp + [sp[0], -1]
  49. end
  50. return sp + ep
  51. end
  52. def on_module(*node)
  53. pos = block_position(node)
  54. name = node[0][1][1]
  55. symbols[:namespaces][name][:assignments] << pos
  56. return node
  57. end
  58. def on_class(*node)
  59. pos = block_position(node)
  60. name = node[0][1][1]
  61. symbols[:classes][name][:assignments] << pos
  62. return node
  63. end
  64. def on_def(*node)
  65. pos = block_position(node)
  66. name = node[0][1]
  67. symbols[:functions][name][:assignments] << pos
  68. return node
  69. end
  70. def on_call(*node)
  71. pos = block_position(node)
  72. name = node[node.count - 1][1]
  73. symbols[:functions][name][:uses] << pos
  74. return node
  75. end
  76. def on_vcall(*node)
  77. pos = block_position(node)
  78. name = node[0][1]
  79. symbols[:functions][name][:uses] << pos
  80. return node
  81. end
  82. def on_assign(*node)
  83. pos = block_position(node)
  84. return node if not node[0][0].is_a? Array
  85. name = node[0][0][1]
  86. symbols[:vars][name][:assignments] << pos
  87. return node
  88. end
  89. def on_var_field(*node)
  90. pos = block_position(node)
  91. name = node[0][1]
  92. symbols[:vars][name][:uses] << pos
  93. return node
  94. end
  95. def on_var_ref(*node)
  96. pos = block_position(node)
  97. name = node[0][1]
  98. symbols[:vars][name][:uses] << pos
  99. return node
  100. end
  101. def on_command(*node)
  102. # catch require statements
  103. end
  104. def to_s
  105. new_symbols = Hash.new {|hash, key| hash[key] = Hash.new}
  106. symbols.each do |type, sym_list|
  107. sym_list.each do |name, sym|
  108. new_symbols[type.to_s][name.to_s] = {
  109. "assignments" => sym[:assignments],
  110. "uses" => sym[:uses]}
  111. end
  112. end
  113. str = new_symbols.to_s
  114. str = str.gsub(/=>/, ":")
  115. return str
  116. end
  117. end