def resolve_declaration(resolver, decl, outer:, prefix:)
def resolve_declaration(resolver, decl, outer:, prefix:)
if decl.is_a?(AST::Declarations::Global)
# @type var decl: AST::Declarations::Global
return AST::Declarations::Global.new(
name: decl.name,
type: absolute_type(resolver, decl.type, context: [Namespace.root]),
location: decl.location,
comment: decl.comment
)
end
context = (outer + [decl]).each.with_object([Namespace.root]) do |decl, array|
head = array.first or raise
array.unshift(head + decl.name.to_namespace)
end
outer_context = context.drop(1)
case decl
when AST::Declarations::Class
outer_ = outer + [decl]
prefix_ = prefix + decl.name.to_namespace
AST::Declarations::Class.new(
name: decl.name.with_prefix(prefix),
type_params: resolve_type_params(resolver, decl.type_params, context: context),
super_class: decl.super_class&.yield_self do |super_class|
AST::Declarations::Class::Super.new(
name: absolute_type_name(resolver, super_class.name, context: outer_context),
args: super_class.args.map {|type| absolute_type(resolver, type, context: outer_context) },
location: super_class.location
)
end,
members: decl.members.map do |member|
case member
when AST::Members::Base
resolve_member(resolver, member, context: context)
when AST::Declarations::Base
resolve_declaration(
resolver,
member,
outer: outer_,
prefix: prefix_
)
else
raise
end
end,
location: decl.location,
annotations: decl.annotations,
comment: decl.comment
)
when AST::Declarations::Module
outer_ = outer + [decl]
prefix_ = prefix + decl.name.to_namespace
AST::Declarations::Module.new(
name: decl.name.with_prefix(prefix),
type_params: resolve_type_params(resolver, decl.type_params, context: context),
self_types: decl.self_types.map do |module_self|
AST::Declarations::Module::Self.new(
name: absolute_type_name(resolver, module_self.name, context: context),
args: module_self.args.map {|type| absolute_type(resolver, type, context: context) },
location: module_self.location
)
end,
members: decl.members.map do |member|
case member
when AST::Members::Base
resolve_member(resolver, member, context: context)
when AST::Declarations::Base
resolve_declaration(
resolver,
member,
outer: outer_,
prefix: prefix_
)
else
raise
end
end,
location: decl.location,
annotations: decl.annotations,
comment: decl.comment
)
when AST::Declarations::Interface
AST::Declarations::Interface.new(
name: decl.name.with_prefix(prefix),
type_params: resolve_type_params(resolver, decl.type_params, context: context),
members: decl.members.map do |member|
resolve_member(resolver, member, context: context)
end,
comment: decl.comment,
location: decl.location,
annotations: decl.annotations
)
when AST::Declarations::Alias
AST::Declarations::Alias.new(
name: decl.name.with_prefix(prefix),
type_params: resolve_type_params(resolver, decl.type_params, context: context),
type: absolute_type(resolver, decl.type, context: context),
location: decl.location,
annotations: decl.annotations,
comment: decl.comment
)
when AST::Declarations::Constant
AST::Declarations::Constant.new(
name: decl.name.with_prefix(prefix),
type: absolute_type(resolver, decl.type, context: context),
location: decl.location,
comment: decl.comment
)
end
end
def resolve_member(resolver, member, context:)
def resolve_member(resolver, member, context:)
case member
when AST::Members::MethodDefinition
AST::Members::MethodDefinition.new(
name: member.name,
kind: member.kind,
types: member.types.map do |type|
resolve_method_type(resolver, type, context: context)
end,
comment: member.comment,
overload: member.overload?,
annotations: member.annotations,
location: member.location
)
when AST::Members::AttrAccessor
AST::Members::AttrAccessor.new(
name: member.name,
type: absolute_type(resolver, member.type, context: context),
kind: member.kind,
annotations: member.annotations,
comment: member.comment,
location: member.location,
ivar_name: member.ivar_name
)
when AST::Members::AttrReader
AST::Members::AttrReader.new(
name: member.name,
type: absolute_type(resolver, member.type, context: context),
kind: member.kind,
annotations: member.annotations,
comment: member.comment,
location: member.location,
ivar_name: member.ivar_name
)
when AST::Members::AttrWriter
AST::Members::AttrWriter.new(
name: member.name,
type: absolute_type(resolver, member.type, context: context),
kind: member.kind,
annotations: member.annotations,
comment: member.comment,
location: member.location,
ivar_name: member.ivar_name
)
when AST::Members::InstanceVariable
AST::Members::InstanceVariable.new(
name: member.name,
type: absolute_type(resolver, member.type, context: context),
comment: member.comment,
location: member.location
)
when AST::Members::ClassInstanceVariable
AST::Members::ClassInstanceVariable.new(
name: member.name,
type: absolute_type(resolver, member.type, context: context),
comment: member.comment,
location: member.location
)
when AST::Members::ClassVariable
AST::Members::ClassVariable.new(
name: member.name,
type: absolute_type(resolver, member.type, context: context),
comment: member.comment,
location: member.location
)
when AST::Members::Include
AST::Members::Include.new(
name: absolute_type_name(resolver, member.name, context: context),
args: member.args.map {|type| absolute_type(resolver, type, context: context) },
comment: member.comment,
location: member.location,
annotations: member.annotations
)
when AST::Members::Extend
AST::Members::Extend.new(
name: absolute_type_name(resolver, member.name, context: context),
args: member.args.map {|type| absolute_type(resolver, type, context: context) },
comment: member.comment,
location: member.location,
annotations: member.annotations
)
when AST::Members::Prepend
AST::Members::Prepend.new(
name: absolute_type_name(resolver, member.name, context: context),
args: member.args.map {|type| absolute_type(resolver, type, context: context) },
comment: member.comment,
location: member.location,
annotations: member.annotations
)
else
member
end
end