Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions lib/steep/type_construction.rb
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,9 @@ def for_class(node)

instance_type = AST::Types::Name::Instance.new(name: class_name, args: class_args)
module_type = AST::Types::Name::Singleton.new(name: class_name)
else
instance_type = AST::Builtin::Object.instance_type
module_type = AST::Builtin::Object.module_type
end

if annots.instance_type
Expand Down Expand Up @@ -879,9 +882,7 @@ def synthesize(node, hint: nil, condition: false)
new.typing.add_context_for_node(node, context: new.context)
new.typing.add_context_for_body(node, context: new.context)

each_child_node(args_node) do |arg|
_, new = new.synthesize(arg)
end
new = new.synthesize_children(args_node)

body_pair = if body_node
return_type = expand_alias(new.method_context&.return_type)
Expand Down Expand Up @@ -936,14 +937,17 @@ def synthesize(node, hint: nil, condition: false)
checker.factory.definition_builder.build_singleton(name)
end

args_node = node.children[2]
new = for_new_method(node.children[1],
node,
args: node.children[2].children,
args: args_node.children,
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 = new.synthesize_children(args_node)

each_child_node(node.children[2]) do |arg|
new.synthesize(arg)
end
Expand Down Expand Up @@ -1091,10 +1095,6 @@ def synthesize(node, hint: nil, condition: false)
add_typing(node, type: type)
else
type = AST::Builtin.any_type
if context&.method_context&.method_type
Steep.logger.error { "Unknown arg type: #{node}" }
end

lvasgn(node, type)
end
end
Expand Down Expand Up @@ -2164,7 +2164,12 @@ def synthesize(node, hint: nil, condition: false)

when :splat
yield_self do
Steep.logger.warn { "Unsupported node #{node.type} (#{node.location.expression.source_buffer.name}:#{node.location.expression.line})" }
typing.add_error(
Errors::UnsupportedSyntax.new(
node: node,
message: "Unsupported splat node occurrence"
)
)

each_child_node node do |child|
synthesize(child)
Expand All @@ -2183,7 +2188,7 @@ def synthesize(node, hint: nil, condition: false)
add_typing node, type: AST::Builtin.any_type, constr: constr

else
raise "Unexpected node: #{node.inspect}, #{node.location.expression}"
typing.add_error(Errors::UnsupportedSyntax.new(node: node))

end.tap do |pair|
unless pair.is_a?(Pair) && !pair.type.is_a?(Pair)
Expand Down
9 changes: 1 addition & 8 deletions test/master_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,7 @@ class Foo
RUBY

finally_holds do
assert_equal [{
range: {
start: { line: 0, character: 6 },
end: { line: 0, character: 9 }
},
severity: 1,
message: "FallbackAny (Foo)"
}],
assert_equal [],
ui.diagnostics_for(project.absolute_path(Pathname("lib/foo.rb")))
end

Expand Down
1 change: 0 additions & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,6 @@ class TrueClass
end
class FalseClass
end

EOS

def checker
Expand Down
94 changes: 59 additions & 35 deletions test/type_construction_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,8 @@ class Address
for_class = construction.for_class(source.node)

assert_nil for_class.module_context.implement_name
assert_nil for_class.module_context.instance_type
assert_nil for_class.module_context.module_type
assert_equal parse_type("::Object"), for_class.module_context.instance_type
assert_equal parse_type("singleton(::Object)"), for_class.module_context.module_type
end
end
end
Expand Down Expand Up @@ -1386,7 +1386,7 @@ def bar
with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)

assert_typing_error(typing, size: 3) do |errors|
assert_typing_error(typing, size: 2) do |errors|
assert_any!(errors) do |error|
assert_instance_of Steep::Errors::IncompatibleAssignment, error
assert_equal parse_type("::String"), error.rhs_type
Expand All @@ -1398,10 +1398,6 @@ def bar
assert_equal parse_type("::String"), error.actual
assert_equal parse_type("::A::String"), error.expected
end

assert_any!(errors) do |error|
assert_instance_of Steep::Errors::FallbackAny, error
end
end
end
end
Expand Down Expand Up @@ -3033,7 +3029,12 @@ def test_splat_from_any
with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)

assert_empty typing.errors
assert_typing_error typing, size: 1 do |errors|
errors[0].tap do |error|
assert_instance_of Steep::Errors::UnsupportedSyntax, error
assert_equal :splat, error.node.type
end
end
end
end
end
Expand Down Expand Up @@ -4564,21 +4565,7 @@ def foo
with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)

assert_typing_error(typing, size: 3) do |errors|
assert_any!(errors) do |error|
assert_instance_of Steep::Errors::NoMethod, error
assert_equal :attr_reader, error.method
end

assert_any!(errors) do |error|
assert_instance_of Steep::Errors::NoMethod, error
assert_equal :to_s, error.method
end

assert_any!(errors) do |error|
assert_instance_of Steep::Errors::FallbackAny, error
end
end
assert_no_error(typing)
end
end
end
Expand Down Expand Up @@ -4980,8 +4967,11 @@ def open(x)
with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)

assert_equal 1, typing.errors.size
assert_instance_of Steep::Errors::MethodArityMismatch, typing.errors[0]
assert_typing_error typing, size: 1 do |errors|
assert_any!(errors) do |error|
assert_instance_of Steep::Errors::MethodArityMismatch, error
end
end
end
end
end
Expand Down Expand Up @@ -5451,16 +5441,7 @@ class << self
with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)

assert_typing_error(typing, size: 2) do |errors|
assert_any!(errors) do |error|
assert_instance_of Steep::Errors::UnsupportedSyntax, error
assert_equal :sclass, error.node.type
end

assert_any!(errors) do |error|
assert_instance_of Steep::Errors::FallbackAny, error
end
end
assert_no_error typing
end
end
end
Expand Down Expand Up @@ -7062,4 +7043,47 @@ def test_case_when_var
end
end
end

def test_defs_self
with_checker() do |checker|
source = parse_ruby(<<'RUBY')
class C < UnknownSuperClass
def self.foo
end
end
RUBY

with_standard_construction(checker, source) do |construction, typing|
type, _ = construction.synthesize(source.node)

assert_typing_error(typing, size: 2) do |errors|
assert_all!(errors) do |error|
assert_instance_of Steep::Errors::FallbackAny, error
end
end
end
end
end

def test_case_when_arg
with_checker() do |checker|
source = parse_ruby(<<'RUBY')
class C
def self.foo(x)
case x
when Integer
x + 1
when String
x + ""
end
end
end
RUBY

with_standard_construction(checker, source) do |construction, typing|
construction.synthesize(source.node)
assert_no_error typing
end
end
end
end