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
@@ -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