typeprof 0.7.0 → 0.10.0
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.
- checksums.yaml +4 -4
- data/Gemfile.lock +8 -5
- data/lib/typeprof/analyzer.rb +211 -98
- data/lib/typeprof/arguments.rb +2 -0
- data/lib/typeprof/block.rb +40 -2
- data/lib/typeprof/builtin.rb +301 -99
- data/lib/typeprof/cli.rb +2 -0
- data/lib/typeprof/config.rb +14 -2
- data/lib/typeprof/container-type.rb +5 -4
- data/lib/typeprof/export.rb +116 -65
- data/lib/typeprof/import.rb +68 -41
- data/lib/typeprof/iseq.rb +46 -11
- data/lib/typeprof/method.rb +47 -23
- data/lib/typeprof/type.rb +96 -18
- data/lib/typeprof/version.rb +1 -1
- data/smoke/alias.rb +5 -4
- data/smoke/alias2.rb +6 -4
- data/smoke/any1.rb +2 -1
- data/smoke/any2.rb +3 -2
- data/smoke/arguments.rb +3 -2
- data/smoke/arguments2.rb +11 -10
- data/smoke/array-each.rb +2 -1
- data/smoke/array-each2.rb +2 -1
- data/smoke/array-each3.rb +2 -1
- data/smoke/array-ltlt.rb +2 -1
- data/smoke/array-ltlt2.rb +2 -1
- data/smoke/array-map.rb +2 -1
- data/smoke/array-map2.rb +2 -1
- data/smoke/array-map3.rb +4 -3
- data/smoke/array-mul.rb +3 -2
- data/smoke/array-plus1.rb +2 -1
- data/smoke/array-plus2.rb +3 -2
- data/smoke/array-pop.rb +2 -1
- data/smoke/array-range-aref.rb +12 -11
- data/smoke/array-replace.rb +2 -1
- data/smoke/array-s-aref.rb +2 -1
- data/smoke/array1.rb +6 -5
- data/smoke/array10.rb +2 -1
- data/smoke/array11.rb +2 -1
- data/smoke/array12.rb +4 -3
- data/smoke/array13.rb +5 -4
- data/smoke/array14.rb +2 -1
- data/smoke/array15.rb +16 -0
- data/smoke/array2.rb +4 -3
- data/smoke/array3.rb +5 -4
- data/smoke/array4.rb +2 -1
- data/smoke/array5.rb +2 -1
- data/smoke/array6.rb +4 -2
- data/smoke/array7.rb +2 -1
- data/smoke/array8.rb +1 -1
- data/smoke/array9.rb +2 -1
- data/smoke/attr-module.rb +27 -0
- data/smoke/attr-vis.rb +43 -0
- data/smoke/attr-vis.rbs +4 -0
- data/smoke/attr.rb +5 -5
- data/smoke/autoload.rb +2 -1
- data/smoke/backtrace.rb +4 -3
- data/smoke/block-ambiguous.rb +9 -8
- data/smoke/block-args1-rest.rb +13 -11
- data/smoke/block-args1.rb +11 -10
- data/smoke/block-args2-rest.rb +13 -11
- data/smoke/block-args2.rb +11 -10
- data/smoke/block-args3-rest.rb +15 -13
- data/smoke/block-args3.rb +13 -12
- data/smoke/block-blockarg.rb +5 -4
- data/smoke/block-kwarg.rb +11 -10
- data/smoke/block1.rb +2 -1
- data/smoke/block10.rb +2 -1
- data/smoke/block11.rb +6 -5
- data/smoke/block12.rb +3 -2
- data/smoke/block14.rb +3 -2
- data/smoke/block2.rb +2 -1
- data/smoke/block3.rb +3 -3
- data/smoke/block4.rb +3 -2
- data/smoke/block5.rb +4 -2
- data/smoke/block6.rb +3 -2
- data/smoke/block7.rb +2 -1
- data/smoke/block8.rb +4 -3
- data/smoke/block9.rb +2 -1
- data/smoke/block_given.rb +37 -0
- data/smoke/blown.rb +2 -1
- data/smoke/break1.rb +3 -2
- data/smoke/break2.rb +2 -1
- data/smoke/break3.rb +13 -0
- data/smoke/case.rb +2 -1
- data/smoke/case2.rb +2 -1
- data/smoke/case3.rb +17 -0
- data/smoke/class-hierarchy.rb +5 -5
- data/smoke/class-hierarchy2.rb +3 -3
- data/smoke/class-new.rb +15 -0
- data/smoke/class_instance_var.rb +1 -1
- data/smoke/class_method.rb +2 -2
- data/smoke/class_method2.rb +2 -2
- data/smoke/class_method3.rb +4 -2
- data/smoke/constant1.rb +6 -6
- data/smoke/constant2.rb +6 -4
- data/smoke/constant3.rb +2 -1
- data/smoke/constant4.rb +2 -1
- data/smoke/context-sensitive1.rb +2 -1
- data/smoke/cvar.rb +7 -5
- data/smoke/cvar2.rb +2 -2
- data/smoke/define_method.rb +2 -2
- data/smoke/define_method2.rb +2 -2
- data/smoke/define_method3.rb +14 -0
- data/smoke/define_method3.rbs +3 -0
- data/smoke/define_method4.rb +15 -0
- data/smoke/define_method4.rbs +3 -0
- data/smoke/define_method5.rb +12 -0
- data/smoke/define_method6.rb +19 -0
- data/smoke/demo.rb +7 -6
- data/smoke/demo1.rb +2 -1
- data/smoke/demo10.rb +3 -2
- data/smoke/demo11.rb +2 -1
- data/smoke/demo2.rb +2 -1
- data/smoke/demo3.rb +2 -1
- data/smoke/demo4.rb +3 -3
- data/smoke/demo5.rb +1 -1
- data/smoke/demo6.rb +4 -3
- data/smoke/demo7.rb +2 -1
- data/smoke/demo8.rb +3 -2
- data/smoke/demo9.rb +4 -2
- data/smoke/dummy-execution1.rb +3 -2
- data/smoke/dummy-execution2.rb +2 -2
- data/smoke/dummy_element.rb +14 -0
- data/smoke/ensure1.rb +3 -2
- data/smoke/enum_for.rb +15 -0
- data/smoke/enum_for2.rb +17 -0
- data/smoke/enumerator.rb +3 -2
- data/smoke/expandarray1.rb +2 -1
- data/smoke/expandarray2.rb +2 -1
- data/smoke/fib.rb +2 -2
- data/smoke/flip-flop.rb +28 -0
- data/smoke/flow1.rb +2 -1
- data/smoke/flow10.rb +17 -0
- data/smoke/flow2.rb +2 -1
- data/smoke/flow3.rb +2 -1
- data/smoke/flow5.rb +2 -1
- data/smoke/flow6.rb +2 -1
- data/smoke/flow7.rb +2 -1
- data/smoke/flow8.rb +2 -1
- data/smoke/flow9.rb +12 -0
- data/smoke/freeze.rb +2 -1
- data/smoke/function.rb +3 -2
- data/smoke/gvar.rb +3 -2
- data/smoke/gvar2.rb +4 -3
- data/smoke/hash-bot.rb +12 -0
- data/smoke/hash-fetch.rb +4 -3
- data/smoke/hash-merge-bang.rb +2 -1
- data/smoke/hash1.rb +3 -2
- data/smoke/hash2.rb +2 -1
- data/smoke/hash3.rb +2 -1
- data/smoke/hash4.rb +2 -1
- data/smoke/hash5.rb +1 -1
- data/smoke/inheritance.rb +4 -4
- data/smoke/inheritance2.rb +2 -2
- data/smoke/initialize.rb +7 -5
- data/smoke/instance_eval.rb +2 -2
- data/smoke/instance_eval2.rb +10 -0
- data/smoke/instance_eval3.rb +25 -0
- data/smoke/int_times.rb +2 -1
- data/smoke/integer.rb +2 -1
- data/smoke/ivar.rb +6 -4
- data/smoke/ivar2.rb +4 -4
- data/smoke/ivar3.rb +4 -3
- data/smoke/ivar4.rb +21 -0
- data/smoke/kernel-class.rb +2 -1
- data/smoke/keyword1.rb +2 -1
- data/smoke/keyword2.rb +2 -1
- data/smoke/keyword3.rb +2 -1
- data/smoke/keyword4.rb +2 -1
- data/smoke/keyword5.rb +2 -1
- data/smoke/kwrest.rb +3 -2
- data/smoke/kwsplat1.rb +5 -4
- data/smoke/kwsplat2.rb +2 -1
- data/smoke/lit-complex.rb +10 -0
- data/smoke/lit-encoding.rb +10 -0
- data/smoke/manual-rbs.rb +6 -4
- data/smoke/manual-rbs2.rb +2 -1
- data/smoke/manual-rbs3.rb +3 -2
- data/smoke/masgn1.rb +2 -1
- data/smoke/masgn2.rb +3 -2
- data/smoke/masgn3.rb +2 -1
- data/smoke/method_in_branch.rb +4 -3
- data/smoke/method_missing.rb +5 -4
- data/smoke/module1.rb +2 -2
- data/smoke/module2.rb +1 -1
- data/smoke/module3.rb +3 -3
- data/smoke/module4.rb +3 -2
- data/smoke/module5.rb +17 -0
- data/smoke/module6.rb +40 -0
- data/smoke/module_function1.rb +4 -3
- data/smoke/module_function2.rb +4 -3
- data/smoke/multiple-include.rb +2 -1
- data/smoke/multiple-superclass.rb +1 -1
- data/smoke/next1.rb +3 -2
- data/smoke/next2.rb +2 -1
- data/smoke/object-send1.rb +4 -3
- data/smoke/object-send2.rb +10 -0
- data/smoke/object-send3.rb +18 -0
- data/smoke/once.rb +2 -1
- data/smoke/optional1.rb +2 -1
- data/smoke/optional2.rb +2 -1
- data/smoke/optional3.rb +2 -1
- data/smoke/parameterizedd-self.rb +4 -2
- data/smoke/parameterizedd-self2.rb +1 -1
- data/smoke/pathname1.rb +2 -1
- data/smoke/pathname2.rb +2 -1
- data/smoke/pattern-match1.rb +2 -1
- data/smoke/pattern-match2.rb +2 -1
- data/smoke/prepend1.rb +33 -0
- data/smoke/prepend2.rb +10 -0
- data/smoke/prepend2.rbs +9 -0
- data/smoke/primitive_method.rb +19 -0
- data/smoke/printf.rb +2 -2
- data/smoke/proc.rb +3 -2
- data/smoke/proc2.rb +2 -1
- data/smoke/proc3.rb +2 -1
- data/smoke/proc4.rb +2 -1
- data/smoke/proc5.rb +19 -0
- data/smoke/public.rb +38 -0
- data/smoke/range.rb +2 -1
- data/smoke/rbs-alias.rb +2 -1
- data/smoke/rbs-attr.rb +6 -5
- data/smoke/rbs-attr2.rb +1 -1
- data/smoke/rbs-extend.rb +2 -1
- data/smoke/rbs-interface.rb +5 -4
- data/smoke/rbs-module.rb +26 -0
- data/smoke/rbs-module.rbs +4 -0
- data/smoke/rbs-opt-and-rest.rb +10 -0
- data/smoke/rbs-opt-and-rest.rbs +3 -0
- data/smoke/rbs-proc1.rb +2 -1
- data/smoke/rbs-proc2.rb +3 -2
- data/smoke/rbs-proc3.rb +2 -1
- data/smoke/rbs-record.rb +3 -2
- data/smoke/rbs-tyvar.rb +3 -2
- data/smoke/rbs-tyvar2.rb +3 -2
- data/smoke/rbs-tyvar3.rb +3 -2
- data/smoke/rbs-tyvar4.rb +4 -3
- data/smoke/rbs-tyvar5.rb +2 -1
- data/smoke/rbs-tyvar6.rb +4 -3
- data/smoke/rbs-tyvar7.rb +2 -1
- data/smoke/rbs-vars.rb +7 -6
- data/smoke/redo1.rb +3 -2
- data/smoke/redo2.rb +3 -2
- data/smoke/req-keyword.rb +2 -1
- data/smoke/rescue1.rb +3 -2
- data/smoke/rescue2.rb +3 -2
- data/smoke/rescue3.rb +20 -0
- data/smoke/rescue4.rb +17 -0
- data/smoke/respond_to.rb +2 -1
- data/smoke/rest-farg.rb +2 -1
- data/smoke/rest1.rb +3 -2
- data/smoke/rest2.rb +2 -1
- data/smoke/rest3.rb +7 -6
- data/smoke/rest4.rb +3 -2
- data/smoke/rest5.rb +2 -1
- data/smoke/rest6.rb +2 -1
- data/smoke/retry1.rb +3 -2
- data/smoke/return.rb +2 -1
- data/smoke/simple.rb +12 -0
- data/smoke/singleton_method.rb +1 -1
- data/smoke/step.rb +4 -3
- data/smoke/string-split.rb +2 -1
- data/smoke/struct-keyword_init.rb +10 -0
- data/smoke/struct.rb +1 -1
- data/smoke/struct2.rb +5 -4
- data/smoke/struct3.rb +2 -2
- data/smoke/struct4.rb +7 -0
- data/smoke/struct5.rb +16 -0
- data/smoke/struct6.rb +15 -0
- data/smoke/struct7.rb +17 -0
- data/smoke/stub-keyword.rb +10 -0
- data/smoke/super1.rb +5 -4
- data/smoke/super2.rb +1 -1
- data/smoke/super3.rb +4 -3
- data/smoke/super4.rb +7 -5
- data/smoke/super5.rb +6 -4
- data/smoke/svar1.rb +2 -1
- data/smoke/symbol-proc-attr.rb +22 -0
- data/smoke/symbol-proc-attr2.rb +15 -0
- data/smoke/symbol-proc-bot.rb +13 -0
- data/smoke/symbol-proc.rb +4 -3
- data/smoke/tap1.rb +3 -2
- data/smoke/toplevel.rb +2 -1
- data/smoke/two-map.rb +3 -2
- data/smoke/type_var.rb +4 -3
- data/smoke/typed_method.rb +2 -1
- data/smoke/uninitialize-var.rb +2 -1
- data/smoke/union-recv.rb +2 -2
- data/smoke/user-demo.rb +3 -3
- data/smoke/wrong-extend.rb +3 -2
- data/smoke/wrong-include.rb +3 -2
- data/smoke/wrong-include2.rb +17 -0
- data/typeprof.gemspec +1 -1
- metadata +57 -5
- data/tools/stackprof-wrapper.rb +0 -10
data/lib/typeprof/cli.rb
CHANGED
@@ -48,6 +48,8 @@ module TypeProf
|
|
48
48
|
end
|
49
49
|
opt.on("--[no-]show-errors", "Display possible errors found during the analysis") {|v| options[:show_errors] = v }
|
50
50
|
opt.on("--[no-]show-untyped", "Display \"Foo | untyped\" instead of \"Foo\"") {|v| options[:show_untyped] = v }
|
51
|
+
opt.on("--[no-]show-parameter-names", "Display parameter names for methods") {|v| options[:show_parameter_names] = v }
|
52
|
+
opt.on("--[no-]show-source-locations", "Display definition source locations for methods") {|v| options[:show_source_locations] = v }
|
51
53
|
|
52
54
|
opt.separator ""
|
53
55
|
opt.separator "Analysis limit options:"
|
data/lib/typeprof/config.rb
CHANGED
@@ -14,6 +14,13 @@ module TypeProf
|
|
14
14
|
keyword_init: true
|
15
15
|
)
|
16
16
|
|
17
|
+
class TypeProfError < StandardError
|
18
|
+
def report(output)
|
19
|
+
output.puts "# Analysis Error"
|
20
|
+
output.puts message
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
17
24
|
class ConfigData
|
18
25
|
def initialize(**opt)
|
19
26
|
opt[:output] ||= $stdout
|
@@ -25,6 +32,8 @@ module TypeProf
|
|
25
32
|
show_indicator: true,
|
26
33
|
show_untyped: false,
|
27
34
|
show_errors: false,
|
35
|
+
show_parameter_names: true,
|
36
|
+
show_source_locations: false,
|
28
37
|
stub_execution: true,
|
29
38
|
type_depth_limit: 5,
|
30
39
|
stackprof: nil,
|
@@ -69,7 +78,7 @@ module TypeProf
|
|
69
78
|
|
70
79
|
prologue_ctx = Context.new(nil, nil, nil)
|
71
80
|
prologue_ep = ExecutionPoint.new(prologue_ctx, -1, nil)
|
72
|
-
prologue_env = Env.new(StaticEnv.new(
|
81
|
+
prologue_env = Env.new(StaticEnv.new(Type.bot, Type.nil, false, true), [], [], Utils::HashWrapper.new({}))
|
73
82
|
|
74
83
|
Config.rb_files.each do |rb|
|
75
84
|
if rb.is_a?(Array) # [String name, String content]
|
@@ -100,6 +109,9 @@ module TypeProf
|
|
100
109
|
end
|
101
110
|
end
|
102
111
|
|
112
|
+
rescue TypeProfError => exc
|
113
|
+
exc.report(Config.output)
|
114
|
+
|
103
115
|
ensure
|
104
116
|
if Config.options[:stackprof] && defined?(StackProf)
|
105
117
|
StackProf.stop
|
@@ -113,7 +125,7 @@ module TypeProf
|
|
113
125
|
ctx = Context.new(iseq, cref, nil)
|
114
126
|
ep = ExecutionPoint.new(ctx, 0, nil)
|
115
127
|
locals = [Type.nil] * iseq.locals.size
|
116
|
-
env = Env.new(StaticEnv.new(recv, Type.nil, false), locals, [], Utils::HashWrapper.new({}))
|
128
|
+
env = Env.new(StaticEnv.new(recv, Type.nil, false, false), locals, [], Utils::HashWrapper.new({}))
|
117
129
|
|
118
130
|
return ep, env
|
119
131
|
end
|
@@ -208,10 +208,6 @@ module TypeProf
|
|
208
208
|
@base_type = base_type
|
209
209
|
end
|
210
210
|
|
211
|
-
def self.dummy_elements
|
212
|
-
Elements.new([], Type.any)
|
213
|
-
end
|
214
|
-
|
215
211
|
attr_reader :elems, :base_type
|
216
212
|
|
217
213
|
def inspect
|
@@ -264,6 +260,10 @@ module TypeProf
|
|
264
260
|
@lead_tys, @rest_ty = lead_tys, rest_ty
|
265
261
|
end
|
266
262
|
|
263
|
+
def self.dummy_elements
|
264
|
+
Elements.new([], Type.any)
|
265
|
+
end
|
266
|
+
|
267
267
|
attr_reader :lead_tys, :rest_ty
|
268
268
|
|
269
269
|
def to_local_type(id, base_ty)
|
@@ -796,6 +796,7 @@ module TypeProf
|
|
796
796
|
class Local < ContainerType
|
797
797
|
def initialize(kind, id, base_type)
|
798
798
|
@kind = kind
|
799
|
+
raise if @kind != Cell && @kind != Array && @kind != Hash
|
799
800
|
@id = id
|
800
801
|
raise unless base_type
|
801
802
|
@base_type = base_type
|
data/lib/typeprof/export.rb
CHANGED
@@ -72,7 +72,7 @@ module TypeProf
|
|
72
72
|
gvars.dump.each do |gvar_name, entry|
|
73
73
|
next if entry.type == Type.bot
|
74
74
|
s = entry.rbs_declared ? "#" : ""
|
75
|
-
output.puts s + "#{ gvar_name }
|
75
|
+
output.puts s + "#{ gvar_name }: #{ entry.type.screen_name(scratch) }"
|
76
76
|
end
|
77
77
|
output.puts
|
78
78
|
end
|
@@ -105,19 +105,20 @@ module TypeProf
|
|
105
105
|
consts[name] = ty.screen_name(@scratch)
|
106
106
|
end
|
107
107
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
108
|
+
modules = class_def.modules.to_h do |kind, mods|
|
109
|
+
mods = mods.to_h do |singleton, mods|
|
110
|
+
mods = mods.filter_map do |mod_def, _type_args, absolute_paths|
|
111
|
+
next if absolute_paths.all? {|path| !path || Config.check_dir_filter(path) == :exclude }
|
112
|
+
Type::Instance.new(mod_def.klass_obj).screen_name(@scratch)
|
113
|
+
end
|
114
|
+
[singleton, mods]
|
115
|
+
end
|
116
|
+
[kind, mods]
|
116
117
|
end
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
|
119
|
+
visibilities = {}
|
120
|
+
source_locations = {}
|
121
|
+
methods = {}
|
121
122
|
ivars = class_def.ivars.dump
|
122
123
|
cvars = class_def.cvars.dump
|
123
124
|
|
@@ -135,28 +136,47 @@ module TypeProf
|
|
135
136
|
method_name = ctx.mid
|
136
137
|
method_name = "self.#{ method_name }" if singleton
|
137
138
|
|
138
|
-
|
139
|
-
|
139
|
+
key = [:iseq, method_name]
|
140
|
+
visibilities[key] ||= mdef.pub_meth
|
141
|
+
source_locations[key] ||= ctx.iseq.source_location(0)
|
142
|
+
(methods[key] ||= []) << @scratch.show_method_signature(ctx)
|
143
|
+
end
|
144
|
+
when AliasMethodDef
|
145
|
+
alias_name, orig_name = mid, mdef.orig_mid
|
146
|
+
if singleton
|
147
|
+
alias_name = "self.#{ alias_name }"
|
148
|
+
orig_name = "self.#{ orig_name }"
|
140
149
|
end
|
150
|
+
key = [:alias, alias_name]
|
151
|
+
visibilities[key] ||= mdef.pub_meth
|
152
|
+
source_locations[key] ||= mdef.def_ep&.source_location
|
153
|
+
methods[key] = orig_name
|
141
154
|
when AttrMethodDef
|
142
|
-
next if !mdef.
|
155
|
+
next if !mdef.def_ep
|
156
|
+
absolute_path = mdef.def_ep.ctx.iseq.absolute_path
|
157
|
+
next if !absolute_path || Config.check_dir_filter(absolute_path) == :exclude
|
143
158
|
mid = mid.to_s[0..-2].to_sym if mid.to_s.end_with?("=")
|
144
159
|
method_name = mid
|
145
160
|
method_name = "self.#{ mid }" if singleton
|
146
161
|
method_name = [method_name, :"@#{ mid }" != mdef.ivar]
|
147
|
-
|
148
|
-
|
149
|
-
|
162
|
+
key = [:attr, method_name]
|
163
|
+
visibilities[key] ||= mdef.pub_meth
|
164
|
+
source_locations[key] ||= mdef.def_ep.source_location
|
165
|
+
if methods[key]
|
166
|
+
if methods[key][0] != mdef.kind
|
167
|
+
methods[key][0] = :accessor
|
150
168
|
end
|
151
169
|
else
|
152
170
|
entry = ivars[[singleton, mdef.ivar]]
|
153
171
|
ty = entry ? entry.type : Type.any
|
154
|
-
|
172
|
+
methods[key] = [mdef.kind, ty.screen_name(@scratch)]
|
155
173
|
end
|
156
174
|
when TypedMethodDef
|
157
175
|
if mdef.rbs_source
|
158
176
|
method_name, sigs = mdef.rbs_source
|
159
|
-
|
177
|
+
key = [:rbs, method_name]
|
178
|
+
methods[key] = sigs
|
179
|
+
visibilities[key] ||= mdef.pub_meth
|
160
180
|
end
|
161
181
|
end
|
162
182
|
end
|
@@ -167,7 +187,7 @@ module TypeProf
|
|
167
187
|
ty = entry.type
|
168
188
|
next unless var.to_s.start_with?("@")
|
169
189
|
var = "self.#{ var }" if singleton
|
170
|
-
next if
|
190
|
+
next if methods[[:attr, [singleton ? "self.#{ var.to_s[1..] }" : var.to_s[1..].to_sym, false]]]
|
171
191
|
next if entry.rbs_declared
|
172
192
|
[var, ty.screen_name(@scratch)]
|
173
193
|
end.compact
|
@@ -179,7 +199,9 @@ module TypeProf
|
|
179
199
|
end.compact
|
180
200
|
|
181
201
|
if !class_def.absolute_path || Config.check_dir_filter(class_def.absolute_path) == :exclude
|
182
|
-
|
202
|
+
if methods.keys.all? {|type,| type == :rbs }
|
203
|
+
return nil if consts.empty? && modules[:before][true].empty? && modules[:before][false].empty? && modules[:after][true].empty? && modules[:after][false].empty? && ivars.empty? && cvars.empty? && inner_classes.empty?
|
204
|
+
end
|
183
205
|
end
|
184
206
|
|
185
207
|
@scratch.namespace = nil
|
@@ -189,18 +211,17 @@ module TypeProf
|
|
189
211
|
name: class_def.name,
|
190
212
|
superclass: superclass,
|
191
213
|
consts: consts,
|
192
|
-
|
193
|
-
extended_mods: extended_mods,
|
214
|
+
modules: modules,
|
194
215
|
ivars: ivars,
|
195
216
|
cvars: cvars,
|
196
|
-
|
197
|
-
|
198
|
-
|
217
|
+
methods: methods,
|
218
|
+
visibilities: visibilities,
|
219
|
+
source_locations: source_locations,
|
199
220
|
inner_classes: inner_classes,
|
200
221
|
)
|
201
222
|
end
|
202
223
|
|
203
|
-
ClassData = Struct.new(:kind, :name, :superclass, :consts, :
|
224
|
+
ClassData = Struct.new(:kind, :name, :superclass, :consts, :modules, :ivars, :cvars, :methods, :visibilities, :source_locations, :inner_classes, keyword_init: true)
|
204
225
|
|
205
226
|
def show(stat_eps, output)
|
206
227
|
# make the class hierarchy
|
@@ -217,7 +238,16 @@ module TypeProf
|
|
217
238
|
|
218
239
|
output.puts "# Classes" # and Modules
|
219
240
|
|
220
|
-
|
241
|
+
prev_nil = true
|
242
|
+
show_class_hierarchy(0, hierarchy).each do |line|
|
243
|
+
if line == nil
|
244
|
+
output.puts line unless prev_nil
|
245
|
+
prev_nil = true
|
246
|
+
else
|
247
|
+
output.puts line
|
248
|
+
prev_nil = false
|
249
|
+
end
|
250
|
+
end
|
221
251
|
|
222
252
|
if ENV["TP_STAT"]
|
223
253
|
output.puts ""
|
@@ -245,13 +275,13 @@ module TypeProf
|
|
245
275
|
end.compact
|
246
276
|
end
|
247
277
|
|
248
|
-
def show_class_hierarchy(depth, hierarchy
|
278
|
+
def show_class_hierarchy(depth, hierarchy)
|
279
|
+
lines = []
|
249
280
|
hierarchy.each do |class_data|
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
show_class_data(depth, class_data, output)
|
281
|
+
lines << nil
|
282
|
+
lines.concat show_class_data(depth, class_data)
|
254
283
|
end
|
284
|
+
lines
|
255
285
|
end
|
256
286
|
|
257
287
|
def show_const(namespace, path)
|
@@ -261,48 +291,69 @@ module TypeProf
|
|
261
291
|
path[i..].join("::")
|
262
292
|
end
|
263
293
|
|
264
|
-
def show_class_data(depth, class_data
|
294
|
+
def show_class_data(depth, class_data)
|
265
295
|
indent = " " * depth
|
266
296
|
name = class_data.name.last
|
267
297
|
superclass = " < " + class_data.superclass if class_data.superclass
|
268
|
-
|
269
|
-
|
298
|
+
first_line = indent + "#{ class_data.kind } #{ name }#{ superclass }"
|
299
|
+
lines = []
|
270
300
|
class_data.consts.each do |name, ty|
|
271
|
-
|
272
|
-
first = false
|
301
|
+
lines << (indent + " #{ name }: #{ ty }")
|
273
302
|
end
|
274
|
-
class_data.
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
303
|
+
class_data.modules.each do |kind, mods|
|
304
|
+
mods.each do |singleton, mods|
|
305
|
+
case
|
306
|
+
when kind == :before && singleton then directive = nil
|
307
|
+
when kind == :before && !singleton then directive = "prepend"
|
308
|
+
when kind == :after && singleton then directive = "extend"
|
309
|
+
when kind == :after && !singleton then directive = "include"
|
310
|
+
end
|
311
|
+
mods.each do |mod|
|
312
|
+
lines << (indent + " #{ directive } #{ mod }") if directive
|
313
|
+
end
|
314
|
+
end
|
281
315
|
end
|
282
316
|
class_data.ivars.each do |var, ty|
|
283
|
-
|
284
|
-
first = false
|
317
|
+
lines << (indent + " #{ var }: #{ ty }") unless var.start_with?("_")
|
285
318
|
end
|
286
319
|
class_data.cvars.each do |var, ty|
|
287
|
-
|
288
|
-
first = false
|
289
|
-
end
|
290
|
-
class_data.attr_methods.each do |(method_name, hidden), (kind, ty)|
|
291
|
-
output.puts indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" } : #{ ty }"
|
292
|
-
first = false
|
320
|
+
lines << (indent + " #{ var }: #{ ty }")
|
293
321
|
end
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
322
|
+
lines << nil
|
323
|
+
prev_vis = true
|
324
|
+
class_data.methods.each do |key, arg|
|
325
|
+
vis = class_data.visibilities[key]
|
326
|
+
if prev_vis != vis
|
327
|
+
lines << nil
|
328
|
+
lines << (indent + " #{ vis ? "public" : "private" }")
|
329
|
+
prev_vis = vis
|
330
|
+
end
|
331
|
+
source_location = class_data.source_locations[key]
|
332
|
+
if Config.options[:show_source_locations] && source_location
|
333
|
+
lines << nil
|
334
|
+
lines << (indent + " # #{ source_location }")
|
335
|
+
end
|
336
|
+
type, (method_name, hidden) = key
|
337
|
+
case type
|
338
|
+
when :attr
|
339
|
+
kind, ty = *arg
|
340
|
+
lines << (indent + " attr_#{ kind } #{ method_name }#{ hidden ? "()" : "" }: #{ ty }")
|
341
|
+
when :rbs
|
342
|
+
sigs = arg.sort.join("\n" + indent + "#" + " " * (method_name.size + 5) + "| ")
|
343
|
+
lines << (indent + "# def #{ method_name }: #{ sigs }")
|
344
|
+
when :iseq
|
345
|
+
sigs = arg.sort.join("\n" + indent + " " * (method_name.size + 6) + "| ")
|
346
|
+
lines << (indent + " def #{ method_name }: #{ sigs }")
|
347
|
+
when :alias
|
348
|
+
orig_name = arg
|
349
|
+
lines << (indent + " alias #{ method_name } #{ orig_name }")
|
350
|
+
end
|
303
351
|
end
|
304
|
-
show_class_hierarchy(depth + 1, class_data.inner_classes
|
305
|
-
|
352
|
+
lines.concat show_class_hierarchy(depth + 1, class_data.inner_classes)
|
353
|
+
lines.shift until lines.empty? || lines.first
|
354
|
+
lines.pop until lines.empty? || lines.last
|
355
|
+
lines.unshift first_line
|
356
|
+
lines << (indent + "end")
|
306
357
|
end
|
307
358
|
end
|
308
359
|
end
|
data/lib/typeprof/import.rb
CHANGED
@@ -26,6 +26,13 @@ module TypeProf
|
|
26
26
|
def load_library(lib)
|
27
27
|
loader = RBS::EnvironmentLoader.new(core_root: nil)
|
28
28
|
loader.add(library: lib)
|
29
|
+
|
30
|
+
case lib
|
31
|
+
when "yaml"
|
32
|
+
loader.add(library: "pstore")
|
33
|
+
loader.add(library: "dbm")
|
34
|
+
end
|
35
|
+
|
29
36
|
new_decls = loader.load(env: @env).map {|decl,| decl }
|
30
37
|
RBSReader.load_rbs(@env, new_decls)
|
31
38
|
end
|
@@ -62,7 +69,6 @@ module TypeProf
|
|
62
69
|
class RBS2JSON
|
63
70
|
def initialize(all_env, cur_env)
|
64
71
|
@all_env, @cur_env = all_env, cur_env
|
65
|
-
@env_walker = RBS::EnvironmentWalker.new(env: @cur_env) # Currently, only each_type_name is used
|
66
72
|
end
|
67
73
|
|
68
74
|
def dump_json
|
@@ -110,13 +116,13 @@ module TypeProf
|
|
110
116
|
end
|
111
117
|
|
112
118
|
type_params = nil
|
113
|
-
|
114
|
-
extended_modules = []
|
119
|
+
modules = { include: [], extend: [], prepend: [] }
|
115
120
|
methods = {}
|
116
121
|
attr_methods = {}
|
117
122
|
ivars = {}
|
118
123
|
cvars = {}
|
119
124
|
rbs_sources = {}
|
125
|
+
visibility = true
|
120
126
|
|
121
127
|
decls.each do |decl|
|
122
128
|
decl = decl.decl
|
@@ -137,7 +143,7 @@ module TypeProf
|
|
137
143
|
end
|
138
144
|
end
|
139
145
|
|
140
|
-
method_def = conv_method_def(method_types)
|
146
|
+
method_def = conv_method_def(method_types, visibility)
|
141
147
|
rbs_source = [(member.kind == :singleton ? "self." : "") + member.name.to_s, member.types.map {|type| type.location.source }]
|
142
148
|
if member.instance?
|
143
149
|
methods[[false, name]] = method_def
|
@@ -149,13 +155,13 @@ module TypeProf
|
|
149
155
|
end
|
150
156
|
when RBS::AST::Members::AttrReader
|
151
157
|
ty = conv_type(member.type)
|
152
|
-
attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty)
|
158
|
+
attr_methods[[false, member.name]] = attr_method_def(:reader, member.name, ty, visibility)
|
153
159
|
when RBS::AST::Members::AttrWriter
|
154
160
|
ty = conv_type(member.type)
|
155
|
-
attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty)
|
161
|
+
attr_methods[[false, member.name]] = attr_method_def(:writer, member.name, ty, visibility)
|
156
162
|
when RBS::AST::Members::AttrAccessor
|
157
163
|
ty = conv_type(member.type)
|
158
|
-
attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty)
|
164
|
+
attr_methods[[false, member.name]] = attr_method_def(:accessor, member.name, ty, visibility)
|
159
165
|
when RBS::AST::Members::Alias
|
160
166
|
# XXX: an alias to attr methods?
|
161
167
|
if member.instance?
|
@@ -172,7 +178,7 @@ module TypeProf
|
|
172
178
|
if name.kind == :class
|
173
179
|
mod = conv_type_name(name)
|
174
180
|
type_args = member.args.map {|type| conv_type(type) }
|
175
|
-
|
181
|
+
modules[:include] << [mod, type_args]
|
176
182
|
else
|
177
183
|
# including an interface is not supported yet
|
178
184
|
end
|
@@ -182,7 +188,17 @@ module TypeProf
|
|
182
188
|
if name.kind == :class
|
183
189
|
mod = conv_type_name(name)
|
184
190
|
type_args = member.args.map {|type| conv_type(type) }
|
185
|
-
|
191
|
+
modules[:extend] << [mod, type_args]
|
192
|
+
else
|
193
|
+
# extending a module with an interface is not supported yet
|
194
|
+
end
|
195
|
+
|
196
|
+
when RBS::AST::Members::Prepend
|
197
|
+
name = member.name
|
198
|
+
if name.kind == :class
|
199
|
+
mod = conv_type_name(name)
|
200
|
+
type_args = member.args.map {|type| conv_type(type) }
|
201
|
+
modules[:prepend] << [mod, type_args]
|
186
202
|
else
|
187
203
|
# extending a module with an interface is not supported yet
|
188
204
|
end
|
@@ -192,7 +208,10 @@ module TypeProf
|
|
192
208
|
when RBS::AST::Members::ClassVariable
|
193
209
|
cvars[member.name] = conv_type(member.type)
|
194
210
|
|
195
|
-
when RBS::AST::Members::Public
|
211
|
+
when RBS::AST::Members::Public
|
212
|
+
visibility = true
|
213
|
+
when RBS::AST::Members::Private
|
214
|
+
visibility = false
|
196
215
|
|
197
216
|
# The following declarations are ignoreable because they are handled in other level
|
198
217
|
when RBS::AST::Declarations::Constant
|
@@ -210,8 +229,7 @@ module TypeProf
|
|
210
229
|
type_params: type_params,
|
211
230
|
superclass: superclass,
|
212
231
|
members: {
|
213
|
-
|
214
|
-
extended_modules: extended_modules,
|
232
|
+
modules: modules,
|
215
233
|
methods: methods,
|
216
234
|
attr_methods: attr_methods,
|
217
235
|
ivars: ivars,
|
@@ -259,19 +277,16 @@ module TypeProf
|
|
259
277
|
yield decl.name
|
260
278
|
if decl.super_class
|
261
279
|
name = decl.super_class.name
|
262
|
-
args = decl.super_class.args
|
263
|
-
if args
|
264
|
-
args.each do |ty|
|
265
|
-
@env_walker.each_type_name(ty, &blk)
|
266
|
-
end
|
267
|
-
end
|
268
280
|
else
|
269
281
|
name = RBS::BuiltinNames::Object.name
|
270
282
|
end
|
271
283
|
return if decl.name == RBS::BuiltinNames::BasicObject.name
|
272
284
|
return if decl.name == name
|
273
|
-
@all_env.class_decls[name]
|
274
|
-
|
285
|
+
decls = @all_env.class_decls[name]
|
286
|
+
if decls
|
287
|
+
decls.decls.each do |decl|
|
288
|
+
each_reference(decl.decl, &blk)
|
289
|
+
end
|
275
290
|
end
|
276
291
|
end
|
277
292
|
|
@@ -294,10 +309,14 @@ module TypeProf
|
|
294
309
|
return RBS::BuiltinNames::Object.name, []
|
295
310
|
end
|
296
311
|
|
297
|
-
def conv_method_def(rbs_method_types)
|
298
|
-
rbs_method_types.map do |method_type|
|
312
|
+
def conv_method_def(rbs_method_types, visibility)
|
313
|
+
sig_rets = rbs_method_types.map do |method_type|
|
299
314
|
conv_func(method_type.type_params, method_type.type, method_type.block)
|
300
315
|
end
|
316
|
+
{
|
317
|
+
sig_rets: sig_rets,
|
318
|
+
visibility: visibility,
|
319
|
+
}
|
301
320
|
end
|
302
321
|
|
303
322
|
def conv_func(type_params, func, block)
|
@@ -327,11 +346,12 @@ module TypeProf
|
|
327
346
|
}
|
328
347
|
end
|
329
348
|
|
330
|
-
def attr_method_def(kind, name, ty)
|
349
|
+
def attr_method_def(kind, name, ty, visibility)
|
331
350
|
{
|
332
351
|
kind: kind,
|
333
352
|
ivar: name,
|
334
353
|
ty: ty,
|
354
|
+
visibility: visibility,
|
335
355
|
}
|
336
356
|
end
|
337
357
|
|
@@ -445,6 +465,8 @@ module TypeProf
|
|
445
465
|
json = scratch.rbs_reader.load_library(feature)
|
446
466
|
rescue RBS::EnvironmentLoader::UnknownLibraryError
|
447
467
|
return nil
|
468
|
+
rescue RBS::DuplicatedDeclarationError
|
469
|
+
return true
|
448
470
|
end
|
449
471
|
# need cache?
|
450
472
|
Import.new(scratch, json).import
|
@@ -476,8 +498,7 @@ module TypeProf
|
|
476
498
|
|
477
499
|
klass = @scratch.get_constant(base_klass, name)
|
478
500
|
if klass.is_a?(Type::Any)
|
479
|
-
|
480
|
-
klass = @scratch.new_class(base_klass, name, type_params, superclass, superclass_type_args, nil)
|
501
|
+
klass = @scratch.new_class(base_klass, name, type_params, superclass, nil)
|
481
502
|
|
482
503
|
# There builtin classes are needed to interpret RBS declarations
|
483
504
|
case classpath
|
@@ -493,26 +514,30 @@ module TypeProf
|
|
493
514
|
end
|
494
515
|
end
|
495
516
|
|
496
|
-
[klass, members]
|
517
|
+
[klass, superclass_type_args, members]
|
497
518
|
end
|
498
519
|
|
499
|
-
classes.each do |klass, members|
|
500
|
-
|
501
|
-
|
520
|
+
classes.each do |klass, superclass_type_args, members|
|
521
|
+
@scratch.add_superclass_type_args!(klass, superclass_type_args&.map {|ty| conv_type(ty) })
|
522
|
+
modules = members[:modules]
|
502
523
|
methods = members[:methods]
|
503
524
|
attr_methods = members[:attr_methods]
|
504
525
|
ivars = members[:ivars]
|
505
526
|
cvars = members[:cvars]
|
506
527
|
rbs_sources = members[:rbs_sources]
|
507
528
|
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
529
|
+
modules.each do |kind, mods|
|
530
|
+
mods.each do |mod, type_args|
|
531
|
+
type_args = type_args&.map {|ty| conv_type(ty) }
|
532
|
+
case kind
|
533
|
+
when :include
|
534
|
+
@scratch.mix_module(:after, klass, path_to_klass(mod), type_args, false, nil)
|
535
|
+
when :extend
|
536
|
+
@scratch.mix_module(:after, klass, path_to_klass(mod), type_args, true, nil)
|
537
|
+
when :prepend
|
538
|
+
@scratch.mix_module(:before, klass, path_to_klass(mod), type_args, false, nil)
|
539
|
+
end
|
540
|
+
end
|
516
541
|
end
|
517
542
|
|
518
543
|
methods.each do |(singleton, method_name), mdef|
|
@@ -525,7 +550,7 @@ module TypeProf
|
|
525
550
|
kind = mdef[:kind]
|
526
551
|
ivar = mdef[:ivar]
|
527
552
|
ty = conv_type(mdef[:ty]).remove_type_vars
|
528
|
-
@scratch.add_attr_method(klass,
|
553
|
+
@scratch.add_attr_method(klass, ivar, :"@#{ ivar }", kind, mdef[:visibility], nil)
|
529
554
|
@scratch.add_ivar_write!(Type::Instance.new(klass), :"@#{ ivar }", ty, nil)
|
530
555
|
end
|
531
556
|
|
@@ -555,11 +580,11 @@ module TypeProf
|
|
555
580
|
end
|
556
581
|
|
557
582
|
def conv_method_def(method_name, mdef, rbs_source)
|
558
|
-
sig_rets = mdef.flat_map do |sig_ret|
|
583
|
+
sig_rets = mdef[:sig_rets].flat_map do |sig_ret|
|
559
584
|
conv_func(sig_ret)
|
560
585
|
end
|
561
586
|
|
562
|
-
TypedMethodDef.new(sig_rets, rbs_source)
|
587
|
+
TypedMethodDef.new(sig_rets, rbs_source, mdef[:visibility])
|
563
588
|
end
|
564
589
|
|
565
590
|
def conv_func(sig_ret)
|
@@ -659,7 +684,9 @@ module TypeProf
|
|
659
684
|
klass = Type::Builtin[:obj]
|
660
685
|
path.each do |name|
|
661
686
|
klass = @scratch.get_constant(klass, name)
|
662
|
-
|
687
|
+
if klass == Type.any
|
688
|
+
raise TypeProfError.new("A constant `#{ path.join("::") }' is used but not defined in RBS")
|
689
|
+
end
|
663
690
|
end
|
664
691
|
klass
|
665
692
|
end
|