module Steep module AST module Signature class Env attr_reader :modules attr_reader :classes attr_reader :extensions attr_reader :interfaces attr_reader :constants attr_reader :globals def initialize() @modules = {} @classes = {} @extensions = {} @interfaces = {} @constants = {} @globals = {} end def add(sig) case sig when Signature::Class raise "Duplicated class: #{sig.name}" if classes.key?(sig.name.absolute!) || modules.key?(sig.name.absolute!) classes[sig.name.absolute!] = sig when Signature::Module raise "Duplicated module: #{sig.name}" if classes.key?(sig.name.absolute!) || modules.key?(sig.name.absolute!) modules[sig.name.absolute!] = sig when Signature::Interface raise "Duplicated interface: #{sig.name}" if interfaces.key?(sig.name) interfaces[sig.name] = sig when Signature::Extension extensions[sig.module_name.absolute!] ||= [] if extensions[sig.module_name.absolute!].any? {|ext| ext.name == sig.name } raise "Duplicated extension: #{sig.module_name.absolute!} (#{sig.name})" end extensions[sig.module_name.absolute!] << sig when Signature::Const constants[sig.name.absolute!] = sig when Signature::Gvar raise "Duplicated global: #{sig.name}" if globals.key?(sig.name) globals[sig.name] = sig else raise "Unknown signature:: #{sig}" end end def find_module(name, current_module: nil) find_name(modules, name, current_module: current_module) or raise "Unknown module: #{name}" end def find_class(name, current_module: nil) find_name(classes, name, current_module: current_module) or raise "Unknown class: #{name}" end def find_class_or_module(name, current_module: nil) sig = find_name(modules, name, current_module: current_module) || find_name(classes, name, current_module: current_module) sig or raise "Unknown class/module: #{name}}" end def find_extensions(name, current_module: nil) find_name(extensions, name, current_module: current_module) || [] end def find_const(name, current_module: nil) find_name(constants, name, current_module: current_module) end def find_gvar(name) globals[name] end def find_name(hash, name, current_module:) if current_module hash[current_module + name] || find_name(hash, name, current_module: current_module.parent) else hash[name.absolute!] end end def find_interface(name) interfaces[name] or raise "Unknown interface: #{name}" end def module?(type_name, current_module: nil) name = type_name.map_module_name {|m| current_module ? current_module + m : m.absolute! }.name modules.key?(name) end def class?(type_name, current_module: nil) name = type_name.map_module_name {|m| current_module ? current_name + m : m.absolute! }.name classes.key?(name) end def class_name?(name, current_module: nil) classes.key?(current_module ? current_module + name : name.absolute!) end def module_name?(name, current_module: nil) modules.key?(current_module ? current_module + name : name.absolute!) end def const_name?(name, current_module: nil) constants.key?(current_module ? current_module + name : name.absolute!) end def each(&block) if block_given? classes.each_value(&block) modules.each_value(&block) interfaces.each_value(&block) constants.each_value(&block) else enum_for :each end end end end end end