typeprof 0.21.11 → 0.30.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 (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
@@ -1,177 +0,0 @@
1
- module TypeProf
2
- class CodeLocation
3
- # In Ruby, lineno is 1-origin, and column is 0-origin
4
- def initialize(lineno, column)
5
- @lineno = lineno
6
- @column = column
7
- end
8
-
9
- def inspect
10
- "(%d,%d)" % [@lineno, @column]
11
- end
12
-
13
- attr_reader :lineno, :column
14
-
15
- def self.from_lsp(lsp_loc)
16
- # In the Language Server Protocol, lineno and column are both 0-origin
17
- CodeLocation.new(lsp_loc[:line] + 1, lsp_loc[:character])
18
- end
19
-
20
- def to_lsp
21
- { line: @lineno - 1, character: @column }
22
- end
23
-
24
- def advance_cursor(offset, source_text)
25
- new_lineno = @lineno
26
- new_column = @column
27
- while offset > 0
28
- line_text = source_text.lines[new_lineno - 1]
29
- if new_column + offset >= line_text.length
30
- advanced = line_text.length - new_column
31
- offset -= advanced
32
- new_lineno += 1
33
- new_column = 0
34
- else
35
- new_column += offset
36
- break
37
- end
38
- end
39
- CodeLocation.new(new_lineno, new_column)
40
- end
41
-
42
- def <=>(other)
43
- ret = @lineno <=> other.lineno
44
- return ret if ret != 0
45
- @column <=> other.column
46
- end
47
-
48
- include Comparable
49
- end
50
-
51
- class CodeRange
52
- def initialize(first, last)
53
- @first, @last = first, last
54
- end
55
-
56
- def inspect
57
- "%p-%p" % [@first, @last]
58
- end
59
-
60
- attr_reader :first
61
- attr_reader :last
62
-
63
- def self.from_lsp(lsp_range)
64
- CodeRange.new(CodeLocation.from_lsp(lsp[:start]), CodeLocation.from_lsp(lsp[:end]))
65
- end
66
-
67
- def self.from_rbs(rbs_loc)
68
- CodeRange.new(
69
- CodeLocation.new(rbs_loc.start_line, rbs_loc.start_column),
70
- CodeLocation.new(rbs_loc.end_line, rbs_loc.end_column),
71
- )
72
- end
73
-
74
- def to_lsp
75
- { start: @first.to_lsp, end: @last.to_lsp }
76
- end
77
-
78
- def contain_loc?(loc)
79
- @first <= loc && loc < @last
80
- end
81
-
82
- def contain?(other)
83
- @first <= other.first && other.last <= @last
84
- end
85
-
86
- def overlap?(other)
87
- if @first <= other.first
88
- return @last > other.first
89
- else
90
- return @first < other.last
91
- end
92
- end
93
- end
94
-
95
- class CodeRangeTable
96
- Entry = Struct.new(:range, :value, :children)
97
-
98
- class Entry
99
- def inspect
100
- "[%p, %p, %p]" % [range, value, children]
101
- end
102
- end
103
-
104
- def initialize(list = [])
105
- @list = list # Array[Entry]
106
- end
107
-
108
- def []=(range, value)
109
- i_b = @list.bsearch_index {|e| e.range.last > range.first } || @list.size
110
- i_e = @list.bsearch_index {|e| e.range.first >= range.last } || @list.size
111
- if i_b < i_e
112
- # for all i in i_b...i_e, @list[i] overlaps with the range
113
- if i_e - i_b == 1
114
- if range.contain?(@list[i_b].range)
115
- @list[i_b] = Entry[range, value, CodeRangeTable.new(@list[i_b, 1])]
116
- elsif @list[i_b].range.contain?(range)
117
- @list[i_b].children[range] = value
118
- else
119
- raise
120
- end
121
- else
122
- if range.contain?(@list[i_b].range) && range.contain?(@list[i_e - 1].range)
123
- @list[i_b...i_e] = [Entry[range, value, CodeRangeTable.new(@list[i_b...i_e])]]
124
- else
125
- raise
126
- end
127
- end
128
- else
129
- @list[i_b, 0] = [Entry[range, value, CodeRangeTable.new]]
130
- end
131
- end
132
-
133
- def [](loc)
134
- e = @list.bsearch {|e| e.range.last > loc }
135
- if e && e.range.contain_loc?(loc)
136
- return e.children[loc] || e.value
137
- end
138
- return nil
139
- end
140
- end
141
- end
142
-
143
- if $0 == __FILE__
144
- include TypeProf
145
- cr1 = CodeRange.new(CodeLocation.new(1, 0), CodeLocation.new(1, 2))
146
- cr2 = CodeRange.new(CodeLocation.new(1, 2), CodeLocation.new(1, 4))
147
- cr3 = CodeRange.new(CodeLocation.new(2, 0), CodeLocation.new(2, 2))
148
- cr4 = CodeRange.new(CodeLocation.new(2, 3), CodeLocation.new(2, 5))
149
- cr1and2 = CodeRange.new(CodeLocation.new(1, 0), CodeLocation.new(1, 5))
150
- cr3and4 = CodeRange.new(CodeLocation.new(2, 0), CodeLocation.new(2, 5))
151
- [[cr1, "A"], [cr2, "B"], [cr3, "C"], [cr4, "D"], [cr1and2, "AB"], [cr3and4, "CD"]].permutation do |ary|
152
- tbl = CodeRangeTable.new
153
- ary.each do |cr, v|
154
- tbl[cr] = v
155
- end
156
- values = []
157
- [1, 2].each do |lineno|
158
- (0..5).each do |column|
159
- values << tbl[CodeLocation.new(lineno, column)]
160
- end
161
- end
162
- raise if values != ["A", "A", "B", "B", "AB", nil, "C", "C", "CD", "D", "D", nil]
163
- end
164
-
165
- source = <<~EOS
166
- AB
167
- CDE
168
- F
169
- EOS
170
- a_loc = CodeLocation.new(1, 0)
171
- b_loc = a_loc.advance_cursor(1, source)
172
- raise unless b_loc.inspect == "(1,1)"
173
- c_loc = a_loc.advance_cursor(3, source)
174
- raise unless c_loc.inspect == "(2,0)"
175
- f_loc = c_loc.advance_cursor(4, source)
176
- raise unless f_loc.inspect == "(3,0)"
177
- end
@@ -1,158 +0,0 @@
1
- require "rbconfig"
2
-
3
- module TypeProf
4
- ConfigData = Struct.new(
5
- :rb_files,
6
- :rbs_files,
7
- :output,
8
- :gem_rbs_features,
9
- :collection_path,
10
- :verbose,
11
- :dir_filter,
12
- :max_iter,
13
- :max_sec,
14
- :options,
15
- :lsp_options,
16
- :lsp,
17
- keyword_init: true
18
- )
19
-
20
- class TypeProfError < StandardError
21
- def report(output)
22
- output.puts "# Analysis Error"
23
- output.puts message
24
- end
25
- end
26
-
27
- class ConfigData
28
- def initialize(**opt)
29
- opt[:output] ||= $stdout
30
- opt[:gem_rbs_features] ||= []
31
- opt[:dir_filter] ||= DEFAULT_DIR_FILTER
32
- opt[:verbose] ||= 0
33
- opt[:options] ||= {}
34
- opt[:options] = {
35
- exclude_untyped: false,
36
- show_typeprof_version: true,
37
- show_indicator: true,
38
- show_untyped: false,
39
- show_errors: false,
40
- show_parameter_names: true,
41
- show_source_locations: false,
42
- stub_execution: true,
43
- type_depth_limit: 5,
44
- union_width_limit: 10,
45
- stackprof: nil,
46
- }.merge(opt[:options])
47
- opt[:lsp_options] = {
48
- port: 0,
49
- stdio: false,
50
- }.merge(opt[:lsp_options] || {})
51
- super(**opt)
52
- end
53
-
54
- def check_dir_filter(path)
55
- dir_filter.reverse_each do |cond, dir|
56
- return cond unless dir
57
- return cond if path.start_with?(dir)
58
- end
59
- end
60
-
61
- DEFAULT_DIR_FILTER = [
62
- [:include],
63
- [:exclude, RbConfig::CONFIG["prefix"]],
64
- [:exclude, Gem.dir],
65
- [:exclude, Gem.user_dir],
66
- ]
67
- end
68
-
69
- module Config
70
- def self.current
71
- Thread.current[:typeprof_config]
72
- end
73
-
74
- def self.set_current(config)
75
- Thread.current[:typeprof_config] = config
76
- end
77
- end
78
-
79
- def self.analyze(config, cancel_token = nil)
80
- # Deploy the config to the TypeProf::Config (Note: This is thread local)
81
- Config.set_current(config)
82
-
83
- if Config.current.options[:stackprof]
84
- require "stackprof"
85
- out = "typeprof-stackprof-#{ Config.current.options[:stackprof] }.dump"
86
- StackProf.start(mode: Config.current.options[:stackprof], out: out, raw: true)
87
- end
88
-
89
- scratch = Scratch.new
90
- Builtin.setup_initial_global_env(scratch)
91
-
92
- Config.current.gem_rbs_features.each do |feature|
93
- Import.import_library(scratch, feature)
94
- end
95
-
96
- rbs_files = []
97
- rbs_codes = []
98
- Config.current.rbs_files.each do |rbs|
99
- if rbs.is_a?(Array) # [String name, String content]
100
- rbs_codes << rbs
101
- else
102
- rbs_files << rbs
103
- end
104
- end
105
- Import.import_rbs_files(scratch, rbs_files)
106
- rbs_codes.each do |name, content|
107
- Import.import_rbs_code(scratch, name, content)
108
- end
109
-
110
- def_code_range_table = nil
111
- caller_code_range_table = nil
112
- Config.current.rb_files.each do |rb|
113
- if rb.is_a?(Array) # [String name, String content]
114
- iseq, def_tbl, caller_tbl = ISeq.compile_str(*rb.reverse)
115
- def_code_range_table ||= def_tbl
116
- caller_code_range_table ||= caller_tbl
117
- else
118
- iseq = rb
119
- end
120
- scratch.add_entrypoint(iseq)
121
- end
122
-
123
- result = scratch.type_profile(cancel_token)
124
-
125
- if Config.current.options[:lsp]
126
- return scratch.report_lsp, def_code_range_table, caller_code_range_table
127
- end
128
-
129
- if Config.current.output.respond_to?(:write)
130
- scratch.report(result, Config.current.output)
131
- else
132
- open(Config.current.output, "w") do |output|
133
- scratch.report(result, output)
134
- end
135
- end
136
-
137
- rescue TypeProfError => exc
138
- exc.report(Config.current.output)
139
-
140
- return nil
141
- ensure
142
- if Config.current.options[:stackprof] && defined?(StackProf)
143
- StackProf.stop
144
- StackProf.results
145
- end
146
- end
147
-
148
- def self.starting_state(iseq)
149
- cref = CRef.new(:bottom, Type::Builtin[:obj], false) # object
150
- recv = Type::Instance.new(Type::Builtin[:obj])
151
- ctx = Context.new(iseq, cref, nil)
152
- ep = ExecutionPoint.new(ctx, 0, nil)
153
- locals = [Type.nil] * iseq.locals.size
154
- env = Env.new(StaticEnv.new(recv, Type.nil, false, false), locals, [], Utils::HashWrapper.new({}))
155
-
156
- return ep, env
157
- end
158
- end