Loading lib/jsduck/ast.rb +51 −5 Original line number Diff line number Diff line Loading @@ -5,15 +5,43 @@ module JsDuck # Analyzes the AST produced by EsprimaParser. class Ast def initialize # Should be initialized with EsprimaParser#parse result. def initialize(docs = []) @serializer = JsDuck::Serializer.new @evaluator = JsDuck::Evaluator.new @docs = docs end # Given parsed code, returns the tagname for documentation item. # Performs the detection of code in all docsets. # # @returns the processes array of docsets. (But it does it # destructively by modifying the passed-in docsets.) # def detect_all! # For now only deal with doc-comments @docs = @docs.find_all {|d| d[:type] == :doc_comment } # Detect code in each docset. Sometimes a docset has already # been as part of detecting some previous docset (like Class # detecting all of its configs) - in such case, skip. @docs.each do |docset| code = docset[:code] docset[:code] = detect(code) unless code && code[:tagname] end @docs end # Given Esprima-produced syntax tree, detects documentation data. # # This method is exposed for testing purposes only, JSDuck itself # only calls the above #detect_all method. # # @param ast :code from Result of EsprimaParser # @returns One of: :class, :method, :property # @returns Hash consisting of the detected :tagname, :name, and # other properties relative to the tag. Like so: # # { :tagname => :method, :name => "foo", ... } # def detect(ast) ast = ast || {} Loading Loading @@ -208,12 +236,30 @@ module JsDuck return nil unless ast && ast["type"] == "ObjectExpression" configs = [] object_expression_to_hash(ast).each_pair do |key, value| configs << make_property(key, value, :cfg) ast["properties"].each do |p| cfg = make_property(key_value(p["key"]), p["value"], :cfg) # When config has a comment, update the related docset, # otherwise add it as new config to current class. docset = find_docset(p) if docset docset[:code] = cfg else configs << cfg end end configs end # Looks up docset associated with given AST node. # A dead-stupid and -slow implementation, but works. def find_docset(ast) @docs.find do |docset| docset[:code] == ast end end def make_method(name, ast=nil) return { :tagname => :method, Loading lib/jsduck/doc_type.rb +1 −3 Original line number Diff line number Diff line Loading @@ -31,10 +31,8 @@ module JsDuck :css_mixin elsif doc_map[:cfg] :cfg elsif code[:tagname] == :method :method else :property code[:tagname] end end Loading lib/jsduck/merger.rb +5 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,11 @@ module JsDuck result = create_bare_class(groups[:class], code) result[:members] = create_class_members(groups, result[:name]) result[:statics] = Class.default_members_hash if code[:members] && code[:members][:cfg] code[:members][:cfg].each do |cfg| result[:members][:cfg] << create_cfg({}, cfg, result[:name]) end end result end Loading lib/jsduck/source_file.rb +1 −6 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ module JsDuck @options = options @html_filename = "" @links = {} @ast = Ast.new doc_parser = DocParser.new Loading Loading @@ -92,11 +91,7 @@ module JsDuck CssParser.new(@contents, @options).parse else docs = EsprimaParser.new(@contents, @options).parse docs = docs.find_all {|d| d[:type] == :doc_comment } docs.each do |docset| docset[:code] = @ast.detect(docset[:code]) end docs Ast.new(docs).detect_all! end rescue puts "Error while parsing #{@filename}: #{$!}" Loading spec/aggregator_cfg_spec.rb 0 → 100644 +68 −0 Original line number Diff line number Diff line require "jsduck/aggregator" require "jsduck/source_file" describe JsDuck::Aggregator do def parse(string) agr = JsDuck::Aggregator.new agr.aggregate(JsDuck::SourceFile.new(string)) agr.result end describe "detecting Ext.define() with configs in code" do let(:cfg) do parse(<<-EOS)[0][:members][:cfg] /** * Some documentation. */ Ext.define("MyClass", { config: { foo: 42, bar: "hello" } }); EOS end it "finds configs" do cfg.should be_kind_of(Array) end it "finds two configs" do cfg.length.should == 2 end end describe "detecting Ext.define() with commented config" do let(:docs) do parse(<<-EOS) /** * Some documentation. */ Ext.define("MyClass", { config: { /** Docs for bar */ bar: "hello" } }); EOS end it "finds one docset" do docs.length.should == 1 end it "detects it as class" do docs[0][:tagname] == :class end it "detects one config within class" do docs[0][:members][:cfg].length.should == 1 end it "detects the config with docs" do docs[0][:members][:cfg][0][:doc].should == "Docs for bar" end end end Loading
lib/jsduck/ast.rb +51 −5 Original line number Diff line number Diff line Loading @@ -5,15 +5,43 @@ module JsDuck # Analyzes the AST produced by EsprimaParser. class Ast def initialize # Should be initialized with EsprimaParser#parse result. def initialize(docs = []) @serializer = JsDuck::Serializer.new @evaluator = JsDuck::Evaluator.new @docs = docs end # Given parsed code, returns the tagname for documentation item. # Performs the detection of code in all docsets. # # @returns the processes array of docsets. (But it does it # destructively by modifying the passed-in docsets.) # def detect_all! # For now only deal with doc-comments @docs = @docs.find_all {|d| d[:type] == :doc_comment } # Detect code in each docset. Sometimes a docset has already # been as part of detecting some previous docset (like Class # detecting all of its configs) - in such case, skip. @docs.each do |docset| code = docset[:code] docset[:code] = detect(code) unless code && code[:tagname] end @docs end # Given Esprima-produced syntax tree, detects documentation data. # # This method is exposed for testing purposes only, JSDuck itself # only calls the above #detect_all method. # # @param ast :code from Result of EsprimaParser # @returns One of: :class, :method, :property # @returns Hash consisting of the detected :tagname, :name, and # other properties relative to the tag. Like so: # # { :tagname => :method, :name => "foo", ... } # def detect(ast) ast = ast || {} Loading Loading @@ -208,12 +236,30 @@ module JsDuck return nil unless ast && ast["type"] == "ObjectExpression" configs = [] object_expression_to_hash(ast).each_pair do |key, value| configs << make_property(key, value, :cfg) ast["properties"].each do |p| cfg = make_property(key_value(p["key"]), p["value"], :cfg) # When config has a comment, update the related docset, # otherwise add it as new config to current class. docset = find_docset(p) if docset docset[:code] = cfg else configs << cfg end end configs end # Looks up docset associated with given AST node. # A dead-stupid and -slow implementation, but works. def find_docset(ast) @docs.find do |docset| docset[:code] == ast end end def make_method(name, ast=nil) return { :tagname => :method, Loading
lib/jsduck/doc_type.rb +1 −3 Original line number Diff line number Diff line Loading @@ -31,10 +31,8 @@ module JsDuck :css_mixin elsif doc_map[:cfg] :cfg elsif code[:tagname] == :method :method else :property code[:tagname] end end Loading
lib/jsduck/merger.rb +5 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,11 @@ module JsDuck result = create_bare_class(groups[:class], code) result[:members] = create_class_members(groups, result[:name]) result[:statics] = Class.default_members_hash if code[:members] && code[:members][:cfg] code[:members][:cfg].each do |cfg| result[:members][:cfg] << create_cfg({}, cfg, result[:name]) end end result end Loading
lib/jsduck/source_file.rb +1 −6 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ module JsDuck @options = options @html_filename = "" @links = {} @ast = Ast.new doc_parser = DocParser.new Loading Loading @@ -92,11 +91,7 @@ module JsDuck CssParser.new(@contents, @options).parse else docs = EsprimaParser.new(@contents, @options).parse docs = docs.find_all {|d| d[:type] == :doc_comment } docs.each do |docset| docset[:code] = @ast.detect(docset[:code]) end docs Ast.new(docs).detect_all! end rescue puts "Error while parsing #{@filename}: #{$!}" Loading
spec/aggregator_cfg_spec.rb 0 → 100644 +68 −0 Original line number Diff line number Diff line require "jsduck/aggregator" require "jsduck/source_file" describe JsDuck::Aggregator do def parse(string) agr = JsDuck::Aggregator.new agr.aggregate(JsDuck::SourceFile.new(string)) agr.result end describe "detecting Ext.define() with configs in code" do let(:cfg) do parse(<<-EOS)[0][:members][:cfg] /** * Some documentation. */ Ext.define("MyClass", { config: { foo: 42, bar: "hello" } }); EOS end it "finds configs" do cfg.should be_kind_of(Array) end it "finds two configs" do cfg.length.should == 2 end end describe "detecting Ext.define() with commented config" do let(:docs) do parse(<<-EOS) /** * Some documentation. */ Ext.define("MyClass", { config: { /** Docs for bar */ bar: "hello" } }); EOS end it "finds one docset" do docs.length.should == 1 end it "detects it as class" do docs[0][:tagname] == :class end it "detects one config within class" do docs[0][:members][:cfg].length.should == 1 end it "detects the config with docs" do docs[0][:members][:cfg][0][:doc].should == "Docs for bar" end end end