Commit dc6089e1 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Parsing of some basic code with EsprimaParser.

parent bb1440dc
Loading
Loading
Loading
Loading
+45 −1
Original line number Diff line number Diff line
@@ -21,7 +21,51 @@ module JsDuck
      @v8['js'] = input

      json = @v8.eval("JSON.stringify(esprima.parse(js, {comment: true, range: true}))")
      JSON.parse(json, :max_nesting => false)
      @ast = JSON.parse(json, :max_nesting => false)

      locate_comments
    end

    def locate_comments
      @ast["comments"].map do |comment|
        {
          :comment => comment["value"],
          :code => stuff_after(comment["range"])
        }
      end
    end

    # Sees if there is some code following the comment at specified
    # range.  Returns the code found.  But if the comment is instead
    # followed by another comment, returns nil.
    def stuff_after(range)
      code = code_after(range)
      comment = comment_after(range)
      if code && comment
        return code["range"][0] < comment["range"][0] ? code : nil
      else
        code
      end
    end

    # Looks for code following the given range
    def code_after(range)
      @ast["body"].each do |item|
        if range[1] < item["range"][0]
          return item
        end
      end
      return nil
    end

    # Looks for comment following the given range
    def comment_after(range)
      @ast["comments"].each do |item|
        if range[1] < item["range"][0]
          return item
        end
      end
      return nil
    end

  end
+77 −0
Original line number Diff line number Diff line
require "jsduck/esprima_parser"

describe JsDuck::EsprimaParser do

  def parse(input)
    JsDuck::EsprimaParser.instance.parse(input)
  end

  describe "parsing comment after function" do
    before do
      @docs = parse(<<-EOS)
        function a() {
        }
        // Function A
      EOS
    end

    it "detects no code associated with comment" do
      @docs[0][:code].should == nil
    end
  end

  describe "parsing two comments each before function" do
    before do
      @docs = parse(<<-EOS)
        // Function A
        function a() {
        }
        // Function B
        function b() {
        }
      EOS
    end

    it "finds two comments" do
      @docs.length.should == 2
    end

    it "detects first comment as belonging to first function" do
      @docs[0][:comment].should == " Function A"
      @docs[0][:code]["type"].should == "FunctionDeclaration"
      @docs[0][:code]["id"]["name"].should == "a"
    end

    it "detects second comment as belonging to second function" do
      @docs[1][:comment].should == " Function B"
      @docs[1][:code]["type"].should == "FunctionDeclaration"
      @docs[1][:code]["id"]["name"].should == "b"
    end
  end

  describe "parsing two comments before one function" do
    before do
      @docs = parse(<<-EOS)
        /* Function A */
        /* Function B */
        function b() {
        }
      EOS
    end

    it "finds two comments" do
      @docs.length.should == 2
    end

    it "detects no code associated with first comment" do
      @docs[0][:code].should == nil
    end

    it "detects second comment as belonging to the function" do
      @docs[1][:code]["type"].should == "FunctionDeclaration"
    end
  end


end