steep 0.40.0 → 0.44.0

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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +38 -0
  3. data/Gemfile +1 -0
  4. data/bin/output_rebaseline.rb +15 -30
  5. data/bin/output_test.rb +23 -57
  6. data/lib/steep.rb +89 -15
  7. data/lib/steep/annotation_parser.rb +10 -2
  8. data/lib/steep/ast/types/class.rb +4 -0
  9. data/lib/steep/cli.rb +31 -6
  10. data/lib/steep/diagnostic/ruby.rb +13 -8
  11. data/lib/steep/diagnostic/signature.rb +152 -2
  12. data/lib/steep/drivers/annotations.rb +18 -36
  13. data/lib/steep/drivers/check.rb +140 -31
  14. data/lib/steep/drivers/diagnostic_printer.rb +20 -11
  15. data/lib/steep/drivers/langserver.rb +4 -8
  16. data/lib/steep/drivers/print_project.rb +10 -9
  17. data/lib/steep/drivers/stats.rb +135 -119
  18. data/lib/steep/drivers/utils/driver_helper.rb +35 -0
  19. data/lib/steep/drivers/utils/jobs_count.rb +9 -0
  20. data/lib/steep/drivers/validate.rb +29 -18
  21. data/lib/steep/drivers/watch.rb +55 -49
  22. data/lib/steep/drivers/worker.rb +11 -8
  23. data/lib/steep/expectations.rb +159 -0
  24. data/lib/steep/index/signature_symbol_provider.rb +23 -1
  25. data/lib/steep/index/source_index.rb +55 -5
  26. data/lib/steep/interface/block.rb +4 -0
  27. data/lib/steep/project.rb +0 -30
  28. data/lib/steep/project/dsl.rb +5 -3
  29. data/lib/steep/project/pattern.rb +56 -0
  30. data/lib/steep/project/target.rb +11 -227
  31. data/lib/steep/server/base_worker.rb +1 -3
  32. data/lib/steep/server/change_buffer.rb +63 -0
  33. data/lib/steep/server/interaction_worker.rb +72 -57
  34. data/lib/steep/server/master.rb +652 -234
  35. data/lib/steep/server/type_check_worker.rb +304 -0
  36. data/lib/steep/server/worker_process.rb +16 -11
  37. data/lib/steep/{project → services}/completion_provider.rb +5 -5
  38. data/lib/steep/services/content_change.rb +61 -0
  39. data/lib/steep/services/file_loader.rb +48 -0
  40. data/lib/steep/services/goto_service.rb +321 -0
  41. data/lib/steep/{project → services}/hover_content.rb +19 -20
  42. data/lib/steep/services/path_assignment.rb +27 -0
  43. data/lib/steep/services/signature_service.rb +403 -0
  44. data/lib/steep/services/stats_calculator.rb +69 -0
  45. data/lib/steep/services/type_check_service.rb +413 -0
  46. data/lib/steep/signature/validator.rb +187 -85
  47. data/lib/steep/source.rb +21 -18
  48. data/lib/steep/subtyping/check.rb +246 -45
  49. data/lib/steep/subtyping/constraints.rb +4 -4
  50. data/lib/steep/type_construction.rb +428 -193
  51. data/lib/steep/type_inference/block_params.rb +1 -1
  52. data/lib/steep/type_inference/context.rb +22 -0
  53. data/lib/steep/type_inference/local_variable_type_env.rb +26 -12
  54. data/lib/steep/type_inference/logic.rb +1 -1
  55. data/lib/steep/type_inference/logic_type_interpreter.rb +4 -4
  56. data/lib/steep/type_inference/type_env.rb +43 -17
  57. data/lib/steep/version.rb +1 -1
  58. data/smoke/alias/test_expectations.yml +96 -0
  59. data/smoke/and/test_expectations.yml +31 -0
  60. data/smoke/array/test_expectations.yml +103 -0
  61. data/smoke/block/test_expectations.yml +125 -0
  62. data/smoke/case/test_expectations.yml +47 -0
  63. data/smoke/class/test_expectations.yml +120 -0
  64. data/smoke/const/test_expectations.yml +129 -0
  65. data/smoke/diagnostics-rbs-duplicated/test_expectations.yml +13 -0
  66. data/smoke/diagnostics-rbs/Steepfile +7 -4
  67. data/smoke/diagnostics-rbs/test_expectations.yml +231 -0
  68. data/smoke/diagnostics-rbs/unknown-type-name-2.rbs +5 -0
  69. data/smoke/{broken → diagnostics-ruby-unsat}/Steepfile +0 -0
  70. data/smoke/diagnostics-ruby-unsat/a.rbs +3 -0
  71. data/smoke/diagnostics-ruby-unsat/test_expectations.yml +27 -0
  72. data/smoke/{diagnostics → diagnostics-ruby-unsat}/unsatisfiable_constraint.rb +0 -1
  73. data/smoke/diagnostics/a.rbs +0 -4
  74. data/smoke/diagnostics/test_expectations.yml +451 -0
  75. data/smoke/dstr/test_expectations.yml +13 -0
  76. data/smoke/ensure/test_expectations.yml +62 -0
  77. data/smoke/enumerator/test_expectations.yml +135 -0
  78. data/smoke/extension/f.rb +2 -0
  79. data/smoke/extension/f.rbs +3 -0
  80. data/smoke/extension/test_expectations.yml +73 -0
  81. data/smoke/hash/test_expectations.yml +81 -0
  82. data/smoke/hello/test_expectations.yml +25 -0
  83. data/smoke/if/test_expectations.yml +34 -0
  84. data/smoke/implements/b.rb +13 -0
  85. data/smoke/implements/b.rbs +12 -0
  86. data/smoke/implements/test_expectations.yml +23 -0
  87. data/smoke/initialize/test_expectations.yml +1 -0
  88. data/smoke/integer/test_expectations.yml +101 -0
  89. data/smoke/interface/test_expectations.yml +23 -0
  90. data/smoke/kwbegin/test_expectations.yml +17 -0
  91. data/smoke/lambda/test_expectations.yml +39 -0
  92. data/smoke/literal/test_expectations.yml +106 -0
  93. data/smoke/map/test_expectations.yml +1 -0
  94. data/smoke/method/test_expectations.yml +90 -0
  95. data/smoke/module/test_expectations.yml +75 -0
  96. data/smoke/regexp/test_expectations.yml +615 -0
  97. data/smoke/regression/issue_328.rb +1 -0
  98. data/smoke/regression/issue_328.rbs +0 -0
  99. data/smoke/regression/issue_332.rb +11 -0
  100. data/smoke/regression/issue_332.rbs +19 -0
  101. data/smoke/regression/issue_372.rb +8 -0
  102. data/smoke/regression/issue_372.rbs +4 -0
  103. data/smoke/regression/masgn.rb +4 -0
  104. data/smoke/regression/test_expectations.yml +60 -0
  105. data/smoke/regression/thread.rb +7 -0
  106. data/smoke/rescue/test_expectations.yml +79 -0
  107. data/smoke/self/test_expectations.yml +23 -0
  108. data/smoke/skip/test_expectations.yml +23 -0
  109. data/smoke/stdout/test_expectations.yml +1 -0
  110. data/smoke/super/test_expectations.yml +69 -0
  111. data/smoke/toplevel/test_expectations.yml +15 -0
  112. data/smoke/tsort/Steepfile +2 -0
  113. data/smoke/tsort/test_expectations.yml +63 -0
  114. data/smoke/type_case/test_expectations.yml +48 -0
  115. data/smoke/unexpected/Steepfile +5 -0
  116. data/smoke/unexpected/test_expectations.yml +25 -0
  117. data/smoke/unexpected/unexpected.rb +1 -0
  118. data/smoke/unexpected/unexpected.rbs +3 -0
  119. data/smoke/yield/test_expectations.yml +68 -0
  120. data/steep.gemspec +4 -3
  121. metadata +127 -80
  122. data/lib/steep/project/file_loader.rb +0 -68
  123. data/lib/steep/project/signature_file.rb +0 -39
  124. data/lib/steep/project/source_file.rb +0 -129
  125. data/lib/steep/project/stats_calculator.rb +0 -80
  126. data/lib/steep/server/code_worker.rb +0 -150
  127. data/lib/steep/server/signature_worker.rb +0 -157
  128. data/lib/steep/server/utils.rb +0 -69
  129. data/smoke/alias/test.yaml +0 -73
  130. data/smoke/and/test.yaml +0 -24
  131. data/smoke/array/test.yaml +0 -80
  132. data/smoke/block/test.yaml +0 -96
  133. data/smoke/broken/broken.rb +0 -0
  134. data/smoke/broken/broken.rbs +0 -0
  135. data/smoke/broken/test.yaml +0 -6
  136. data/smoke/case/test.yaml +0 -36
  137. data/smoke/class/test.yaml +0 -89
  138. data/smoke/const/test.yaml +0 -96
  139. data/smoke/diagnostics-rbs-duplicated/test.yaml +0 -10
  140. data/smoke/diagnostics-rbs/test.yaml +0 -142
  141. data/smoke/diagnostics/test.yaml +0 -333
  142. data/smoke/dstr/test.yaml +0 -10
  143. data/smoke/ensure/test.yaml +0 -47
  144. data/smoke/enumerator/test.yaml +0 -100
  145. data/smoke/extension/test.yaml +0 -50
  146. data/smoke/hash/test.yaml +0 -62
  147. data/smoke/hello/test.yaml +0 -18
  148. data/smoke/if/test.yaml +0 -27
  149. data/smoke/implements/test.yaml +0 -16
  150. data/smoke/initialize/test.yaml +0 -4
  151. data/smoke/integer/test.yaml +0 -66
  152. data/smoke/interface/test.yaml +0 -16
  153. data/smoke/kwbegin/test.yaml +0 -14
  154. data/smoke/lambda/test.yaml +0 -28
  155. data/smoke/literal/test.yaml +0 -79
  156. data/smoke/map/test.yaml +0 -4
  157. data/smoke/method/test.yaml +0 -71
  158. data/smoke/module/test.yaml +0 -51
  159. data/smoke/regexp/test.yaml +0 -372
  160. data/smoke/regression/test.yaml +0 -38
  161. data/smoke/rescue/test.yaml +0 -60
  162. data/smoke/self/test.yaml +0 -16
  163. data/smoke/skip/test.yaml +0 -16
  164. data/smoke/stdout/test.yaml +0 -4
  165. data/smoke/super/test.yaml +0 -52
  166. data/smoke/toplevel/test.yaml +0 -12
  167. data/smoke/tsort/test.yaml +0 -32
  168. data/smoke/type_case/test.yaml +0 -33
  169. data/smoke/yield/test.yaml +0 -49
@@ -1,68 +0,0 @@
1
- module Steep
2
- class Project
3
- class FileLoader
4
- attr_reader :project
5
-
6
- def initialize(project:)
7
- @project = project
8
- end
9
-
10
- def each_path_in_patterns(patterns, ext)
11
- patterns.each do |path|
12
- absolute_path = project.base_dir + path
13
-
14
- if absolute_path.file?
15
- yield project.relative_path(absolute_path)
16
- else
17
- files = if absolute_path.directory?
18
- Pathname.glob("#{absolute_path}/**/*#{ext}")
19
- else
20
- Pathname.glob(absolute_path)
21
- end
22
-
23
- files.sort.each do |source_path|
24
- yield project.relative_path(source_path)
25
- end
26
- end
27
- end
28
- end
29
-
30
- def load_sources(command_line_patterns)
31
- loaded_paths = Set[]
32
-
33
- project.targets.each do |target|
34
- Steep.logger.tagged "target=#{target.name}" do
35
- target_patterns = command_line_patterns.empty? ? target.source_patterns : command_line_patterns
36
-
37
- each_path_in_patterns(target_patterns, ".rb") do |path|
38
- if target.possible_source_file?(path)
39
- if loaded_paths.include?(path)
40
- Steep.logger.warn { "Skipping #{target} while loading #{path}... (Already loaded to another target.)" }
41
- else
42
- Steep.logger.info { "Adding source file: #{path}" }
43
- target.add_source path, project.absolute_path(path).read
44
- loaded_paths << path
45
- end
46
- end
47
- end
48
- end
49
- end
50
- end
51
-
52
- def load_signatures()
53
- project.targets.each do |target|
54
- Steep.logger.tagged "target=#{target.name}" do
55
- each_path_in_patterns target.signature_patterns, ".rbs" do |path|
56
- if target.possible_signature_file?(path)
57
- unless target.signature_file?(path)
58
- Steep.logger.info { "Adding signature file: #{path}" }
59
- target.add_signature path, project.absolute_path(path).read
60
- end
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,39 +0,0 @@
1
- module Steep
2
- class Project
3
- class SignatureFile
4
- attr_reader :path
5
- attr_reader :content
6
- attr_reader :content_updated_at
7
-
8
- ParseErrorStatus = Struct.new(:error, :timestamp, keyword_init: true)
9
- DeclarationsStatus = Struct.new(:declarations, :timestamp, keyword_init: true)
10
-
11
- def initialize(path:)
12
- @path = path
13
- self.content = ""
14
- end
15
-
16
- def content=(content)
17
- @content_updated_at = Time.now
18
- @content = content
19
- @status = nil
20
- end
21
-
22
- def status
23
- unless @status
24
- @status = DeclarationsStatus.new(declarations: [], timestamp: Time.now)
25
- end
26
-
27
- @status
28
- end
29
-
30
- def load!
31
- buffer = RBS::Buffer.new(name: path, content: content)
32
- decls = RBS::Parser.parse_signature(buffer)
33
- @status = DeclarationsStatus.new(declarations: decls, timestamp: Time.now)
34
- rescue RBS::Parser::SyntaxError, RBS::Parser::SemanticsError => exn
35
- @status = ParseErrorStatus.new(error: exn, timestamp: Time.now)
36
- end
37
- end
38
- end
39
- end
@@ -1,129 +0,0 @@
1
- module Steep
2
- class Project
3
- class SourceFile
4
- attr_reader :path
5
- attr_reader :content
6
- attr_reader :content_updated_at
7
- attr_reader :factory
8
-
9
- attr_accessor :status
10
-
11
- ParseErrorStatus = Struct.new(:error, :timestamp, keyword_init: true)
12
- AnnotationSyntaxErrorStatus = Struct.new(:error, :location, :timestamp, keyword_init: true)
13
- TypeCheckStatus = Struct.new(:typing, :source, :timestamp, keyword_init: true)
14
- TypeCheckErrorStatus = Struct.new(:error, :timestamp, keyword_init: true)
15
-
16
- def initialize(path:)
17
- @path = path
18
- @content = false
19
- self.content = ""
20
- end
21
-
22
- def content=(content)
23
- @content_updated_at = Time.now
24
- @content = content
25
- @status = nil
26
- end
27
-
28
- def errors
29
- case status
30
- when TypeCheckStatus
31
- status.typing.errors
32
- else
33
- []
34
- end
35
- end
36
-
37
- def self.parse(source_code, path:, factory:)
38
- Source.parse(source_code, path: path.to_s, factory: factory, labeling: ASTUtils::Labeling.new)
39
- end
40
-
41
- def self.type_check(source, subtyping:)
42
- annotations = source.annotations(block: source.node, factory: subtyping.factory, current_module: RBS::Namespace.root)
43
- const_env = TypeInference::ConstantEnv.new(factory: subtyping.factory, context: [RBS::Namespace.root])
44
- type_env = TypeInference::TypeEnv.build(annotations: annotations,
45
- subtyping: subtyping,
46
- const_env: const_env,
47
- signatures: subtyping.factory.env)
48
- lvar_env = TypeInference::LocalVariableTypeEnv.empty(
49
- subtyping: subtyping,
50
- self_type: AST::Builtin::Object.instance_type
51
- ).annotate(annotations)
52
-
53
- context = TypeInference::Context.new(
54
- block_context: nil,
55
- module_context: TypeInference::Context::ModuleContext.new(
56
- instance_type: AST::Builtin::Object.instance_type,
57
- module_type: AST::Builtin::Object.module_type,
58
- implement_name: nil,
59
- current_namespace: RBS::Namespace.root,
60
- const_env: const_env,
61
- class_name: AST::Builtin::Object.module_name,
62
- instance_definition: subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name),
63
- module_definition: subtyping.factory.definition_builder.build_singleton(AST::Builtin::Object.module_name)
64
- ),
65
- method_context: nil,
66
- break_context: nil,
67
- self_type: AST::Builtin::Object.instance_type,
68
- type_env: type_env,
69
- lvar_env: lvar_env,
70
- call_context: TypeInference::MethodCall::TopLevelContext.new
71
- )
72
-
73
- typing = Typing.new(source: source, root_context: context)
74
-
75
- construction = TypeConstruction.new(
76
- checker: subtyping,
77
- annotations: annotations,
78
- source: source,
79
- context: context,
80
- typing: typing
81
- )
82
-
83
- construction.synthesize(source.node) if source.node
84
-
85
- typing
86
- end
87
-
88
- def type_check(subtyping, env_updated_at)
89
- # skip type check
90
- return false if status && env_updated_at <= status.timestamp
91
-
92
- now = Time.now
93
-
94
- parse(subtyping.factory) do |source|
95
- typing = self.class.type_check(source, subtyping: subtyping)
96
- @status = TypeCheckStatus.new(typing: typing, source: source, timestamp: now)
97
- rescue RBS::NoTypeFoundError,
98
- RBS::NoMixinFoundError,
99
- RBS::NoSuperclassFoundError,
100
- RBS::DuplicatedMethodDefinitionError,
101
- RBS::InvalidTypeApplicationError => exn
102
- # Skip logging known signature errors (they are handled with load_signatures(validate: true))
103
- @status = TypeCheckErrorStatus.new(error: exn, timestamp: now)
104
- rescue => exn
105
- Steep.log_error(exn)
106
- @status = TypeCheckErrorStatus.new(error: exn, timestamp: now)
107
- end
108
-
109
- true
110
- end
111
-
112
- def parse(factory)
113
- now = Time.now
114
-
115
- if status.is_a?(TypeCheckStatus)
116
- yield status.source
117
- else
118
- yield self.class.parse(content, path: path, factory: factory)
119
- end
120
- rescue AnnotationParser::SyntaxError => exn
121
- Steep.logger.warn { "Annotation syntax error on #{path}: #{exn.inspect}" }
122
- @status = AnnotationSyntaxErrorStatus.new(error: exn, location: exn.location, timestamp: now)
123
- rescue ::Parser::SyntaxError, EncodingError => exn
124
- Steep.logger.warn { "Source parsing error on #{path}: #{exn.inspect}" }
125
- @status = ParseErrorStatus.new(error: exn, timestamp: now)
126
- end
127
- end
128
- end
129
- end
@@ -1,80 +0,0 @@
1
- module Steep
2
- class Project
3
- class StatsCalculator
4
- SuccessStats = Struct.new(:target, :path, :typed_calls_count, :untyped_calls_count, :error_calls_count, keyword_init: true) do
5
- def as_json
6
- {
7
- type: "success",
8
- target: target.name.to_s,
9
- path: path.to_s,
10
- typed_calls: typed_calls_count,
11
- untyped_calls: untyped_calls_count,
12
- error_calls: error_calls_count,
13
- total_calls: typed_calls_count + untyped_calls_count + error_calls_count
14
- }
15
- end
16
- end
17
- ErrorStats = Struct.new(:target, :path, :status, keyword_init: true) do
18
- def as_json
19
- {
20
- type: "error",
21
- target: target.name.to_s,
22
- path: path.to_s,
23
- status: status.class.to_s
24
- }
25
- end
26
- end
27
-
28
- attr_reader :project
29
-
30
- def initialize(project:)
31
- @project = project
32
- end
33
-
34
- def calc_stats(target, path)
35
- source_file = target.source_files[path] or raise
36
-
37
- target.type_check(
38
- target_sources: [source_file],
39
- validate_signatures: false
40
- )
41
-
42
- if target.status.is_a?(Target::TypeCheckStatus)
43
- case source_file.status
44
- when SourceFile::TypeCheckStatus
45
- typing = source_file.status.typing
46
-
47
- typed = 0
48
- untyped = 0
49
- errors = 0
50
- total = 0
51
- typing.method_calls.each_value do |call|
52
- case call
53
- when TypeInference::MethodCall::Typed
54
- typed += 1
55
- when TypeInference::MethodCall::Untyped
56
- untyped += 1
57
- when TypeInference::MethodCall::Error, TypeInference::MethodCall::NoMethodError
58
- errors += 1
59
- else
60
- raise
61
- end
62
- end
63
-
64
- SuccessStats.new(
65
- target: target,
66
- path: path,
67
- typed_calls_count: typed,
68
- untyped_calls_count: untyped,
69
- error_calls_count: errors
70
- )
71
- when SourceFile::TypeCheckErrorStatus, SourceFile::AnnotationSyntaxErrorStatus, SourceFile::ParseErrorStatus
72
- ErrorStats.new(target: target, path: path, status: source_file.status)
73
- end
74
- else
75
- ErrorStats.new(target: target, path: path, status: target.status)
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,150 +0,0 @@
1
- module Steep
2
- module Server
3
- class CodeWorker < BaseWorker
4
- LSP = LanguageServer::Protocol
5
-
6
- TypeCheckJob = Struct.new(:target, :path, keyword_init: true)
7
- StatsJob = Struct.new(:request, :paths, keyword_init: true)
8
-
9
- include Utils
10
-
11
- attr_reader :typecheck_paths
12
- attr_reader :queue
13
-
14
- def initialize(project:, reader:, writer:, queue: Queue.new)
15
- super(project: project, reader: reader, writer: writer)
16
-
17
- @typecheck_paths = Set[]
18
- @queue = queue
19
- end
20
-
21
- def enqueue_type_check(target:, path:)
22
- Steep.logger.info "Enqueueing type check: #{target.name}::#{path}..."
23
- queue << TypeCheckJob.new(target: target, path: path)
24
- end
25
-
26
- def typecheck_file(path, target)
27
- Steep.logger.info "Starting type checking: #{target.name}::#{path}..."
28
-
29
- source = target.source_files[path]
30
- target.type_check(target_sources: [source], validate_signatures: false)
31
-
32
- if target.status.is_a?(Project::Target::TypeCheckStatus) && target.status.type_check_sources.empty?
33
- Steep.logger.debug "Skipped type checking: #{target.name}::#{path}"
34
- else
35
- Steep.logger.info "Finished type checking: #{target.name}::#{path}"
36
- end
37
-
38
- diagnostics = source_diagnostics(source, target.options)
39
-
40
- writer.write(
41
- method: :"textDocument/publishDiagnostics",
42
- params: LSP::Interface::PublishDiagnosticsParams.new(
43
- uri: URI.parse(project.absolute_path(path).to_s).tap {|uri| uri.scheme = "file"},
44
- diagnostics: diagnostics
45
- )
46
- )
47
- end
48
-
49
- def calculate_stats(request_id, paths)
50
- calculator = Project::StatsCalculator.new(project: project)
51
-
52
- stats = paths.map do |path|
53
- if typecheck_paths.include?(path)
54
- if target = project.target_for_source_path(path)
55
- calculator.calc_stats(target, path)
56
- end
57
- end
58
- end.compact
59
-
60
- writer.write(
61
- id: request_id,
62
- result: stats.map(&:as_json)
63
- )
64
- end
65
-
66
- def source_diagnostics(source, options)
67
- case status = source.status
68
- when Project::SourceFile::ParseErrorStatus
69
- []
70
- when Project::SourceFile::AnnotationSyntaxErrorStatus
71
- [
72
- LSP::Interface::Diagnostic.new(
73
- message: "Annotation syntax error: #{status.error.cause.message}",
74
- severity: LSP::Constant::DiagnosticSeverity::ERROR,
75
- range: LSP::Interface::Range.new(
76
- start: LSP::Interface::Position.new(
77
- line: status.location.start_line - 1,
78
- character: status.location.start_column
79
- ),
80
- end: LSP::Interface::Position.new(
81
- line: status.location.end_line - 1,
82
- character: status.location.end_column
83
- )
84
- )
85
- )
86
- ]
87
- when Project::SourceFile::TypeCheckStatus
88
- formatter = Diagnostic::LSPFormatter.new()
89
- status.typing.errors.select {|error| options.error_to_report?(error) }.map {|error| formatter.format(error) }
90
- when Project::SourceFile::TypeCheckErrorStatus
91
- []
92
- end
93
- end
94
-
95
- def handle_request(request)
96
- case request[:method]
97
- when "initialize"
98
- project.targets.each do |target|
99
- target.source_files.each_key do |path|
100
- if typecheck_paths.include?(path)
101
- enqueue_type_check(target: target, path: path)
102
- end
103
- end
104
- end
105
-
106
- writer.write({ id: request[:id], result: nil })
107
-
108
- when "workspace/executeCommand"
109
- Steep.logger.info { "Executing command: #{request[:params][:command]}, arguments=#{request[:params][:arguments].map(&:inspect).join(", ")}" }
110
- case request[:params][:command]
111
- when "steep/registerSourceToWorker"
112
- paths = request[:params][:arguments].map {|arg| source_path(URI.parse(arg)) }
113
- typecheck_paths.merge(paths)
114
- when "steep/stats"
115
- paths = request[:params][:arguments].map {|arg| source_path(URI.parse(arg)) }
116
- queue << StatsJob.new(paths: paths, request: request)
117
- end
118
-
119
- when "textDocument/didChange"
120
- update_source(request) do |path, _|
121
- source_target, signature_targets = project.targets_for_path(path)
122
-
123
- if source_target
124
- if typecheck_paths.include?(path)
125
- enqueue_type_check(target: source_target, path: path)
126
- end
127
- end
128
-
129
- signature_targets.each do |target|
130
- target.source_files.each_key do |source_path|
131
- if typecheck_paths.include?(source_path)
132
- enqueue_type_check(target: target, path: source_path)
133
- end
134
- end
135
- end
136
- end
137
- end
138
- end
139
-
140
- def handle_job(job)
141
- case job
142
- when TypeCheckJob
143
- typecheck_file(job.path, job.target)
144
- when StatsJob
145
- calculate_stats(job.request[:id], job.paths)
146
- end
147
- end
148
- end
149
- end
150
- end