steep-relaxed 1.9.3.3

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 (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/.gitmodules +0 -0
  4. data/CHANGELOG.md +1032 -0
  5. data/LICENSE +21 -0
  6. data/README.md +260 -0
  7. data/Rakefile +227 -0
  8. data/STDGEM_DEPENDENCIES.txt +59 -0
  9. data/Steepfile +68 -0
  10. data/bin/console +14 -0
  11. data/bin/generate-diagnostics-docs.rb +112 -0
  12. data/bin/mem_graph.rb +67 -0
  13. data/bin/mem_prof.rb +102 -0
  14. data/bin/output_rebaseline.rb +34 -0
  15. data/bin/output_test.rb +60 -0
  16. data/bin/rbs +20 -0
  17. data/bin/rbs-inline +19 -0
  18. data/bin/setup +9 -0
  19. data/bin/stackprof_test.rb +19 -0
  20. data/bin/steep +19 -0
  21. data/bin/steep-check.rb +251 -0
  22. data/bin/steep-prof +16 -0
  23. data/doc/narrowing.md +195 -0
  24. data/doc/shape.md +194 -0
  25. data/exe/steep +18 -0
  26. data/guides/README.md +5 -0
  27. data/guides/src/gem-rbs-collection/gem-rbs-collection.md +126 -0
  28. data/guides/src/getting-started/getting-started.md +163 -0
  29. data/guides/src/nil-optional/nil-optional.md +195 -0
  30. data/lib/steep/annotation_parser.rb +199 -0
  31. data/lib/steep/ast/annotation/collection.rb +172 -0
  32. data/lib/steep/ast/annotation.rb +137 -0
  33. data/lib/steep/ast/builtin.rb +104 -0
  34. data/lib/steep/ast/ignore.rb +148 -0
  35. data/lib/steep/ast/node/type_application.rb +88 -0
  36. data/lib/steep/ast/node/type_assertion.rb +81 -0
  37. data/lib/steep/ast/types/any.rb +35 -0
  38. data/lib/steep/ast/types/boolean.rb +45 -0
  39. data/lib/steep/ast/types/bot.rb +35 -0
  40. data/lib/steep/ast/types/class.rb +43 -0
  41. data/lib/steep/ast/types/factory.rb +557 -0
  42. data/lib/steep/ast/types/helper.rb +40 -0
  43. data/lib/steep/ast/types/instance.rb +42 -0
  44. data/lib/steep/ast/types/intersection.rb +93 -0
  45. data/lib/steep/ast/types/literal.rb +59 -0
  46. data/lib/steep/ast/types/logic.rb +84 -0
  47. data/lib/steep/ast/types/name.rb +128 -0
  48. data/lib/steep/ast/types/nil.rb +41 -0
  49. data/lib/steep/ast/types/proc.rb +117 -0
  50. data/lib/steep/ast/types/record.rb +79 -0
  51. data/lib/steep/ast/types/self.rb +43 -0
  52. data/lib/steep/ast/types/shared_instance.rb +11 -0
  53. data/lib/steep/ast/types/top.rb +35 -0
  54. data/lib/steep/ast/types/tuple.rb +60 -0
  55. data/lib/steep/ast/types/union.rb +97 -0
  56. data/lib/steep/ast/types/var.rb +65 -0
  57. data/lib/steep/ast/types/void.rb +35 -0
  58. data/lib/steep/cli.rb +401 -0
  59. data/lib/steep/diagnostic/deprecated/else_on_exhaustive_case.rb +20 -0
  60. data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
  61. data/lib/steep/diagnostic/helper.rb +18 -0
  62. data/lib/steep/diagnostic/lsp_formatter.rb +78 -0
  63. data/lib/steep/diagnostic/result_printer2.rb +48 -0
  64. data/lib/steep/diagnostic/ruby.rb +1221 -0
  65. data/lib/steep/diagnostic/signature.rb +570 -0
  66. data/lib/steep/drivers/annotations.rb +52 -0
  67. data/lib/steep/drivers/check.rb +339 -0
  68. data/lib/steep/drivers/checkfile.rb +210 -0
  69. data/lib/steep/drivers/diagnostic_printer.rb +105 -0
  70. data/lib/steep/drivers/init.rb +66 -0
  71. data/lib/steep/drivers/langserver.rb +56 -0
  72. data/lib/steep/drivers/print_project.rb +113 -0
  73. data/lib/steep/drivers/stats.rb +203 -0
  74. data/lib/steep/drivers/utils/driver_helper.rb +143 -0
  75. data/lib/steep/drivers/utils/jobs_option.rb +26 -0
  76. data/lib/steep/drivers/vendor.rb +27 -0
  77. data/lib/steep/drivers/watch.rb +194 -0
  78. data/lib/steep/drivers/worker.rb +58 -0
  79. data/lib/steep/equatable.rb +23 -0
  80. data/lib/steep/expectations.rb +228 -0
  81. data/lib/steep/index/rbs_index.rb +350 -0
  82. data/lib/steep/index/signature_symbol_provider.rb +185 -0
  83. data/lib/steep/index/source_index.rb +167 -0
  84. data/lib/steep/interface/block.rb +103 -0
  85. data/lib/steep/interface/builder.rb +843 -0
  86. data/lib/steep/interface/function.rb +1090 -0
  87. data/lib/steep/interface/method_type.rb +330 -0
  88. data/lib/steep/interface/shape.rb +239 -0
  89. data/lib/steep/interface/substitution.rb +159 -0
  90. data/lib/steep/interface/type_param.rb +115 -0
  91. data/lib/steep/located_value.rb +20 -0
  92. data/lib/steep/method_name.rb +42 -0
  93. data/lib/steep/module_helper.rb +24 -0
  94. data/lib/steep/node_helper.rb +273 -0
  95. data/lib/steep/path_helper.rb +30 -0
  96. data/lib/steep/project/dsl.rb +268 -0
  97. data/lib/steep/project/group.rb +31 -0
  98. data/lib/steep/project/options.rb +63 -0
  99. data/lib/steep/project/pattern.rb +59 -0
  100. data/lib/steep/project/target.rb +92 -0
  101. data/lib/steep/project.rb +78 -0
  102. data/lib/steep/rake_task.rb +132 -0
  103. data/lib/steep/range_extension.rb +29 -0
  104. data/lib/steep/server/base_worker.rb +97 -0
  105. data/lib/steep/server/change_buffer.rb +73 -0
  106. data/lib/steep/server/custom_methods.rb +77 -0
  107. data/lib/steep/server/delay_queue.rb +45 -0
  108. data/lib/steep/server/interaction_worker.rb +492 -0
  109. data/lib/steep/server/lsp_formatter.rb +455 -0
  110. data/lib/steep/server/master.rb +922 -0
  111. data/lib/steep/server/target_group_files.rb +205 -0
  112. data/lib/steep/server/type_check_controller.rb +366 -0
  113. data/lib/steep/server/type_check_worker.rb +303 -0
  114. data/lib/steep/server/work_done_progress.rb +64 -0
  115. data/lib/steep/server/worker_process.rb +176 -0
  116. data/lib/steep/services/completion_provider.rb +802 -0
  117. data/lib/steep/services/content_change.rb +61 -0
  118. data/lib/steep/services/file_loader.rb +74 -0
  119. data/lib/steep/services/goto_service.rb +441 -0
  120. data/lib/steep/services/hover_provider/rbs.rb +88 -0
  121. data/lib/steep/services/hover_provider/ruby.rb +221 -0
  122. data/lib/steep/services/hover_provider/singleton_methods.rb +20 -0
  123. data/lib/steep/services/path_assignment.rb +46 -0
  124. data/lib/steep/services/signature_help_provider.rb +202 -0
  125. data/lib/steep/services/signature_service.rb +428 -0
  126. data/lib/steep/services/stats_calculator.rb +68 -0
  127. data/lib/steep/services/type_check_service.rb +394 -0
  128. data/lib/steep/services/type_name_completion.rb +236 -0
  129. data/lib/steep/signature/validator.rb +651 -0
  130. data/lib/steep/source/ignore_ranges.rb +69 -0
  131. data/lib/steep/source.rb +691 -0
  132. data/lib/steep/subtyping/cache.rb +30 -0
  133. data/lib/steep/subtyping/check.rb +1113 -0
  134. data/lib/steep/subtyping/constraints.rb +341 -0
  135. data/lib/steep/subtyping/relation.rb +101 -0
  136. data/lib/steep/subtyping/result.rb +324 -0
  137. data/lib/steep/subtyping/variable_variance.rb +89 -0
  138. data/lib/steep/test.rb +9 -0
  139. data/lib/steep/thread_waiter.rb +43 -0
  140. data/lib/steep/type_construction.rb +5183 -0
  141. data/lib/steep/type_inference/block_params.rb +416 -0
  142. data/lib/steep/type_inference/case_when.rb +303 -0
  143. data/lib/steep/type_inference/constant_env.rb +56 -0
  144. data/lib/steep/type_inference/context.rb +195 -0
  145. data/lib/steep/type_inference/logic_type_interpreter.rb +613 -0
  146. data/lib/steep/type_inference/method_call.rb +193 -0
  147. data/lib/steep/type_inference/method_params.rb +531 -0
  148. data/lib/steep/type_inference/multiple_assignment.rb +194 -0
  149. data/lib/steep/type_inference/send_args.rb +712 -0
  150. data/lib/steep/type_inference/type_env.rb +341 -0
  151. data/lib/steep/type_inference/type_env_builder.rb +138 -0
  152. data/lib/steep/typing.rb +321 -0
  153. data/lib/steep/version.rb +3 -0
  154. data/lib/steep.rb +369 -0
  155. data/manual/annotations.md +181 -0
  156. data/manual/ignore.md +20 -0
  157. data/manual/ruby-diagnostics.md +1879 -0
  158. data/sample/Steepfile +22 -0
  159. data/sample/lib/conference.rb +49 -0
  160. data/sample/lib/length.rb +35 -0
  161. data/sample/sig/conference.rbs +42 -0
  162. data/sample/sig/generics.rbs +15 -0
  163. data/sample/sig/length.rbs +34 -0
  164. data/steep-relaxed.gemspec +56 -0
  165. metadata +340 -0
@@ -0,0 +1,60 @@
1
+ module Steep
2
+ module AST
3
+ module Types
4
+ class Tuple
5
+ attr_reader :types
6
+
7
+ def initialize(types:)
8
+ @types = types
9
+ end
10
+
11
+ def ==(other)
12
+ other.is_a?(Tuple) &&
13
+ other.types == types
14
+ end
15
+
16
+ def hash
17
+ self.class.hash ^ types.hash
18
+ end
19
+
20
+ alias eql? ==
21
+
22
+ def subst(s)
23
+ self.class.new(types: types.map {|ty| ty.subst(s) })
24
+ end
25
+
26
+ def to_s
27
+ "[#{types.join(", ")}]"
28
+ end
29
+
30
+ def free_variables()
31
+ @fvs ||= each_child.with_object(Set[]) do |type, set| #$ Set[variable]
32
+ set.merge(type.free_variables)
33
+ end
34
+ end
35
+
36
+ include Helper::ChildrenLevel
37
+
38
+ def each_child(&block)
39
+ if block
40
+ types.each(&block)
41
+ else
42
+ types.each
43
+ end
44
+ end
45
+
46
+ def map_type(&block)
47
+ Tuple.new(types: types.map(&block))
48
+ end
49
+
50
+ def level
51
+ [0] + level_of_children(types)
52
+ end
53
+
54
+ def with_location(new_location)
55
+ self.class.new(types: types)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,97 @@
1
+ module Steep
2
+ module AST
3
+ module Types
4
+ class Union
5
+ attr_reader :types
6
+
7
+ def initialize(types:)
8
+ @types = types
9
+ end
10
+
11
+ def self.build(types:)
12
+ return AST::Types::Bot.instance if types.empty?
13
+ if types.size == 1
14
+ return types.first || raise
15
+ end
16
+
17
+ types.flat_map do |type|
18
+ if type.is_a?(Union)
19
+ type.types
20
+ else
21
+ [type]
22
+ end
23
+ end.map do |type|
24
+ case type
25
+ when AST::Types::Any
26
+ return AST::Types::Any.instance()
27
+ when AST::Types::Top
28
+ return AST::Types::Top.instance
29
+ when AST::Types::Bot
30
+ nil
31
+ else
32
+ type
33
+ end
34
+ end.compact.uniq.yield_self do |tys|
35
+ case tys.size
36
+ when 0
37
+ AST::Types::Bot.instance
38
+ when 1
39
+ tys.first || raise
40
+ else
41
+ new(types: tys)
42
+ end
43
+ end
44
+ end
45
+
46
+ def ==(other)
47
+ other.is_a?(Union) &&
48
+ Set.new(other.types) == Set.new(types)
49
+ end
50
+
51
+ def hash
52
+ @hash ||= types.inject(self.class.hash) {|c, type| type.hash ^ c } #$ Integer
53
+ end
54
+
55
+ alias eql? ==
56
+
57
+ def subst(s)
58
+ self.class.build(types: types.map {|ty| ty.subst(s) })
59
+ end
60
+
61
+ def to_s
62
+ "(#{types.map(&:to_s).join(" | ")})"
63
+ end
64
+
65
+ def free_variables
66
+ @fvs ||= Set.new.tap do |set|
67
+ types.each do |type|
68
+ set.merge(type.free_variables)
69
+ end
70
+ end
71
+ end
72
+
73
+ def each_child(&block)
74
+ if block
75
+ types.each(&block)
76
+ else
77
+ types.each
78
+ end
79
+ end
80
+
81
+ def map_type(&block)
82
+ Union.build(types: types.map(&block))
83
+ end
84
+
85
+ include Helper::ChildrenLevel
86
+
87
+ def level
88
+ [0] + level_of_children(types)
89
+ end
90
+
91
+ def with_location(new_location)
92
+ self.class.new(types: types)
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,65 @@
1
+ module Steep
2
+ module AST
3
+ module Types
4
+ class Var
5
+ attr_reader :name
6
+
7
+ def initialize(name:)
8
+ @name = name
9
+ end
10
+
11
+ def ==(other)
12
+ other.is_a?(Var) &&
13
+ other.name == name
14
+ end
15
+
16
+ def hash
17
+ self.class.hash ^ name.hash
18
+ end
19
+
20
+ alias eql? ==
21
+
22
+ def self.fresh_name(name)
23
+ @mutex ||= Thread::Mutex.new
24
+
25
+ @mutex.synchronize do
26
+ @max ||= 0
27
+ @max += 1
28
+
29
+ :"#{name}(#{@max})"
30
+ end
31
+ end
32
+
33
+ def self.fresh(name, location: nil)
34
+ new(name: fresh_name(name))
35
+ end
36
+
37
+ def to_s
38
+ name.to_s
39
+ end
40
+
41
+ def subst(s)
42
+ if s.key?(name)
43
+ s[name]
44
+ else
45
+ self
46
+ end
47
+ end
48
+
49
+ def free_variables()
50
+ @fvs ||= Set.new([name])
51
+ end
52
+
53
+ include Helper::NoChild
54
+
55
+ def level
56
+ [0]
57
+ end
58
+
59
+ def update(name: self.name)
60
+ self.class.new(name: name)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,35 @@
1
+ module Steep
2
+ module AST
3
+ module Types
4
+ class Void
5
+ extend SharedInstance
6
+
7
+ def ==(other)
8
+ other.is_a?(Void)
9
+ end
10
+
11
+ def hash
12
+ self.class.hash
13
+ end
14
+
15
+ alias eql? ==
16
+
17
+ def subst(s)
18
+ self
19
+ end
20
+
21
+ def to_s
22
+ "void"
23
+ end
24
+
25
+ include Helper::NoFreeVariables
26
+
27
+ include Helper::NoChild
28
+
29
+ def level
30
+ [0]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
data/lib/steep/cli.rb ADDED
@@ -0,0 +1,401 @@
1
+ require 'optparse'
2
+
3
+ module Steep
4
+ class CLI
5
+ attr_reader :argv
6
+ attr_reader :stdout
7
+ attr_reader :stdin
8
+ attr_reader :stderr
9
+ attr_reader :command
10
+
11
+ def initialize(stdout:, stdin:, stderr:, argv:)
12
+ @stdout = stdout
13
+ @stdin = stdin
14
+ @stderr = stderr
15
+ @argv = argv
16
+ end
17
+
18
+ def self.available_commands
19
+ [:init, :check, :validate, :annotations, :version, :project, :watch, :langserver, :stats, :binstub, :checkfile]
20
+ end
21
+
22
+ def process_global_options
23
+ OptionParser.new do |opts|
24
+ opts.banner = <<~USAGE
25
+ Usage: steep [options]
26
+
27
+ available commands: #{CLI.available_commands.join(', ')}
28
+
29
+ Options:
30
+ USAGE
31
+
32
+ opts.on("--version") do
33
+ process_version
34
+ exit 0
35
+ end
36
+
37
+ handle_logging_options(opts)
38
+ end.order!(argv)
39
+
40
+ true
41
+ end
42
+
43
+ def setup_command
44
+ return false unless command = argv.shift&.to_sym
45
+ @command = command
46
+
47
+ if CLI.available_commands.include?(@command) || @command == :worker || @command == :vendor
48
+ true
49
+ else
50
+ stderr.puts "Unknown command: #{command}"
51
+ stderr.puts " available commands: #{CLI.available_commands.join(', ')}"
52
+ false
53
+ end
54
+ end
55
+
56
+ def run
57
+ process_global_options or return 1
58
+ setup_command or return 1
59
+
60
+ __send__(:"process_#{command}")
61
+ end
62
+
63
+ def handle_logging_options(opts)
64
+ opts.on("--log-level=LEVEL", "Specify log level: debug, info, warn, error, fatal") do |level|
65
+ Steep.logger.level = level
66
+ Steep.ui_logger.level = level
67
+ end
68
+
69
+ opts.on("--log-output=PATH", "Print logs to given path") do |file|
70
+ Steep.log_output = file
71
+ end
72
+
73
+ opts.on("--verbose", "Set log level to debug") do
74
+ Steep.logger.level = Logger::DEBUG
75
+ Steep.ui_logger.level = Logger::DEBUG
76
+ end
77
+ end
78
+
79
+ def handle_jobs_option(option, opts)
80
+ opts.on("-j N", "--jobs=N", "Specify the number of type check workers (defaults: #{option.default_jobs_count})") do |count|
81
+ option.jobs_count = Integer(count) if Integer(count) > 0
82
+ end
83
+
84
+ opts.on("--steep-command=COMMAND", "Specify command to exec Steep CLI for worker (defaults: steep)") do |cmd|
85
+ option.steep_command = cmd
86
+ end
87
+ end
88
+
89
+ def setup_jobs_for_ci(jobs_option)
90
+ if ENV["CI"]
91
+ unless jobs_option.jobs_count
92
+ stderr.puts Rainbow("CI environment is detected but no `--jobs` option is given.").yellow
93
+ stderr.puts " Using `[2, #{jobs_option.default_jobs_count} (# or processors)].min` to avoid hitting memory limit."
94
+ stderr.puts " Specify `--jobs` option to increase the number of jobs."
95
+
96
+ jobs_option.jobs_count = [2, jobs_option.default_jobs_count].min
97
+ end
98
+ end
99
+ end
100
+
101
+ def process_init
102
+ Drivers::Init.new(stdout: stdout, stderr: stderr).tap do |command|
103
+ OptionParser.new do |opts|
104
+ opts.banner = "Usage: steep init [options]"
105
+
106
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
107
+ opts.on("--force") { command.force_write = true }
108
+
109
+ handle_logging_options opts
110
+ end.parse!(argv)
111
+ end.run()
112
+ end
113
+
114
+ def process_check
115
+ Drivers::Check.new(stdout: stdout, stderr: stderr).tap do |command|
116
+ OptionParser.new do |opts|
117
+ opts.banner = "Usage: steep check [options] [sources]"
118
+
119
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
120
+ opts.on("--with-expectations[=PATH]", "Type check with expectations saved in PATH (or steep_expectations.yml)") do |path|
121
+ command.with_expectations_path = Pathname(path || "steep_expectations.yml")
122
+ end
123
+ opts.on("--save-expectations[=PATH]", "Save expectations with current type check result to PATH (or steep_expectations.yml)") do |path|
124
+ command.save_expectations_path = Pathname(path || "steep_expectations.yml")
125
+ end
126
+ opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
127
+ command.severity_level = level.to_sym
128
+ end
129
+
130
+ opts.on("--group=GROUP", "Specify target/group name to type check") do |arg|
131
+ # @type var arg: String
132
+ target, group = arg.split(".")
133
+ target or raise
134
+ case group
135
+ when "*"
136
+ command.active_group_names << [target.to_sym, true]
137
+ when nil
138
+ command.active_group_names << [target.to_sym, nil]
139
+ else
140
+ command.active_group_names << [target.to_sym, group.to_sym]
141
+ end
142
+ end
143
+
144
+ opts.on("--[no-]type-check", "Type check Ruby code") do |v|
145
+ command.type_check_code = v ? true : false
146
+ end
147
+
148
+ opts.on("--validate=OPTION", ["skip", "group", "project", "library"], "Validation levels of signatures (default: group, options: skip,group,project,library)") do |level|
149
+ case level
150
+ when "skip"
151
+ command.validate_group_signatures = false
152
+ command.validate_project_signatures = false
153
+ command.validate_library_signatures = false
154
+ when "group"
155
+ command.validate_group_signatures = true
156
+ command.validate_project_signatures = false
157
+ command.validate_library_signatures = false
158
+ when "project"
159
+ command.validate_group_signatures = true
160
+ command.validate_project_signatures = true
161
+ command.validate_library_signatures = false
162
+ when "library"
163
+ command.validate_group_signatures = true
164
+ command.validate_project_signatures = true
165
+ command.validate_library_signatures = true
166
+ end
167
+ end
168
+
169
+ handle_jobs_option command.jobs_option, opts
170
+ handle_logging_options opts
171
+ end.parse!(argv)
172
+
173
+ setup_jobs_for_ci(command.jobs_option)
174
+
175
+ command.command_line_patterns.push *argv
176
+ end.run
177
+ end
178
+
179
+ def process_checkfile
180
+ Drivers::Checkfile.new(stdout: stdout, stderr: stderr).tap do |command|
181
+ OptionParser.new do |opts|
182
+ opts.banner = "Usage: steep checkfile [options] [files]"
183
+
184
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
185
+ opts.on("--all-rbs", "Type check all RBS files") { command.all_rbs = true }
186
+ opts.on("--all-ruby", "Type check all Ruby files") { command.all_ruby = true }
187
+ opts.on("--stdin", "Read files to type check from stdin") do
188
+ while line = stdin.gets()
189
+ object = JSON.parse(line, symbolize_names: true)
190
+ Steep.logger.info { "Loading content of `#{object[:path]}` from stdin: #{object[:content].lines[0].chomp}" }
191
+ command.stdin_input[Pathname(object[:path])] = object[:content]
192
+ end
193
+ end
194
+ handle_jobs_option command.jobs_option, opts
195
+ handle_logging_options opts
196
+ end.parse!(argv)
197
+
198
+ setup_jobs_for_ci(command.jobs_option)
199
+
200
+ command.command_line_args.push *argv
201
+ end.run
202
+ end
203
+
204
+ def process_stats
205
+ Drivers::Stats.new(stdout: stdout, stderr: stderr).tap do |command|
206
+ OptionParser.new do |opts|
207
+ opts.banner = "Usage: steep stats [options] [sources]"
208
+
209
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
210
+ opts.on("--format=FORMAT", "Specify output format: csv, table") {|format| command.format = format }
211
+ handle_jobs_option command.jobs_option, opts
212
+ handle_logging_options opts
213
+ end.parse!(argv)
214
+
215
+ setup_jobs_for_ci(command.jobs_option)
216
+
217
+ command.command_line_patterns.push *argv
218
+ end.run
219
+ end
220
+
221
+ def process_validate
222
+ stderr.puts "`steep validate` is deprecated. Use `steep check` with `--validate` option instead."
223
+ 1
224
+ end
225
+
226
+ def process_annotations
227
+ Drivers::Annotations.new(stdout: stdout, stderr: stderr).tap do |command|
228
+ OptionParser.new do |opts|
229
+ opts.banner = "Usage: steep annotations [options] [sources]"
230
+ handle_logging_options opts
231
+ end.parse!(argv)
232
+
233
+ command.command_line_patterns.push *argv
234
+ end.run
235
+ end
236
+
237
+ def process_project
238
+ Drivers::PrintProject.new(stdout: stdout, stderr: stderr).tap do |command|
239
+ OptionParser.new do |opts|
240
+ opts.banner = "Usage: steep project [options]"
241
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
242
+ opts.on("--[no-]print-files", "Print files") {|v|
243
+ command.print_files = v ? true : false
244
+ }
245
+ handle_logging_options opts
246
+ end.parse!(argv)
247
+ end.run
248
+ end
249
+
250
+ def process_watch
251
+ Drivers::Watch.new(stdout: stdout, stderr: stderr).tap do |command|
252
+ OptionParser.new do |opts|
253
+ opts.banner = "Usage: steep watch [options] [dirs]"
254
+ opts.on("--severity-level=LEVEL", /^error|warning|information|hint$/, "Specify the minimum diagnostic severity to be recognized as an error (defaults: warning): error, warning, information, or hint") do |level|
255
+ # @type var level: String
256
+ command.severity_level = _ = level.to_sym
257
+ end
258
+ handle_jobs_option command.jobs_option, opts
259
+ handle_logging_options opts
260
+ end.parse!(argv)
261
+
262
+ setup_jobs_for_ci(command.jobs_option)
263
+
264
+ dirs = argv.map {|dir| Pathname(dir) }
265
+ command.dirs.push(*dirs)
266
+ end.run
267
+ end
268
+
269
+ def process_langserver
270
+ Drivers::Langserver.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
271
+ OptionParser.new do |opts|
272
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
273
+ handle_jobs_option command.jobs_option, opts
274
+ handle_logging_options opts
275
+ end.parse!(argv)
276
+ end.run
277
+ end
278
+
279
+ def process_vendor
280
+ Drivers::Vendor.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
281
+ OptionParser.new do |opts|
282
+ opts.banner = "Usage: steep vendor [options] [dir]"
283
+ handle_logging_options opts
284
+
285
+ opts.on("--[no-]clean") do |v|
286
+ command.clean_before = v
287
+ end
288
+ end.parse!(argv)
289
+
290
+ command.vendor_dir = Pathname(argv[0] || "vendor/sigs")
291
+ end.run
292
+ end
293
+
294
+ def process_binstub
295
+ path = Pathname("bin/steep")
296
+ root_path = Pathname.pwd
297
+ force = false
298
+
299
+ OptionParser.new do |opts|
300
+ opts.banner = <<BANNER
301
+ Usage: steep binstub [options]
302
+
303
+ Generate a binstub to execute Steep with setting up Bundler and rbenv/rvm.
304
+ Use the executable for LSP integration setup.
305
+
306
+ Options:
307
+ BANNER
308
+ handle_logging_options opts
309
+
310
+ opts.on("-o PATH", "--output=PATH", "The path of the executable file (defaults to `bin/steep`)") do |v|
311
+ path = Pathname(v)
312
+ end
313
+
314
+ opts.on("--root=PATH", "The repository root path (defaults to `.`)") do |v|
315
+ root_path = (Pathname.pwd + v).cleanpath
316
+ end
317
+
318
+ opts.on("--[no-]force", "Overwrite file (defaults to false)") do
319
+ force = true
320
+ end
321
+ end.parse!(argv)
322
+
323
+ binstub_path = (Pathname.pwd + path).cleanpath
324
+ bindir_path = binstub_path.parent
325
+
326
+ bindir_path.mkpath
327
+
328
+ gemfile_path =
329
+ if defined?(Bundler)
330
+ Bundler.default_gemfile.relative_path_from(bindir_path)
331
+ else
332
+ Pathname("../Gemfile")
333
+ end
334
+
335
+ if binstub_path.file?
336
+ if force
337
+ stdout.puts Rainbow("#{path} already exists. Overwriting...").yellow
338
+ else
339
+ stdout.puts Rainbow(''"⚠️ #{path} already exists. Bye! 👋").red
340
+ return 0
341
+ end
342
+ end
343
+
344
+ template = <<TEMPLATE
345
+ #!/usr/bin/env bash
346
+
347
+ BINSTUB_DIR=$(cd $(dirname $0); pwd)
348
+ GEMFILE=$(readlink -f ${BINSTUB_DIR}/#{gemfile_path})
349
+ ROOT_DIR=$(readlink -f ${BINSTUB_DIR}/#{root_path.relative_path_from(bindir_path)})
350
+
351
+ STEEP="bundle exec --gemfile=${GEMFILE} steep"
352
+
353
+ if type "rbenv" > /dev/null 2>&1; then
354
+ STEEP="rbenv exec ${STEEP}"
355
+ else
356
+ if type "rvm" > /dev/null 2>&1; then
357
+ if [ -e ${ROOT_DIR}/.ruby-version ]; then
358
+ STEEP="rvm ${ROOT_DIR} do ${STEEP}"
359
+ fi
360
+ fi
361
+ fi
362
+
363
+ exec $STEEP $@
364
+ TEMPLATE
365
+
366
+ binstub_path.write(template)
367
+ binstub_path.chmod(0755)
368
+
369
+ stdout.puts Rainbow("Successfully generated executable #{path} 🎉").blue
370
+
371
+ 0
372
+ end
373
+
374
+ def process_version
375
+ stdout.puts Steep::VERSION
376
+ 0
377
+ end
378
+
379
+ def process_worker
380
+ Drivers::Worker.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
381
+ OptionParser.new do |opts|
382
+ opts.banner = "Usage: steep worker [options] [dir]"
383
+ handle_logging_options opts
384
+
385
+ opts.on("--interaction") { command.worker_type = :interaction }
386
+ opts.on("--typecheck") { command.worker_type = :typecheck }
387
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
388
+ opts.on("--name=NAME") {|name| command.worker_name = name }
389
+ opts.on("--delay-shutdown") { command.delay_shutdown = true }
390
+ opts.on("--max-index=COUNT") {|count| command.max_index = Integer(count) }
391
+ opts.on("--index=INDEX") {|index| command.index = Integer(index) }
392
+ end.parse!(argv)
393
+
394
+ # Disable any `ui_logger` output in workers
395
+ Steep.ui_logger.level = :fatal
396
+
397
+ command.commandline_args.push(*argv)
398
+ end.run
399
+ end
400
+ end
401
+ end
@@ -0,0 +1,20 @@
1
+ Steep.logger.error "Diagnostic `Ruby::ElseOnExhaustiveCase` is deprecated. Use `Ruby::UnreachableBranch` instead."
2
+
3
+ module Steep
4
+ module Diagnostic
5
+ module Ruby
6
+ class ElseOnExhaustiveCase < Base
7
+ attr_reader :type
8
+
9
+ def initialize(node:, type:)
10
+ super(node: node)
11
+ @type = type
12
+ end
13
+
14
+ def header_line
15
+ "The branch is unreachable because the condition is exhaustive"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ Steep.logger.error "Diagnostic `Ruby::UnknownConstantAssigned` is deprecated. Use `Ruby::UnknownConstant` instead."
2
+
3
+ module Steep
4
+ module Diagnostic
5
+ module Ruby
6
+ class UnknownConstantAssigned < Base
7
+ attr_reader :context
8
+ attr_reader :name
9
+
10
+ def initialize(node:, context:, name:)
11
+ const = node.children[0]
12
+ loc = if const
13
+ const.loc.expression.join(node.loc.name)
14
+ else
15
+ node.loc.name
16
+ end
17
+ super(node: node, location: loc)
18
+ @context = context
19
+ @name = name
20
+ end
21
+
22
+ def header_line
23
+ "Cannot find the declaration of constant `#{name}`"
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end