zapata 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/CONTRIBUTING.md +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +22 -0
  7. data/README.md +152 -0
  8. data/Rakefile +2 -0
  9. data/bin/zapata +20 -0
  10. data/lib/zapata.rb +91 -0
  11. data/lib/zapata/analyst.rb +34 -0
  12. data/lib/zapata/core/collector.rb +9 -0
  13. data/lib/zapata/core/loader.rb +38 -0
  14. data/lib/zapata/core/reader.rb +10 -0
  15. data/lib/zapata/core/writer.rb +33 -0
  16. data/lib/zapata/db.rb +32 -0
  17. data/lib/zapata/diver.rb +81 -0
  18. data/lib/zapata/predictor/args.rb +94 -0
  19. data/lib/zapata/predictor/chooser.rb +27 -0
  20. data/lib/zapata/primitive/arg.rb +24 -0
  21. data/lib/zapata/primitive/array.rb +39 -0
  22. data/lib/zapata/primitive/base.rb +28 -0
  23. data/lib/zapata/primitive/basic.rb +22 -0
  24. data/lib/zapata/primitive/casgn.rb +15 -0
  25. data/lib/zapata/primitive/const.rb +15 -0
  26. data/lib/zapata/primitive/def.rb +33 -0
  27. data/lib/zapata/primitive/defs.rb +32 -0
  28. data/lib/zapata/primitive/hash.rb +31 -0
  29. data/lib/zapata/primitive/ivar.rb +6 -0
  30. data/lib/zapata/primitive/klass.rb +34 -0
  31. data/lib/zapata/primitive/lvar.rb +24 -0
  32. data/lib/zapata/primitive/missing.rb +17 -0
  33. data/lib/zapata/primitive/modul.rb +20 -0
  34. data/lib/zapata/primitive/nil.rb +16 -0
  35. data/lib/zapata/primitive/optarg.rb +18 -0
  36. data/lib/zapata/primitive/raw.rb +16 -0
  37. data/lib/zapata/primitive/send.rb +48 -0
  38. data/lib/zapata/primitive/sklass.rb +20 -0
  39. data/lib/zapata/primitive/var.rb +25 -0
  40. data/lib/zapata/printer.rb +93 -0
  41. data/lib/zapata/rzpec/runner.rb +67 -0
  42. data/lib/zapata/rzpec/writer.rb +115 -0
  43. data/lib/zapata/version.rb +3 -0
  44. data/spec/array_spec.rb +37 -0
  45. data/spec/definition_spec.rb +43 -0
  46. data/spec/hash_spec.rb +43 -0
  47. data/spec/klass_types_spec.rb +55 -0
  48. data/spec/send_spec.rb +31 -0
  49. data/spec/simple_types_spec.rb +90 -0
  50. data/spec/spec_helper.rb +124 -0
  51. data/spec/support/rails_test_app/.gitignore +16 -0
  52. data/spec/support/rails_test_app/.rspec +3 -0
  53. data/spec/support/rails_test_app/Gemfile +45 -0
  54. data/spec/support/rails_test_app/Gemfile.lock +200 -0
  55. data/spec/support/rails_test_app/README.md +3 -0
  56. data/spec/support/rails_test_app/Rakefile +6 -0
  57. data/spec/support/rails_test_app/app/assets/images/.keep +0 -0
  58. data/spec/support/rails_test_app/app/assets/javascripts/application.js +16 -0
  59. data/spec/support/rails_test_app/app/assets/stylesheets/application.css +15 -0
  60. data/spec/support/rails_test_app/app/controllers/application_controller.rb +5 -0
  61. data/spec/support/rails_test_app/app/controllers/concerns/.keep +0 -0
  62. data/spec/support/rails_test_app/app/helpers/application_helper.rb +2 -0
  63. data/spec/support/rails_test_app/app/mailers/.keep +0 -0
  64. data/spec/support/rails_test_app/app/models/.keep +0 -0
  65. data/spec/support/rails_test_app/app/models/concerns/.keep +0 -0
  66. data/spec/support/rails_test_app/app/models/robot_to_test.rb +49 -0
  67. data/spec/support/rails_test_app/app/models/test_array.rb +34 -0
  68. data/spec/support/rails_test_app/app/models/test_const.rb +14 -0
  69. data/spec/support/rails_test_app/app/models/test_definition.rb +38 -0
  70. data/spec/support/rails_test_app/app/models/test_float.rb +14 -0
  71. data/spec/support/rails_test_app/app/models/test_hash.rb +39 -0
  72. data/spec/support/rails_test_app/app/models/test_int.rb +14 -0
  73. data/spec/support/rails_test_app/app/models/test_send.rb +75 -0
  74. data/spec/support/rails_test_app/app/models/test_str.rb +14 -0
  75. data/spec/support/rails_test_app/app/models/test_sym.rb +14 -0
  76. data/spec/support/rails_test_app/app/models/testing_module/bare.rb +6 -0
  77. data/spec/support/rails_test_app/app/models/testing_module/klass_methods.rb +47 -0
  78. data/spec/support/rails_test_app/app/models/testing_module/nested/inside.rb +8 -0
  79. data/spec/support/rails_test_app/app/views/layouts/application.html.erb +14 -0
  80. data/spec/support/rails_test_app/config.ru +4 -0
  81. data/spec/support/rails_test_app/config/application.rb +23 -0
  82. data/spec/support/rails_test_app/config/boot.rb +4 -0
  83. data/spec/support/rails_test_app/config/database.yml +25 -0
  84. data/spec/support/rails_test_app/config/environment.rb +5 -0
  85. data/spec/support/rails_test_app/config/environments/development.rb +37 -0
  86. data/spec/support/rails_test_app/config/environments/production.rb +83 -0
  87. data/spec/support/rails_test_app/config/environments/test.rb +39 -0
  88. data/spec/support/rails_test_app/config/initializers/backtrace_silencers.rb +7 -0
  89. data/spec/support/rails_test_app/config/initializers/cookies_serializer.rb +3 -0
  90. data/spec/support/rails_test_app/config/initializers/filter_parameter_logging.rb +4 -0
  91. data/spec/support/rails_test_app/config/initializers/inflections.rb +16 -0
  92. data/spec/support/rails_test_app/config/initializers/mime_types.rb +4 -0
  93. data/spec/support/rails_test_app/config/initializers/session_store.rb +3 -0
  94. data/spec/support/rails_test_app/config/initializers/wrap_parameters.rb +14 -0
  95. data/spec/support/rails_test_app/config/locales/en.yml +23 -0
  96. data/spec/support/rails_test_app/config/routes.rb +56 -0
  97. data/spec/support/rails_test_app/config/secrets.yml +22 -0
  98. data/spec/support/rails_test_app/db/seeds.rb +7 -0
  99. data/spec/support/rails_test_app/lib/assets/.keep +0 -0
  100. data/spec/support/rails_test_app/lib/tasks/.keep +0 -0
  101. data/spec/support/rails_test_app/log/.keep +0 -0
  102. data/spec/support/rails_test_app/public/404.html +67 -0
  103. data/spec/support/rails_test_app/public/422.html +67 -0
  104. data/spec/support/rails_test_app/public/500.html +66 -0
  105. data/spec/support/rails_test_app/public/favicon.ico +0 -0
  106. data/spec/support/rails_test_app/public/robots.txt +5 -0
  107. data/spec/support/rails_test_app/spec/models/robot_to_test_spec.rb +33 -0
  108. data/spec/support/rails_test_app/spec/models/test_array_spec.rb +27 -0
  109. data/spec/support/rails_test_app/spec/models/test_const_spec.rb +11 -0
  110. data/spec/support/rails_test_app/spec/models/test_definition_spec.rb +31 -0
  111. data/spec/support/rails_test_app/spec/models/test_float_spec.rb +11 -0
  112. data/spec/support/rails_test_app/spec/models/test_hash_spec.rb +31 -0
  113. data/spec/support/rails_test_app/spec/models/test_int_spec.rb +11 -0
  114. data/spec/support/rails_test_app/spec/models/test_send_spec.rb +53 -0
  115. data/spec/support/rails_test_app/spec/models/test_str_spec.rb +11 -0
  116. data/spec/support/rails_test_app/spec/models/test_sym_spec.rb +11 -0
  117. data/spec/support/rails_test_app/spec/models/testing_module/bare_spec.rb +7 -0
  118. data/spec/support/rails_test_app/spec/models/testing_module/klass_methods_spec.rb +19 -0
  119. data/spec/support/rails_test_app/spec/models/testing_module/nested/inside_spec.rb +7 -0
  120. data/spec/support/rails_test_app/spec/rails_helper.rb +43 -0
  121. data/spec/support/rails_test_app/spec/spec_helper.rb +78 -0
  122. data/spec/support/rails_test_app/test/controllers/.keep +0 -0
  123. data/spec/support/rails_test_app/test/fixtures/.keep +0 -0
  124. data/spec/support/rails_test_app/test/helpers/.keep +0 -0
  125. data/spec/support/rails_test_app/test/integration/.keep +0 -0
  126. data/spec/support/rails_test_app/test/mailers/.keep +0 -0
  127. data/spec/support/rails_test_app/test/models/.keep +0 -0
  128. data/spec/support/rails_test_app/test/test_helper.rb +13 -0
  129. data/spec/support/rails_test_app/vendor/assets/javascripts/.keep +0 -0
  130. data/spec/support/rails_test_app/vendor/assets/stylesheets/.keep +0 -0
  131. data/zapata.gemspec +34 -0
  132. metadata +446 -0
data/lib/zapata/db.rb ADDED
@@ -0,0 +1,32 @@
1
+ module Zapata
2
+ class DB
3
+ @records = []
4
+ @locs = []
5
+
6
+ class << self
7
+ def create(record)
8
+ loc = record.code.loc
9
+
10
+ unless @locs.include?(loc)
11
+ @records << record
12
+ @locs << loc
13
+ record
14
+ end
15
+ end
16
+
17
+ def all
18
+ @records
19
+ end
20
+
21
+ def destroy_all
22
+ @records = []
23
+ end
24
+ end
25
+ end
26
+
27
+ class SaveManager
28
+ def self.clean(name)
29
+ name.to_s.delete('@').to_sym
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,81 @@
1
+ module Zapata
2
+ RETURN_TYPES = %i(missing raw const_send sym float str int ivar true false const nil)
3
+ DIVE_TYPES = %i(args begin block defined? nth_ref splat kwsplat class
4
+ block_pass sclass masgn or and irange erange when and
5
+ return array kwbegin yield while dstr ensure pair)
6
+ ASSIGN_TYPES = %i(ivasgn lvasgn or_asgn casgn optarg)
7
+ DEF_TYPES = %i(def defs)
8
+ HARD_TYPES = %i(if dsym resbody mlhs next self break zsuper
9
+ super retry rescue match_with_lvasgn case op_asgn regopt regexp)
10
+ TYPES_BY_SEARCH_FOR = {
11
+ klass: %i(class),
12
+ var: ASSIGN_TYPES,
13
+ def: DEF_TYPES,
14
+ send: %i(send),
15
+ }
16
+
17
+ PRIMITIVE_TYPES = {
18
+ Def: %i(def),
19
+ Defs: %i(defs),
20
+ Send: %i(send),
21
+ Array: %i(args array),
22
+ Hash: %i(hash),
23
+ Ivar: %i(ivar),
24
+ Lvar: %i(lvar),
25
+ Klass: %i(class),
26
+ Sklass: %i(sclass),
27
+ Modul: %i(module),
28
+ Const: %i(const),
29
+ Optarg: %i(optarg),
30
+ Arg: %i(arg),
31
+ Basic: RETURN_TYPES,
32
+ Casgn: %i(casgn),
33
+ Var: ASSIGN_TYPES,
34
+ }.freeze
35
+
36
+ class Diver
37
+ class << self
38
+ attr_accessor :current_moduls, :current_klass, :current_sklass, :access_level
39
+
40
+ def search_for(what)
41
+ @search_for = what
42
+ @current_moduls ||= []
43
+ end
44
+
45
+ def dive(code)
46
+ unless code
47
+ return Primitive::Nil.new
48
+ end
49
+
50
+ current_type = code.type
51
+ return Primitive::Raw.new(:missing, :hard_type) if HARD_TYPES.include?(current_type)
52
+
53
+ subklass_pair = PRIMITIVE_TYPES.detect do |_, types|
54
+ types.include?(current_type)
55
+ end
56
+
57
+ if subklass_pair
58
+ klass = "Zapata::Primitive::#{subklass_pair.first}".constantize
59
+ result = klass.new(code)
60
+
61
+ DB.create(result) if search_for_types.include?(current_type)
62
+ else
63
+ end
64
+
65
+ deeper_dives(code) if DIVE_TYPES.include?(current_type)
66
+
67
+ result || Primitive::Raw.new(:super, nil)
68
+ end
69
+
70
+ def search_for_types
71
+ TYPES_BY_SEARCH_FOR[@search_for]
72
+ end
73
+
74
+ def deeper_dives(code)
75
+ code.to_a.compact.each do |part|
76
+ dive(part)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,94 @@
1
+ module Zapata
2
+ module Predictor
3
+ class Args
4
+ class << self
5
+ def literal(args_node)
6
+ raw_args = Diver.dive(args_node).to_raw
7
+ chosen_args = choose_values(raw_args)
8
+
9
+ args_in_string = case chosen_args
10
+ when Array
11
+ rebuilt = chosen_args.map do |primitive|
12
+ Printer.print(primitive)
13
+ end
14
+
15
+ raw_array = Primitive::Raw.new(:array, rebuilt)
16
+ Printer.print(raw_array)
17
+ when Hash
18
+ rebuilt = chosen_args.each_with_object({}) do |(key, val), obj|
19
+ obj[Printer.print(key)] = Printer.print(val)
20
+ end
21
+
22
+ raw_hash = Primitive::Raw.new(:hash, rebuilt)
23
+ Printer.print(raw_hash)
24
+ when Integer
25
+ raw_int = Primitive::Raw.new(:int, chosen_args)
26
+ Printer.print(raw_int)
27
+ when NilClass
28
+ nil
29
+ when Symbol
30
+ raw_sym = Primitive::Raw.new(:sym, chosen_args)
31
+ Printer.print(raw_sym)
32
+ else
33
+ raise "Not yet implemented"
34
+ end
35
+
36
+ Printer.args(args_in_string, chosen_args.class)
37
+ end
38
+
39
+ def choose_values(raw_args)
40
+ case raw_args.type
41
+ when :array
42
+ raw_args.value.map do |arg|
43
+ if (RETURN_TYPES + [:array, :hash]).include?(arg.type)
44
+ arg
45
+ else
46
+ choose_value(arg.value, arg).to_raw
47
+ end
48
+ end
49
+ when :hash
50
+ raw_args.value.each_with_object({}) do |(rkey, rval), obj|
51
+ key = if RETURN_TYPES.include?(rkey.type)
52
+ rkey
53
+ else
54
+ choose_value(rkey.value, rkey).to_raw
55
+ end
56
+
57
+ val = if RETURN_TYPES.include?(rval.type)
58
+ rval
59
+ else
60
+ choose_value(rval.value, rval).to_raw
61
+ end
62
+
63
+ obj[key] = val
64
+ end
65
+ when :int, :missing, :nil
66
+ raw_args.value
67
+ else
68
+ raise "Not yet implemented"
69
+ end
70
+ end
71
+
72
+ def choose_value(name, finder = nil)
73
+ return Primitive::Raw.new(:nil, nil) if name.nil?
74
+ return finder if finder and RETURN_TYPES.include?(finder.type)
75
+
76
+ possible_values = Revolutionist.analysis_as_array.select do |element|
77
+ !is_a_finder?(element, finder) and element.name == name
78
+ end
79
+
80
+ if possible_values.empty?
81
+ return Primitive::Raw.new(:super, name)
82
+ end
83
+
84
+ Chooser.new(possible_values).by_probability
85
+ end
86
+
87
+ def is_a_finder?(primitive, finder)
88
+ return false unless finder
89
+ primitive.class == finder.class and primitive.name == finder.name
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,27 @@
1
+ module Zapata
2
+ module Predictor
3
+ class Chooser
4
+ def initialize(possible_values)
5
+ @possible_values = possible_values.dup
6
+ end
7
+
8
+ def by_probability
9
+ return if @possible_values.empty?
10
+
11
+ by_count
12
+ end
13
+
14
+ private
15
+
16
+ def by_count
17
+ group_with_counts(@possible_values).max_by { |_, v| v }.first
18
+ end
19
+
20
+ def group_with_counts(values)
21
+ values.each_with_object(Hash.new(0)) do |value, obj|
22
+ obj[value] += 1
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Arg < Base
4
+ def node
5
+ name = @code.to_a.first
6
+ type = @code.type
7
+ OpenStruct.new(type: type, name: name, body: @code)
8
+ end
9
+
10
+ def dive_deeper
11
+ end
12
+
13
+ def to_raw
14
+ chosen_value = Predictor::Args.choose_value(node.name, self).to_raw
15
+
16
+ if chosen_value.type == :super
17
+ Missing.new(node.name).to_raw
18
+ else
19
+ chosen_value
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,39 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Array < Base
4
+ def node
5
+ body = @code
6
+ type = @code.type
7
+ OpenStruct.new(type: type, body: body)
8
+ end
9
+
10
+ def dive_deeper
11
+ end
12
+
13
+ def to_a
14
+ value
15
+ end
16
+
17
+ def to_raw
18
+ value = node.body.to_a.map do |node|
19
+ primitive = Diver.dive(node)
20
+ raw = primitive.to_raw
21
+
22
+ if raw.type == :super
23
+ predicted = Predictor::Args.choose_value(raw.value).to_raw
24
+
25
+ if predicted.type == :super
26
+ Missing.new(primitive.name).to_raw
27
+ else
28
+ predicted
29
+ end
30
+ else
31
+ raw
32
+ end
33
+ end
34
+
35
+ Raw.new(:array, value)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,28 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Base
4
+ attr_accessor :code, :type
5
+
6
+ def initialize(code)
7
+ @code = code
8
+ @type = code.type
9
+ dive_deeper
10
+ end
11
+
12
+ def name
13
+ SaveManager.clean(node.name)
14
+ end
15
+
16
+ def dive_deeper
17
+ unless RETURN_TYPES.include?(node.type)
18
+ Diver.dive(node.args)
19
+ Diver.dive(node.body)
20
+ end
21
+ end
22
+
23
+ def to_raw
24
+ Diver.dive(node.body).to_raw
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,22 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Basic < Primitive::Base
4
+ def to_a
5
+ [value]
6
+ end
7
+
8
+ def node
9
+ body = @code
10
+ type = @code.type
11
+ OpenStruct.new(type: type, body: body)
12
+ end
13
+
14
+ def dive_deeper
15
+ end
16
+
17
+ def to_raw
18
+ Raw.new(node.body.type, node.body.to_a.last)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Casgn < Base
4
+ def node
5
+ modul, name, body = @code.to_a
6
+ type = @code.type
7
+ OpenStruct.new(type: type, modul: modul, name: name, body: body)
8
+ end
9
+
10
+ def literal
11
+ Diver.dive(node.body).literal
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Const < Primitive::Basic
4
+ def node
5
+ modul, klass = @code.to_a
6
+ type = @code.type
7
+ OpenStruct.new(modul: modul, klass: klass, type: type)
8
+ end
9
+
10
+ def to_raw
11
+ Raw.new(:const, [node.modul, node.klass].compact.join('::'))
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,33 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Def < Base
4
+ attr_accessor :klass
5
+
6
+ def initialize(code)
7
+ @code = code
8
+ @klass = Diver.current_klass
9
+ @self = Diver.current_sklass
10
+ @access_level = Diver.access_level
11
+ dive_deeper
12
+ end
13
+
14
+ def self?
15
+ !!@self
16
+ end
17
+
18
+ def public?
19
+ @access_level == :public
20
+ end
21
+
22
+ def node
23
+ name, args, body = @code.to_a
24
+ type = @code.type
25
+ OpenStruct.new(type: type, name: name, args: args, body: body)
26
+ end
27
+
28
+ def literal_predicted_args
29
+ Predictor::Args.literal(node.args)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,32 @@
1
+ module Zapata
2
+ module Primitive
3
+ class Defs < Base
4
+ attr_accessor :klass
5
+
6
+ def initialize(code)
7
+ @code = code
8
+ @klass = Diver.current_klass
9
+ @access_level = Diver.access_level
10
+ dive_deeper
11
+ end
12
+
13
+ def self?
14
+ true
15
+ end
16
+
17
+ def public?
18
+ @access_level == :public
19
+ end
20
+
21
+ def node
22
+ receiver, name, args, body = @code.to_a
23
+ type = @code.type
24
+ OpenStruct.new(type: type, name: name, args: args, body: body)
25
+ end
26
+
27
+ def literal_predicted_args
28
+ Predictor::Args.literal(node.args)
29
+ end
30
+ end
31
+ end
32
+ end