From bc82b53ce97075e8ce5b37f0d73187afafcb3c75 Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Tue, 6 Aug 2024 10:44:24 +0900 Subject: [PATCH 1/6] =?UTF-8?q?bundle=20update=20=E2=80=94bundler?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Gemfile.lock | 2 +- gemfile_steep/Gemfile.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index db9bcf255..ea31d4db1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -107,4 +107,4 @@ DEPENDENCIES vernier (~> 1.0) BUNDLED WITH - 2.3.8 + 2.5.17 diff --git a/gemfile_steep/Gemfile.lock b/gemfile_steep/Gemfile.lock index 3e341ffba..e7cbe7f76 100644 --- a/gemfile_steep/Gemfile.lock +++ b/gemfile_steep/Gemfile.lock @@ -74,4 +74,4 @@ DEPENDENCIES steep (~> 1.7.0.dev) BUNDLED WITH - 2.3.15 + 2.5.17 From 7a9e863eab09eed075197d894259941cd5cd2c93 Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Tue, 6 Aug 2024 10:44:34 +0900 Subject: [PATCH 2/6] Add CursorContext --- lib/steep/services/type_check_service.rb | 2 +- lib/steep/typing.rb | 59 +++++++++++++++++++++--- sig/steep/typing.rbs | 23 ++++++++- test/logic_type_interpreter_test.rb | 18 ++++---- test/test_helper.rb | 2 +- test/type_construction_test.rb | 4 +- test/typing_test.rb | 10 ++-- 7 files changed, 93 insertions(+), 25 deletions(-) diff --git a/lib/steep/services/type_check_service.rb b/lib/steep/services/type_check_service.rb index 1000271ec..9889ad9cd 100644 --- a/lib/steep/services/type_check_service.rb +++ b/lib/steep/services/type_check_service.rb @@ -418,7 +418,7 @@ def self.type_check(source:, subtyping:, constant_resolver:) variable_context: TypeInference::Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context) + typing = Typing.new(source: source, root_context: context, cursor: nil) construction = TypeConstruction.new( checker: subtyping, diff --git a/lib/steep/typing.rb b/lib/steep/typing.rb index 20b789922..72432cecc 100644 --- a/lib/steep/typing.rb +++ b/lib/steep/typing.rb @@ -11,6 +11,42 @@ def initialize(op, node:) end end + class CursorContext + attr_reader :index + + attr_reader :data + + def initialize(index) + @index = index + end + + def set(range, context = nil) + if range.is_a?(CursorContext) + range, context = range.data + range or return + context or return + end + + context or raise + return unless index + + if current_range = self.range + if range.begin <= index && index <= range.end + if current_range.begin <= range.begin && range.end <= current_range.end + @data = [range, context] + end + end + else + @data = [range, context] + end + end + + # def set!(other) + # @data = other.data + # self + # end + end + attr_reader :source attr_reader :errors attr_reader :typing @@ -22,8 +58,9 @@ def initialize(op, node:) attr_reader :root_context attr_reader :method_calls attr_reader :source_index + attr_reader :cursor_context - def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil, source_index: nil) + def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil, source_index: nil, cursor:) @source = source @parent = parent @@ -37,6 +74,11 @@ def initialize(source:, root_context:, parent: nil, parent_last_update: parent&. @contexts = contexts || TypeInference::ContextArray.from_source(source: source, context: root_context) (@method_calls = {}).compare_by_identity + @cursor_context = CursorContext.new(cursor) + if root_context + cursor_context.set(0..source.buffer.content&.size || 0, root_context) + end + @source_index = source_index || Index::SourceIndex.new(source: source) end @@ -225,11 +267,14 @@ def self.summary(node) def new_child(range) context = contexts[range.begin] || contexts.root.context - child = self.class.new(source: source, - parent: self, - root_context: root_context, - contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: context), - source_index: source_index.new_child) + child = self.class.new( + source: source, + parent: self, + root_context: root_context, + contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: context), + source_index: source_index.new_child, + cursor: cursor_context.index + ) @should_update = true if block_given? @@ -259,6 +304,8 @@ def save! parent.add_error error end + parent.cursor_context.set(cursor_context) + parent.source_index.merge!(source_index) end end diff --git a/sig/steep/typing.rbs b/sig/steep/typing.rbs index 27471f984..f6db566ba 100644 --- a/sig/steep/typing.rbs +++ b/sig/steep/typing.rbs @@ -10,6 +10,25 @@ module Steep def initialize: (Symbol op, node: Parser::AST::Node) -> void end + # Maps the context for a given cursor position + # + class CursorContext + attr_reader index: Integer? + + attr_reader data: [Range[Integer], Context]? + + def initialize: (Integer? index) -> void + + def set: (Range[Integer], Context context) -> void + | (CursorContext) -> void + + # def set!: (CursorContext) -> self + + %a{pure} def context: () -> Context? + + %a{pure} def range: () -> Range[Integer]? + end + attr_reader source: Source attr_reader errors: Array[Diagnostic::Ruby::Base] @@ -24,6 +43,8 @@ module Steep attr_reader should_update: bool + attr_reader cursor_context: CursorContext + attr_reader contexts: ContextArray attr_reader root_context: Context @@ -32,7 +53,7 @@ module Steep attr_reader source_index: Index::SourceIndex - def initialize: (source: Source, root_context: Context, ?parent: Typing?, ?parent_last_update: Integer?, ?contexts: ContextArray?, ?source_index: Index::SourceIndex?) -> void + def initialize: (source: Source, root_context: Context, ?parent: Typing?, ?parent_last_update: Integer?, ?contexts: ContextArray?, ?source_index: Index::SourceIndex?, cursor: Integer?) -> void def add_error: (Diagnostic::Ruby::Base error) -> void diff --git a/test/logic_type_interpreter_test.rb b/test/logic_type_interpreter_test.rb index f48b5c5da..8be7b6df7 100644 --- a/test/logic_type_interpreter_test.rb +++ b/test/logic_type_interpreter_test.rb @@ -32,7 +32,7 @@ def test_lvar_assignment with_checker do |checker| source = parse_ruby("a = @x") - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(source.node), parse_type("::String?"), nil) typing.add_typing(dig(source.node, 1), parse_type("::String?"), nil) @@ -52,7 +52,7 @@ def test_masgn with_checker do |checker| source = parse_ruby("a, b = @x") - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(source.node), parse_type("[::String, ::Integer]?"), nil) typing.add_typing(dig(source.node, 1), parse_type("[::String, ::Integer]?"), nil) @@ -96,7 +96,7 @@ class Article return_type: parse_type("::String?") ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil, cursor: nil) typing.add_typing(dig(node), parse_type("::String?"), nil) typing.add_typing(dig(node, 1), parse_type("::String?"), nil) typing.add_typing(dig(node, 1, 0), parse_type("::Article"), nil) @@ -141,7 +141,7 @@ def test_call_is_a_p return_type: AST::Types::Logic::ReceiverIsArg.new() ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(node), AST::Types::Logic::ReceiverIsArg.new(), nil) typing.add_typing(dig(node, 0), parse_type("::String?"), nil) typing.add_typing(dig(node, 2), parse_type("singleton(::String)"), nil) @@ -182,7 +182,7 @@ def test_call_nil_p return_type: AST::Types::Logic::ReceiverIsNil.new() ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(node), AST::Types::Logic::ReceiverIsNil.new(), nil) typing.add_typing(dig(node, 0), parse_type("::String?"), nil) @@ -222,7 +222,7 @@ def test_call_arg_is_receiver return_type: AST::Types::Logic::ArgIsReceiver.new() ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(node), AST::Types::Logic::ArgIsReceiver.new(), nil) typing.add_typing(dig(node, 0), parse_type("singleton(::String)"), nil) typing.add_typing(dig(node, 2), parse_type("::String?"), nil) @@ -263,7 +263,7 @@ def test_call_arg_equals_receiver return_type: AST::Types::Logic::ArgEqualsReceiver.new() ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(node), AST::Types::Logic::ArgEqualsReceiver.new(), nil) typing.add_typing(dig(node, 0), parse_type("::String"), nil) typing.add_typing(dig(node, 2), parse_type("::String?"), nil) @@ -303,7 +303,7 @@ def test_call_arg_is_ancestor return_type: AST::Types::Logic::ArgIsAncestor.new() ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(node), AST::Types::Logic::ArgIsAncestor.new(), nil) typing.add_typing(dig(node, 0), parse_type("singleton(::Object)"), nil) typing.add_typing(dig(node, 2), parse_type("singleton(::String)"), nil) @@ -345,7 +345,7 @@ def test_call_not return_type: AST::Types::Logic::Not.new() ) - typing = Typing.new(source: source, root_context: nil) + typing = Typing.new(source: source, root_context: nil, cursor: nil) typing.add_typing(dig(node), AST::Types::Logic::Not.new(), nil) typing.add_typing(dig(node, 0), parse_type("::String?"), nil) diff --git a/test/test_helper.rb b/test/test_helper.rb index 1f0c0b089..7ad031a6c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -626,7 +626,7 @@ def with_standard_construction(checker, source) call_context: TypeInference::MethodCall::TopLevelContext.new(), variable_context: Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context) + typing = Typing.new(source: source, root_context: context, cursor: nil) construction = TypeConstruction.new(checker: checker, source: source, diff --git a/test/type_construction_test.rb b/test/type_construction_test.rb index ff8eb185f..d5274961b 100644 --- a/test/type_construction_test.rb +++ b/test/type_construction_test.rb @@ -1069,7 +1069,7 @@ class Names call_context: MethodCall::TopLevelContext.new, variable_context: Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context) + typing = Typing.new(source: source, root_context: context, cursor: nil) module_name_class_node = source.node.children[1] @@ -1160,7 +1160,7 @@ class Steep end call_context: MethodCall::ModuleContext.new(type_name: TypeName("::Steep")), variable_context: Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context) + typing = Typing.new(source: source, root_context: context, cursor: nil) module_node = source.node.children.last diff --git a/test/typing_test.rb b/test/typing_test.rb index 8428f1591..215e3ad62 100644 --- a/test/typing_test.rb +++ b/test/typing_test.rb @@ -34,7 +34,7 @@ def test_1 source = parse_ruby("123") node = source.node - typing = Steep::Typing.new(source: source, root_context: context) + typing = Steep::Typing.new(source: source, root_context: context, cursor: nil) type = parse_type("::String") @@ -48,7 +48,7 @@ def test_new_child_with_save source = parse_ruby("123 + 456") node = source.node - typing = Steep::Typing.new(source: source, root_context: context) + typing = Steep::Typing.new(source: source, root_context: context, cursor: nil) type = parse_type("::String") @@ -72,7 +72,7 @@ def test_new_child_without_save source = parse_ruby("123 + 456") node = source.node - typing = Steep::Typing.new(source: source, root_context: context) + typing = Steep::Typing.new(source: source, root_context: context, cursor: nil) type = parse_type("::String") @@ -94,7 +94,7 @@ def test_new_child_check source = parse_ruby("123 + 456") node = source.node - typing = Steep::Typing.new(source: source, root_context: context) + typing = Steep::Typing.new(source: source, root_context: context, cursor: nil) type = parse_type("::String") @@ -114,7 +114,7 @@ def test_new_child_check2 source = parse_ruby("123 + 456") node = source.node - typing = Steep::Typing.new(source: source, root_context: context) + typing = Steep::Typing.new(source: source, root_context: context, cursor: nil) type = parse_type("::String") From 850b661236891590b936731d8aa1475721a2c08b Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Tue, 6 Aug 2024 11:24:00 +0900 Subject: [PATCH 3/6] Avoid passing `nil` to `Buffer` --- lib/steep/services/signature_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/steep/services/signature_service.rb b/lib/steep/services/signature_service.rb index b4c7332bc..0f75f57a2 100644 --- a/lib/steep/services/signature_service.rb +++ b/lib/steep/services/signature_service.rb @@ -156,6 +156,7 @@ def apply_changes(files, changes) old_text = files[path]&.content content = cs.inject(old_text || "") {|text, change| change.apply_to(text) } + content ||= "" # It was not clear why `content` can be `nil`, but it happens with `master_test`. buffer = RBS::Buffer.new(name: path, content: content) update[path] = From d5394c5b17e343197f36e2fbd5acbfd298cb7c89 Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Tue, 6 Aug 2024 15:22:00 +0900 Subject: [PATCH 4/6] Use CursorContext --- bin/steep-check.rb | 2 +- lib/steep/services/completion_provider.rb | 21 +- lib/steep/services/goto_service.rb | 5 +- lib/steep/services/hover_provider/ruby.rb | 11 +- lib/steep/services/signature_help_provider.rb | 3 +- lib/steep/services/type_check_service.rb | 6 +- lib/steep/type_construction.rb | 50 ++-- lib/steep/typing.rb | 269 ++++++++++++------ sig/steep/services/type_check_service.rbs | 4 +- sig/steep/type_construction.rbs | 8 +- sig/steep/typing.rbs | 18 +- test/server/lsp_formatter_test.rb | 2 +- test/test_helper.rb | 9 +- test/type_construction_test.rb | 116 ++++---- 14 files changed, 333 insertions(+), 191 deletions(-) diff --git a/bin/steep-check.rb b/bin/steep-check.rb index 157e0a41d..2405f3490 100755 --- a/bin/steep-check.rb +++ b/bin/steep-check.rb @@ -134,7 +134,7 @@ def type_check_files(command_line_args, env) variable_context: TypeInference::Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context) + typing = Typing.new(source: source, root_context: context, cursor: nil) construction = TypeConstruction.new(checker: subtyping, source: source, annotations: annotations, context: context, typing: typing) construction.synthesize(source.node) diff --git a/lib/steep/services/completion_provider.rb b/lib/steep/services/completion_provider.rb index 1734f2ca2..624359b51 100644 --- a/lib/steep/services/completion_provider.rb +++ b/lib/steep/services/completion_provider.rb @@ -183,8 +183,9 @@ def type_check!(text, line:, column:) end Steep.measure "typechecking" do + location = source.buffer.loc_to_pos([line, column]) resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder) - @typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver) + @typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: location) end end @@ -348,7 +349,7 @@ def items_for_trigger(position:) items = [] #: Array[item] - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise case when node.type == :send && node.children[0] == nil && at_end?(position, of: (_ = node.loc).selector) @@ -469,7 +470,7 @@ def items_for_dot(position:) if at_end?(shift_pos, of: node.loc) begin - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise receiver_type = case (type = typing.type_of(node: node)) when AST::Types::Self @@ -499,7 +500,7 @@ def items_for_qcall(position:) if at_end?(shift_pos, of: node.loc) begin - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise receiver_type = case (type = typing.type_of(node: node)) when AST::Types::Self @@ -529,11 +530,11 @@ def items_for_colon2(position:) case node&.type when :const # Constant:: ← - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise constant_items_for_context(context, parent: node, position: position, items: items, prefix: "") when nil # :: ← - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise constant_items_for_context(context, parent: nil, position: position, items: items, prefix: "") end @@ -552,7 +553,7 @@ def items_for_atmark(position:) return [] unless node - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise items = [] #: Array[item] instance_variable_items_for_context(context, prefix: "@", position: position, items: items) items @@ -561,7 +562,7 @@ def items_for_atmark(position:) def items_for_rbs(position:, buffer:) items = [] #: Array[item] - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise completion = TypeNameCompletion.new(env: context.env, context: context.module_context.nesting, dirs: []) prefix = TypeNameCompletion::Prefix.parse(buffer, line: position.line, column: position.column) @@ -609,7 +610,7 @@ def items_for_following_keyword_arguments(text, index:, line:, column:, items:) def method_items_for_receiver_type(type, include_private:, prefix:, position:, items:) range = range_for(position, prefix: prefix) - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise config = if (module_type = context.module_context&.module_type) && (instance_type = context.module_context&.instance_type) @@ -731,7 +732,7 @@ def keyword_argument_items_for_method(call_node:, send_node:, position:, prefix: case call when TypeInference::MethodCall::Typed, TypeInference::MethodCall::Error - context = typing.context_at(line: position.line, column: position.column) + context = typing.cursor_context.context or raise type = call.receiver_type type = type.subst(Interface::Substitution.build([], self_type: context.self_type, module_type: context.module_context&.module_type, instance_type: context.module_context&.instance_type)) diff --git a/lib/steep/services/goto_service.rb b/lib/steep/services/goto_service.rb index 46ae81138..b1db71810 100644 --- a/lib/steep/services/goto_service.rb +++ b/lib/steep/services/goto_service.rb @@ -176,7 +176,7 @@ def query_at(path:, line:, column:) when :def, :defs named_location = (_ = node.location) #: Parser::AST::_NamedLocation if test_ast_location(named_location.name, line: line, column: column) - if method_context = typing.context_at(line: line, column: column).method_context + if method_context = typing.cursor_context.context&.method_context if method = method_context.method method.defs.each do |defn| singleton_method = @@ -285,8 +285,9 @@ def type_check_path(target:, path:, content:, line:, column:) 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) + loc = source.buffer.loc_to_pos([line, column]) [ - Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver), + Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: loc), signature_service ] rescue diff --git a/lib/steep/services/hover_provider/ruby.rb b/lib/steep/services/hover_provider/ruby.rb index 266950245..bb0fb519f 100644 --- a/lib/steep/services/hover_provider/ruby.rb +++ b/lib/steep/services/hover_provider/ruby.rb @@ -84,7 +84,8 @@ def typecheck(target, path:, content:, line:, column:) 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, constant_resolver: resolver) + pos = source.buffer.loc_to_pos([line, column]) + Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: pos) rescue nil end @@ -118,7 +119,7 @@ def content_for(target:, path:, line:, column:) case node.type when :lvar var_name = node.children[0] - context = typing.context_at(line: line, column: column) + context = typing.cursor_context.context or raise var_type = context.type_env[var_name] || AST::Types::Any.new(location: nil) return VariableContent.new( @@ -130,7 +131,7 @@ def content_for(target:, path:, line:, column:) when :lvasgn var_name, rhs = node.children - context = typing.context_at(line: line, column: column) + context = typing.cursor_context.context or raise type = context.type_env[var_name] || typing.type_of(node: node) return VariableContent.new( @@ -165,7 +166,7 @@ def content_for(target:, path:, line:, column:) end when :def, :defs - context = typing.context_at(line: line, column: column) + context = typing.cursor_context.context or raise method_context = context.method_context if method_context && method_context.method @@ -181,7 +182,7 @@ def content_for(target:, path:, line:, column:) end when :const, :casgn - context = typing.context_at(line: line, column: column) + context = typing.cursor_context.context or raise type = typing.type_of(node: node) const_name = typing.source_index.reference(constant_node: node) diff --git a/lib/steep/services/signature_help_provider.rb b/lib/steep/services/signature_help_provider.rb index 190f746a0..bac139770 100644 --- a/lib/steep/services/signature_help_provider.rb +++ b/lib/steep/services/signature_help_provider.rb @@ -76,7 +76,8 @@ def run(line:, column:) def type_check!(line:, column:) source = self.source.without_unrelated_defs(line: line, column: column) resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder) - TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver) + pos = self.source.buffer.loc_to_pos([line, column]) + TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: pos) end def last_argument_nodes_for(argument_nodes:, line:, column:) diff --git a/lib/steep/services/type_check_service.rb b/lib/steep/services/type_check_service.rb index 9889ad9cd..1e8b52419 100644 --- a/lib/steep/services/type_check_service.rb +++ b/lib/steep/services/type_check_service.rb @@ -363,7 +363,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, constant_resolver: yield) + typing = TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: yield, cursor: nil) ignores = Source::IgnoreRanges.new(ignores: source.ignores) SourceFile.with_typing(path: path, content: text, node: source.node, typing: typing, ignores: ignores) end @@ -380,7 +380,7 @@ def type_check_file(target:, subtyping:, path:, text:) SourceFile.no_data(path: path, content: text) end - def self.type_check(source:, subtyping:, constant_resolver:) + def self.type_check(source:, subtyping:, constant_resolver:, cursor:) annotations = source.annotations(block: source.node, factory: subtyping.factory, context: nil) definition = subtyping.factory.definition_builder.build_instance(AST::Builtin::Object.module_name) @@ -418,7 +418,7 @@ def self.type_check(source:, subtyping:, constant_resolver:) variable_context: TypeInference::Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context, cursor: nil) + typing = Typing.new(source: source, root_context: context, cursor: cursor) construction = TypeConstruction.new( checker: subtyping, diff --git a/lib/steep/type_construction.rb b/lib/steep/type_construction.rb index e854ea8ab..1c75661d7 100644 --- a/lib/steep/type_construction.rb +++ b/lib/steep/type_construction.rb @@ -705,7 +705,7 @@ def synthesize(node, hint: nil, condition: false) if new_pair.constr.context != pair.constr.context # update context range = node.loc.expression.end_pos..end_pos - typing.add_context(range, context: new_pair.constr.context) + typing.cursor_context.set(range, new_pair.constr.context) end end end @@ -949,8 +949,8 @@ def synthesize(node, hint: nil, condition: false) ) do |new| # @type var new: TypeConstruction - new.typing.add_context_for_node(node, context: new.context) - new.typing.add_context_for_body(node, context: new.context) + new.typing.cursor_context.set_node_context(node, new.context) + new.typing.cursor_context.set_body_context(node, new.context) new.method_context!.tap do |method_context| if method_context.method @@ -1028,7 +1028,7 @@ def synthesize(node, hint: nil, condition: false) # Skip end-less def begin_pos = body_node.loc.expression.end_pos end_pos = node.loc.end.begin_pos - typing.add_context(begin_pos..end_pos, context: body_pair.context) + typing.cursor_context.set(begin_pos..end_pos, body_pair.context) end end @@ -1061,8 +1061,8 @@ def synthesize(node, hint: nil, condition: false) self_type: self_type, definition: definition ) - new.typing.add_context_for_node(node, context: new.context) - new.typing.add_context_for_body(node, context: new.context) + new.typing.cursor_context.set_node_context(node, new.context) + new.typing.cursor_context.set_body_context(node, new.context) new.method_context!.tap do |method_context| if method_context.method @@ -1505,8 +1505,8 @@ def synthesize(node, hint: nil, condition: false) _, constructor = constructor.fallback_to_any(name_node) end - constructor.typing.add_context_for_node(node, context: constructor.context) - constructor.typing.add_context_for_body(node, context: constructor.context) + constructor.typing.cursor_context.set_node_context(node, constructor.context) + constructor.typing.cursor_context.set_body_context(node, constructor.context) constructor.synthesize(node.children[2]) if node.children[2] @@ -1544,8 +1544,8 @@ def synthesize(node, hint: nil, condition: false) _, constructor = constructor.fallback_to_any(name_node) end - constructor.typing.add_context_for_node(node, context: constructor.context) - constructor.typing.add_context_for_body(node, context: constructor.context) + constructor.typing.cursor_context.set_node_context(node, constructor.context) + constructor.typing.cursor_context.set_body_context(node, constructor.context) constructor.synthesize(node.children[1]) if node.children[1] @@ -1572,8 +1572,8 @@ def synthesize(node, hint: nil, condition: false) return constr.add_typing(node, type: AST::Builtin.nil_type) end - constructor.typing.add_context_for_node(node, context: constructor.context) - constructor.typing.add_context_for_body(node, context: constructor.context) + constructor.typing.cursor_context.set_node_context(node, constructor.context) + constructor.typing.cursor_context.set_body_context(node, constructor.context) constructor.synthesize(node.children[1]) if node.children[1] @@ -1760,7 +1760,7 @@ def synthesize(node, hint: nil, condition: false) right_type, constr, right_context = constr .update_type_env { left_truthy.env } - .tap {|constr| typing.add_context_for_node(right_node, context: constr.context) } + .tap {|constr| typing.cursor_context.set_node_context(right_node, constr.context) } .for_branch(right_node) .synthesize(right_node, hint: hint, condition: true).to_ary @@ -1819,7 +1819,7 @@ def synthesize(node, hint: nil, condition: false) right_type, constr, right_context = constr .update_type_env { left_falsy.env } - .tap {|constr| typing.add_context_for_node(right_node, context: constr.context) } + .tap {|constr| typing.cursor_context.set_node_context(right_node, constr.context) } .for_branch(right_node) .synthesize(right_node, hint: left_truthy.type, condition: true).to_ary @@ -1871,7 +1871,7 @@ def synthesize(node, hint: nil, condition: false) constr .update_type_env { truthy.env } .for_branch(true_clause) - .tap {|constr| typing.add_context_for_node(true_clause, context: constr.context) } + .tap {|constr| typing.cursor_context.set_node_context(true_clause, constr.context) } .synthesize(true_clause, hint: hint) end @@ -1880,7 +1880,7 @@ def synthesize(node, hint: nil, condition: false) constr .update_type_env { falsy.env } .for_branch(false_clause) - .tap {|constr| typing.add_context_for_node(false_clause, context: constr.context) } + .tap {|constr| typing.cursor_context.set_node_context(false_clause, constr.context) } .synthesize(false_clause, hint: hint) end @@ -2010,7 +2010,7 @@ def synthesize(node, hint: nil, condition: false) when_clause_constr .for_branch(body) .update_type_env {|env| env.join(*body_envs) } - .tap {|constr| typing.add_context_for_node(body, context: constr.context) } + .tap {|constr| typing.cursor_context.set_node_context(body, constr.context) } .synthesize(body, hint: hint) else Pair.new(type: AST::Builtin.nil_type, constr: when_clause_constr) @@ -2112,7 +2112,7 @@ def synthesize(node, hint: nil, condition: false) end if body - resbody_construction.typing.add_context_for_node(body, context: resbody_construction.context) + resbody_construction.typing.cursor_context.set_node_context(body, resbody_construction.context) resbody_construction.synthesize(body, hint: hint) else Pair.new(constr: body_constr, type: AST::Builtin.nil_type) @@ -2213,7 +2213,7 @@ def synthesize(node, hint: nil, condition: false) type_env.merge(local_variable_types: pins) end - typing.add_context_for_body(node, context: body_constr.context) + typing.cursor_context.set_body_context(node, body_constr.context) _, _, body_context = body_constr.synthesize(body).to_ary constr = constr.update_type_env do |env| @@ -2267,7 +2267,7 @@ def synthesize(node, hint: nil, condition: false) constr .update_type_env { body_env } .for_branch(body, break_context: TypeInference::Context::BreakContext.new(break_type: hint || AST::Builtin.nil_type, next_type: nil)) - .tap {|constr| typing.add_context_for_node(body, context: constr.context) } + .tap {|constr| typing.cursor_context.set_node_context(body, constr.context) } .synthesize(body).to_ary constr = constr.update_type_env {|env| env.join(exit_env, body_constr.context.type_env) } @@ -2290,7 +2290,7 @@ def synthesize(node, hint: nil, condition: false) .update_type_env {|env| env.merge(local_variable_types: env.pin_local_variables(nil)) } .for_branch(body, break_context: TypeInference::Context::BreakContext.new(break_type: hint || AST::Builtin.nil_type, next_type: nil)) - typing.add_context_for_node(body, context: for_loop.context) + typing.cursor_context.set_node_context(body, for_loop.context) _, body_constr, body_context = for_loop.synthesize(body) constr = cond_constr.update_type_env {|env| env.join(env, body_context.type_env) } @@ -3087,7 +3087,7 @@ def type_lambda(node, params_node:, body_node:, type_hint:) node_type_hint: nil ) - block_constr.typing.add_context_for_body(node, context: block_constr.context) + block_constr.typing.cursor_context.set_body_context(node, block_constr.context) params.each_single_param do |param| _, block_constr = block_constr.synthesize(param.node, hint: param.type) @@ -3998,7 +3998,7 @@ def try_method_type(node, receiver_type:, method_name:, method_type:, arguments: block_constr.typing.new_child(block_constr.typing.block_range(node)) ) - block_constr.typing.add_context_for_body(node, context: block_constr.context) + block_constr.typing.cursor_context.set_body_context(node, block_constr.context) pairs.each do |param, type| case param @@ -4345,7 +4345,7 @@ def type_block_without_hint(node:, block_annotations:, block_params:, block_body node_type_hint: nil ) - block_constr.typing.add_context_for_body(node, context: block_constr.context) + block_constr.typing.cursor_context.set_body_context(node, block_constr.context) block_params.params.each do |param| param.each_param do |param| @@ -4523,7 +4523,7 @@ def synthesize_block(node:, block_type_hint:, block_body:) body_type, _, context = synthesize(block_body, hint: block_context&.body_type || block_type_hint) range = block_body.loc.expression.end_pos..node.loc.end.begin_pos - typing.add_context(range, context: context) + typing.cursor_context.set(range, context) body_type else diff --git a/lib/steep/typing.rb b/lib/steep/typing.rb index 72432cecc..a5730967a 100644 --- a/lib/steep/typing.rb +++ b/lib/steep/typing.rb @@ -41,10 +41,115 @@ def set(range, context = nil) end end - # def set!(other) - # @data = other.data - # self - # end + def set_node_context(node, context) + begin_pos = node.loc.expression.begin_pos + end_pos = node.loc.expression.end_pos + + set(begin_pos..end_pos, context) + end + + def set_body_context(node, context) + case node.type + when :class + name_node, super_node, _ = node.children + begin_pos = if super_node + super_node.loc.expression.end_pos + else + name_node.loc.expression.end_pos + end + end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + + set(begin_pos..end_pos, context) + + when :module + name_node = node.children[0] + begin_pos = name_node.loc.expression.end_pos + end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + set(begin_pos..end_pos, context) + + when :sclass + name_node = node.children[0] + begin_pos = name_node.loc.expression.end_pos + end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + set(begin_pos..end_pos, context) + + when :def, :defs + if node.children.last + args_node = + case node.type + when :def + node.children[1] + when :defs + node.children[2] + end + + body_begin_pos = + case + when node.loc.assignment # steep:ignore NoMethod + # endless def + node.loc.assignment.end_pos # steep:ignore NoMethod + when args_node.loc.expression + # with args + args_node.loc.expression.end_pos + else + # without args + node.loc.name.end_pos # steep:ignore NoMethod + end + + body_end_pos = + if node.loc.end # steep:ignore NoMethod + node.loc.end.begin_pos # steep:ignore NoMethod + else + node.loc.expression.end_pos + end + + set(body_begin_pos..body_end_pos, context) + end + + when :block, :numblock + range = block_range(node) + set(range, context) + + when :for + _, collection, _ = node.children + + begin_pos = collection.loc.expression.end_pos + end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + + set(begin_pos..end_pos, context) + else + raise "Unexpected node for insert_context: #{node.type}" + end + end + + def block_range(node) + case node.type + when :block + send_node, args_node, _ = node.children + begin_pos = if send_node.type != :lambda && args_node.loc.expression + args_node.loc.expression.end_pos + else + node.loc.begin.end_pos # steep:ignore NoMethod + end + end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + when :numblock + send_node, _ = node.children + begin_pos = node.loc.begin.end_pos # steep:ignore NoMethod + end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + end + + begin_pos..end_pos + end + + def range + range, _ = data + range + end + + def context + _, context = data + context + end end attr_reader :source @@ -138,12 +243,12 @@ def call_of(node:) end end - def add_context_for_node(node, context:) - begin_pos = node.loc.expression.begin_pos - end_pos = node.loc.expression.end_pos + # def add_context_for_node(node, context:) + # begin_pos = node.loc.expression.begin_pos + # end_pos = node.loc.expression.end_pos - add_context(begin_pos..end_pos, context: context) - end + # add_context(begin_pos..end_pos, context: context) + # end def block_range(node) case node.type @@ -164,79 +269,79 @@ def block_range(node) begin_pos..end_pos end - def add_context_for_body(node, context:) - case node.type - when :class - name_node, super_node, _ = node.children - begin_pos = if super_node - super_node.loc.expression.end_pos - else - name_node.loc.expression.end_pos - end - end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - - add_context(begin_pos..end_pos, context: context) - - when :module - name_node = node.children[0] - begin_pos = name_node.loc.expression.end_pos - end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - add_context(begin_pos..end_pos, context: context) - - when :sclass - name_node = node.children[0] - begin_pos = name_node.loc.expression.end_pos - end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - add_context(begin_pos..end_pos, context: context) - - when :def, :defs - if node.children.last - args_node = - case node.type - when :def - node.children[1] - when :defs - node.children[2] - end - - body_begin_pos = - case - when node.loc.assignment # steep:ignore NoMethod - # endless def - node.loc.assignment.end_pos # steep:ignore NoMethod - when args_node.loc.expression - # with args - args_node.loc.expression.end_pos - else - # without args - node.loc.name.end_pos # steep:ignore NoMethod - end - - body_end_pos = - if node.loc.end # steep:ignore NoMethod - node.loc.end.begin_pos # steep:ignore NoMethod - else - node.loc.expression.end_pos - end - - add_context(body_begin_pos..body_end_pos, context: context) - end - - when :block, :numblock - range = block_range(node) - add_context(range, context: context) - - when :for - _, collection, _ = node.children - - begin_pos = collection.loc.expression.end_pos - end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - - add_context(begin_pos..end_pos, context: context) - else - raise "Unexpected node for insert_context: #{node.type}" - end - end + # def add_context_for_body(node, context:) + # case node.type + # when :class + # name_node, super_node, _ = node.children + # begin_pos = if super_node + # super_node.loc.expression.end_pos + # else + # name_node.loc.expression.end_pos + # end + # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + + # add_context(begin_pos..end_pos, context: context) + + # when :module + # name_node = node.children[0] + # begin_pos = name_node.loc.expression.end_pos + # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + # add_context(begin_pos..end_pos, context: context) + + # when :sclass + # name_node = node.children[0] + # begin_pos = name_node.loc.expression.end_pos + # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + # add_context(begin_pos..end_pos, context: context) + + # when :def, :defs + # if node.children.last + # args_node = + # case node.type + # when :def + # node.children[1] + # when :defs + # node.children[2] + # end + + # body_begin_pos = + # case + # when node.loc.assignment # steep:ignore NoMethod + # # endless def + # node.loc.assignment.end_pos # steep:ignore NoMethod + # when args_node.loc.expression + # # with args + # args_node.loc.expression.end_pos + # else + # # without args + # node.loc.name.end_pos # steep:ignore NoMethod + # end + + # body_end_pos = + # if node.loc.end # steep:ignore NoMethod + # node.loc.end.begin_pos # steep:ignore NoMethod + # else + # node.loc.expression.end_pos + # end + + # add_context(body_begin_pos..body_end_pos, context: context) + # end + + # when :block, :numblock + # range = block_range(node) + # add_context(range, context: context) + + # when :for + # _, collection, _ = node.children + + # begin_pos = collection.loc.expression.end_pos + # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod + + # add_context(begin_pos..end_pos, context: context) + # else + # raise "Unexpected node for insert_context: #{node.type}" + # end + # end def context_at(line:, column:) contexts.at(line: line, column: column) || diff --git a/sig/steep/services/type_check_service.rbs b/sig/steep/services/type_check_service.rbs index 83ecac028..c153cb6b3 100644 --- a/sig/steep/services/type_check_service.rbs +++ b/sig/steep/services/type_check_service.rbs @@ -42,7 +42,7 @@ module Steep def update_content: (String content) -> SourceFile # Diagnostics filgered by `ignores` - # + # def diagnostics: () -> Array[Diagnostic::Ruby::Base] end @@ -98,7 +98,7 @@ module Steep 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, constant_resolver: RBS::Resolver::ConstantResolver) -> Typing + def self.type_check: (source: Source, subtyping: Subtyping::Check, constant_resolver: RBS::Resolver::ConstantResolver, cursor: Integer?) -> Typing def source_file?: (Pathname path) -> Project::Target? diff --git a/sig/steep/type_construction.rbs b/sig/steep/type_construction.rbs index 10a3cf3be..f97d2ec6d 100644 --- a/sig/steep/type_construction.rbs +++ b/sig/steep/type_construction.rbs @@ -90,13 +90,13 @@ module Steep def default_module_context: (AST::Annotation::Implements::Module? implement_module_name, nesting: RBS::Resolver::context) -> TypeInference::Context::ModuleContext - def for_module: (untyped node, untyped new_module_name) -> untyped + def for_module: (untyped node, untyped new_module_name) -> TypeConstruction - def with_module_constr: (untyped node, untyped module_name) { (untyped) -> untyped } -> untyped + def with_module_constr: [T] (untyped node, untyped module_name) { (TypeConstruction) -> T } -> T - def for_class: (untyped node, untyped new_class_name, untyped super_class_name) -> untyped + def for_class: (untyped node, untyped new_class_name, untyped super_class_name) -> TypeConstruction - def with_class_constr: (untyped node, untyped new_class_name, untyped super_class_name) { (untyped) -> untyped } -> untyped + def with_class_constr: [T] (Parser::AST::Node node, untyped new_class_name, untyped super_class_name) { (TypeConstruction) -> T } -> T def with_sclass_constr: [A] (Parser::AST::Node node, AST::Types::t `type`) { (TypeConstruction?) -> A } -> A diff --git a/sig/steep/typing.rbs b/sig/steep/typing.rbs index f6db566ba..f6c827b67 100644 --- a/sig/steep/typing.rbs +++ b/sig/steep/typing.rbs @@ -22,11 +22,23 @@ module Steep def set: (Range[Integer], Context context) -> void | (CursorContext) -> void - # def set!: (CursorContext) -> self + # Assign the context for the range that covers given node + # + def set_node_context: (Parser::AST::Node node, Context context) -> void + + # Assign the context for the range that covert the *body* of the given node + # + # What the *body* exactly is depends on the node type. + # + def set_body_context: (Parser::AST::Node node, Context context) -> void %a{pure} def context: () -> Context? %a{pure} def range: () -> Range[Integer]? + + private + + def block_range: (Parser::AST::Node) -> Range[Integer] end attr_reader source: Source @@ -69,11 +81,11 @@ module Steep def call_of: (node: Parser::AST::Node) -> TypeInference::MethodCall::t - def add_context_for_node: (Parser::AST::Node node, context: Context) -> void + # def add_context_for_node: (Parser::AST::Node node, context: Context) -> void def block_range: (Parser::AST::Node node) -> Range[Integer] - def add_context_for_body: (Parser::AST::Node node, context: Context) -> void + # def add_context_for_body: (Parser::AST::Node node, context: Context) -> void def context_at: (line: Integer, column: Integer) -> Context diff --git a/test/server/lsp_formatter_test.rb b/test/server/lsp_formatter_test.rb index 934633420..c50c4a846 100644 --- a/test/server/lsp_formatter_test.rb +++ b/test/server/lsp_formatter_test.rb @@ -13,7 +13,7 @@ def type_check(content) builder = Interface::Builder.new(factory) subtyping = Subtyping::Check.new(builder: builder) resolver = RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder) - Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver) + Services::TypeCheckService.type_check(source: source, subtyping: subtyping, constant_resolver: resolver, cursor: nil) end def test_ruby_hover_variable diff --git a/test/test_helper.rb b/test/test_helper.rb index 7ad031a6c..a25575239 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -593,7 +593,7 @@ module TypeConstructionHelper AST = Steep::AST TypeInference = Steep::TypeInference - def with_standard_construction(checker, source) + def with_standard_construction(checker, source, cursor: nil) self_type = parse_type("::Object") annotations = source.annotations(block: source.node, factory: checker.factory, context: nil) @@ -626,7 +626,12 @@ def with_standard_construction(checker, source) call_context: TypeInference::MethodCall::TopLevelContext.new(), variable_context: Context::TypeVariableContext.empty ) - typing = Typing.new(source: source, root_context: context, cursor: nil) + loc = + if cursor + source.buffer.loc_to_pos(cursor) + end + + typing = Typing.new(source: source, root_context: context, cursor: loc) construction = TypeConstruction.new(checker: checker, source: source, diff --git a/test/type_construction_test.rb b/test/type_construction_test.rb index d5274961b..08c34bb2b 100644 --- a/test/type_construction_test.rb +++ b/test/type_construction_test.rb @@ -113,16 +113,24 @@ def test_lvar_without_annotation_infer z = x EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [1, 0]) do |construction, typing| pair = construction.synthesize(source.node) assert_equal parse_type("::Integer"), typing.type_of(node: source.node) - assert_nil typing.context_at(line: 1, column: 0).type_env[:x] - assert_nil typing.context_at(line: 1, column: 0).type_env[:z] + assert_nil typing.cursor_context.context.type_env[:x] + assert_nil typing.cursor_context.context.type_env[:z] + + assert_empty typing.errors + end - assert_equal parse_type("::Integer"), typing.context_at(line: 1, column: 5).type_env[:x] - assert_nil typing.context_at(line: 1, column: 5).type_env[:z] + with_standard_construction(checker, source, cursor: [1, 5]) do |construction, typing| + pair = construction.synthesize(source.node) + + assert_equal parse_type("::Integer"), typing.type_of(node: source.node) + + assert_equal parse_type("::Integer"), typing.cursor_context.context.type_env[:x] + assert_nil typing.cursor_context.context.type_env[:z] assert_equal parse_type("::Integer"), pair.context.type_env[:x] assert_equal parse_type("::Integer"), pair.context.type_env[:z] @@ -140,14 +148,9 @@ def test_lvar_without_annotation_redef EOF with_standard_construction(checker, source) do |construction, typing| - pair = construction.synthesize(source.node) + construction.synthesize(source.node) assert_equal parse_type("::String"), typing.type_of(node: source.node) - - assert_nil typing.context_at(line: 1, column: 0).type_env[:x] - assert_equal parse_type("::Integer"), typing.context_at(line: 1, column: 5).type_env[:x] - assert_equal parse_type("::String"), pair.context.type_env[:x] - assert_empty typing.errors end end @@ -418,11 +421,11 @@ def foo end EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [4, 0]) do |construction, typing| construction.synthesize(source.node) assert_equal parse_type("untyped"), typing.type_of(node: dig(source.node, 2)) - assert_equal parse_type("::_A"), typing.context_at(line: 4, column: 0).type_env[:x] + assert_equal parse_type("::_A"), typing.cursor_context.context.type_env[:x] end end end @@ -579,16 +582,13 @@ def test_block_shadow end EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [7, 0]) do |construction, typing| pair = construction.synthesize(source.node) assert_equal parse_type("::_X"), pair.context.type_env[:a] - assert_equal parse_type("::_A"), typing.context_at(line: 6, column: 0).type_env[:a] - assert_nil typing.context_at(line: 6, column: 0).type_env[:b] - - assert_equal parse_type("::_A"), typing.context_at(line: 7, column: 0).type_env[:a] - assert_equal parse_type("::_A"), typing.context_at(line: 7, column: 0).type_env[:b] + assert_equal parse_type("::_A"), typing.cursor_context.context.type_env[:a] + assert_equal parse_type("::_A"), typing.cursor_context.context.type_env[:b] end end end @@ -606,7 +606,7 @@ def test_block_param_type end EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [8, 0]) do |construction, typing| pair = construction.synthesize(source.node) assert_no_error typing @@ -615,10 +615,11 @@ def test_block_param_type assert_nil pair.context.type_env[:a] assert_nil pair.context.type_env[:d] - block_context = typing.context_at(line: 8, column: 0) - assert_equal parse_type("::_A"), block_context.type_env[:a] - assert_equal parse_type("::_D"), block_context.type_env[:d] - assert_equal parse_type("::_X"), block_context.type_env[:x] + typing.cursor_context.context.tap do |context| + assert_equal parse_type("::_A"), context.type_env[:a] + assert_equal parse_type("::_D"), context.type_env[:d] + assert_equal parse_type("::_X"), context.type_env[:x] + end end end end @@ -2998,16 +2999,16 @@ def test_if_annotation_success end EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [6, 3]) do |construction, typing| construction.synthesize(source.node) - assert_no_error typing + assert_equal parse_type("::String"), typing.cursor_context.context.type_env[:x] + end - true_context = typing.context_at(line: 6, column: 3) - assert_equal parse_type("::String"), true_context.type_env[:x] - - true_context = typing.context_at(line: 9, column: 3) - assert_equal parse_type("::Integer"), true_context.type_env[:x] + with_standard_construction(checker, source, cursor: [9, 3]) do |construction, typing| + construction.synthesize(source.node) + assert_no_error typing + assert_equal parse_type("::Integer"), typing.cursor_context.context.type_env[:x] end end end @@ -3083,7 +3084,9 @@ def test_while_typing assert_no_error typing - assert_equal parse_type("::Integer"), typing.context_at(line: 6, column: 2).type_env[:x] + typing.source.find_nodes(line: 6, column: 2).tap do |x, *| + assert_equal parse_type("::Integer"), typing.type_of(node: x) + end assert_equal parse_type("::Integer | ::String"), pair.context.type_env[:x] end end @@ -3592,12 +3595,12 @@ def test_while end EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [2, 2]) do |construction, typing| pair = construction.synthesize(source.node) assert_empty typing.errors - assert_equal parse_type("::String"), typing.context_at(line: 2, column: 2).type_env[:line] + assert_equal parse_type("::String"), typing.cursor_context.context.type_env[:line] assert_equal parse_type("::String?"), pair.context.type_env[:line] assert_equal parse_type("::String?"), pair.context.type_env[:x] @@ -4652,13 +4655,13 @@ def test_lambda1 end EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [3, 3]) do |construction, typing| pair = construction.synthesize(source.node) assert_no_error typing assert_equal "^(::Integer, untyped) -> ::Integer", pair.context.type_env[:l].to_s - lambda_context = typing.context_at(line: 3, column: 3) + lambda_context = typing.cursor_context.context assert_equal parse_type("::Integer"), lambda_context.type_env[:x] assert_equal parse_type("untyped"), lambda_context.type_env[:y] end @@ -5223,12 +5226,12 @@ def test_context_toplevel b = 123 EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [0, 0]) do |construction, typing| construction.synthesize(source.node) assert_empty typing.errors # a = ... - typing.context_at(line: 0, column: 0).tap do |ctx| + typing.cursor_context.context.tap do |ctx| assert_instance_of Context, ctx assert_equal construction.module_context, ctx.module_context assert_nil ctx.method_context @@ -5256,12 +5259,12 @@ class Hello < Object b = 123 EOF - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [5, 2]) do |construction, typing| construction.synthesize(source.node) assert_no_error typing # class Hello - typing.context_at(line: 5, column: 2).tap do |ctx| + typing.cursor_context.context.tap do |ctx| assert_instance_of Context, ctx assert_equal "::Hello", ctx.module_context.class_name.to_s assert_nil ctx.method_context @@ -6860,10 +6863,23 @@ def to_a: () -> [Integer] with_standard_construction(checker, source) do |construction, typing| _, constr = construction.synthesize(source.node) - type_env = typing.context_at(line: 5, column: 10).type_env - assert_equal parse_type("::Integer"), type_env[:x] - assert_equal parse_type("nil"), type_env[:y] - assert_equal parse_type("::String"), type_env[:z] + assert_typing_error typing, size: 3 do |errors| + assert_any!(errors) do |error| + assert_instance_of Diagnostic::Ruby::NoMethod, error + assert_equal parse_type("::Integer"), error.type + assert_equal :type_of_x, error.method + end + assert_any!(errors) do |error| + assert_instance_of Diagnostic::Ruby::NoMethod, error + assert_equal parse_type("nil"), error.type + assert_equal :type_of_y, error.method + end + assert_any!(errors) do |error| + assert_instance_of Diagnostic::Ruby::NoMethod, error + assert_equal parse_type("::String"), error.type + assert_equal :type_of_z, error.method + end + end end end end @@ -8635,10 +8651,10 @@ def bar end RUBY - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [4, 5]) do |construction, typing| type, _ = construction.synthesize(source.node) - assert_equal parse_type("[X, untyped]", variables: [:X]), typing.context_at(line: 4, column: 5).type_env[:z] + assert_equal parse_type("[X, untyped]", variables: [:X]), typing.cursor_context.context.type_env[:z] end end end @@ -8662,10 +8678,10 @@ def bar end RUBY - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [7, 5]) do |construction, typing| type, _ = construction.synthesize(source.node) - assert_equal parse_type("[X, untyped]", variables: [:X]), typing.context_at(line: 7, column: 5).type_env[:z] + assert_equal parse_type("[X, untyped]", variables: [:X]), typing.cursor_context.context.type_env[:z] end end end @@ -8686,10 +8702,10 @@ def bar end RUBY - with_standard_construction(checker, source) do |construction, typing| + with_standard_construction(checker, source, cursor: [4, 5]) do |construction, typing| type, _ = construction.synthesize(source.node) - assert_equal parse_type("[X, untyped]", variables: [:X]), typing.context_at(line: 4, column: 5).type_env[:z] + assert_equal parse_type("[X, untyped]", variables: [:X]), typing.cursor_context.context.type_env[:z] end end end From e23c40d2fcacd4344dcd10dd754cc957ca71c59a Mon Sep 17 00:00:00 2001 From: Soutaro Matsumoto Date: Tue, 6 Aug 2024 16:25:45 +0900 Subject: [PATCH 5/6] Delete ContextArray --- lib/steep.rb | 1 - lib/steep/services/signature_help_provider.rb | 2 +- lib/steep/type_construction.rb | 31 ++--- lib/steep/type_inference/context_array.rb | 112 ------------------ lib/steep/typing.rb | 100 +--------------- sig/steep/type_construction.rbs | 6 +- sig/steep/type_inference/context_array.rbs | 38 ------ sig/steep/typing.rbs | 18 +-- test/context_array_test.rb | 91 -------------- test/typing_test.rb | 11 +- 10 files changed, 26 insertions(+), 384 deletions(-) delete mode 100644 lib/steep/type_inference/context_array.rb delete mode 100644 sig/steep/type_inference/context_array.rbs delete mode 100644 test/context_array_test.rb diff --git a/lib/steep.rb b/lib/steep.rb index df7c386d9..38fc693cc 100644 --- a/lib/steep.rb +++ b/lib/steep.rb @@ -83,7 +83,6 @@ require "steep/typing" require "steep/type_construction" require "steep/type_inference/context" -require "steep/type_inference/context_array" require "steep/type_inference/send_args" require "steep/type_inference/block_params" require "steep/type_inference/method_params" diff --git a/lib/steep/services/signature_help_provider.rb b/lib/steep/services/signature_help_provider.rb index bac139770..cf55570cf 100644 --- a/lib/steep/services/signature_help_provider.rb +++ b/lib/steep/services/signature_help_provider.rb @@ -100,7 +100,7 @@ def last_argument_nodes_for(argument_nodes:, line:, column:) def signature_help_for(node, argument, last_argument, typing) call = typing.call_of(node: node) - context = typing.context_at(line: node.loc.expression.line, column: node.loc.expression.column) + context = typing.cursor_context.context or raise items = [] #: Array[Item] index = nil #: Integer? diff --git a/lib/steep/type_construction.rb b/lib/steep/type_construction.rb index 1c75661d7..c124cdb5a 100644 --- a/lib/steep/type_construction.rb +++ b/lib/steep/type_construction.rb @@ -1711,13 +1711,11 @@ def synthesize(node, hint: nil, condition: false) add_typing node, type: AST::Builtin::Array.instance_type(AST::Builtin.any_type) end else - node_range = node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos } - if hint tuples = select_flatten_types(hint) {|type| type.is_a?(AST::Types::Tuple) } #: Array[AST::Types::Tuple] unless tuples.empty? tuples.each do |tuple| - typing.new_child(node_range) do |child_typing| + typing.new_child() do |child_typing| if pair = with_new_typing(child_typing).try_tuple_type(node, tuple) return pair.with(constr: pair.constr.save_typing) end @@ -1730,7 +1728,7 @@ def synthesize(node, hint: nil, condition: false) arrays = select_flatten_types(hint) {|type| AST::Builtin::Array.instance_type?(type) } #: Array[AST::Types::Name::Instance] unless arrays.empty? arrays.each do |array| - typing.new_child(node_range) do |child_typing| + typing.new_child() do |child_typing| pair = with_new_typing(child_typing).try_array_type(node, array) if pair.constr.check_relation(sub_type: pair.type, super_type: hint).success? return pair.with(constr: pair.constr.save_typing) @@ -3573,14 +3571,12 @@ def try_special_method(node, receiver_type:, method_name:, method_type:, argumen end def type_method_call(node, method_name:, receiver_type:, method:, arguments:, block_params:, block_body:, tapp:, hint:) - node_range = node.loc.expression.to_range - # @type var fails: Array[[TypeInference::MethodCall::t, TypeConstruction]] fails = [] method.method_types.each do |method_type| Steep.logger.tagged method_type.to_s do - typing.new_child(node_range) do |child_typing| + typing.new_child() do |child_typing| constr = self.with_new_typing(child_typing) call, constr = constr.try_special_method( @@ -3648,8 +3644,8 @@ def type_method_call(node, method_name:, receiver_type:, method:, arguments:, bl end end - def with_child_typing(range:) - constr = with_new_typing(typing.new_child(range)) + def with_child_typing() + constr = with_new_typing(typing.new_child()) if block_given? yield constr @@ -3752,7 +3748,7 @@ def type_check_args(method_name, args, constraints, errors) when TypeInference::SendArgs::PositionalArgs::SplatArg arg_type, _ = constr - .with_child_typing(range: arg.node.loc.expression.begin_pos ... arg.node.loc.expression.end_pos) + .with_child_typing() .try_tuple_type!(arg.node.children[0]) arg.type = arg_type @@ -3995,7 +3991,7 @@ def try_method_type(node, receiver_type:, method_name:, method_type:, arguments: ) block_constr = block_constr.with_new_typing( - block_constr.typing.new_child(block_constr.typing.block_range(node)) + block_constr.typing.new_child() ) block_constr.typing.cursor_context.set_body_context(node, block_constr.context) @@ -4788,9 +4784,7 @@ def to_instance_type(type, args: nil) def try_tuple_type!(node, hint: nil) if node.type == :array if hint.nil? || hint.is_a?(AST::Types::Tuple) - node_range = node.loc.expression.to_range - - typing.new_child(node_range) do |child_typing| + typing.new_child() do |child_typing| if pair = with_new_typing(child_typing).try_tuple_type(node, hint) return pair.with(constr: pair.constr.save_typing) end @@ -4998,18 +4992,17 @@ def type_hash(hash_node, hint:) if hint hint = deep_expand_alias(hint) end - range = hash_node.loc.expression.yield_self {|l| l.begin_pos..l.end_pos } case hint when AST::Types::Record - with_child_typing(range: range) do |constr| + with_child_typing() do |constr| pair = constr.type_hash_record(hash_node, hint) if pair return pair.with(constr: pair.constr.save_typing) end end when AST::Types::Union - pair = pick_one_of(hint.types, range: range) do |type, constr| + pair = pick_one_of(hint.types) do |type, constr| constr.type_hash(hash_node, hint: type) end @@ -5075,9 +5068,9 @@ def type_hash(hash_node, hint:) constr.add_typing(hash_node, type: hash_type) end - def pick_one_of(types, range:) + def pick_one_of(types) types.each do |type| - with_child_typing(range: range) do |constr| + with_child_typing() do |constr| if (type_, constr = yield(type, constr)) constr.check_relation(sub_type: type_, super_type: type).then do constr = constr.save_typing diff --git a/lib/steep/type_inference/context_array.rb b/lib/steep/type_inference/context_array.rb deleted file mode 100644 index 0fdf95abd..000000000 --- a/lib/steep/type_inference/context_array.rb +++ /dev/null @@ -1,112 +0,0 @@ -module Steep - module TypeInference - class ContextArray - class Entry - attr_reader :range, :context, :sub_entries - - def initialize(range:, context:) - @range = range - @context = context - @sub_entries = Set[].compare_by_identity - end - end - - attr_reader :buffer - attr_reader :root - - def initialize(buffer:, context:, range: 0..buffer.content.size) - @buffer = buffer - @root = Entry.new(range: range, context: context) - end - - def range - root.range - end - - def self.from_source(source:, range: nil, context:) - content = if source.node - source.node.location.expression.source_buffer.source - else - "" - end - buffer = RBS::Buffer.new(name: source.path, content: content) - range ||= 0..buffer.content.size - new(buffer: buffer, context: context, range: range) - end - - def insert_context(range, context:, entry: self.root) - entry.sub_entries.each do |sub| - next if sub.range.begin <= range.begin && range.end <= sub.range.end - next if range.begin <= sub.range.begin && sub.range.end <= range.end - next if range.end <= sub.range.begin - next if sub.range.end <= range.begin - - Steep.logger.error { "Range crossing: sub range=#{sub.range}, new range=#{range}" } - raise - end - - sup = entry.sub_entries.find do |sub| - sub.range.begin < range.begin && range.end <= sub.range.end - end - - if sup - insert_context(range, context: context, entry: sup) - else - subs = entry.sub_entries.select do |sub| - range.begin < sub.range.begin && sub.range.end <= range.end - end - - new_entry = Entry.new(range: range, context: context) - entry.sub_entries.subtract(subs) - new_entry.sub_entries.merge(subs) - entry.sub_entries << new_entry - end - end - - def each_entry(&block) - if block - es = [root] - - while e = es.pop - es.push(*e.sub_entries.to_a) - - yield e - end - else - enum_for :each_entry - end - end - - def context_at(index, entry: self.root) - return nil if index < entry.range.begin || entry.range.end < index - - sub = entry.sub_entries.find do |sub| - sub.range.begin <= index && index <= sub.range.end - end - - if sub - context_at(index, entry: sub) - else - entry.context - end - end - - def [](index) - context_at(index) - end - - def at(line:, column:) - pos = buffer.loc_to_pos([line, column]) - self[pos] - end - - def merge(subtree) - subtree.each_entry do |entry| - if entry.context - insert_context entry.range, context: entry.context - end - end - end - end - end -end diff --git a/lib/steep/typing.rb b/lib/steep/typing.rb index a5730967a..a371710d9 100644 --- a/lib/steep/typing.rb +++ b/lib/steep/typing.rb @@ -165,7 +165,7 @@ def context attr_reader :source_index attr_reader :cursor_context - def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil, source_index: nil, cursor:) + def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, source_index: nil, cursor:) @source = source @parent = parent @@ -176,7 +176,6 @@ def initialize(source:, root_context:, parent: nil, parent_last_update: parent&. @errors = [] (@typing = {}).compare_by_identity @root_context = root_context - @contexts = contexts || TypeInference::ContextArray.from_source(source: source, context: root_context) (@method_calls = {}).compare_by_identity @cursor_context = CursorContext.new(cursor) @@ -204,11 +203,6 @@ def add_call(node, call) call end - def add_context(range, context:) - contexts.insert_context(range, context: context) - @last_update += 1 - end - def has_type?(node) typing.key?(node) end @@ -243,13 +237,6 @@ def call_of(node:) end end - # def add_context_for_node(node, context:) - # begin_pos = node.loc.expression.begin_pos - # end_pos = node.loc.expression.end_pos - - # add_context(begin_pos..end_pos, context: context) - # end - def block_range(node) case node.type when :block @@ -269,85 +256,6 @@ def block_range(node) begin_pos..end_pos end - # def add_context_for_body(node, context:) - # case node.type - # when :class - # name_node, super_node, _ = node.children - # begin_pos = if super_node - # super_node.loc.expression.end_pos - # else - # name_node.loc.expression.end_pos - # end - # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - - # add_context(begin_pos..end_pos, context: context) - - # when :module - # name_node = node.children[0] - # begin_pos = name_node.loc.expression.end_pos - # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - # add_context(begin_pos..end_pos, context: context) - - # when :sclass - # name_node = node.children[0] - # begin_pos = name_node.loc.expression.end_pos - # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - # add_context(begin_pos..end_pos, context: context) - - # when :def, :defs - # if node.children.last - # args_node = - # case node.type - # when :def - # node.children[1] - # when :defs - # node.children[2] - # end - - # body_begin_pos = - # case - # when node.loc.assignment # steep:ignore NoMethod - # # endless def - # node.loc.assignment.end_pos # steep:ignore NoMethod - # when args_node.loc.expression - # # with args - # args_node.loc.expression.end_pos - # else - # # without args - # node.loc.name.end_pos # steep:ignore NoMethod - # end - - # body_end_pos = - # if node.loc.end # steep:ignore NoMethod - # node.loc.end.begin_pos # steep:ignore NoMethod - # else - # node.loc.expression.end_pos - # end - - # add_context(body_begin_pos..body_end_pos, context: context) - # end - - # when :block, :numblock - # range = block_range(node) - # add_context(range, context: context) - - # when :for - # _, collection, _ = node.children - - # begin_pos = collection.loc.expression.end_pos - # end_pos = node.loc.end.begin_pos # steep:ignore NoMethod - - # add_context(begin_pos..end_pos, context: context) - # else - # raise "Unexpected node for insert_context: #{node.type}" - # end - # end - - def context_at(line:, column:) - contexts.at(line: line, column: column) || - (parent ? parent.context_at(line: line, column: column) : root_context) - end - def dump(io) # steep:ignore:start io.puts "Typing: " @@ -370,13 +278,11 @@ def self.summary(node) "#{line}:#{col}:#{src}" end - def new_child(range) - context = contexts[range.begin] || contexts.root.context + def new_child() child = self.class.new( source: source, parent: self, root_context: root_context, - contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: context), source_index: source_index.new_child, cursor: cursor_context.index ) @@ -401,8 +307,6 @@ def save! parent.add_typing(node, type, nil) end - parent.contexts.merge(contexts) - parent.method_calls.merge!(method_calls) errors.each do |error| diff --git a/sig/steep/type_construction.rbs b/sig/steep/type_construction.rbs index f97d2ec6d..27b60ea8c 100644 --- a/sig/steep/type_construction.rbs +++ b/sig/steep/type_construction.rbs @@ -279,8 +279,8 @@ module Steep def inspect: () -> ::String - def with_child_typing: [A] (range: Range[Integer]) { (TypeConstruction) -> A } -> A - | (range: Range[Integer]) -> TypeConstruction + def with_child_typing: [A] () { (TypeConstruction) -> A } -> A + | () -> TypeConstruction # Bypass :splat and :kwsplat def bypass_splat: (untyped node) { (untyped) -> untyped } -> untyped @@ -506,7 +506,7 @@ module Steep # Returns the first one from elements of `types` that returns a type `t` where `t <: hint`. # - def pick_one_of: (Array[AST::Types::t] types, range: untyped) { (AST::Types::t hint, TypeConstruction) -> Pair? } -> Pair? + def pick_one_of: (Array[AST::Types::t] types) { (AST::Types::t hint, TypeConstruction) -> Pair? } -> Pair? # *Commit* the transaction (current typing) and returns a `TypeConstruction` with saved typing # diff --git a/sig/steep/type_inference/context_array.rbs b/sig/steep/type_inference/context_array.rbs deleted file mode 100644 index c5b8b3a3e..000000000 --- a/sig/steep/type_inference/context_array.rbs +++ /dev/null @@ -1,38 +0,0 @@ -module Steep - module TypeInference - class ContextArray - class Entry - attr_reader range: Range[Integer] - - attr_reader context: Context - - attr_reader sub_entries: Set[Entry] - - def initialize: (range: Range[Integer], context: Context) -> void - end - - attr_reader buffer: RBS::Buffer - - attr_reader root: Entry - - def initialize: (buffer: RBS::Buffer, context: Context, ?range: Range[Integer]) -> void - - def range: () -> Range[Integer] - - def self.from_source: (source: Source, ?range: Range[Integer]?, context: Context) -> ContextArray - - def insert_context: (Range[Integer] range, context: Context, ?entry: Entry) -> void - - def each_entry: () { (Entry) -> void } -> void - | () -> Enumerator[Entry, void] - - def context_at: (Integer index, ?entry: Entry) -> Context? - - def []: (Integer index) -> Context? - - def at: (line: Integer, column: Integer) -> Context? - - def merge: (ContextArray subtree) -> void - end - end -end diff --git a/sig/steep/typing.rbs b/sig/steep/typing.rbs index f6c827b67..0e817312f 100644 --- a/sig/steep/typing.rbs +++ b/sig/steep/typing.rbs @@ -57,15 +57,13 @@ module Steep attr_reader cursor_context: CursorContext - attr_reader contexts: ContextArray - attr_reader root_context: Context attr_reader method_calls: Hash[Parser::AST::Node, MethodCall::t] attr_reader source_index: Index::SourceIndex - def initialize: (source: Source, root_context: Context, ?parent: Typing?, ?parent_last_update: Integer?, ?contexts: ContextArray?, ?source_index: Index::SourceIndex?, cursor: Integer?) -> void + def initialize: (source: Source, root_context: Context, ?parent: Typing?, ?parent_last_update: Integer?, ?source_index: Index::SourceIndex?, cursor: Integer?) -> void def add_error: (Diagnostic::Ruby::Base error) -> void @@ -73,28 +71,18 @@ module Steep def add_call: (Parser::AST::Node node, MethodCall::t call) -> void - def add_context: (Range[Integer] range, context: Context) -> void - def has_type?: (Parser::AST::Node node) -> bool def type_of: (node: Parser::AST::Node) -> AST::Types::t def call_of: (node: Parser::AST::Node) -> TypeInference::MethodCall::t - # def add_context_for_node: (Parser::AST::Node node, context: Context) -> void - - def block_range: (Parser::AST::Node node) -> Range[Integer] - - # def add_context_for_body: (Parser::AST::Node node, context: Context) -> void - - def context_at: (line: Integer, column: Integer) -> Context - def dump: (untyped io) -> untyped def self.summary: (untyped node) -> ::String - def new_child: [A] (Range[Integer] range) { (Typing) -> A } -> A - | (Range[Integer]) -> Typing + def new_child: [A] () { (Typing) -> A } -> A + | () -> Typing def each_typing: () { ([Parser::AST::Node, AST::Types::t]) -> void } -> void diff --git a/test/context_array_test.rb b/test/context_array_test.rb deleted file mode 100644 index 8427eaf38..000000000 --- a/test/context_array_test.rb +++ /dev/null @@ -1,91 +0,0 @@ -require_relative "test_helper" - -class ContextArrayTest < Minitest::Test - include Minitest::Hooks - include TestHelper - include FactoryHelper - - ContextArray = Steep::TypeInference::ContextArray - AST = Steep::AST - - def dump(array, entry = array.root, prefix: "") - puts "#{prefix}#{entry.range} => #{entry.context}" - entry.sub_entries.each do |sub| - dump array, sub, prefix: "#{prefix} " - end - end - - def test_array_1 - with_factory do - buffer = RBS::Buffer.new(name: :buf, content: < Date: Tue, 6 Aug 2024 17:07:37 +0900 Subject: [PATCH 6/6] Fix StackProf setup --- bin/steep-check.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/steep-check.rb b/bin/steep-check.rb index 2405f3490..cf8cf8639 100755 --- a/bin/steep-check.rb +++ b/bin/steep-check.rb @@ -201,7 +201,7 @@ def type_check_files(command_line_args, env) require "stackprof" out = Pathname.pwd + "tmp/typecheck-#{Process.pid}.stackprof" puts ">> Profiling with stackprof: #{out}" - StackProf.run(mode: :cpu, out: out, raw: true, interval: 1000) do + StackProf.run(out: out, raw: true, interval: 1000) do typings = command.type_check_files(command_line_args, env) end