typeprof 0.21.11 → 0.30.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -31
  3. data/bin/typeprof +5 -0
  4. data/doc/doc.ja.md +134 -0
  5. data/doc/doc.md +136 -0
  6. data/lib/typeprof/cli/cli.rb +178 -0
  7. data/lib/typeprof/cli.rb +3 -133
  8. data/lib/typeprof/code_range.rb +112 -0
  9. data/lib/typeprof/core/ast/base.rb +263 -0
  10. data/lib/typeprof/core/ast/call.rb +259 -0
  11. data/lib/typeprof/core/ast/const.rb +126 -0
  12. data/lib/typeprof/core/ast/control.rb +433 -0
  13. data/lib/typeprof/core/ast/meta.rb +150 -0
  14. data/lib/typeprof/core/ast/method.rb +339 -0
  15. data/lib/typeprof/core/ast/misc.rb +263 -0
  16. data/lib/typeprof/core/ast/module.rb +123 -0
  17. data/lib/typeprof/core/ast/pattern.rb +140 -0
  18. data/lib/typeprof/core/ast/sig_decl.rb +471 -0
  19. data/lib/typeprof/core/ast/sig_type.rb +663 -0
  20. data/lib/typeprof/core/ast/value.rb +319 -0
  21. data/lib/typeprof/core/ast/variable.rb +315 -0
  22. data/lib/typeprof/core/ast.rb +472 -0
  23. data/lib/typeprof/core/builtin.rb +146 -0
  24. data/lib/typeprof/core/env/method.rb +137 -0
  25. data/lib/typeprof/core/env/method_entity.rb +55 -0
  26. data/lib/typeprof/core/env/module_entity.rb +408 -0
  27. data/lib/typeprof/core/env/static_read.rb +155 -0
  28. data/lib/typeprof/core/env/type_alias_entity.rb +27 -0
  29. data/lib/typeprof/core/env/value_entity.rb +32 -0
  30. data/lib/typeprof/core/env.rb +366 -0
  31. data/lib/typeprof/core/graph/box.rb +998 -0
  32. data/lib/typeprof/core/graph/change_set.rb +224 -0
  33. data/lib/typeprof/core/graph/filter.rb +155 -0
  34. data/lib/typeprof/core/graph/vertex.rb +225 -0
  35. data/lib/typeprof/core/service.rb +514 -0
  36. data/lib/typeprof/core/type.rb +352 -0
  37. data/lib/typeprof/core/util.rb +81 -0
  38. data/lib/typeprof/core.rb +31 -0
  39. data/lib/typeprof/diagnostic.rb +35 -0
  40. data/lib/typeprof/lsp/messages.rb +415 -0
  41. data/lib/typeprof/lsp/server.rb +203 -0
  42. data/lib/typeprof/lsp/text.rb +69 -0
  43. data/lib/typeprof/lsp/util.rb +51 -0
  44. data/lib/typeprof/lsp.rb +4 -907
  45. data/lib/typeprof/version.rb +1 -1
  46. data/lib/typeprof.rb +4 -18
  47. data/typeprof.gemspec +5 -7
  48. metadata +47 -33
  49. data/.github/dependabot.yml +0 -6
  50. data/.github/workflows/main.yml +0 -39
  51. data/.gitignore +0 -9
  52. data/Gemfile +0 -17
  53. data/Gemfile.lock +0 -41
  54. data/Rakefile +0 -10
  55. data/exe/typeprof +0 -10
  56. data/lib/typeprof/analyzer.rb +0 -2598
  57. data/lib/typeprof/arguments.rb +0 -414
  58. data/lib/typeprof/block.rb +0 -176
  59. data/lib/typeprof/builtin.rb +0 -893
  60. data/lib/typeprof/code-range.rb +0 -177
  61. data/lib/typeprof/config.rb +0 -158
  62. data/lib/typeprof/container-type.rb +0 -912
  63. data/lib/typeprof/export.rb +0 -589
  64. data/lib/typeprof/import.rb +0 -852
  65. data/lib/typeprof/insns-def.rb +0 -65
  66. data/lib/typeprof/iseq.rb +0 -864
  67. data/lib/typeprof/method.rb +0 -355
  68. data/lib/typeprof/type.rb +0 -1140
  69. data/lib/typeprof/utils.rb +0 -212
  70. data/tools/coverage.rb +0 -14
  71. data/tools/setup-insns-def.rb +0 -30
  72. data/typeprof-lsp +0 -3
@@ -0,0 +1,352 @@
1
+ module TypeProf::Core
2
+ class Type
3
+ # This new method does memoize creation of types
4
+ #: (GlobalEnv, *untyped) -> instance
5
+ def self.new(genv, *args)
6
+ genv.type_table[[self] + args] ||= super(genv, *args)
7
+ end
8
+
9
+ def self.strip_parens(s)
10
+ #s =~ /\A\((.*)\)\z/ ? $1 : s
11
+ s.start_with?("(") && s.end_with?(")") ? s[1..-2] || raise : s
12
+ end
13
+
14
+ def self.strip_array(s)
15
+ s.start_with?("Array[") && s.end_with?("]") ? s[6..-2] || raise : s
16
+ end
17
+
18
+ def self.default_param_map(genv, ty)
19
+ ty = ty.base_type(genv)
20
+ instance_ty = ty.is_a?(Type::Instance) ? ty : Type::Instance.new(genv, ty.mod, []) # TODO: type params
21
+ singleton_ty = ty.is_a?(Type::Instance) ? Type::Singleton.new(genv, ty.mod) : ty
22
+ {
23
+ "*self": Source.new(ty),
24
+ "*instance": Source.new(instance_ty),
25
+ "*class": Source.new(singleton_ty),
26
+ }
27
+ end
28
+
29
+ class Singleton < Type
30
+ #: (GlobalEnv, ModuleEntity) -> void
31
+ def initialize(genv, mod)
32
+ raise unless mod.is_a?(ModuleEntity)
33
+ # TODO: type_param
34
+ @mod = mod
35
+ end
36
+
37
+ attr_reader :mod
38
+
39
+ def base_type(_)
40
+ self
41
+ end
42
+
43
+ def check_match(genv, changes, vtx)
44
+ vtx.each_type do |other_ty|
45
+ case other_ty
46
+ when Singleton
47
+ other_mod = other_ty.mod
48
+ if other_mod.module?
49
+ # TODO: implement
50
+ else
51
+ mod = @mod
52
+ while mod
53
+ return true if mod == other_mod
54
+ changes.add_depended_superclass(mod)
55
+ mod = mod.superclass
56
+ end
57
+ end
58
+ when Instance
59
+ base_ty = @mod.module? ? genv.mod_type : genv.cls_type
60
+ return true if base_ty.check_match(genv, changes, Source.new(other_ty))
61
+ end
62
+ end
63
+ return false
64
+ end
65
+
66
+ def show
67
+ "singleton(#{ @mod.show_cpath })"
68
+ end
69
+
70
+ def get_instance_type(genv)
71
+ params = @mod.type_params
72
+ Instance.new(genv, @mod, params ? params.map { Source.new } : [])
73
+ end
74
+ end
75
+
76
+ class Instance < Type
77
+ #: (GlobalEnv, ModuleEntity, ::Array[Vertex]) -> void
78
+ def initialize(genv, mod, args)
79
+ raise mod.class.to_s unless mod.is_a?(ModuleEntity)
80
+ @mod = mod
81
+ @args = args
82
+ raise unless @args.is_a?(::Array)
83
+ end
84
+
85
+ attr_reader :mod, :args
86
+
87
+ def base_type(_)
88
+ self
89
+ end
90
+
91
+ def check_match(genv, changes, vtx)
92
+ vtx.each_type do |other_ty|
93
+ case other_ty
94
+ when Instance
95
+ ty = self
96
+ while ty
97
+ if ty.mod == other_ty.mod
98
+ args_all_match = true
99
+ ty.args.zip(other_ty.args) do |arg, other_arg|
100
+ unless arg.check_match(genv, changes, other_arg)
101
+ args_all_match = false
102
+ break
103
+ end
104
+ end
105
+ return true if args_all_match
106
+ end
107
+ changes.add_depended_superclass(ty.mod)
108
+
109
+ if other_ty.mod.module?
110
+ return true if check_match_included_modules(genv, changes, ty, other_ty)
111
+ end
112
+
113
+ ty = genv.get_superclass_type(ty, changes, {})
114
+ end
115
+ end
116
+ end
117
+ return false
118
+ end
119
+
120
+ def check_match_included_modules(genv, changes, ty, other_ty)
121
+ ty.mod.included_modules.each do |inc_decl, inc_mod|
122
+ if inc_decl.is_a?(AST::SigIncludeNode) && inc_mod.type_params
123
+ inc_ty = genv.get_instance_type(inc_mod, inc_decl.args, changes, {}, ty)
124
+ else
125
+ type_params = inc_mod.type_params.map {|ty_param| Source.new() } # TODO: better support
126
+ inc_ty = Type::Instance.new(genv, inc_mod, type_params)
127
+ end
128
+ if inc_ty.mod == other_ty.mod
129
+ args_all_match = true
130
+ inc_ty.args.zip(other_ty.args) do |arg, other_arg|
131
+ if other_arg && !arg.check_match(genv, changes, other_arg)
132
+ args_all_match = false
133
+ break
134
+ end
135
+ end
136
+ return true if args_all_match
137
+ end
138
+ changes.add_depended_superclass(inc_ty.mod)
139
+
140
+ return true if check_match_included_modules(genv, changes, inc_ty, other_ty)
141
+ end
142
+ return false
143
+ end
144
+
145
+ def show
146
+ case @mod.cpath
147
+ when [:NilClass] then "nil"
148
+ when [:TrueClass] then "true"
149
+ when [:FalseClass] then "false"
150
+ else
151
+ "#{ @mod.show_cpath }#{ @args.empty? ? "" : "[#{ @args.map {|arg| Type.strip_parens(arg.show) }.join(", ") }]" }"
152
+ end
153
+ end
154
+ end
155
+
156
+ class Array < Type
157
+ #: (GlobalEnv, ::Array[Vertex], Instance) -> void
158
+ def initialize(genv, elems, base_type)
159
+ @elems = elems
160
+ @base_type = base_type
161
+ raise unless base_type.is_a?(Instance)
162
+ end
163
+
164
+ attr_reader :elems
165
+
166
+ def get_elem(genv, idx = nil)
167
+ if idx && @elems
168
+ @elems[idx] || Source.new(genv.nil_type)
169
+ else
170
+ @base_type.args.first
171
+ end
172
+ end
173
+
174
+ def splat_assign(genv, lefts, rest_elem, rights)
175
+ edges = []
176
+ state = :left
177
+ j = nil
178
+ @elems.each_with_index do |elem, i|
179
+ case state
180
+ when :left
181
+ if i < lefts.size
182
+ edges << [elem, lefts[i]]
183
+ else
184
+ break unless rest_elem
185
+ state = :rest
186
+ redo
187
+ end
188
+ when :rest
189
+ if @elems.size - i > rights.size
190
+ edges << [elem, rest_elem]
191
+ else
192
+ state = :right
193
+ j = i
194
+ redo
195
+ end
196
+ when :right
197
+ edges << [elem, rights[i - j]]
198
+ end
199
+ end
200
+ edges
201
+ end
202
+
203
+ def base_type(genv)
204
+ @base_type
205
+ end
206
+
207
+ def check_match(genv, changes, vtx)
208
+ vtx.each_type do |other_ty|
209
+ if other_ty.is_a?(Array)
210
+ if @elems.size == other_ty.elems.size
211
+ match = true
212
+ @elems.zip(other_ty.elems) do |elem, other_elem|
213
+ unless elem.check_match(genv, changes, other_elem)
214
+ match = false
215
+ break
216
+ end
217
+ end
218
+ return true if match
219
+ end
220
+ end
221
+ end
222
+ @base_type.check_match(genv, changes, vtx)
223
+ end
224
+
225
+ def show
226
+ if @elems
227
+ "[#{ @elems.map {|e| Type.strip_parens(e.show) }.join(", ") }]"
228
+ else
229
+ "#{ @base_type.mod.show_cpath }[#{ Type.strip_parens(@unified_elem.show) }]"
230
+ end
231
+ end
232
+ end
233
+
234
+ class Hash < Type
235
+ #: (GlobalEnv, ::Array[Vertex], Instance) -> void
236
+ def initialize(genv, literal_pairs, base_type)
237
+ @literal_pairs = literal_pairs
238
+ @base_type = base_type
239
+ raise unless base_type.is_a?(Instance)
240
+ end
241
+
242
+ def get_key
243
+ @base_type.args[0]
244
+ end
245
+
246
+ def get_value(key = nil)
247
+ @literal_pairs[key] || @base_type.args[1]
248
+ end
249
+
250
+ def base_type(genv)
251
+ @base_type
252
+ end
253
+
254
+ def check_match(genv, changes, vtx)
255
+ # TODO: implement
256
+ @base_type.check_match(genv, changes, vtx)
257
+ end
258
+
259
+ def show
260
+ @base_type.show
261
+ end
262
+ end
263
+
264
+ class Proc < Type
265
+ def initialize(genv, block)
266
+ @block = block
267
+ end
268
+
269
+ attr_reader :block
270
+
271
+ def base_type(genv)
272
+ genv.proc_type
273
+ end
274
+
275
+ def check_match(genv, changes, vtx)
276
+ genv.proc_type.check_match(genv, changes, vtx)
277
+ end
278
+
279
+ def show
280
+ "<Proc>"
281
+ end
282
+ end
283
+
284
+ class Symbol < Type
285
+ #: (GlobalEnv, ::Symbol) -> void
286
+ def initialize(genv, sym)
287
+ @sym = sym
288
+ end
289
+
290
+ attr_reader :sym
291
+
292
+ def base_type(genv)
293
+ genv.symbol_type
294
+ end
295
+
296
+ def check_match(genv, changes, vtx)
297
+ vtx.each_type do |other_ty|
298
+ case other_ty
299
+ when Symbol
300
+ return true if @sym == other_ty.sym
301
+ when Instance
302
+ return true if genv.symbol_type.check_match(genv, changes, Source.new(other_ty))
303
+ end
304
+ end
305
+ return false
306
+ end
307
+
308
+ def show
309
+ @sym.inspect
310
+ end
311
+ end
312
+
313
+ class Bot < Type
314
+ def initialize(genv)
315
+ end
316
+
317
+ def base_type(genv)
318
+ genv.obj_type
319
+ end
320
+
321
+ def check_match(genv, changes, vtx)
322
+ return true
323
+ end
324
+
325
+ def show
326
+ "bot"
327
+ end
328
+ end
329
+
330
+ class Var < Type
331
+ #: (GlobalEnv, ::Symbol, Vertex) -> void
332
+ def initialize(genv, name, vtx)
333
+ @name = name
334
+ @vtx = vtx
335
+ end
336
+
337
+ attr_reader :name, :vtx
338
+
339
+ def base_type(genv)
340
+ genv.obj_type # Is this ok?
341
+ end
342
+
343
+ def check_match(genv, changes, vtx)
344
+ true # should implement a better support...
345
+ end
346
+
347
+ def show
348
+ "var[#{ @name }]"
349
+ end
350
+ end
351
+ end
352
+ end
@@ -0,0 +1,81 @@
1
+ module TypeProf::Core
2
+ class Set
3
+ def self.[](*elems)
4
+ h = Hash.new(false)
5
+ elems.each {|elem| h[elem] = true }
6
+ new(h)
7
+ end
8
+
9
+ def initialize(hash)
10
+ @hash = hash
11
+ end
12
+
13
+ def internal_hash = @hash
14
+
15
+ def dup
16
+ Set.new(@hash.dup)
17
+ end
18
+
19
+ def <<(elem)
20
+ raise if @hash.include?(elem)
21
+ @hash[elem] = true
22
+ self
23
+ end
24
+
25
+ def include?(elem)
26
+ @hash[elem]
27
+ end
28
+
29
+ def merge(set)
30
+ raise NotImplementedError
31
+ end
32
+
33
+ def each(&blk)
34
+ @hash.each_key(&blk)
35
+ end
36
+
37
+ def empty?
38
+ @hash.empty?
39
+ end
40
+
41
+ def delete(elem)
42
+ raise unless @hash.include?(elem)
43
+ @hash.delete(elem)
44
+ end
45
+
46
+ def clear
47
+ @hash.clear
48
+ end
49
+
50
+ def to_a
51
+ @hash.keys
52
+ end
53
+
54
+ def size
55
+ @hash.size
56
+ end
57
+
58
+ def -(other)
59
+ h = @hash.dup
60
+ other.each do |elem|
61
+ h.delete(elem)
62
+ end
63
+ Set.new(h)
64
+ end
65
+
66
+ def pretty_print(q)
67
+ q.text "Set["
68
+ q.group do
69
+ q.nest(1) do
70
+ @hash.each_key do |elem|
71
+ q.breakable ""
72
+ q.pp elem
73
+ q.text ","
74
+ end
75
+ end
76
+ q.breakable ""
77
+ end
78
+ q.text "]"
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,31 @@
1
+ require "rbs"
2
+ require "prism"
3
+ require_relative "core/util"
4
+ require_relative "core/ast"
5
+ require_relative "core/ast/base"
6
+ require_relative "core/ast/module"
7
+ require_relative "core/ast/method"
8
+ require_relative "core/ast/call"
9
+ require_relative "core/ast/control"
10
+ require_relative "core/ast/const"
11
+ require_relative "core/ast/variable"
12
+ require_relative "core/ast/value"
13
+ require_relative "core/ast/misc"
14
+ require_relative "core/ast/meta"
15
+ require_relative "core/ast/pattern"
16
+ require_relative "core/ast/sig_decl"
17
+ require_relative "core/ast/sig_type"
18
+ require_relative "core/type"
19
+ require_relative "core/env"
20
+ require_relative "core/env/method_entity"
21
+ require_relative "core/env/module_entity"
22
+ require_relative "core/env/type_alias_entity"
23
+ require_relative "core/env/value_entity"
24
+ require_relative "core/env/method"
25
+ require_relative "core/env/static_read"
26
+ require_relative "core/graph/change_set"
27
+ require_relative "core/graph/vertex"
28
+ require_relative "core/graph/filter"
29
+ require_relative "core/graph/box"
30
+ require_relative "core/builtin"
31
+ require_relative "core/service"
@@ -0,0 +1,35 @@
1
+ module TypeProf
2
+ class Diagnostic
3
+ def initialize(node, meth, msg)
4
+ @node = node
5
+ @meth = meth
6
+ @msg = msg
7
+ @severity = :error # TODO: keyword argument
8
+ @tags = nil # TODO: keyword argument
9
+ end
10
+
11
+ def reuse(new_node)
12
+ @node = new_node
13
+ end
14
+
15
+ attr_reader :msg, :severity
16
+
17
+ def code_range
18
+ @node.send(@meth)
19
+ end
20
+
21
+ SEVERITY = { error: 1, warning: 2, info: 3, hint: 4 }
22
+ TAG = { unnecessary: 1, deprecated: 2 }
23
+
24
+ def to_lsp
25
+ json = {
26
+ range: code_range.to_lsp,
27
+ source: "TypeProf",
28
+ message: @msg,
29
+ }
30
+ json[:severity] = SEVERITY[@severity] if @severity
31
+ json[:tags] = @tags.map {|tag| TAG[tag] } if @tags
32
+ json
33
+ end
34
+ end
35
+ end