Steepコードリーディング(6日目)
今回は以下のJobが何をしているのかざっくりと追い、目的の型検査のJobを見つける。
StartTypeCheckJob
ValidateAppSignatureJob
ValidateLibrarySignatureJob
TypeCheckCodeJob
WorkspaceSymbolJob
StatsJob
GotoJob
と意気込んでいたが、Job自体は単なるStructオブジェクトに過ぎなかった。
WorkspaceSymbolJob = _ = Struct.new(:query, :id, keyword_init: true)
StatsJob = _ = Struct.new(:id, keyword_init: true)
StartTypeCheckJob = _ = Struct.new(:guid, :changes, keyword_init: true)
TypeCheckCodeJob = _ = Struct.new(:guid, :path, :target, keyword_init: true)
ValidateAppSignatureJob = _ = Struct.new(:guid, :path, :target, keyword_init: true)
ValidateLibrarySignatureJob = _ = Struct.new(:guid, :path, :target, keyword_init: true)
class GotoJob < Struct.new(:id, :kind, :params, keyword_init: true)
def self.implementation(id:, params:)
new(
kind: :implementation,
id: id,
params: params
)
end
def self.definition(id:, params:)
new(
kind: :definition,
id: id,
params: params
)
end
def self.type_definition(id:, params:)
new(
kind: :type_definition,
id: id,
params: params
)
end
def implementation?
kind == :implementation
end
def definition?
kind == :definition
end
def type_definition?
kind == :type_definition
end
end
仕方ないのでhandle_job
での処理内容からいくつかあたりをつけて追っていくことにする。
StartTypeCheckJob
ログを吐いてservice.update
を行っている。
when StartTypeCheckJob
Steep.logger.info { "Processing StartTypeCheckJob for guid=#{job.guid}" }
service.update(changes: job.changes)
service
メソッドの中身はこれ。
def service
@service ||= Services::TypeCheckService.new(project: project)
end
ん?なんか早くもゴールを見つけた気がする...?
ValidateAppSignatureJob
service.validate_signature
を行っている。メソッド名から察するにRBSのSyntaxチェックとかだろうか。
when ValidateAppSignatureJob
if job.guid == current_type_check_guid
Steep.logger.info { "Processing ValidateAppSignature for guid=#{job.guid}, path=#{job.path}" }
formatter = Diagnostic::LSPFormatter.new({}, **{})
diagnostics = service.validate_signature(path: project.relative_path(job.path), target: job.target)
typecheck_progress(
path: job.path,
guid: job.guid,
target: job.target,
diagnostics: diagnostics.filter_map { formatter.format(_1) }
)
end
typecheck_progress
はこれ。
def typecheck_progress(guid:, path:, target:, diagnostics:)
writer.write(CustomMethods::TypeCheck__Progress.notification({ guid: guid, path: path.to_s, target: target.name.to_s, diagnostics: diagnostics }))
end
ValidateLibrarySignatureJob
これもservice.validate_signature
を行っている。差分でいうとpathがprojectではなくjobの持っているpathになっていること。名前から察するにgem_rbs_collectionやRBS本体が持っているライブラリのRBSのSyntaxチェックとかだろうか。
when ValidateLibrarySignatureJob
if job.guid == current_type_check_guid
Steep.logger.info { "Processing ValidateLibrarySignature for guid=#{job.guid}, path=#{job.path}" }
formatter = Diagnostic::LSPFormatter.new({}, **{})
diagnostics = service.validate_signature(path: job.path, target: job.target)
typecheck_progress(path: job.path, guid: job.guid, target: job.target, diagnostics: diagnostics.filter_map { formatter.format(_1) })
end
TypeCheckCodeJob
service.typecheck_source
を実行している。直前で出てくる変数名やtypecheck_source
というメソッド名がいかにもアプリケーションの型検査していますと言っている。
when TypeCheckCodeJob
if job.guid == current_type_check_guid
Steep.logger.info { "Processing TypeCheckCodeJob for guid=#{job.guid}, path=#{job.path}, target=#{job.target.name}" }
group_target = project.group_for_source_path(job.path) || job.target
formatter = Diagnostic::LSPFormatter.new(group_target.code_diagnostics_config)
relative_path = project.relative_path(job.path)
diagnostics = service.typecheck_source(path: relative_path, target: job.target)
typecheck_progress(path: job.path, guid: job.guid, target: job.target, diagnostics: diagnostics&.filter_map { formatter.format(_1) })
end
ここまでで、型検査自体はservice.typecheck_source
、Syntaxチェックなどはservice.validate_signature
を追っていけば良さそうなあたりがついた。
WorkspaceSymbolJob
、StatsJob
、GotoJob
標準入力に何か入力していそうだけど、型検査自体とは無関係と見て良さそう。
when WorkspaceSymbolJob
writer.write(
id: job.id,
result: workspace_symbol_result(job.query)
)
when StatsJob
writer.write(
id: job.id,
result: stats_result().map(&:as_json)
)
when GotoJob
writer.write(
id: job.id,
result: goto(job)
)
end
以後型検査周りはservice.typecheck_source
とservice.validate_signature
を追っていけば良さそうなあたりがついた。今興味があるのは型検査部分なので、ひとまずservice.typecheck_source
を追い、時間が余ればservice.validate_signature
も見ていく感じとしていきたい。