Loading lib/jsduck/inherit_doc.rb +41 −20 Original line number Diff line number Diff line Loading @@ -2,11 +2,13 @@ require 'jsduck/logger' module JsDuck # Deals with inheriting documentation class InheritDoc def initialize(relations) @relations = relations end # Performs all inheriting def resolve_all @relations.each do |cls| cls.each_member do |member| Loading @@ -17,38 +19,57 @@ module JsDuck end end # Copy over doc/params/return from original member to new one. # Copy over doc/params/return from parent member. def resolve(m) orig = find_original(m) m[:doc] = m[:doc] + "\n\n" + orig[:doc] m[:params] = orig[:params] if orig[:params] m[:return] = orig[:return] if orig[:return] parent = find_parent(m) m[:doc] = (m[:doc] + "\n\n" + parent[:doc]).strip m[:params] = parent[:params] if parent[:params] m[:return] = parent[:return] if parent[:return] end # Finds the member to which inheritdoc refers to. # If the original also happens to alos have @inheritdoc, continue recursively. def find_original(m) # Finds parent member of the given member. When @inheritdoc names # a member to inherit from, finds that member instead. # # If the parent also has @inheritdoc, continues recursively. def find_parent(m) context = m[:files][0] inherit = m[:inheritdoc] orig = @relations[inherit[:cls]] unless orig Logger.instance.warn(:inheritdoc, "Class #{inherit[:cls]} not found", context[:filename], context[:linenr]) if inherit[:cls] parent_cls = @relations[inherit[:cls]] unless parent_cls warn("@inheritdoc #{inherit[:cls]}##{inherit[:member]} - class not found", context) return m end orig = orig.get_member(inherit[:member], inherit[:type] || m[:tagname]) unless orig Logger.instance.warn(:inheritdoc, "Member #{inherit[:cls]}##{inherit[:member]} not found", context[:filename], context[:linenr]) parent = parent_cls.get_member(inherit[:member], inherit[:type] || m[:tagname]) unless parent warn("@inheritdoc #{inherit[:cls]}##{inherit[:member]} - member not found", context) return m end else parent_cls = @relations[m[:owner]].parent unless parent_cls warn("@inheritdoc - parent class not found", context) return m end parent = parent_cls.get_member(m[:name], m[:tagname]) unless parent warn("@inheritdoc - parent member not found", context) return m end end if orig[:inheritdoc] find_original(orig) if parent[:inheritdoc] find_parent(parent) else orig parent end end def warn(msg, context) Logger.instance.warn(:inheritdoc, msg, context[:filename], context[:linenr]) end end end spec/aggregator_inheritdoc_spec.rb +78 −0 Original line number Diff line number Diff line Loading @@ -3,9 +3,14 @@ require "jsduck/source_file" require "jsduck/class" require "jsduck/relations" require "jsduck/inherit_doc" require "jsduck/logger" describe JsDuck::Aggregator do before do JsDuck::Logger.instance.set_warning(:inheritdoc, false) end def parse(string) agr = JsDuck::Aggregator.new agr.aggregate(JsDuck::SourceFile.new(string)) Loading Loading @@ -288,5 +293,78 @@ describe JsDuck::Aggregator do end end describe "@inheritdoc without parameter" do before do @docs = parse(<<-EOF) /** * @class Parent */ /** * @method foo * Original comment. * @param arg1 * @param arg2 * @return {String} */ /** * @class Child * @extends Parent */ /** * @method foo * @inheritdoc */ EOF @method = @docs["Child"][:members][:method][0] end it "inherits docs from parent class method" do @method[:doc].should == "Original comment." end end describe "@inheritdoc without parent" do before do @docs = parse(<<-EOF) /** * @class Child */ /** * @method foo * @inheritdoc */ EOF @method = @docs["Child"][:members][:method][0] end it "inherits nothing" do @method[:doc].should == "" end end describe "@inheritdoc without method in parent" do before do @docs = parse(<<-EOF) /** * @class Parent */ /** * @class Child * @extends Parent */ /** * @method foo * @inheritdoc */ EOF @method = @docs["Child"][:members][:method][0] end it "inherits nothing" do @method[:doc].should == "" end end end Loading
lib/jsduck/inherit_doc.rb +41 −20 Original line number Diff line number Diff line Loading @@ -2,11 +2,13 @@ require 'jsduck/logger' module JsDuck # Deals with inheriting documentation class InheritDoc def initialize(relations) @relations = relations end # Performs all inheriting def resolve_all @relations.each do |cls| cls.each_member do |member| Loading @@ -17,38 +19,57 @@ module JsDuck end end # Copy over doc/params/return from original member to new one. # Copy over doc/params/return from parent member. def resolve(m) orig = find_original(m) m[:doc] = m[:doc] + "\n\n" + orig[:doc] m[:params] = orig[:params] if orig[:params] m[:return] = orig[:return] if orig[:return] parent = find_parent(m) m[:doc] = (m[:doc] + "\n\n" + parent[:doc]).strip m[:params] = parent[:params] if parent[:params] m[:return] = parent[:return] if parent[:return] end # Finds the member to which inheritdoc refers to. # If the original also happens to alos have @inheritdoc, continue recursively. def find_original(m) # Finds parent member of the given member. When @inheritdoc names # a member to inherit from, finds that member instead. # # If the parent also has @inheritdoc, continues recursively. def find_parent(m) context = m[:files][0] inherit = m[:inheritdoc] orig = @relations[inherit[:cls]] unless orig Logger.instance.warn(:inheritdoc, "Class #{inherit[:cls]} not found", context[:filename], context[:linenr]) if inherit[:cls] parent_cls = @relations[inherit[:cls]] unless parent_cls warn("@inheritdoc #{inherit[:cls]}##{inherit[:member]} - class not found", context) return m end orig = orig.get_member(inherit[:member], inherit[:type] || m[:tagname]) unless orig Logger.instance.warn(:inheritdoc, "Member #{inherit[:cls]}##{inherit[:member]} not found", context[:filename], context[:linenr]) parent = parent_cls.get_member(inherit[:member], inherit[:type] || m[:tagname]) unless parent warn("@inheritdoc #{inherit[:cls]}##{inherit[:member]} - member not found", context) return m end else parent_cls = @relations[m[:owner]].parent unless parent_cls warn("@inheritdoc - parent class not found", context) return m end parent = parent_cls.get_member(m[:name], m[:tagname]) unless parent warn("@inheritdoc - parent member not found", context) return m end end if orig[:inheritdoc] find_original(orig) if parent[:inheritdoc] find_parent(parent) else orig parent end end def warn(msg, context) Logger.instance.warn(:inheritdoc, msg, context[:filename], context[:linenr]) end end end
spec/aggregator_inheritdoc_spec.rb +78 −0 Original line number Diff line number Diff line Loading @@ -3,9 +3,14 @@ require "jsduck/source_file" require "jsduck/class" require "jsduck/relations" require "jsduck/inherit_doc" require "jsduck/logger" describe JsDuck::Aggregator do before do JsDuck::Logger.instance.set_warning(:inheritdoc, false) end def parse(string) agr = JsDuck::Aggregator.new agr.aggregate(JsDuck::SourceFile.new(string)) Loading Loading @@ -288,5 +293,78 @@ describe JsDuck::Aggregator do end end describe "@inheritdoc without parameter" do before do @docs = parse(<<-EOF) /** * @class Parent */ /** * @method foo * Original comment. * @param arg1 * @param arg2 * @return {String} */ /** * @class Child * @extends Parent */ /** * @method foo * @inheritdoc */ EOF @method = @docs["Child"][:members][:method][0] end it "inherits docs from parent class method" do @method[:doc].should == "Original comment." end end describe "@inheritdoc without parent" do before do @docs = parse(<<-EOF) /** * @class Child */ /** * @method foo * @inheritdoc */ EOF @method = @docs["Child"][:members][:method][0] end it "inherits nothing" do @method[:doc].should == "" end end describe "@inheritdoc without method in parent" do before do @docs = parse(<<-EOF) /** * @class Parent */ /** * @class Child * @extends Parent */ /** * @method foo * @inheritdoc */ EOF @method = @docs["Child"][:members][:method][0] end it "inherits nothing" do @method[:doc].should == "" end end end