kurangu 0.0.10 → 0.0.11

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 (5) hide show
  1. checksums.yaml +4 -4
  2. data/lib/kurangu.rb +1 -0
  3. data/lib/signature.rb +89 -15
  4. data/lib/trace.rb +19 -8
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de19d11be4850cfac46c8a8d9c338ac9b5d3d84c
4
- data.tar.gz: 458809234d98ccb3733cb5ce51a05d484a16ab53
3
+ metadata.gz: d43dd760ec18c5c98d6d78531bbc57075eb7e748
4
+ data.tar.gz: 5e715a872a89d9d130b479f09cb6eb8d133947e1
5
5
  SHA512:
6
- metadata.gz: fe1150d50de545a07d1606e068fda70d15566b952262b2f39fe7bb51044c20ed6e1090cdac0fc5ebae819c4b15e9e38489b0f7782b4a2134e0432bbe63a69c69
7
- data.tar.gz: 41209ce3aab337bbd146c716ba4ef69de4d6b7ca077acf8c1e043164e1154c682715ea3cb16b3dbc8928bb8ee0bc97b9b637083d3414a451583443b4d32afb38
6
+ metadata.gz: 50cf6eb33524ad31b69fcb78592a939bf4d8ef76cbbb265f37392cd502840076c6214bffdfbc0e98231f06c270e390b8d2e47c565dde6608469708944fac35e7
7
+ data.tar.gz: 399b8baea12c636de0e64d01f969d529b12fa3651e8cb62b99d41287d778b8efb39503fde261155c3fa40c0488e04cc21f52ab41517d168a6d10b49814a6793f
@@ -9,6 +9,7 @@ class Kurangu
9
9
  puts "\ngenerating annotations\n"
10
10
  Open3.popen2("#{ruby} -r #{trace_file} #{input_file}") {|stdin, stdout, wait_thr|
11
11
  stdin.puts(input_file)
12
+ puts stdout.read
12
13
  }
13
14
  end
14
15
 
@@ -1,38 +1,112 @@
1
1
  class MethodSignature
2
- def initialize(line, class_name, method_id, parameters)
2
+ def initialize(line, class_name, method_id, is_block, parameters, other_signatures)
3
3
  @line = line
4
4
  @class_name = class_name
5
5
  @method_id = method_id
6
+ @is_block = is_block
6
7
  @parameters = parameters
7
8
  # For each parameter signature (key), store a set of return types (value)
8
- @signatures = Hash.new { | h, k | h[k] = Set.new }
9
+ @return_values = Hash.new { | h, k | h[k] = Set.new }
10
+ @parameter_values = Hash.new
11
+ @other_signatures = other_signatures
9
12
  end
10
-
11
- def generate_parameter_signature(parameter_types)
13
+
14
+ def signature_prefix
15
+ if !@is_block
16
+ "#{@class_name}, :#{@method_id}, "
17
+ else
18
+ ""
19
+ end
20
+ end
21
+
22
+ def expand_block(block)
23
+ if block.class.to_s != "Proc"
24
+ return
25
+ end
26
+ block_params = block.parameters
27
+ block_id = "#{block.source_location[0]} #{block.source_location[1]}"
28
+ if @other_signatures.key?(block_id)
29
+ @other_signatures[block_id].update_parameters(block_params)
30
+ block_signatures = @other_signatures[block_id].get_signatures
31
+ if block_signatures.size == 1
32
+ "{#{block_signatures[0]}}"
33
+ elsif block_signatures.size > 1
34
+ "{\n#{@other_signatures[block_id].get_signatures.join("\n")}\n}"
35
+ end
36
+ end
37
+ end
38
+
39
+ def generate_parameter_signature(parameter_values)
12
40
  signatures = @parameters.map do |parameter|
13
41
  prefix = ""
14
42
  if parameter[0] == :opt
15
43
  prefix = "?"
16
44
  end
17
- "#{prefix}#{parameter_types[parameter[1]]} #{parameter[1]}"
45
+ name = parameter[1]
46
+ value = parameter_values[name]
47
+ type = value.class
48
+ if type.to_s == "Proc"
49
+ expanded = expand_block(value)
50
+ if expanded
51
+ type = expanded
52
+ end
53
+ end
54
+ "#{prefix}#{type} #{name}"
55
+ end
56
+ method_block_signature = ""
57
+ if @parameters[-1][0] == :block
58
+ expanded = expand_block(parameter_values[@parameters[-1][1]])
59
+ if expanded
60
+ signatures.pop
61
+ method_block_signature = " #{expanded}"
62
+ end
63
+ end
64
+ "(#{signatures.join(", ")})#{method_block_signature}"
65
+ end
66
+
67
+ def generate_return_signature(return_values)
68
+ types = return_values.to_a.map do |return_value|
69
+ if return_value == "self"
70
+ return_value
71
+ else
72
+ expanded = expand_block(return_value)
73
+ if !expanded
74
+ return_value.class
75
+ else
76
+ expanded
77
+ end
78
+ end
79
+ end
80
+ types.join(" or ")
81
+ end
82
+
83
+ def update_parameters(parameters)
84
+ @parameters = parameters
85
+ end
86
+
87
+ def get_signatures
88
+ @return_values.to_a.map do |a|
89
+ parameter_values = @parameter_values[a[0]]
90
+ parameter_signature = generate_parameter_signature(parameter_values)
91
+ return_signature = generate_return_signature(a[1])
92
+ "#{parameter_signature} -> #{return_signature}"
18
93
  end
19
- signatures.join(", ")
20
94
  end
21
95
 
22
96
  def to_s
23
- signatures = @signatures.to_a.map { |a|
24
- prefix = "#{@class_name}, :#{@method_id}"
25
- "#{@line} type #{prefix}, '(#{a[0]}) -> #{a[1].to_a.join(" or ")}'"
26
- }
97
+ signatures = get_signatures.map do |signature|
98
+ "#{@line} type #{signature_prefix}'#{signature}'"
99
+ end
27
100
  signatures.join("\n")
28
101
  end
29
102
 
30
- def add(parameter_types, return_type, owner)
31
- parameter_signature = generate_parameter_signature(parameter_types)
32
- if return_type.to_s == owner.class.name or @method_id == :initialize
33
- return_type = "self"
103
+ def add(parameter_values, return_value, owner)
104
+ if return_value.class.to_s == owner.class.name or @method_id == :initialize
105
+ return_value = "self"
34
106
  end
35
- @signatures[parameter_signature].add(return_type)
107
+ parameter_sig = generate_parameter_signature(parameter_values)
108
+ @return_values[parameter_sig].add(return_value)
109
+ @parameter_values[parameter_sig] = parameter_values
36
110
  end
37
111
 
38
112
  end
@@ -16,17 +16,28 @@ def write_annotations(path, signatures)
16
16
  IO.write(path, signatures.values.join("\n"))
17
17
  end
18
18
 
19
- trace_return = TracePoint.new(:return) do |t|
19
+ def is_block(t)
20
+ t.event == :b_return or t.event == :b_call
21
+ end
22
+
23
+ def tracepoint_line(t)
24
+ if is_block(t)
25
+ t.lineno
26
+ else
27
+ t.self.method(t.method_id).source_location[1]
28
+ end
29
+ end
30
+
31
+ trace_return = TracePoint.new(:return, :b_return) do |t|
20
32
  if File.dirname(t.path) == File.dirname(INPUT_FILE)
21
- s = "#{t.defined_class}, :#{t.method_id}"
33
+ s = "#{t.path} #{tracepoint_line(t)}"
22
34
  args = stack[s].pop
23
35
  if args
24
- line = t.self.method(t.method_id).source_location[1]
25
36
  if !signatures.key?(s)
26
37
  parameters = t.self.method(t.method_id).parameters
27
- signatures[s] = MethodSignature.new(line, t.defined_class, t.method_id, parameters)
38
+ signatures[s] = MethodSignature.new(tracepoint_line(t), t.defined_class, t.method_id, is_block(t), parameters, signatures)
28
39
  end
29
- signatures[s].add(args, t.return_value.class, t.self)
40
+ signatures[s].add(args, t.return_value, t.self)
30
41
  path = "#{t.path}.annotations"
31
42
  dir = File.dirname(t.path)
32
43
  write_annotations_paths(dir, paths.add(path))
@@ -35,12 +46,12 @@ trace_return = TracePoint.new(:return) do |t|
35
46
  end
36
47
  end
37
48
 
38
- trace_call = TracePoint.new(:call) do |t|
49
+ trace_call = TracePoint.new(:call, :b_call) do |t|
39
50
  if File.dirname(t.path) == File.dirname(INPUT_FILE)
40
- s = "#{t.defined_class}, :#{t.method_id}"
51
+ s = "#{t.path} #{tracepoint_line(t)}"
41
52
  args = t.binding.eval("local_variables").inject({}) do |vars, name|
42
53
  value = t.binding.eval name.to_s
43
- vars[name] = value.class
54
+ vars[name] = value
44
55
  vars
45
56
  end
46
57
  stack[s] << args
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kurangu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arpith Siromoney