steep 0.14.0 → 0.16.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (211) hide show
  1. checksums.yaml +4 -4
  2. data/.gitmodules +0 -3
  3. data/CHANGELOG.md +25 -0
  4. data/Rakefile +0 -13
  5. data/bin/setup +0 -2
  6. data/bin/smoke_runner.rb +0 -1
  7. data/exe/steep +0 -1
  8. data/lib/steep.rb +18 -2
  9. data/lib/steep/annotation_parser.rb +4 -4
  10. data/lib/steep/ast/buffer.rb +11 -7
  11. data/lib/steep/ast/builtin.rb +8 -0
  12. data/lib/steep/ast/types/factory.rb +55 -55
  13. data/lib/steep/cli.rb +16 -1
  14. data/lib/steep/drivers/annotations.rb +1 -1
  15. data/lib/steep/drivers/check.rb +20 -4
  16. data/lib/steep/drivers/langserver.rb +13 -457
  17. data/lib/steep/drivers/utils/driver_helper.rb +1 -1
  18. data/lib/steep/drivers/vendor.rb +2 -2
  19. data/lib/steep/drivers/watch.rb +97 -85
  20. data/lib/steep/drivers/worker.rb +51 -0
  21. data/lib/steep/project.rb +9 -5
  22. data/lib/steep/project/completion_provider.rb +9 -13
  23. data/lib/steep/project/dsl.rb +14 -0
  24. data/lib/steep/project/file.rb +43 -46
  25. data/lib/steep/project/hover_content.rb +17 -8
  26. data/lib/steep/project/options.rb +25 -3
  27. data/lib/steep/project/target.rb +40 -24
  28. data/lib/steep/server/base_worker.rb +56 -0
  29. data/lib/steep/server/code_worker.rb +151 -0
  30. data/lib/steep/server/interaction_worker.rb +281 -0
  31. data/lib/steep/server/master.rb +196 -0
  32. data/lib/steep/server/signature_worker.rb +148 -0
  33. data/lib/steep/server/utils.rb +36 -0
  34. data/lib/steep/server/worker_process.rb +62 -0
  35. data/lib/steep/signature/errors.rb +1 -1
  36. data/lib/steep/signature/validator.rb +13 -13
  37. data/lib/steep/source.rb +1 -1
  38. data/lib/steep/type_construction.rb +996 -726
  39. data/lib/steep/type_inference/constant_env.rb +3 -11
  40. data/lib/steep/type_inference/context.rb +8 -3
  41. data/lib/steep/type_inference/context_array.rb +111 -0
  42. data/lib/steep/type_inference/local_variable_type_env.rb +226 -0
  43. data/lib/steep/type_inference/logic.rb +130 -0
  44. data/lib/steep/type_inference/type_env.rb +5 -69
  45. data/lib/steep/typing.rb +79 -22
  46. data/lib/steep/version.rb +1 -1
  47. data/smoke/alias/Steepfile +1 -0
  48. data/smoke/and/Steepfile +1 -0
  49. data/smoke/array/Steepfile +1 -0
  50. data/smoke/array/b.rb +0 -2
  51. data/smoke/block/Steepfile +1 -0
  52. data/smoke/case/Steepfile +1 -0
  53. data/smoke/class/Steepfile +1 -0
  54. data/smoke/const/Steepfile +1 -0
  55. data/smoke/dstr/Steepfile +1 -0
  56. data/smoke/ensure/Steepfile +1 -0
  57. data/smoke/enumerator/Steepfile +1 -0
  58. data/smoke/extension/Steepfile +1 -0
  59. data/smoke/extension/c.rb +1 -0
  60. data/smoke/hash/Steepfile +1 -0
  61. data/smoke/hello/Steepfile +1 -0
  62. data/smoke/if/Steepfile +1 -0
  63. data/smoke/if/a.rb +1 -1
  64. data/smoke/implements/Steepfile +1 -0
  65. data/smoke/initialize/Steepfile +1 -0
  66. data/smoke/integer/Steepfile +1 -0
  67. data/smoke/interface/Steepfile +1 -0
  68. data/smoke/kwbegin/Steepfile +1 -0
  69. data/smoke/lambda/Steepfile +1 -0
  70. data/smoke/literal/Steepfile +1 -0
  71. data/smoke/map/Steepfile +1 -0
  72. data/smoke/method/Steepfile +1 -0
  73. data/smoke/module/Steepfile +1 -0
  74. data/smoke/regexp/Steepfile +1 -0
  75. data/smoke/regression/Steepfile +1 -0
  76. data/smoke/rescue/Steepfile +1 -0
  77. data/smoke/rescue/a.rb +1 -1
  78. data/smoke/self/Steepfile +1 -0
  79. data/smoke/skip/Steepfile +1 -0
  80. data/smoke/stdout/Steepfile +1 -0
  81. data/smoke/super/Steepfile +1 -0
  82. data/smoke/type_case/Steepfile +1 -0
  83. data/smoke/yield/Steepfile +1 -0
  84. data/steep.gemspec +7 -8
  85. metadata +26 -141
  86. data/exe/rbs +0 -3
  87. data/exe/ruby-signature +0 -3
  88. data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
  89. data/vendor/ruby-signature/.gitignore +0 -12
  90. data/vendor/ruby-signature/.rubocop.yml +0 -15
  91. data/vendor/ruby-signature/BSDL +0 -22
  92. data/vendor/ruby-signature/COPYING +0 -56
  93. data/vendor/ruby-signature/Gemfile +0 -6
  94. data/vendor/ruby-signature/README.md +0 -93
  95. data/vendor/ruby-signature/Rakefile +0 -67
  96. data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -156
  97. data/vendor/ruby-signature/bin/console +0 -14
  98. data/vendor/ruby-signature/bin/query-rdoc +0 -103
  99. data/vendor/ruby-signature/bin/setup +0 -10
  100. data/vendor/ruby-signature/bin/sort +0 -88
  101. data/vendor/ruby-signature/bin/test_runner.rb +0 -17
  102. data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
  103. data/vendor/ruby-signature/docs/sigs.md +0 -148
  104. data/vendor/ruby-signature/docs/stdlib.md +0 -152
  105. data/vendor/ruby-signature/docs/syntax.md +0 -528
  106. data/vendor/ruby-signature/exe/rbs +0 -3
  107. data/vendor/ruby-signature/exe/ruby-signature +0 -7
  108. data/vendor/ruby-signature/lib/ruby/signature.rb +0 -64
  109. data/vendor/ruby-signature/lib/ruby/signature/ast/annotation.rb +0 -29
  110. data/vendor/ruby-signature/lib/ruby/signature/ast/comment.rb +0 -29
  111. data/vendor/ruby-signature/lib/ruby/signature/ast/declarations.rb +0 -391
  112. data/vendor/ruby-signature/lib/ruby/signature/ast/members.rb +0 -364
  113. data/vendor/ruby-signature/lib/ruby/signature/buffer.rb +0 -52
  114. data/vendor/ruby-signature/lib/ruby/signature/builtin_names.rb +0 -54
  115. data/vendor/ruby-signature/lib/ruby/signature/cli.rb +0 -555
  116. data/vendor/ruby-signature/lib/ruby/signature/constant.rb +0 -28
  117. data/vendor/ruby-signature/lib/ruby/signature/constant_table.rb +0 -152
  118. data/vendor/ruby-signature/lib/ruby/signature/definition.rb +0 -172
  119. data/vendor/ruby-signature/lib/ruby/signature/definition_builder.rb +0 -921
  120. data/vendor/ruby-signature/lib/ruby/signature/environment.rb +0 -283
  121. data/vendor/ruby-signature/lib/ruby/signature/environment_loader.rb +0 -138
  122. data/vendor/ruby-signature/lib/ruby/signature/environment_walker.rb +0 -126
  123. data/vendor/ruby-signature/lib/ruby/signature/errors.rb +0 -189
  124. data/vendor/ruby-signature/lib/ruby/signature/location.rb +0 -104
  125. data/vendor/ruby-signature/lib/ruby/signature/method_type.rb +0 -125
  126. data/vendor/ruby-signature/lib/ruby/signature/namespace.rb +0 -93
  127. data/vendor/ruby-signature/lib/ruby/signature/parser.y +0 -1344
  128. data/vendor/ruby-signature/lib/ruby/signature/prototype/rb.rb +0 -444
  129. data/vendor/ruby-signature/lib/ruby/signature/prototype/rbi.rb +0 -579
  130. data/vendor/ruby-signature/lib/ruby/signature/prototype/runtime.rb +0 -383
  131. data/vendor/ruby-signature/lib/ruby/signature/substitution.rb +0 -48
  132. data/vendor/ruby-signature/lib/ruby/signature/test.rb +0 -28
  133. data/vendor/ruby-signature/lib/ruby/signature/test/errors.rb +0 -63
  134. data/vendor/ruby-signature/lib/ruby/signature/test/hook.rb +0 -290
  135. data/vendor/ruby-signature/lib/ruby/signature/test/setup.rb +0 -58
  136. data/vendor/ruby-signature/lib/ruby/signature/test/spy.rb +0 -327
  137. data/vendor/ruby-signature/lib/ruby/signature/test/test_helper.rb +0 -185
  138. data/vendor/ruby-signature/lib/ruby/signature/test/type_check.rb +0 -256
  139. data/vendor/ruby-signature/lib/ruby/signature/type_name.rb +0 -72
  140. data/vendor/ruby-signature/lib/ruby/signature/types.rb +0 -932
  141. data/vendor/ruby-signature/lib/ruby/signature/variance_calculator.rb +0 -140
  142. data/vendor/ruby-signature/lib/ruby/signature/vendorer.rb +0 -49
  143. data/vendor/ruby-signature/lib/ruby/signature/version.rb +0 -5
  144. data/vendor/ruby-signature/lib/ruby/signature/writer.rb +0 -271
  145. data/vendor/ruby-signature/ruby-signature.gemspec +0 -45
  146. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -3
  147. data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -15
  148. data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
  149. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
  150. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
  151. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -35
  152. data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
  153. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
  154. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
  155. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
  156. data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
  157. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
  158. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -419
  159. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -606
  160. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
  161. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
  162. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
  163. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
  164. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -193
  165. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
  166. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
  167. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
  168. data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -476
  169. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
  170. data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
  171. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -121
  172. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
  173. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -710
  174. data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
  175. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -574
  176. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -135
  177. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -271
  178. data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -66
  179. data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -182
  180. data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -248
  181. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
  182. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
  183. data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
  184. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -426
  185. data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -354
  186. data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -93
  187. data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
  188. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
  189. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -10
  190. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -1083
  191. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
  192. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
  193. data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -1894
  194. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -13
  195. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
  196. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -230
  197. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1112
  198. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
  199. data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -739
  200. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -91
  201. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
  202. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -159
  203. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
  204. data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -18
  205. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -44
  206. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -21
  207. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
  208. data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
  209. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
  210. data/vendor/ruby-signature/stdlib/set/set.rbs +0 -77
  211. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
@@ -8,7 +8,7 @@ module Steep
8
8
  raise "Cannot find a configuration at #{path}: `steep init` to scaffold" unless path.file?
9
9
 
10
10
  steep_file_path = path.absolute? ? path : Pathname.pwd + path
11
- Project.new(base_dir: steep_file_path.parent).tap do |project|
11
+ Project.new(steepfile_path: steep_file_path).tap do |project|
12
12
  Project::DSL.parse(project, path.read, filename: path.to_s)
13
13
  end
14
14
  end
@@ -20,7 +20,7 @@ module Steep
20
20
  def run
21
21
  stdout.puts "Vendoring into #{vendor_dir}..."
22
22
 
23
- vendorer = Ruby::Signature::Vendorer.new(vendor_dir: vendor_dir)
23
+ vendorer = RBS::Vendorer.new(vendor_dir: vendor_dir)
24
24
 
25
25
  if clean_before
26
26
  stdout.puts " Cleaning directory..."
@@ -32,7 +32,7 @@ module Steep
32
32
 
33
33
  if defined?(Bundler)
34
34
  Bundler.locked_gems.specs.each do |spec|
35
- if Ruby::Signature::EnvironmentLoader.gem_sig_path(spec.name, spec.version.to_s).directory?
35
+ if RBS::EnvironmentLoader.gem_sig_path(spec.name, spec.version.to_s).directory?
36
36
  stdout.puts " Vendoring rubygem: #{spec.full_name}..."
37
37
  vendorer.gem! spec.name, spec.version.to_s
38
38
  end
@@ -15,110 +15,122 @@ module Steep
15
15
  @queue = Thread::Queue.new
16
16
  end
17
17
 
18
- def listener
19
- @listener ||= begin
20
- Steep.logger.info "Watching #{dirs.join(", ")}..."
21
- Listen.to(*dirs.map(&:to_s)) do |modified, added, removed|
22
- Steep.logger.tagged "watch" do
23
- Steep.logger.info "Received file system updates: modified=[#{modified.join(",")}], added=[#{added.join(",")}], removed=[#{removed.join(",")}]"
24
- end
25
- queue << [modified, added, removed]
26
- end
18
+ def run()
19
+ if dirs.empty?
20
+ stdout.puts "Specify directories to watch"
21
+ return 1
27
22
  end
28
- end
29
23
 
30
- def type_check_loop(project)
31
- until queue.closed?
32
- stdout.puts "🚥 Waiting for updates..."
24
+ project = load_config()
33
25
 
34
- events = []
35
- events << queue.deq
36
- until queue.empty?
37
- events << queue.deq(nonblock: true)
38
- end
26
+ loader = Project::FileLoader.new(project: project)
27
+ loader.load_sources(dirs)
28
+ loader.load_signatures()
39
29
 
40
- events.compact.each do |modified, added, removed|
41
- modified.each do |name|
42
- path = Pathname(name).relative_path_from(Pathname.pwd)
30
+ client_read, server_write = IO.pipe
31
+ server_read, client_write = IO.pipe
43
32
 
44
- project.targets.each do |target|
45
- target.update_source path, path.read if target.source_file?(path)
46
- target.update_signature path, path.read if target.signature_file?(path)
47
- end
48
- end
33
+ client_reader = LanguageServer::Protocol::Transport::Io::Reader.new(client_read)
34
+ client_writer = LanguageServer::Protocol::Transport::Io::Writer.new(client_write)
49
35
 
50
- added.each do |name|
51
- path = Pathname(name).relative_path_from(Pathname.pwd)
36
+ server_reader = LanguageServer::Protocol::Transport::Io::Reader.new(server_read)
37
+ server_writer = LanguageServer::Protocol::Transport::Io::Writer.new(server_write)
52
38
 
53
- project.targets.each do |target|
54
- target.add_source path, path.read if target.possible_source_file?(path)
55
- target.add_signature path, path.read if target.possible_signature_file?(path)
56
- end
57
- end
39
+ interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path)
40
+ signature_worker = Server::WorkerProcess.spawn_worker(:signature, name: "signature", steepfile: project.steepfile_path)
41
+ code_workers = Server::WorkerProcess.spawn_code_workers(steepfile: project.steepfile_path)
58
42
 
59
- removed.each do |name|
60
- path = Pathname(name).relative_path_from(Pathname.pwd)
43
+ master = Server::Master.new(
44
+ project: project,
45
+ reader: server_reader,
46
+ writer: server_writer,
47
+ interaction_worker: interaction_worker,
48
+ signature_worker: signature_worker,
49
+ code_workers: code_workers
50
+ )
61
51
 
62
- project.targets.each do |target|
63
- target.remove_source path if target.source_file?(path)
64
- target.remove_signature path if target.signature_file?(path)
65
- end
52
+ main_thread = Thread.start do
53
+ master.start()
54
+ end
55
+ main_thread.abort_on_exception = true
56
+
57
+ client_writer.write(method: "initialize", id: 0)
58
+
59
+ Steep.logger.info "Watching #{dirs.join(", ")}..."
60
+ listener = Listen.to(*dirs.map(&:to_s)) do |modified, added, removed|
61
+ stdout.puts "🔬 Type checking updated files..."
62
+
63
+ version = Time.now.to_i
64
+ Steep.logger.tagged "watch" do
65
+ Steep.logger.info "Received file system updates: modified=[#{modified.join(",")}], added=[#{added.join(",")}], removed=[#{removed.join(",")}]"
66
+
67
+ (modified + added).each do |path|
68
+ client_writer.write(
69
+ method: "textDocument/didChange",
70
+ params: {
71
+ textDocument: {
72
+ uri: "file://#{path}",
73
+ version: version
74
+ },
75
+ contentChanges: [
76
+ {
77
+ text: Pathname(path).read
78
+ }
79
+ ]
80
+ }
81
+ )
66
82
  end
67
- end
68
83
 
69
- stdout.puts "🔬 Type checking..."
70
- type_check project
71
- print_project_result project
72
- end
73
- rescue ClosedQueueError
74
- # nop
75
- end
84
+ removed.each do |path|
85
+ client_writer.write(
86
+ method: "textDocument/didChange",
87
+ params: {
88
+ textDocument: {
89
+ uri: "file://#{path}",
90
+ version: version
91
+ },
92
+ contentChanges: [
93
+ {
94
+ text: ""
95
+ }
96
+ ]
97
+ }
98
+ )
99
+ end
100
+ end
101
+ end.tap(&:start)
76
102
 
77
- def print_project_result(project)
78
- project.targets.each do |target|
79
- Steep.logger.tagged "target=#{target.name}" do
80
- case (status = target.status)
81
- when Project::Target::SignatureSyntaxErrorStatus
82
- printer = SignatureErrorPrinter.new(stdout: stdout, stderr: stderr)
83
- printer.print_syntax_errors(status.errors)
84
- when Project::Target::SignatureValidationErrorStatus
85
- printer = SignatureErrorPrinter.new(stdout: stdout, stderr: stderr)
86
- printer.print_semantic_errors(status.errors)
87
- when Project::Target::TypeCheckStatus
88
- status.type_check_sources.each do |source_file|
89
- source_file.errors.each do |error|
90
- error.print_to stdout
103
+ begin
104
+ stdout.puts "👀 Watching directories, Ctrl-C to stop."
105
+ client_reader.read do |response|
106
+ case response[:method]
107
+ when "textDocument/publishDiagnostics"
108
+ uri = URI.parse(response[:params][:uri])
109
+ path = project.relative_path(Pathname(uri.path))
110
+
111
+ diagnostics = response[:params][:diagnostics]
112
+
113
+ unless diagnostics.empty?
114
+ diagnostics.each do |diagnostic|
115
+ start = diagnostic[:range][:start]
116
+ loc = "#{start[:line]+1}:#{start[:character]}"
117
+ message = diagnostic[:message].chomp.lines.join(" ")
118
+
119
+ stdout.puts "#{path}:#{loc}: #{message}"
91
120
  end
92
121
  end
93
122
  end
94
123
  end
95
- end
96
- end
97
-
98
- def run()
99
- if dirs.empty?
100
- stdout.puts "Specify directories to watch"
101
- return 1
102
- end
103
-
104
- project = load_config()
105
-
106
- loader = Project::FileLoader.new(project: project)
107
- loader.load_sources([])
108
- loader.load_signatures()
109
-
110
- type_check project
111
- print_project_result project
112
-
113
- listener.start
114
-
115
- stdout.puts "👀 Watching directories, Ctrl-C to stop."
116
- begin
117
- type_check_loop project
118
124
  rescue Interrupt
119
- # bye
125
+ stdout.puts "Shutting down workers..."
126
+ client_writer.write({ method: :shutdown, id: 10000 })
127
+ client_writer.write({ method: :exit })
128
+ client_writer.io.close()
120
129
  end
121
130
 
131
+ listener.stop
132
+ main_thread.join
133
+
122
134
  0
123
135
  end
124
136
  end
@@ -0,0 +1,51 @@
1
+ module Steep
2
+ module Drivers
3
+ class Worker
4
+ attr_reader :stdout, :stderr, :stdin
5
+
6
+ attr_accessor :steepfile_path
7
+ attr_accessor :worker_type
8
+ attr_accessor :worker_name
9
+
10
+ include Utils::DriverHelper
11
+
12
+ def initialize(stdout:, stderr:, stdin:)
13
+ @stdout = stdout
14
+ @stderr = stderr
15
+ @stdin = stdin
16
+ end
17
+
18
+ def run()
19
+ Steep.logger.tagged("#{worker_type}:#{worker_name}") do
20
+ project = load_config()
21
+
22
+ loader = Project::FileLoader.new(project: project)
23
+ loader.load_sources([])
24
+ loader.load_signatures()
25
+
26
+ reader = LanguageServer::Protocol::Transport::Io::Reader.new(stdin)
27
+ writer = LanguageServer::Protocol::Transport::Io::Writer.new(stdout)
28
+
29
+ worker = case worker_type
30
+ when :code
31
+ Server::CodeWorker.new(project: project, reader: reader, writer: writer)
32
+ when :signature
33
+ Server::SignatureWorker.new(project: project, reader: reader, writer: writer)
34
+ when :interaction
35
+ Server::InteractionWorker.new(project: project, reader: reader, writer: writer)
36
+ else
37
+ raise "Unknown worker type: #{worker_type}"
38
+ end
39
+
40
+ Steep.logger.info "Starting #{worker_type} worker..."
41
+
42
+ worker.run()
43
+ rescue Interrupt
44
+ Steep.logger.info "Shutting down by interrupt..."
45
+ end
46
+
47
+ 0
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,17 +1,21 @@
1
1
  module Steep
2
2
  class Project
3
3
  attr_reader :targets
4
- attr_reader :base_dir
4
+ attr_reader :steepfile_path
5
5
 
6
- def initialize(base_dir:)
6
+ def initialize(steepfile_path:)
7
7
  @targets = []
8
- @base_dir = base_dir
8
+ @steepfile_path = steepfile_path
9
9
 
10
- unless base_dir.absolute?
11
- raise "Project#initialize(base_dir:): base_dir should be absolute path"
10
+ unless steepfile_path.absolute?
11
+ raise "Project#initialize(steepfile_path:): steepfile_path should be absolute path"
12
12
  end
13
13
  end
14
14
 
15
+ def base_dir
16
+ steepfile_path.parent
17
+ end
18
+
15
19
  def relative_path(path)
16
20
  path.relative_path_from(base_dir)
17
21
  end
@@ -47,8 +47,10 @@ module Steep
47
47
  position = Position.new(line: line, column: column)
48
48
 
49
49
  begin
50
- Steep.measure "type_check!" do
51
- type_check!(source_text)
50
+ Steep.logger.tagged "completion_provider#run(line: #{line}, column: #{column})" do
51
+ Steep.measure "type_check!" do
52
+ type_check!(source_text)
53
+ end
52
54
  end
53
55
 
54
56
  Steep.measure "completion item collection" do
@@ -99,10 +101,11 @@ module Steep
99
101
 
100
102
  items = []
101
103
 
104
+ context = typing.context_at(line: position.line, column: position.column)
105
+
102
106
  case
103
107
  when node.type == :send && node.children[0] == nil && at_end?(position, of: node.loc.selector)
104
108
  # foo ←
105
- context = typing.context_of(node: node)
106
109
  prefix = node.children[1].to_s
107
110
 
108
111
  method_items_for_receiver_type(context.self_type,
@@ -114,12 +117,10 @@ module Steep
114
117
 
115
118
  when node.type == :lvar && at_end?(position, of: node.loc)
116
119
  # foo ← (lvar)
117
- context = typing.context_of(node: node)
118
120
  local_variable_items_for_context(context, position: position, prefix: node.children[0].name.to_s, items: items)
119
121
 
120
122
  when node.type == :send && node.children[0] && at_end?(position, of: node.loc.selector)
121
123
  # foo.ba ←
122
- context = typing.context_of(node: node)
123
124
  receiver_type = case (type = typing.type_of(node: node.children[0]))
124
125
  when AST::Types::Self
125
126
  context.self_type
@@ -136,7 +137,6 @@ module Steep
136
137
 
137
138
  when node.type == :const && node.children[0] == nil && at_end?(position, of: node.loc)
138
139
  # Foo ← (const)
139
- context = typing.context_of(node: node)
140
140
  prefix = node.children[1].to_s
141
141
 
142
142
  method_items_for_receiver_type(context.self_type,
@@ -147,7 +147,6 @@ module Steep
147
147
 
148
148
  when node.type == :send && at_end?(position, of: node.loc.dot)
149
149
  # foo.← ba
150
- context = typing.context_of(node: node)
151
150
  receiver_type = case (type = typing.type_of(node: node.children[0]))
152
151
  when AST::Types::Self
153
152
  context.self_type
@@ -163,12 +162,9 @@ module Steep
163
162
 
164
163
  when node.type == :ivar && at_end?(position, of: node.loc)
165
164
  # @fo ←
166
- context = typing.context_of(node: node)
167
165
  instance_variable_items_for_context(context, position: position, prefix: node.children[0].to_s, items: items)
168
166
 
169
167
  else
170
- context = typing.context_of(node: node)
171
-
172
168
  method_items_for_receiver_type(context.self_type,
173
169
  include_private: true,
174
170
  prefix: "",
@@ -190,7 +186,7 @@ module Steep
190
186
  return [] unless node
191
187
 
192
188
  if at_end?(shift_pos, of: node.loc)
193
- context = typing.context_of(node: node)
189
+ context = typing.context_at(line: position.line, column: position.column)
194
190
  receiver_type = case (type = typing.type_of(node: node))
195
191
  when AST::Types::Self
196
192
  context.self_type
@@ -218,7 +214,7 @@ module Steep
218
214
 
219
215
  return [] unless node
220
216
 
221
- context = typing.context_of(node: node)
217
+ context = typing.context_at(line: position.line, column: position.column)
222
218
  items = []
223
219
  instance_variable_items_for_context(context, prefix: "", position: position, items: items)
224
220
  items
@@ -263,7 +259,7 @@ module Steep
263
259
 
264
260
  def local_variable_items_for_context(context, position:, prefix:, items:)
265
261
  range = range_for(position, prefix: prefix)
266
- context.type_env.lvar_types.each do |name, type|
262
+ context.lvar_env.each do |name, type|
267
263
  if name.to_s.start_with?(prefix)
268
264
  items << LocalVariableItem.new(identifier: name,
269
265
  range: range,
@@ -9,6 +9,7 @@ module Steep
9
9
  attr_reader :ignored_sources
10
10
  attr_reader :no_builtin
11
11
  attr_reader :vendor_dir
12
+ attr_reader :strictness_level
12
13
 
13
14
  def initialize(name, sources: [], libraries: [], signatures: [], ignored_sources: [])
14
15
  @name = name
@@ -17,6 +18,7 @@ module Steep
17
18
  @signatures = signatures
18
19
  @ignored_sources = ignored_sources
19
20
  @vendor_dir = nil
21
+ @strictness_level = :default
20
22
  end
21
23
 
22
24
  def initialize_copy(other)
@@ -26,6 +28,7 @@ module Steep
26
28
  @signatures = other.signatures.dup
27
29
  @ignored_sources = other.ignored_sources.dup
28
30
  @vendor_dir = other.vendor_dir
31
+ @strictness_level = other.strictness_level
29
32
  end
30
33
 
31
34
  def check(*args)
@@ -40,6 +43,10 @@ module Steep
40
43
  libraries.push(*args)
41
44
  end
42
45
 
46
+ def typing_options(level)
47
+ @strictness_level = level
48
+ end
49
+
43
50
  def signature(*args)
44
51
  signatures.push(*args)
45
52
  end
@@ -114,6 +121,13 @@ module Steep
114
121
  options: Options.new.tap do |options|
115
122
  options.libraries.push(*target.libraries)
116
123
 
124
+ case target.strictness_level
125
+ when :strict
126
+ options.apply_strict_typing_options!
127
+ when :lenient
128
+ options.apply_lenient_typing_options!
129
+ end
130
+
117
131
  case target.vendor_dir
118
132
  when Array
119
133
  options.vendored_stdlib_path = target.vendor_dir[0]