Skip to content

Commit

Permalink
Merge pull request #673 from soutaro/cache-constant-resolver
Browse files Browse the repository at this point in the history
Cache `constant_resolver` among files in a target
  • Loading branch information
soutaro committed Nov 22, 2022
2 parents 3f4983a + dc4a48f commit c852773
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 10 deletions.
3 changes: 2 additions & 1 deletion lib/steep/services/completion_provider.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ def type_check!(text, line:, column:)
end

Steep.measure "typechecking" do
@typing = TypeCheckService.type_check(source: source, subtyping: subtyping)
resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
@typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver)
end
end

Expand Down
3 changes: 2 additions & 1 deletion lib/steep/services/goto_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,9 @@ def type_check_path(target:, path:, content:, line:, column:)
subtyping = signature_service.current_subtyping or return
source = Source.parse(content, path: path, factory: subtyping.factory)
source = source.without_unrelated_defs(line: line, column: column)
resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
[
Services::TypeCheckService.type_check(source: source, subtyping: subtyping),
Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver),
signature_service
]
rescue
Expand Down
3 changes: 2 additions & 1 deletion lib/steep/services/hover_provider/ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ def typecheck(target, path:, content:, line:, column:)
subtyping = service.signature_services[target.name].current_subtyping or return
source = Source.parse(content, path: path, factory: subtyping.factory)
source = source.without_unrelated_defs(line: line, column: column)
Services::TypeCheckService.type_check(source: source, subtyping: subtyping)
resolver = ::RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver)
rescue
nil
end
Expand Down
16 changes: 16 additions & 0 deletions lib/steep/services/signature_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ def rbs_index
builder.env(last_builder.env)
end
end

def constant_resolver
@constant_resolver ||= RBS::Resolver::ConstantResolver.new(builder: last_builder)
end
end

class AncestorErrorStatus
Expand All @@ -37,6 +41,10 @@ def rbs_index
builder.env(last_builder.env)
end
end

def constant_resolver
@constant_resolver ||= RBS::Resolver::ConstantResolver.new(builder: last_builder)
end
end

class LoadedStatus
Expand All @@ -61,6 +69,10 @@ def rbs_index
builder.env(self.builder.env)
end
end

def constant_resolver
@constant_resolver ||= RBS::Resolver::ConstantResolver.new(builder: builder)
end
end

FileStatus = _ = Struct.new(:path, :content, :decls, keyword_init: true)
Expand Down Expand Up @@ -125,6 +137,10 @@ def latest_rbs_index
status.rbs_index
end

def latest_constant_resolver
status.constant_resolver
end

def current_subtyping
if status.is_a?(LoadedStatus)
status.subtyping
Expand Down
8 changes: 4 additions & 4 deletions lib/steep/services/type_check_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def typecheck_source(path:, target: project.target_for_source_path(path), &block

if subtyping
text = source_files[path].content
file = type_check_file(target: target, subtyping: subtyping, path: path, text: text)
file = type_check_file(target: target, subtyping: subtyping, path: path, text: text) { signature_service.latest_constant_resolver }
yield [file.path, file.diagnostics]
source_files[path] = file
end
Expand Down Expand Up @@ -326,7 +326,7 @@ def update_sources(changes:, requests:)
def type_check_file(target:, subtyping:, path:, text:)
Steep.logger.tagged "#type_check_file(#{path}@#{target.name})" do
source = Source.parse(text, path: path, factory: subtyping.factory)
typing = TypeCheckService.type_check(source: source, subtyping: subtyping)
typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: yield)
SourceFile.with_typing(path: path, content: text, node: source.node, typing: typing)
end
rescue AnnotationParser::SyntaxError => exn
Expand All @@ -342,15 +342,15 @@ def type_check_file(target:, subtyping:, path:, text:)
SourceFile.no_data(path: path, content: text)
end

def self.type_check(source:, subtyping:)
def self.type_check(source:, subtyping:, constant_resolver:)
annotations = source.annotations(block: source.node, factory: subtyping.factory, context: nil)

definition = subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name)

const_env = TypeInference::ConstantEnv.new(
factory: subtyping.factory,
context: nil,
resolver: RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
resolver: constant_resolver
)
type_env = TypeInference::TypeEnv.new(const_env)
type_env = TypeInference::TypeEnvBuilder.new(
Expand Down
14 changes: 14 additions & 0 deletions sig/steep/services/signature_service.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ module Steep

@rbs_index: Index::RBSIndex?

@constant_resolver: RBS::Resolver::ConstantResolver?

def initialize: (files: Hash[Pathname, FileStatus], changed_paths: Set[Pathname], diagnostics: Array[Diagnostic::Signature::Base], last_builder: RBS::DefinitionBuilder) -> void

def rbs_index: () -> Index::RBSIndex

def constant_resolver: () -> RBS::Resolver::ConstantResolver
end

class AncestorErrorStatus
Expand All @@ -32,9 +36,13 @@ module Steep

@rbs_index: Index::RBSIndex?

@constant_resolver: RBS::Resolver::ConstantResolver?

def initialize: (files: Hash[Pathname, FileStatus], changed_paths: Set[Pathname], diagnostics: Array[Diagnostic::Signature::Base], last_builder: RBS::DefinitionBuilder) -> void

def rbs_index: () -> Index::RBSIndex

def constant_resolver: () -> RBS::Resolver::ConstantResolver
end

class LoadedStatus
Expand All @@ -46,11 +54,15 @@ module Steep

@subtyping: Subtyping::Check?

@constant_resolver: RBS::Resolver::ConstantResolver?

def initialize: (files: Hash[Pathname, FileStatus], builder: RBS::DefinitionBuilder) -> void

def subtyping: () -> Subtyping::Check

def rbs_index: () -> Index::RBSIndex

def constant_resolver: () -> RBS::Resolver::ConstantResolver
end

class FileStatus
Expand Down Expand Up @@ -88,6 +100,8 @@ module Steep

def latest_rbs_index: () -> Index::RBSIndex

def latest_constant_resolver: () -> RBS::Resolver::ConstantResolver

def current_subtyping: () -> Subtyping::Check?

def apply_changes: (Hash[Pathname, FileStatus] files, Server::ChangeBuffer::changes changes) -> Hash[Pathname, FileStatus]
Expand Down
4 changes: 2 additions & 2 deletions sig/steep/services/type_check_service.rbs
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,9 @@ module Steep

def update_sources: (changes: Server::ChangeBuffer::changes, requests: Hash[Project::Target, TargetRequest]) -> void

def type_check_file: (target: Project::Target, subtyping: Subtyping::Check, path: Pathname, text: String) -> SourceFile
def type_check_file: (target: Project::Target, subtyping: Subtyping::Check, path: Pathname, text: String) { () -> RBS::Resolver::ConstantResolver } -> SourceFile

def self.type_check: (source: Source, subtyping: Subtyping::Check) -> Typing
def self.type_check: (source: Source, subtyping: Subtyping::Check, constant_resolver: RBS::Resolver::ConstantResolver) -> Typing

def source_file?: (Pathname path) -> Project::Target?

Expand Down
3 changes: 2 additions & 1 deletion test/server/lsp_formatter_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def type_check(content)
source = Source.parse(content, path: Pathname("a.rb"), factory: factory)
builder = Interface::Builder.new(factory)
subtyping = Subtyping::Check.new(builder: builder)
Services::TypeCheckService.type_check(source: source, subtyping: subtyping)
resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver)
end

def test_ruby_hover_variable
Expand Down

0 comments on commit c852773

Please sign in to comment.