steep 0.15.0 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (164) 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 +12 -1
  9. data/lib/steep/cli.rb +16 -1
  10. data/lib/steep/drivers/annotations.rb +1 -1
  11. data/lib/steep/drivers/check.rb +1 -12
  12. data/lib/steep/drivers/langserver.rb +13 -462
  13. data/lib/steep/drivers/utils/driver_helper.rb +1 -1
  14. data/lib/steep/drivers/watch.rb +97 -85
  15. data/lib/steep/drivers/worker.rb +51 -0
  16. data/lib/steep/project.rb +9 -5
  17. data/lib/steep/project/completion_provider.rb +4 -2
  18. data/lib/steep/project/file.rb +2 -1
  19. data/lib/steep/project/hover_content.rb +6 -3
  20. data/lib/steep/project/options.rb +15 -0
  21. data/lib/steep/project/target.rb +30 -20
  22. data/lib/steep/server/base_worker.rb +56 -0
  23. data/lib/steep/server/code_worker.rb +151 -0
  24. data/lib/steep/server/interaction_worker.rb +281 -0
  25. data/lib/steep/server/master.rb +196 -0
  26. data/lib/steep/server/signature_worker.rb +148 -0
  27. data/lib/steep/server/utils.rb +36 -0
  28. data/lib/steep/server/worker_process.rb +62 -0
  29. data/lib/steep/signature/validator.rb +5 -5
  30. data/lib/steep/type_construction.rb +13 -19
  31. data/lib/steep/type_inference/constant_env.rb +2 -10
  32. data/lib/steep/type_inference/context.rb +1 -0
  33. data/lib/steep/version.rb +1 -1
  34. data/steep.gemspec +7 -8
  35. metadata +22 -142
  36. data/exe/rbs +0 -3
  37. data/vendor/ruby-signature/.github/workflows/ruby.yml +0 -27
  38. data/vendor/ruby-signature/.gitignore +0 -12
  39. data/vendor/ruby-signature/.rubocop.yml +0 -15
  40. data/vendor/ruby-signature/BSDL +0 -22
  41. data/vendor/ruby-signature/COPYING +0 -56
  42. data/vendor/ruby-signature/Gemfile +0 -6
  43. data/vendor/ruby-signature/README.md +0 -93
  44. data/vendor/ruby-signature/Rakefile +0 -67
  45. data/vendor/ruby-signature/bin/annotate-with-rdoc +0 -157
  46. data/vendor/ruby-signature/bin/console +0 -14
  47. data/vendor/ruby-signature/bin/query-rdoc +0 -103
  48. data/vendor/ruby-signature/bin/setup +0 -10
  49. data/vendor/ruby-signature/bin/sort +0 -89
  50. data/vendor/ruby-signature/bin/test_runner.rb +0 -16
  51. data/vendor/ruby-signature/docs/CONTRIBUTING.md +0 -97
  52. data/vendor/ruby-signature/docs/sigs.md +0 -148
  53. data/vendor/ruby-signature/docs/stdlib.md +0 -152
  54. data/vendor/ruby-signature/docs/syntax.md +0 -528
  55. data/vendor/ruby-signature/exe/rbs +0 -7
  56. data/vendor/ruby-signature/lib/rbs.rb +0 -64
  57. data/vendor/ruby-signature/lib/rbs/ast/annotation.rb +0 -27
  58. data/vendor/ruby-signature/lib/rbs/ast/comment.rb +0 -27
  59. data/vendor/ruby-signature/lib/rbs/ast/declarations.rb +0 -395
  60. data/vendor/ruby-signature/lib/rbs/ast/members.rb +0 -362
  61. data/vendor/ruby-signature/lib/rbs/buffer.rb +0 -50
  62. data/vendor/ruby-signature/lib/rbs/builtin_names.rb +0 -55
  63. data/vendor/ruby-signature/lib/rbs/cli.rb +0 -558
  64. data/vendor/ruby-signature/lib/rbs/constant.rb +0 -26
  65. data/vendor/ruby-signature/lib/rbs/constant_table.rb +0 -150
  66. data/vendor/ruby-signature/lib/rbs/definition.rb +0 -170
  67. data/vendor/ruby-signature/lib/rbs/definition_builder.rb +0 -919
  68. data/vendor/ruby-signature/lib/rbs/environment.rb +0 -281
  69. data/vendor/ruby-signature/lib/rbs/environment_loader.rb +0 -136
  70. data/vendor/ruby-signature/lib/rbs/environment_walker.rb +0 -124
  71. data/vendor/ruby-signature/lib/rbs/errors.rb +0 -187
  72. data/vendor/ruby-signature/lib/rbs/location.rb +0 -102
  73. data/vendor/ruby-signature/lib/rbs/method_type.rb +0 -123
  74. data/vendor/ruby-signature/lib/rbs/namespace.rb +0 -91
  75. data/vendor/ruby-signature/lib/rbs/parser.y +0 -1344
  76. data/vendor/ruby-signature/lib/rbs/prototype/rb.rb +0 -553
  77. data/vendor/ruby-signature/lib/rbs/prototype/rbi.rb +0 -587
  78. data/vendor/ruby-signature/lib/rbs/prototype/runtime.rb +0 -381
  79. data/vendor/ruby-signature/lib/rbs/substitution.rb +0 -46
  80. data/vendor/ruby-signature/lib/rbs/test.rb +0 -26
  81. data/vendor/ruby-signature/lib/rbs/test/errors.rb +0 -61
  82. data/vendor/ruby-signature/lib/rbs/test/hook.rb +0 -294
  83. data/vendor/ruby-signature/lib/rbs/test/setup.rb +0 -58
  84. data/vendor/ruby-signature/lib/rbs/test/spy.rb +0 -325
  85. data/vendor/ruby-signature/lib/rbs/test/test_helper.rb +0 -183
  86. data/vendor/ruby-signature/lib/rbs/test/type_check.rb +0 -254
  87. data/vendor/ruby-signature/lib/rbs/type_name.rb +0 -70
  88. data/vendor/ruby-signature/lib/rbs/types.rb +0 -936
  89. data/vendor/ruby-signature/lib/rbs/variance_calculator.rb +0 -138
  90. data/vendor/ruby-signature/lib/rbs/vendorer.rb +0 -47
  91. data/vendor/ruby-signature/lib/rbs/version.rb +0 -3
  92. data/vendor/ruby-signature/lib/rbs/writer.rb +0 -269
  93. data/vendor/ruby-signature/lib/ruby/signature.rb +0 -7
  94. data/vendor/ruby-signature/rbs.gemspec +0 -45
  95. data/vendor/ruby-signature/stdlib/abbrev/abbrev.rbs +0 -60
  96. data/vendor/ruby-signature/stdlib/base64/base64.rbs +0 -71
  97. data/vendor/ruby-signature/stdlib/benchmark/benchmark.rbs +0 -372
  98. data/vendor/ruby-signature/stdlib/builtin/array.rbs +0 -1997
  99. data/vendor/ruby-signature/stdlib/builtin/basic_object.rbs +0 -280
  100. data/vendor/ruby-signature/stdlib/builtin/binding.rbs +0 -177
  101. data/vendor/ruby-signature/stdlib/builtin/builtin.rbs +0 -44
  102. data/vendor/ruby-signature/stdlib/builtin/class.rbs +0 -145
  103. data/vendor/ruby-signature/stdlib/builtin/comparable.rbs +0 -116
  104. data/vendor/ruby-signature/stdlib/builtin/complex.rbs +0 -400
  105. data/vendor/ruby-signature/stdlib/builtin/constants.rbs +0 -37
  106. data/vendor/ruby-signature/stdlib/builtin/data.rbs +0 -5
  107. data/vendor/ruby-signature/stdlib/builtin/deprecated.rbs +0 -2
  108. data/vendor/ruby-signature/stdlib/builtin/dir.rbs +0 -413
  109. data/vendor/ruby-signature/stdlib/builtin/encoding.rbs +0 -607
  110. data/vendor/ruby-signature/stdlib/builtin/enumerable.rbs +0 -404
  111. data/vendor/ruby-signature/stdlib/builtin/enumerator.rbs +0 -260
  112. data/vendor/ruby-signature/stdlib/builtin/errno.rbs +0 -781
  113. data/vendor/ruby-signature/stdlib/builtin/errors.rbs +0 -582
  114. data/vendor/ruby-signature/stdlib/builtin/exception.rbs +0 -194
  115. data/vendor/ruby-signature/stdlib/builtin/false_class.rbs +0 -40
  116. data/vendor/ruby-signature/stdlib/builtin/fiber.rbs +0 -68
  117. data/vendor/ruby-signature/stdlib/builtin/fiber_error.rbs +0 -12
  118. data/vendor/ruby-signature/stdlib/builtin/file.rbs +0 -1076
  119. data/vendor/ruby-signature/stdlib/builtin/file_test.rbs +0 -59
  120. data/vendor/ruby-signature/stdlib/builtin/float.rbs +0 -696
  121. data/vendor/ruby-signature/stdlib/builtin/gc.rbs +0 -243
  122. data/vendor/ruby-signature/stdlib/builtin/hash.rbs +0 -1029
  123. data/vendor/ruby-signature/stdlib/builtin/integer.rbs +0 -707
  124. data/vendor/ruby-signature/stdlib/builtin/io.rbs +0 -683
  125. data/vendor/ruby-signature/stdlib/builtin/kernel.rbs +0 -576
  126. data/vendor/ruby-signature/stdlib/builtin/marshal.rbs +0 -161
  127. data/vendor/ruby-signature/stdlib/builtin/match_data.rbs +0 -271
  128. data/vendor/ruby-signature/stdlib/builtin/math.rbs +0 -369
  129. data/vendor/ruby-signature/stdlib/builtin/method.rbs +0 -185
  130. data/vendor/ruby-signature/stdlib/builtin/module.rbs +0 -1104
  131. data/vendor/ruby-signature/stdlib/builtin/nil_class.rbs +0 -82
  132. data/vendor/ruby-signature/stdlib/builtin/numeric.rbs +0 -409
  133. data/vendor/ruby-signature/stdlib/builtin/object.rbs +0 -824
  134. data/vendor/ruby-signature/stdlib/builtin/proc.rbs +0 -429
  135. data/vendor/ruby-signature/stdlib/builtin/process.rbs +0 -1227
  136. data/vendor/ruby-signature/stdlib/builtin/random.rbs +0 -267
  137. data/vendor/ruby-signature/stdlib/builtin/range.rbs +0 -226
  138. data/vendor/ruby-signature/stdlib/builtin/rational.rbs +0 -424
  139. data/vendor/ruby-signature/stdlib/builtin/rb_config.rbs +0 -57
  140. data/vendor/ruby-signature/stdlib/builtin/regexp.rbs +0 -1083
  141. data/vendor/ruby-signature/stdlib/builtin/ruby_vm.rbs +0 -14
  142. data/vendor/ruby-signature/stdlib/builtin/signal.rbs +0 -55
  143. data/vendor/ruby-signature/stdlib/builtin/string.rbs +0 -1901
  144. data/vendor/ruby-signature/stdlib/builtin/string_io.rbs +0 -284
  145. data/vendor/ruby-signature/stdlib/builtin/struct.rbs +0 -40
  146. data/vendor/ruby-signature/stdlib/builtin/symbol.rbs +0 -228
  147. data/vendor/ruby-signature/stdlib/builtin/thread.rbs +0 -1108
  148. data/vendor/ruby-signature/stdlib/builtin/thread_group.rbs +0 -23
  149. data/vendor/ruby-signature/stdlib/builtin/time.rbs +0 -1047
  150. data/vendor/ruby-signature/stdlib/builtin/trace_point.rbs +0 -290
  151. data/vendor/ruby-signature/stdlib/builtin/true_class.rbs +0 -46
  152. data/vendor/ruby-signature/stdlib/builtin/unbound_method.rbs +0 -153
  153. data/vendor/ruby-signature/stdlib/builtin/warning.rbs +0 -17
  154. data/vendor/ruby-signature/stdlib/coverage/coverage.rbs +0 -62
  155. data/vendor/ruby-signature/stdlib/csv/csv.rbs +0 -773
  156. data/vendor/ruby-signature/stdlib/erb/erb.rbs +0 -392
  157. data/vendor/ruby-signature/stdlib/find/find.rbs +0 -40
  158. data/vendor/ruby-signature/stdlib/ipaddr/ipaddr.rbs +0 -247
  159. data/vendor/ruby-signature/stdlib/pathname/pathname.rbs +0 -1093
  160. data/vendor/ruby-signature/stdlib/prime/integer-extension.rbs +0 -23
  161. data/vendor/ruby-signature/stdlib/prime/prime.rbs +0 -188
  162. data/vendor/ruby-signature/stdlib/securerandom/securerandom.rbs +0 -9
  163. data/vendor/ruby-signature/stdlib/set/set.rbs +0 -301
  164. data/vendor/ruby-signature/stdlib/tmpdir/tmpdir.rbs +0 -53
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 498c3c95c9c03e8ef047c774aff47158d8681e2ae485d5b0449a74fae33cd06b
4
- data.tar.gz: 64e9572dc4ec5b5fea6035c1a1fbb7241a758f76c5d328d2ac0011c37e176044
3
+ metadata.gz: f60fa7be29b63a36a6f25cb94138d558d0bbaa652cb40ab5f2a4a24f1a0d58ac
4
+ data.tar.gz: 83582c3c37c5afefe079a545860e96a8edce020b891755b49f6a1cbdf53cce04
5
5
  SHA512:
6
- metadata.gz: acef7a13109ecd0660d72dff4559b4432f96c62f79aa4dcb762722f9a96678bb6f68f0bd288017381c6ebef65f9648a24f2b349d2af28f1a6f0c66560d56aee6
7
- data.tar.gz: 9d31c49a37770c7493cefcde0f608ee6b6c94bd5fa1935c3ce963bae70b3e526b678000ae1b2b9f59d94a775c5103cbabf7effd480262725db476f70e6124dcf
6
+ metadata.gz: 38e917a0030c6f0f993d6d0bd6bd9e26bb955cdd08609802df87992f7242933f03f3b35311c53fec9e6f74a12cb5d2237c5e03d6461fc56f44d019b8011ed12e
7
+ data.tar.gz: 5a5fa1b3502b23d3a9e6c1391de6c3313e8309adbbf353589eda27ed356414201ec2c6f6cdceb01b5f2afd8425a777a3d02921e509ba15674295c65f04bbdc0e
@@ -1,3 +0,0 @@
1
- [submodule "vendor/ruby-signature"]
2
- path = vendor/ruby-signature
3
- url = https://github.com/ruby/ruby-signature.git
@@ -2,6 +2,31 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.17.0 (2020-06-13)
6
+
7
+ * Fix `steep watch` and `steep langserver` to correctly handle error message filterings based on options ([#152](https://github.com/soutaro/steep/pull/152))
8
+ * Fix typing of collections ([#151](https://github.com/soutaro/steep/pull/151))
9
+
10
+ ## 0.16.3
11
+
12
+ * Fix `steep watch` ([#147](https://github.com/soutaro/steep/pull/147))
13
+ * Stop using pry ([#148](https://github.com/soutaro/steep/pull/148))
14
+
15
+ ## 0.16.2 (2020-05-27)
16
+
17
+ * Update gems ([#144](https://github.com/soutaro/steep/pull/144), [#145](https://github.com/soutaro/steep/pull/145))
18
+
19
+ ## 0.16.1 (2020-05-22)
20
+
21
+ * Fix constant resolution ([#143](https://github.com/soutaro/steep/pull/143))
22
+ * Fix RBS diagnostics line number in LSP ([#142](https://github.com/soutaro/steep/pull/142))
23
+ * Fix crash caused by hover on `def` in LSP ([#140](https://github.com/soutaro/steep/pull/140))
24
+
25
+ ## 0.16.0 (2020-05-19)
26
+
27
+ * Spawn workers for type check performance ([#137](https://github.com/soutaro/steep/pull/137))
28
+ * Fix `check` and `signature` methods in Steepfile ([8f3e4c7](https://github.com/soutaro/steep/pull/137/commits/8f3e4c75b29ac26920f02294be06d6c68dbd4dca))
29
+
5
30
  ## 0.15.0 (2020-05-05)
6
31
 
7
32
  * Add type checking configuration to dsl ([#132](https://github.com/soutaro/steep/pull/132))
data/Rakefile CHANGED
@@ -8,19 +8,6 @@ Rake::TestTask.new(:test) do |t|
8
8
  end
9
9
 
10
10
  task :default => :test
11
- task :build => :parser
12
- task :test => :parser
13
- task :install => [:reset, :parser]
14
-
15
- task :parser do
16
- Dir.chdir "vendor/ruby-signature" do
17
- sh "bundle exec rake parser"
18
- end
19
- end
20
-
21
- task :reset do
22
- sh "git submodule update -f --init"
23
- end
24
11
 
25
12
  task :smoke do
26
13
  sh "bundle", "exec", "bin/smoke_runner.rb", *Dir.glob("smoke/*")
data/bin/setup CHANGED
@@ -5,5 +5,3 @@ set -vx
5
5
 
6
6
  bundle install
7
7
 
8
- # Do any other automated setup that you need to do here
9
- bundle exec rake reset parser
@@ -2,7 +2,6 @@
2
2
 
3
3
  require "pathname"
4
4
 
5
- $LOAD_PATH << Pathname(__dir__) + '../vendor/ruby-signature/lib'
6
5
  $LOAD_PATH << Pathname(__dir__) + "../lib"
7
6
 
8
7
  require "steep"
data/exe/steep CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'pathname'
4
4
 
5
- $LOAD_PATH << Pathname(__dir__) + "../vendor/ruby-signature/lib"
6
5
  $LOAD_PATH << Pathname(__dir__) + "../lib"
7
6
 
8
7
  require 'steep'
@@ -8,8 +8,10 @@ require "logger"
8
8
  require "active_support/tagged_logging"
9
9
  require "rainbow"
10
10
  require "listen"
11
- require 'pry'
12
11
  require 'language_server-protocol'
12
+ require "etc"
13
+ require "open3"
14
+ require "stringio"
13
15
 
14
16
  require "rbs"
15
17
 
@@ -70,6 +72,14 @@ require "steep/type_inference/local_variable_type_env"
70
72
  require "steep/type_inference/logic"
71
73
  require "steep/ast/types"
72
74
 
75
+ require "steep/server/utils"
76
+ require "steep/server/base_worker"
77
+ require "steep/server/code_worker"
78
+ require "steep/server/signature_worker"
79
+ require "steep/server/worker_process"
80
+ require "steep/server/interaction_worker"
81
+ require "steep/server/master"
82
+
73
83
  require "steep/project"
74
84
  require "steep/project/file"
75
85
  require "steep/project/options"
@@ -89,6 +99,7 @@ require "steep/drivers/trace_printer"
89
99
  require "steep/drivers/print_project"
90
100
  require "steep/drivers/init"
91
101
  require "steep/drivers/vendor"
102
+ require "steep/drivers/worker"
92
103
 
93
104
  if ENV["NO_COLOR"]
94
105
  Rainbow.enabled = false
@@ -34,7 +34,7 @@ module Steep
34
34
 
35
35
  def setup_command
36
36
  @command = argv.shift&.to_sym
37
- if CLI.available_commands.include?(@command)
37
+ if CLI.available_commands.include?(@command) || @command == :worker
38
38
  true
39
39
  else
40
40
  stderr.puts "Unknown command: #{command}"
@@ -159,5 +159,20 @@ module Steep
159
159
  stdout.puts Steep::VERSION
160
160
  0
161
161
  end
162
+
163
+ def process_worker
164
+ Drivers::Worker.new(stdout: stdout, stderr: stderr, stdin: stdin).tap do |command|
165
+ OptionParser.new do |opts|
166
+ opts.banner = "Usage: steep worker [options] [dir]"
167
+ handle_logging_options opts
168
+
169
+ opts.on("--interaction") { command.worker_type = :interaction }
170
+ opts.on("--code") { command.worker_type = :code }
171
+ opts.on("--signature") { command.worker_type = :signature }
172
+ opts.on("--steepfile=PATH") {|path| command.steepfile = Pathname(path) }
173
+ opts.on("--name=NAME") {|name| command.worker_name = name }
174
+ end.parse!(argv)
175
+ end.run
176
+ end
162
177
  end
163
178
  end
@@ -25,7 +25,7 @@ module Steep
25
25
 
26
26
  project.targets.each do |target|
27
27
  Steep.logger.tagged "target=#{target.name}" do
28
- target.load_signatures do |_, subtyping, _|
28
+ target.load_signatures(validate: false) do |_, subtyping, _|
29
29
  case (status = target.status)
30
30
  when nil # status set on error cases
31
31
  target.source_files.each_value do |file|
@@ -53,18 +53,7 @@ module Steep
53
53
  status.type_check_sources.each do |source_file|
54
54
  case source_file.status
55
55
  when Project::SourceFile::TypeCheckStatus
56
- source_file.errors.reject do |error|
57
- case
58
- when error.is_a?(Errors::FallbackAny)
59
- target.options.allow_fallback_any
60
- when error.is_a?(Errors::MethodDefinitionMissing)
61
- target.options.allow_missing_definitions
62
- when error.is_a?(Errors::NoMethod)
63
- target.options.allow_unknown_method_calls
64
- when error.is_a?(Errors::UnknownConstantAssigned)
65
- target.options.allow_unknown_constant_assignment
66
- end
67
- end.each do |error|
56
+ source_file.errors.select {|error| target.options.error_to_report?(error) }.each do |error|
68
57
  error.print_to stdout
69
58
  end
70
59
  when Project::SourceFile::TypeCheckErrorStatus
@@ -33,11 +33,6 @@ module Steep
33
33
  @project or raise "Empty #project"
34
34
  end
35
35
 
36
- def enqueue_type_check(version)
37
- @latest_update_version = version
38
- type_check_queue << TypeCheckRequest.new(version: version)
39
- end
40
-
41
36
  def run
42
37
  @project = load_config()
43
38
 
@@ -45,466 +40,22 @@ module Steep
45
40
  loader.load_sources([])
46
41
  loader.load_signatures()
47
42
 
48
- start_type_check()
49
-
50
- reader.read do |request|
51
- Steep.logger.tagged "lsp" do
52
- Steep.logger.debug { "Received a request: request=#{request.to_json}" }
53
- handle_request(request) do |id, result|
54
- if id
55
- write_mutex.synchronize do
56
- Steep.logger.debug { "Writing response to #{id}: #{result.to_json}" }
57
- writer.write(id: id, result: result)
58
- end
59
- end
60
- end
61
- end
62
- end
63
-
64
- 0
65
- end
66
-
67
- def write(method:, params:)
68
- write_mutex.synchronize do
69
- Steep.logger.debug { "Sending request: method=#{method}, params=#{params.to_json}"}
70
- writer.write(method: method, params: params)
71
- end
72
- end
73
-
74
- def handle_request(request)
75
- id = request[:id]
76
- method = request[:method].to_sym
77
-
78
- Steep.logger.tagged "id=#{id}, method=#{method}" do
79
- case method
80
- when :initialize
81
- yield id, LanguageServer::Protocol::Interface::InitializeResult.new(
82
- capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
83
- text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
84
- change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL
85
- ),
86
- hover_provider: true,
87
- completion_provider: LanguageServer::Protocol::Interface::CompletionOptions.new(
88
- trigger_characters: [".", "@"],
89
- )
90
- )
91
- )
92
-
93
- enqueue_type_check nil
94
-
95
- when :"textDocument/completion"
96
- Steep.logger.error request.inspect
97
- begin
98
- params = request[:params]
99
- uri = URI.parse(params[:textDocument][:uri])
100
- path = project.relative_path(Pathname(uri.path))
101
- target = project.targets.find {|target| target.source_file?(path) }
102
- case (status = target&.status)
103
- when Project::Target::TypeCheckStatus
104
- subtyping = status.subtyping
105
- source = target.source_files[path]
106
-
107
- line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
108
- trigger = params[:context][:triggerCharacter]
109
-
110
- Steep.logger.error "line: #{line}, column: #{column}, trigger: #{trigger}"
111
-
112
- provider = Project::CompletionProvider.new(source_text: source.content, path: path, subtyping: subtyping)
113
- items = begin
114
- provider.run(line: line, column: column)
115
- rescue Parser::SyntaxError
116
- []
117
- end
118
-
119
- completion_items = items.map do |item|
120
- format_completion_item(item)
121
- end
122
-
123
- Steep.logger.debug "items = #{completion_items.inspect}"
124
-
125
- yield id, LanguageServer::Protocol::Interface::CompletionList.new(
126
- is_incomplete: false,
127
- items: completion_items
128
- )
129
- end
130
-
131
- rescue Typing::UnknownNodeError => exn
132
- Steep.log_error exn, message: "Failed to compute completion: #{exn.inspect}"
133
- yield id, nil
134
- end
135
-
136
- when :"textDocument/didChange"
137
- uri = URI.parse(request[:params][:textDocument][:uri])
138
- path = project.relative_path(Pathname(uri.path))
139
- text = request[:params][:contentChanges][0][:text]
140
-
141
- Steep.logger.debug { "path=#{path}, content=#{text.lines.first&.chomp}..." }
142
-
143
- project.targets.each do |target|
144
- Steep.logger.tagged "target=#{target.name}" do
145
- case
146
- when target.source_file?(path)
147
- if text.empty? && !path.file?
148
- Steep.logger.info { "Deleting source file: #{path}..." }
149
- target.remove_source(path)
150
- report_diagnostics path, []
151
- else
152
- Steep.logger.info { "Updating source file: #{path}..." }
153
- target.update_source(path, text)
154
- end
155
- when target.possible_source_file?(path)
156
- Steep.logger.info { "Adding source file: #{path}..." }
157
- target.add_source(path, text)
158
- when target.signature_file?(path)
159
- if text.empty? && !path.file?
160
- Steep.logger.info { "Deleting signature file: #{path}..." }
161
- target.remove_signature(path)
162
- report_diagnostics path, []
163
- else
164
- Steep.logger.info { "Updating signature file: #{path}..." }
165
- target.update_signature(path, text)
166
- end
167
- when target.possible_signature_file?(path)
168
- Steep.logger.info { "Adding signature file: #{path}..." }
169
- target.add_signature(path, text)
170
- end
171
- end
172
- end
173
-
174
- version = request[:params][:textDocument][:version]
175
- enqueue_type_check version
176
- when :"textDocument/hover"
177
- uri = URI.parse(request[:params][:textDocument][:uri])
178
- path = project.relative_path(Pathname(uri.path))
179
- line = request[:params][:position][:line]
180
- column = request[:params][:position][:character]
181
-
182
- yield id, response_to_hover(path: path, line: line, column: column)
183
-
184
- when :shutdown
185
- yield id, nil
186
-
187
- when :exit
188
- type_check_queue << nil
189
- type_check_thread.join
190
- exit
191
- end
192
- end
193
- end
194
-
195
- def start_type_check
196
- @type_check_thread = Thread.start do
197
- while request = type_check_queue.deq
198
- if @latest_update_version == nil || @latest_update_version == request.version
199
- begin
200
- run_type_check()
201
- rescue => exn
202
- Steep.log_error exn
203
- end
204
- end
205
- end
206
- end
207
- end
208
-
209
- def run_type_check()
210
- Steep.logger.tagged "#run_type_check" do
211
- Steep.logger.info { "Running type check..." }
212
- type_check project
213
-
214
- Steep.logger.info { "Sending diagnostics..." }
215
- project.targets.each do |target|
216
- Steep.logger.tagged "target=#{target.name}, status=#{target.status.class}" do
217
- Steep.logger.info { "Clearing signature diagnostics..." }
218
- target.signature_files.each_value do |file|
219
- report_diagnostics file.path, []
220
- end
221
-
222
- case (status = target.status)
223
- when Project::Target::SignatureValidationErrorStatus
224
- Steep.logger.info { "Signature validation error" }
225
- status.errors.group_by(&:path).each do |path, errors|
226
- diagnostics = errors.map {|error| diagnostic_for_validation_error(error) }
227
- report_diagnostics path, diagnostics
228
- end
229
- when Project::Target::TypeCheckStatus
230
- Steep.logger.info { "Type check" }
231
- status.type_check_sources.each do |source|
232
- diagnostics = case source.status
233
- when Project::SourceFile::TypeCheckStatus
234
- source.errors.map {|error| diagnostic_for_type_error(error) }
235
- when Project::SourceFile::AnnotationSyntaxErrorStatus
236
- [diagnostics_raw(source.status.error.message, source.status.location)]
237
- when Project::SourceFile::ParseErrorStatus
238
- []
239
- when Project::SourceFile::TypeCheckErrorStatus
240
- Steep.log_error source.status.error
241
- []
242
- end
243
-
244
- if diagnostics
245
- report_diagnostics source.path, diagnostics
246
- end
247
- end
248
- when Project::Target::SignatureSyntaxErrorStatus
249
- Steep.logger.info { "Signature syntax error" }
250
- end
251
- end
252
- end
253
- end
254
- end
255
-
256
- def report_diagnostics(path, diagnostics)
257
- Steep.logger.info { "Reporting #{diagnostics.size} diagnostics for #{path}..." }
258
- write(
259
- method: :"textDocument/publishDiagnostics",
260
- params: LanguageServer::Protocol::Interface::PublishDiagnosticsParams.new(
261
- uri: URI.parse(project.absolute_path(path).to_s).tap {|uri| uri.scheme = "file"},
262
- diagnostics: diagnostics,
263
- )
264
- )
265
- end
266
-
267
- def diagnostic_for_validation_error(error)
268
- LanguageServer::Protocol::Interface::Diagnostic.new(
269
- message: StringIO.new("").tap {|io| error.puts(io) }.string,
270
- severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
271
- range: LanguageServer::Protocol::Interface::Range.new(
272
- start: LanguageServer::Protocol::Interface::Position.new(
273
- line: error.location.start_line - 1,
274
- character: error.location.start_column,
275
- ),
276
- end: LanguageServer::Protocol::Interface::Position.new(
277
- line: error.location.end_line - 1,
278
- character: error.location.end_column,
279
- ),
280
- )
281
- )
282
- end
283
-
284
- def diagnostics_raw(message, loc)
285
- LanguageServer::Protocol::Interface::Diagnostic.new(
286
- message: message,
287
- severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
288
- range: LanguageServer::Protocol::Interface::Range.new(
289
- start: LanguageServer::Protocol::Interface::Position.new(
290
- line: loc.start_line - 1,
291
- character: loc.start_column,
292
- ),
293
- end: LanguageServer::Protocol::Interface::Position.new(
294
- line: loc.end_line - 1,
295
- character: loc.end_column,
296
- ),
297
- )
298
- )
299
- end
300
-
301
- def diagnostic_for_type_error(error)
302
- LanguageServer::Protocol::Interface::Diagnostic.new(
303
- message: error.to_s,
304
- severity: LanguageServer::Protocol::Constant::DiagnosticSeverity::ERROR,
305
- range: LanguageServer::Protocol::Interface::Range.new(
306
- start: LanguageServer::Protocol::Interface::Position.new(
307
- line: error.node.loc.line - 1,
308
- character: error.node.loc.column,
309
- ),
310
- end: LanguageServer::Protocol::Interface::Position.new(
311
- line: error.node.loc.last_line - 1,
312
- character: error.node.loc.last_column,
313
- ),
314
- )
43
+ interaction_worker = Server::WorkerProcess.spawn_worker(:interaction, name: "interaction", steepfile: project.steepfile_path)
44
+ signature_worker = Server::WorkerProcess.spawn_worker(:signature, name: "signature", steepfile: project.steepfile_path)
45
+ code_workers = Server::WorkerProcess.spawn_code_workers(steepfile: project.steepfile_path)
46
+
47
+ master = Server::Master.new(
48
+ project: project,
49
+ reader: reader,
50
+ writer: writer,
51
+ interaction_worker: interaction_worker,
52
+ signature_worker: signature_worker,
53
+ code_workers: code_workers
315
54
  )
316
- end
317
-
318
- def response_to_hover(path:, line:, column:)
319
- Steep.logger.info { "path=#{path}, line=#{line}, column=#{column}" }
320
-
321
- hover = Project::HoverContent.new(project: project)
322
- content = hover.content_for(path: path, line: line+1, column: column+1)
323
- if content
324
- range = content.location.yield_self do |location|
325
- start_position = { line: location.line - 1, character: location.column }
326
- end_position = { line: location.last_line - 1, character: location.last_column }
327
- { start: start_position, end: end_position }
328
- end
329
55
 
330
- LanguageServer::Protocol::Interface::Hover.new(
331
- contents: { kind: "markdown", value: format_hover(content) },
332
- range: range
333
- )
334
- end
335
- rescue Typing::UnknownNodeError => exn
336
- Steep.log_error exn, message: "Failed to compute hover: #{exn.inspect}"
337
- nil
338
- end
339
-
340
- def format_hover(content)
341
- case content
342
- when Project::HoverContent::VariableContent
343
- "`#{content.name}`: `#{content.type.to_s}`"
344
- when Project::HoverContent::MethodCallContent
345
- method_name = case content.method_name
346
- when Project::HoverContent::InstanceMethodName
347
- "#{content.method_name.class_name}##{content.method_name.method_name}"
348
- when Project::HoverContent::SingletonMethodName
349
- "#{content.method_name.class_name}.#{content.method_name.method_name}"
350
- else
351
- nil
352
- end
353
-
354
- if method_name
355
- string = <<HOVER
356
- ```
357
- #{method_name} ~> #{content.type}
358
- ```
359
- HOVER
360
- if content.definition
361
- if content.definition.comment
362
- string << "\n----\n\n#{content.definition.comment.string}"
363
- end
364
-
365
- string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
366
- end
367
- else
368
- "`#{content.type}`"
369
- end
370
- when Project::HoverContent::DefinitionContent
371
- string = <<HOVER
372
- ```
373
- def #{content.method_name}: #{content.method_type}
374
- ```
375
- HOVER
376
- if (comment = content.definition.comment)
377
- string << "\n----\n\n#{comment.string}\n"
378
- end
379
-
380
- if content.definition.method_types.size > 1
381
- string << "\n----\n\n#{content.definition.method_types.map {|x| "- `#{x}`\n" }.join()}"
382
- end
383
-
384
- string
385
- when Project::HoverContent::TypeContent
386
- "`#{content.type}`"
387
- end
388
- end
389
-
390
- def format_completion_item(item)
391
- range = LanguageServer::Protocol::Interface::Range.new(
392
- start: LanguageServer::Protocol::Interface::Position.new(
393
- line: item.range.start.line-1,
394
- character: item.range.start.column
395
- ),
396
- end: LanguageServer::Protocol::Interface::Position.new(
397
- line: item.range.end.line-1,
398
- character: item.range.end.column
399
- )
400
- )
56
+ master.start()
401
57
 
402
- case item
403
- when Project::CompletionProvider::LocalVariableItem
404
- LanguageServer::Protocol::Interface::CompletionItem.new(
405
- label: item.identifier,
406
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::VARIABLE,
407
- detail: "#{item.identifier}: #{item.type}",
408
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
409
- range: range,
410
- new_text: "#{item.identifier}"
411
- )
412
- )
413
- when Project::CompletionProvider::MethodNameItem
414
- label = "def #{item.identifier}: #{item.method_type}"
415
- method_type_snippet = method_type_to_snippet(item.method_type)
416
- LanguageServer::Protocol::Interface::CompletionItem.new(
417
- label: label,
418
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::METHOD,
419
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
420
- new_text: "#{item.identifier}#{method_type_snippet}",
421
- range: range
422
- ),
423
- documentation: item.definition.comment&.string,
424
- insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET
425
- )
426
- when Project::CompletionProvider::InstanceVariableItem
427
- label = "#{item.identifier}: #{item.type}"
428
- LanguageServer::Protocol::Interface::CompletionItem.new(
429
- label: label,
430
- kind: LanguageServer::Protocol::Constant::CompletionItemKind::FIELD,
431
- text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
432
- range: range,
433
- new_text: item.identifier,
434
- ),
435
- insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET
436
- )
437
- end
438
- end
439
-
440
- def method_type_to_snippet(method_type)
441
- params = if method_type.type.each_param.count == 0
442
- ""
443
- else
444
- "(#{params_to_snippet(method_type.type)})"
445
- end
446
-
447
-
448
- block = if method_type.block
449
- open, space, close = if method_type.block.type.return_type.is_a?(RBS::Types::Bases::Void)
450
- ["do", " ", "end"]
451
- else
452
- ["{", "", "}"]
453
- end
454
-
455
- if method_type.block.type.each_param.count == 0
456
- " #{open} $0 #{close}"
457
- else
458
- " #{open}#{space}|#{params_to_snippet(method_type.block.type)}| $0 #{close}"
459
- end
460
- else
461
- ""
462
- end
463
-
464
- "#{params}#{block}"
465
- end
466
-
467
- def params_to_snippet(fun)
468
- params = []
469
-
470
- index = 1
471
-
472
- fun.required_positionals.each do |param|
473
- if name = param.name
474
- params << "${#{index}:#{param.type}}"
475
- else
476
- params << "${#{index}:#{param.type}}"
477
- end
478
-
479
- index += 1
480
- end
481
-
482
- if fun.rest_positionals
483
- params << "${#{index}:*#{fun.rest_positionals.type}}"
484
- index += 1
485
- end
486
-
487
- fun.trailing_positionals.each do |param|
488
- if name = param.name
489
- params << "${#{index}:#{param.type}}"
490
- else
491
- params << "${#{index}:#{param.type}}"
492
- end
493
-
494
- index += 1
495
- end
496
-
497
- fun.required_keywords.each do |keyword, param|
498
- if name = param.name
499
- params << "#{keyword}: ${#{index}:#{name}_}"
500
- else
501
- params << "#{keyword}: ${#{index}:#{param.type}_}"
502
- end
503
-
504
- index += 1
505
- end
506
-
507
- params.join(", ")
58
+ 0
508
59
  end
509
60
  end
510
61
  end