lib/steep/server/code_worker.rb in steep-0.39.0 vs lib/steep/server/code_worker.rb in steep-0.40.0
- old
+ new
@@ -1,10 +1,13 @@
module Steep
module Server
class CodeWorker < BaseWorker
LSP = LanguageServer::Protocol
+ TypeCheckJob = Struct.new(:target, :path, keyword_init: true)
+ StatsJob = Struct.new(:request, :paths, keyword_init: true)
+
include Utils
attr_reader :typecheck_paths
attr_reader :queue
@@ -15,11 +18,11 @@
@queue = queue
end
def enqueue_type_check(target:, path:)
Steep.logger.info "Enqueueing type check: #{target.name}::#{path}..."
- queue << [target, path]
+ queue << TypeCheckJob.new(target: target, path: path)
end
def typecheck_file(path, target)
Steep.logger.info "Starting type checking: #{target.name}::#{path}..."
@@ -41,10 +44,27 @@
diagnostics: diagnostics
)
)
end
+ def calculate_stats(request_id, paths)
+ calculator = Project::StatsCalculator.new(project: project)
+
+ stats = paths.map do |path|
+ if typecheck_paths.include?(path)
+ if target = project.target_for_source_path(path)
+ calculator.calc_stats(target, path)
+ end
+ end
+ end.compact
+
+ writer.write(
+ id: request_id,
+ result: stats.map(&:as_json)
+ )
+ end
+
def source_diagnostics(source, options)
case status = source.status
when Project::SourceFile::ParseErrorStatus
[]
when Project::SourceFile::AnnotationSyntaxErrorStatus
@@ -63,49 +83,39 @@
)
)
)
]
when Project::SourceFile::TypeCheckStatus
- status.typing.errors.select {|error| options.error_to_report?(error) }.map do |error|
- loc = error.location_to_str
-
- LSP::Interface::Diagnostic.new(
- message: StringIO.new.tap {|io| error.print_to(io) }.string.gsub(/\A#{Regexp.escape(loc)}: /, "").chomp,
- severity: LSP::Constant::DiagnosticSeverity::ERROR,
- range: LSP::Interface::Range.new(
- start: LSP::Interface::Position.new(
- line: error.node.loc.line - 1,
- character: error.node.loc.column
- ),
- end: LSP::Interface::Position.new(
- line: error.node.loc.last_line - 1,
- character: error.node.loc.last_column
- )
- )
- )
- end
+ formatter = Diagnostic::LSPFormatter.new()
+ status.typing.errors.select {|error| options.error_to_report?(error) }.map {|error| formatter.format(error) }
when Project::SourceFile::TypeCheckErrorStatus
[]
end
end
def handle_request(request)
case request[:method]
when "initialize"
- # Don't respond to initialize request, but start type checking.
project.targets.each do |target|
target.source_files.each_key do |path|
if typecheck_paths.include?(path)
enqueue_type_check(target: target, path: path)
end
end
end
+ writer.write({ id: request[:id], result: nil })
+
when "workspace/executeCommand"
- if request[:params][:command] == "steep/registerSourceToWorker"
+ Steep.logger.info { "Executing command: #{request[:params][:command]}, arguments=#{request[:params][:arguments].map(&:inspect).join(", ")}" }
+ case request[:params][:command]
+ when "steep/registerSourceToWorker"
paths = request[:params][:arguments].map {|arg| source_path(URI.parse(arg)) }
typecheck_paths.merge(paths)
+ when "steep/stats"
+ paths = request[:params][:arguments].map {|arg| source_path(URI.parse(arg)) }
+ queue << StatsJob.new(paths: paths, request: request)
end
when "textDocument/didChange"
update_source(request) do |path, _|
source_target, signature_targets = project.targets_for_path(path)
@@ -126,12 +136,15 @@
end
end
end
def handle_job(job)
- target, path = job
-
- typecheck_file(path, target)
+ case job
+ when TypeCheckJob
+ typecheck_file(job.path, job.target)
+ when StatsJob
+ calculate_stats(job.request[:id], job.paths)
+ end
end
end
end
end