Skip to content

Commit

Permalink
Merge pull request #836 from soutaro/resolve-types-in-node
Browse files Browse the repository at this point in the history
Resolve type names from TypeAssertion and TypeApplication
  • Loading branch information
soutaro authored Jul 5, 2023
2 parents ee0a525 + 2897ff7 commit 3ddcabc
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 9 deletions.
5 changes: 4 additions & 1 deletion lib/steep/ast/node/type_application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@ def source
end

def types(context, subtyping, type_vars)
resolver = RBS::Resolver::TypeNameResolver.new(subtyping.factory.env)

# @type var types: Array[Types::t]
types = []

loc = type_location

while true
ty = RBS::Parser.parse_type(loc.buffer, range: loc.range, variables: type_vars) or break
ty = ty.map_type_name {|name| resolver.resolve(name, context: context) || name.absolute! }

validator = Signature::Validator.new(checker: subtyping)
validator.validate_type(ty)
Expand All @@ -41,7 +44,7 @@ def types(context, subtyping, type_vars)
end

ty = subtyping.factory.type(ty)
types << subtyping.factory.absolute_type(ty, context: context)
types << ty

match = RBS::Location.new(loc.buffer, ty.location.end_pos, type_location.end_pos).source.match(/\A\s*,\s*/) or break
offset = match.length
Expand Down
6 changes: 4 additions & 2 deletions lib/steep/ast/node/type_assertion.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ def line

def type(context, subtyping, type_vars)
if ty = RBS::Parser.parse_type(type_location.buffer, range: type_location.range, variables: type_vars, require_eof: true)
resolver = RBS::Resolver::TypeNameResolver.new(subtyping.factory.env)
ty = ty.map_type_name {|name| resolver.resolve(name, context: context) || name.absolute! }

validator = Signature::Validator.new(checker: subtyping)
validator.validate_type(ty)

unless validator.has_error?
ty = subtyping.factory.type(ty)
subtyping.factory.absolute_type(ty, context: context)
subtyping.factory.type(ty)
end
else
nil
Expand Down
17 changes: 11 additions & 6 deletions test/ast/node/type_application_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@ def buffer(string)
end

def test_one_type
with_checker do
loc = buffer("$String")
with_checker(<<~RBS) do
class Foo
class Bar
end
end
RBS
loc = buffer("$Bar")

app = Steep::AST::Node::TypeApplication.parse(loc)

assert_equal "String", app.type_str
app.types(nil, checker, []).tap do |types|
assert_equal "Bar", app.type_str
app.types([nil, TypeName("::Foo")], checker, []).tap do |types|
assert_equal 1, types.size
assert_equal parse_type("::String"), types[0]
assert_equal "String", types[0].location.source
assert_equal parse_type("::Foo::Bar"), types[0]
assert_equal "Bar", types[0].location.source
end
end
end
Expand Down
45 changes: 45 additions & 0 deletions test/ast/node/type_assertion_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require_relative "../../test_helper"

class AST__Node__TypeAssertionTest < Minitest::Test
include TestHelper
include FactoryHelper
include SubtypingHelper

def buffer(string)
buffer = RBS::Buffer.new(name: "foo.rbs", content: string)
RBS::Location.new(buffer, 0, string.size)
end

def test_type
with_checker do
loc = buffer(": String")

assertion = Steep::AST::Node::TypeAssertion.parse(loc)

assert_equal "String", assertion.type_str
assert_predicate assertion, :type_syntax?

type = assertion.type(nil, checker, [])
assert_equal parse_type("::String"), type
end
end

def test_relative_type
with_checker(<<~RBS) do
class Foo
class Bar
end
end
RBS
loc = buffer(": Array[Bar]")

assertion = Steep::AST::Node::TypeAssertion.parse(loc)

assert_equal "Array[Bar]", assertion.type_str
assert_predicate assertion, :type_syntax?

type = assertion.type([nil, TypeName("::Foo")], checker, [])
assert_equal parse_type("::Array[::Foo::Bar]"), type
end
end
end
26 changes: 26 additions & 0 deletions test/type_check_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -783,4 +783,30 @@ def test_or_shortcut__false
YAML
)
end

def test_type_assertion__generic_type_error
run_type_check_test(
signatures: {
"a.rbs" => <<~RBS
class Foo
class Bar
end
end
RBS
},
code: {
"a.rb" => <<~RUBY
class Foo
a = [] #: Array[Bar]
a.map {|x| x } #$ Bar
end
RUBY
},
expectations: <<~YAML
---
- file: a.rb
diagnostics: []
YAML
)
end
end

0 comments on commit 3ddcabc

Please sign in to comment.