class Yoda::Store::YardImporter
Attributes
@return [Objects::Patch]
@return [String, nil]
Public Class Methods
@param file [String] @param root_path
[String, nil] @return [Objects::Patch]
# File lib/yoda/store/yard_importer.rb, line 15 def self.import(file, root_path: nil) store = YARD::RegistryStore.new store.load(file) root_path ||= File.expand_path('..', file) new(file, root_path: root_path).import(store.values).patch end
@param id [String]
# File lib/yoda/store/yard_importer.rb, line 23 def initialize(id, root_path: nil) @patch = Objects::Patch.new(id) @root_path = root_path @registered = Set.new end
Public Instance Methods
@param values [Array<YARD::CodeObjects::Base>] @return [self]
# File lib/yoda/store/yard_importer.rb, line 31 def import(values) values.each do |el| register(el) end self end
@param code_object [YARD::CodeObjects::Base]
# File lib/yoda/store/yard_importer.rb, line 39 def register(code_object) return if @registered.member?(code_object.path) @registered.add(code_object.path) register(code_object.parent) if code_object.parent new_objects = begin case code_object.type when :root convert_root_object(code_object) when :class convert_class_object(code_object) when :module convert_module_object(code_object) when :classvariable # convert_class_variable_object(code_object) when :method convert_method_object(code_object) when :macro # convert_macro_object(code_object) when :constant convert_constant_object(code_object) when :proxy create_proxy_module(code_object) else fail ArgumentError, 'Unsupported type code object' end end # In YARD, proxy module is undetermined its absolute path and its defined namespace is undetermined. # In Yoda, proxy module is assumed to be defined directory under parent namespace. register_to_parent(code_object) if code_object.parent && (code_object.type == :proxy || code_object.parent.type == :proxy) [new_objects].flatten.compact.each { |new_object| patch.register(new_object) } end
Private Instance Methods
@param code_object [::YARD::CodeObjects::Base] @return [String] absolute object path to store.
# File lib/yoda/store/yard_importer.rb, line 277 def calc_path_to_store(object) return 'Object' if object.root? parent_path = path_to_store(object.parent) if object.type == :proxy || object.is_a?(YARD::CodeObjects::Proxy) # For now, we suppose the proxy object exists directly under its namespace. [path_to_store(object.parent), object.name].join('::') elsif object.parent.path == path_to_store(object.parent) object.path else [path_to_store(object.parent), object.name].join(object.sep) end.gsub(/^Object::/, '') end
@param code_object [::YARD::CodeObjects::ClassObject] @return [Array<Objects::ClassObject, Objects::MetaClassObject>]
# File lib/yoda/store/yard_importer.rb, line 172 def convert_class_object(code_object) class_object = Objects::ClassObject.new( path: path_to_store(code_object), document: code_object.docstring.to_s, tag_list: code_object.tags.map { |tag| convert_tag(tag, path_to_store(code_object)) }, sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, instance_method_addresses: code_object.meths(included: false, scope: :instance).map { |meth| path_to_store(meth) }, mixin_addresses: code_object.instance_mixins.map { |mixin| path_to_store(mixin) }, constant_addresses: code_object.children.select{ |child| %i(constant module class).include?(child.type) }.map { |constant| path_to_store(constant) }, superclass_path: !code_object.superclass || code_object.superclass&.path == 'Qnil' ? nil : path_to_store(code_object.superclass), ) meta_class_object = Objects::MetaClassObject.new( path: path_to_store(code_object), sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, instance_method_addresses: code_object.meths(included: false, scope: :class).map { |meth| path_to_store(meth) }, mixin_addresses: code_object.class_mixins.map { |mixin| path_to_store(mixin) }, ) [class_object, meta_class_object] end
@param code_object [::YARD::CodeObjects::ConstantObject] @return [Objects::ValueObject]
# File lib/yoda/store/yard_importer.rb, line 100 def convert_constant_object(code_object) Objects::ValueObject.new( path: path_to_store(code_object), document: code_object.docstring.to_s, tag_list: code_object.tags.map { |tag| convert_tag(tag, path_to_store(code_object.namespace)) }, sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, value: code_object.value, ) end
@param code_object [::YARD::CodeObjects::MethodObject] @return [Objects::MethodObject, (Objects::MethodObject
, Object::ClassObject)]
# File lib/yoda/store/yard_importer.rb, line 113 def convert_method_object(code_object) if code_object.namespace.root? # @todo Remove root oriented method path from Object namespace method_object = Objects::MethodObject.new( path: "Object#{code_object.sep}#{code_object.name}", document: code_object.docstring.to_s, tag_list: code_object.tags.map { |tag| convert_tag(tag, path_to_store(code_object.namespace)) }, overloads: code_object.tags(:overload).map { |tag| convert_overload_tag(tag, path_to_store(code_object.namespace)) }, sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, parameters: code_object.parameters, visibility: :private, ) object_object = Objects::ClassObject.new( path: 'Object', instance_method_addresses: ["Object#{code_object.sep}#{code_object.name}"], ) [method_object, object_object] else Objects::MethodObject.new( path: path_to_store(code_object), document: code_object.docstring.to_s, tag_list: code_object.tags.map { |tag| convert_tag(tag, path_to_store(code_object.namespace)) }, overloads: code_object.tags(:overload).map { |tag| convert_overload_tag(tag, path_to_store(code_object.namespace)) }, sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, parameters: code_object.parameters, visibility: code_object.visibility, ) end end
@param code_object [::YARD::CodeObjects::ModuleObject] @return [Array<Objects::ModuleObject, Objects::MetaClassObject>]
# File lib/yoda/store/yard_importer.rb, line 147 def convert_module_object(code_object) module_object = Objects::ModuleObject.new( path: path_to_store(code_object), document: code_object.docstring.to_s, tag_list: code_object.tags.map { |tag| convert_tag(tag, path_to_store(code_object)) }, sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, instance_method_addresses: code_object.meths(included: false, scope: :instance).map { |meth| path_to_store(meth) }, mixin_addresses: code_object.instance_mixins.map { |mixin| path_to_store(mixin) }, constant_addresses: code_object.children.select{ |child| %i(constant module class).include?(child.type) }.map { |constant| constant.path }, ) meta_class_object = Objects::MetaClassObject.new( path: path_to_store(code_object), sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, instance_method_addresses: code_object.meths(included: false, scope: :class).map { |meth| path_to_store(meth) }, mixin_addresses: code_object.instance_mixins.map { |mixin| path_to_store(mixin) }, ) [module_object, meta_class_object] end
@param tag [::YARD::Tags::OverloadTag] @param namespace [String] @return [Objects::Tag]
# File lib/yoda/store/yard_importer.rb, line 206 def convert_overload_tag(tag, namespace) Objects::Overload.new(name: tag.name.to_s, tag_list: tag.tags.map { |tag| convert_tag(tag, namespace) }, document: tag.docstring.to_s, parameters: tag.parameters) end
@param code_object [::YARD::CodeObjects::NamespaceObject] @return [Objects::ClassObject]
# File lib/yoda/store/yard_importer.rb, line 77 def convert_root_object(code_object) object_class = Objects::ClassObject.new( path: path_to_store(code_object), document: code_object.docstring.to_s, tag_list: code_object.tags.map { |tag| convert_tag(tag, '') }, sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, instance_method_addresses: code_object.meths(included: false, scope: :instance).map { |meth| path_to_store(meth) }, mixin_addresses: code_object.instance_mixins.map { |mixin| path_to_store(mixin) }, constant_addresses: (code_object.children.select{ |child| %i(constant module class).include?(child.type) }.map { |constant| constant.path } + ['Object']).uniq, ) object_meta_class = Objects::MetaClassObject.new( path: path_to_store(code_object), sources: code_object.files.map(&method(:convert_source)), primary_source: code_object[:current_file_has_comments] ? convert_source(code_object.files.first) : nil, instance_method_addresses: code_object.meths(included: false, scope: :class).map { |meth| path_to_store(meth) }, mixin_addresses: code_object.instance_mixins.map { |mixin| path_to_store(mixin) }, ) [object_class, object_meta_class] end
@param source [(String, Integer)] @return [(String, Integer, Integer)]
# File lib/yoda/store/yard_importer.rb, line 263 def convert_source(source) file, line = source [root_path ? File.expand_path(file, root_path) : file, line, 0] end
@param tag [::YARD::Tags::Tag] @param namespace [String] @return [Objects::Tag]
# File lib/yoda/store/yard_importer.rb, line 199 def convert_tag(tag, namespace) Objects::Tag.new(tag_name: tag.tag_name, name: tag.name, yard_types: tag.types, text: tag.text, lexical_scope: convert_to_lexical_scope(namespace)) end
@param namespace [String] @return [Array<String>]
# File lib/yoda/store/yard_importer.rb, line 212 def convert_to_lexical_scope(namespace) path = Model::Path.new(namespace) ((path.to_s.empty? ? [] : [path]) + path.parent_paths).map(&:to_s) end
@param symbol [Symbol] @return [Symbol]
# File lib/yoda/store/yard_importer.rb, line 219 def convert_yard_object_type(type) case type when :constant :value else type end end
@param code_object [::YARD::CodeObjects::Proxy] @return [Array<Objects::ModuleObject>]
# File lib/yoda/store/yard_importer.rb, line 230 def create_proxy_module(code_object) module_object = Objects::ModuleObject.new( path: path_to_store(code_object), document: '', tag_list: [], sources: [], primary_source: nil, instance_method_addresses: [], mixin_addresses: [], constant_addresses: [], ) meta_class_object = Objects::MetaClassObject.new( path: path_to_store(code_object), sources: [], primary_source: nil, instance_method_addresses: [], mixin_addresses: [], ) [module_object, meta_class_object] end
@param code_object [::YARD::CodeObjects::Base] @return [String]
# File lib/yoda/store/yard_importer.rb, line 270 def path_to_store(object) @paths_to_store ||= {} @paths_to_store[[object.type, object.path]] ||= calc_path_to_store(object) end
@param code_object [::YARD::CodeObjects::Base] @return [vaid]
# File lib/yoda/store/yard_importer.rb, line 255 def register_to_parent(code_object) parent_module = patch.find(path_to_store(code_object.parent)) parent_module.instance_method_addresses.push(path_to_store(code_object)) if code_object.type == :method parent_module.constant_addresses.push(path_to_store(code_object)) if [:class, :module, :proxy].include?(code_object.type) end