typeprof 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -125,7 +125,7 @@ module TypeProf
125
125
  "#{ @path }:#{ @linenos[pc] }"
126
126
  end
127
127
 
128
- attr_reader :name, :path, :abolute_path, :start_lineno, :type, :locals, :fargs_format, :catch_table, :insns, :linenos
128
+ attr_reader :name, :path, :absolute_path, :start_lineno, :type, :locals, :fargs_format, :catch_table, :insns, :linenos
129
129
  attr_reader :id
130
130
 
131
131
  def pretty_print(q)
@@ -38,7 +38,7 @@ module TypeProf
38
38
 
39
39
  # XXX: need to check .rbs fargs and .rb fargs
40
40
 
41
- ctx = Context.new(@iseq, @cref, mid) # XXX: to support opts, rest, etc
41
+ ctx = Context.new(@iseq, @cref, mid)
42
42
  callee_ep = ExecutionPoint.new(ctx, start_pc, nil)
43
43
 
44
44
  locals = [Type.nil] * @iseq.locals.size
@@ -110,12 +110,13 @@ module TypeProf
110
110
  end
111
111
 
112
112
  class AttrMethodDef < MethodDef
113
- def initialize(ivar, kind)
113
+ def initialize(ivar, kind, absolute_path)
114
114
  @ivar = ivar
115
115
  @kind = kind # :reader | :writer
116
+ @absolute_path = absolute_path
116
117
  end
117
118
 
118
- attr_reader :ivar, :kind
119
+ attr_reader :ivar, :kind, :absolute_path
119
120
 
120
121
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
121
122
  case @kind
@@ -153,7 +154,6 @@ module TypeProf
153
154
  aargs = scratch.globalize_type(aargs, caller_env, caller_ep)
154
155
  @sigs.each do |fargs, ret_ty|
155
156
  ncaller_env = caller_env
156
- # XXX: need to interpret args more correctly
157
157
  #pp [mid, aargs, fargs]
158
158
  # XXX: support self type in fargs
159
159
  subst = { Type::Var.new(:self) => recv }
@@ -187,46 +187,48 @@ module TypeProf
187
187
  scratch.add_callsite!(dummy_ctx, nil, caller_ep, ncaller_env, &ctn)
188
188
  nfargs = fargs.blk_ty.fargs
189
189
  alloc_site = AllocationSite.new(caller_ep).add_id(self)
190
- nfargs = nfargs.map.with_index do |nfarg, i|
190
+ nlead_tys = (nfargs.lead_tys + nfargs.opt_tys).map.with_index do |ty, i|
191
191
  if recv.is_a?(Type::Array)
192
192
  tyvar_elem = Type::Var.new(:Elem)
193
- nfarg = nfarg.substitute(subst.merge({ tyvar_elem => recv.elems.squash }), Config.options[:type_depth_limit])
193
+ ty = ty.substitute(subst.merge({ tyvar_elem => recv.elems.squash }), Config.options[:type_depth_limit])
194
194
  else
195
- nfarg = nfarg.substitute(subst, Config.options[:type_depth_limit])
195
+ ty = ty.substitute(subst, Config.options[:type_depth_limit])
196
196
  end
197
- nfarg = nfarg.remove_type_vars
197
+ ty = ty.remove_type_vars
198
198
  alloc_site2 = alloc_site.add_id(i)
199
- dummy_env, nfarg = scratch.localize_type(nfarg, dummy_env, dummy_ep, alloc_site2)
200
- nfarg
199
+ dummy_env, ty = scratch.localize_type(ty, dummy_env, dummy_ep, alloc_site2)
200
+ ty
201
201
  end
202
- naargs = ActualArguments.new(nfargs, nil, nil, Type.nil) # XXX: support block to block?
203
- scratch.do_invoke_block(false, aargs.blk_ty, naargs, dummy_ep, dummy_env) do |blk_ret_ty, _ep, _env|
204
- subst2 = {}
205
- if blk_ret_ty.consistent?(fargs.blk_ty.ret_ty, subst2)
206
- if recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
207
- tyvar_elem = Type::Var.new(:Elem)
208
- if subst2[tyvar_elem]
209
- ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id) do |elems|
210
- elems.update(nil, subst2[tyvar_elem])
202
+ 0.upto(nfargs.opt_tys.size) do |n|
203
+ naargs = ActualArguments.new(nlead_tys[0, nfargs.lead_tys.size + n], nil, nil, Type.nil) # XXX: support block to block?
204
+ scratch.do_invoke_block(false, aargs.blk_ty, naargs, dummy_ep, dummy_env) do |blk_ret_ty, _ep, _env|
205
+ subst2 = {}
206
+ if blk_ret_ty.consistent?(fargs.blk_ty.ret_ty, subst2)
207
+ if recv.is_a?(Type::Array) && recv_orig.is_a?(Type::LocalArray)
208
+ tyvar_elem = Type::Var.new(:Elem)
209
+ if subst2[tyvar_elem]
210
+ ncaller_env = scratch.update_container_elem_types(ncaller_env, caller_ep, recv_orig.id) do |elems|
211
+ elems.update(nil, subst2[tyvar_elem])
212
+ end
213
+ scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
211
214
  end
212
- scratch.merge_return_env(caller_ep) {|env| env ? env.merge(ncaller_env) : ncaller_env }
215
+ ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
216
+ else
217
+ ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
213
218
  end
214
- ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
215
219
  else
216
- ret_ty = ret_ty.substitute(subst2, Config.options[:type_depth_limit])
220
+ # raise "???"
221
+ # XXX: need warning
222
+ ret_ty = Type.any
217
223
  end
218
- else
219
- # raise "???"
220
- # XXX: need warning
221
- ret_ty = Type.any
224
+ ret_ty = ret_ty.remove_type_vars
225
+ # XXX: check the return type from the block
226
+ # sig.blk_ty.ret_ty.eql?(_ret_ty) ???
227
+ scratch.add_return_type!(dummy_ctx, ret_ty)
222
228
  end
223
- ret_ty = ret_ty.remove_type_vars
224
- # XXX: check the return type from the block
225
- # sig.blk_ty.ret_ty.eql?(_ret_ty) ???
226
- scratch.add_return_type!(dummy_ctx, ret_ty)
229
+ # scratch.add_return_type!(dummy_ctx, ret_ty) ?
230
+ # This makes `def foo; 1.times { return "str" }; end` return Integer|String
227
231
  end
228
- # scratch.add_return_type!(dummy_ctx, ret_ty) ?
229
- # This makes `def foo; 1.times { return "str" }; end` return Integer|String
230
232
  else
231
233
  # XXX: a block is passed to a method that does not accept block.
232
234
  # Should we call the passed block with any arguments?
@@ -259,7 +261,6 @@ module TypeProf
259
261
  end
260
262
 
261
263
  def do_send(recv, mid, aargs, caller_ep, caller_env, scratch, &ctn)
262
- # XXX: ctn?
263
264
  scratch.merge_return_env(caller_ep) {|env| env ? env.merge(caller_env) : caller_env } # for Kernel#lambda
264
265
  @impl[recv, mid, aargs, caller_ep, caller_env, scratch, &ctn]
265
266
  end
@@ -533,8 +533,6 @@ module TypeProf
533
533
 
534
534
  class TypedProc < Type
535
535
  def initialize(fargs, ret_ty, type)
536
- # XXX: need to receive blk_ty?
537
- # XXX: may refactor "arguments = arg_tys * blk_ty" out
538
536
  @fargs = fargs
539
537
  @ret_ty = ret_ty
540
538
  @type = type
@@ -639,10 +637,9 @@ module TypeProf
639
637
  end
640
638
  end
641
639
 
642
- def self.gen_hash
640
+ def self.gen_hash(base_ty = Type::Instance.new(Type::Builtin[:hash]))
643
641
  hg = HashGenerator.new
644
642
  yield hg
645
- base_ty = Type::Instance.new(Type::Builtin[:hash])
646
643
  Type::Hash.new(Type::Hash::Elements.new(hg.map_tys), base_ty)
647
644
  end
648
645
 
data/run.sh CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/bin/bash
2
2
 
3
- bundle exe ruby exe/type-profiler $@
3
+ bundle exe ruby exe/typeprof $@
@@ -0,0 +1,9 @@
1
+ foo do |n|
2
+ p n
3
+ end
4
+
5
+ __END__
6
+ # Revealed types
7
+ # smoke/block13.rb:2 #=> Integer?
8
+
9
+ # Classes
@@ -0,0 +1,3 @@
1
+ class Object
2
+ def foo : { (?Integer) -> String } -> String
3
+ end
@@ -3,3 +3,5 @@ class Foo
3
3
  end
4
4
  __END__
5
5
  # Classes
6
+ class Foo
7
+ end
@@ -30,6 +30,9 @@ Foo::Bar.new.get4 # Integer
30
30
 
31
31
  __END__
32
32
  # Classes
33
+ class Foo
34
+ end
35
+
33
36
  class Foo::Bar
34
37
  def get1 : -> String
35
38
  def get2 : -> Integer
@@ -11,3 +11,6 @@ __END__
11
11
  class A
12
12
  def self.foo : (Integer | Integer.class) -> String
13
13
  end
14
+
15
+ class B < A
16
+ end
@@ -5,7 +5,7 @@ log($foo)
5
5
 
6
6
  __END__
7
7
  # Global variables
8
- # $foo : Integer | String
8
+ $foo : Integer | String
9
9
 
10
10
  # Classes
11
11
  class Object
@@ -0,0 +1,17 @@
1
+ $foo = 1
2
+
3
+ def log
4
+ $foo
5
+ end
6
+
7
+ __END__
8
+ # Errors
9
+ smoke/gvar2.rb:1: [warning] inconsistent assignment to RBS-declared global variable
10
+
11
+ # Global variables
12
+ #$foo : String
13
+
14
+ # Classes
15
+ class Object
16
+ def log : -> String
17
+ end
@@ -0,0 +1 @@
1
+ $foo : String
@@ -27,3 +27,9 @@ end
27
27
  class Base < SuperBase
28
28
  def self.foo : -> (A.class | B.class)
29
29
  end
30
+
31
+ class A < Base
32
+ end
33
+
34
+ class B < Base
35
+ end
@@ -0,0 +1,16 @@
1
+ class Foo
2
+ def initialize
3
+ @foo = "str"
4
+ @bar = "str"
5
+ end
6
+ end
7
+
8
+ __END__
9
+ # Errors
10
+ smoke/ivar3.rb:3: [warning] inconsistent assignment to RBS-declared global variable
11
+
12
+ # Classes
13
+ class Foo
14
+ @bar : String
15
+ def initialize : -> String
16
+ end
@@ -0,0 +1,3 @@
1
+ class Foo
2
+ @foo : Integer
3
+ end
@@ -12,7 +12,7 @@ end
12
12
 
13
13
  __END__
14
14
  # Errors
15
- smoke/manual-rbs2.rb:4: [error] undefined method: A::B.class#unknown
15
+ smoke/manual-rbs2.rb:4: [error] undefined method: A::B#unknown
16
16
 
17
17
  # Classes
18
18
  class Object
@@ -0,0 +1,12 @@
1
+ class Foo
2
+ def foo
3
+ @foo = 1
4
+ end
5
+ end
6
+
7
+ __END__
8
+ # Classes
9
+ class Foo
10
+ @foo : Integer
11
+ # def foo : -> Integer
12
+ end
@@ -0,0 +1,3 @@
1
+ class Foo
2
+ def foo: -> Integer
3
+ end
@@ -27,3 +27,6 @@ end
27
27
  module M1
28
28
  def foo : -> :m1_foo
29
29
  end
30
+
31
+ class C
32
+ end
@@ -14,3 +14,11 @@ __END__
14
14
  smoke/multiple-superclass.rb:9: [warning] superclass is not a class; Object is used instead
15
15
 
16
16
  # Classes
17
+ class A
18
+ end
19
+
20
+ class B
21
+ end
22
+
23
+ class C
24
+ end
@@ -0,0 +1,9 @@
1
+ def log
2
+ Foo.new.bar
3
+ end
4
+
5
+ __END__
6
+ # Classes
7
+ class Object
8
+ def log : -> Integer
9
+ end
@@ -0,0 +1,4 @@
1
+ class Foo
2
+ def foo: -> Integer
3
+ alias bar foo
4
+ end
@@ -0,0 +1,26 @@
1
+ def read_test_1
2
+ Foo.new.reader_example
3
+ end
4
+
5
+ def read_test_2
6
+ Foo.new.accessor_example
7
+ end
8
+
9
+ def write_test
10
+ Foo.new.writer_example = 1
11
+ Foo.new.writer_example = "str"
12
+ Foo.new.accessor_example = 1
13
+ Foo.new.accessor_example = "str"
14
+ end
15
+
16
+ __END__
17
+ # Errors
18
+ smoke/rbs-attr.rb:11: [error] failed to resolve overload: Foo#writer_example=
19
+ smoke/rbs-attr.rb:13: [error] failed to resolve overload: Foo#accessor_example=
20
+
21
+ # Classes
22
+ class Object
23
+ def read_test_1 : -> Integer
24
+ def read_test_2 : -> Integer
25
+ def write_test : -> String
26
+ end
@@ -0,0 +1,5 @@
1
+ class Foo
2
+ attr_reader reader_example: Integer
3
+ attr_writer writer_example: Integer
4
+ attr_accessor accessor_example: Integer
5
+ end
@@ -0,0 +1,39 @@
1
+ def gvar_test
2
+ $gvar
3
+ end
4
+
5
+ class Foo
6
+ def const_test
7
+ CONST
8
+ end
9
+
10
+ def ivar_test
11
+ @ivar
12
+ end
13
+
14
+ def cvar_test
15
+ @@cvar
16
+ end
17
+
18
+ def self.cvar_test2
19
+ @@cvar
20
+ end
21
+ end
22
+
23
+ __END__
24
+ # Global variables
25
+ #$gvar : :gvar_example
26
+
27
+ # Classes
28
+ class Object
29
+ def gvar_test : -> :gvar_example
30
+ end
31
+
32
+ class Foo
33
+ # @ivar : :ivar_example
34
+ # @@cvar : :cvar_example
35
+ def const_test : -> :const_example
36
+ def ivar_test : -> :ivar_example
37
+ def cvar_test : -> :cvar_example
38
+ def self.cvar_test2 : -> :cvar_example
39
+ end
@@ -0,0 +1,7 @@
1
+ $gvar: :gvar_example
2
+
3
+ class Foo
4
+ CONST: :const_example
5
+ @ivar: :ivar_example
6
+ @@cvar: :cvar_example
7
+ end
@@ -7,3 +7,6 @@ __END__
7
7
  class (Struct) < Struct
8
8
  attr_accessor a() : untyped
9
9
  end
10
+
11
+ class Foo < (Struct)
12
+ end
@@ -37,6 +37,24 @@ class Object
37
37
  def log : (Baz) -> nil
38
38
  end
39
39
 
40
+ class A
41
+ end
42
+
43
+ class B
44
+ end
45
+
46
+ class C
47
+ end
48
+
49
+ class X
50
+ end
51
+
52
+ class Y
53
+ end
54
+
55
+ class Z
56
+ end
57
+
40
58
  class Foo
41
59
  def f : (C) -> X
42
60
  end
@@ -27,3 +27,9 @@ end
27
27
  class Base < SuperBase
28
28
  def self.foo : -> (A.class | B.class)
29
29
  end
30
+
31
+ class A < Base
32
+ end
33
+
34
+ class B < Base
35
+ end