Commit 2ef1f7d3 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Replace default value parsing with simpler implementation.

Instead of using JsLiteralParser, we just scan the string and attempt to
balance braces.  It's not really fool-proof, but should easily cover
more than 99% of use cases.  The only problem is when a default value
contains a string with "[" or "]" in it - but then it can be just
documented manually.

Getting rid of this use of JsLiteralParser and JsLiteralBuilder will
allow us to get rid of those classes together with JsParser completely -
replacing them with EsprimaJS.
parent 71a42c10
Loading
Loading
Loading
Loading
+18 −10
Original line number Diff line number Diff line
require 'strscan'
require 'jsduck/js_literal_parser'
require 'jsduck/js_literal_builder'
require 'jsduck/meta_tag_registry'

module JsDuck
@@ -418,22 +416,32 @@ module JsDuck
      end
    end

    # attempts to match javascript literal,
    # when it fails grabs anything up to closing "]"
    # Attempts to allow balanced braces in default value.
    # When the nested parsing doesn't finish at closing "]",
    # roll back to beginning and simply grab anything up to closing "]".
    def default_value
      start_pos = @input.pos
      lit = JsLiteralParser.new(@input).literal
      if lit && look(/ *\]/)
        # When lital matched and there's nothing after it up to the closing "]"
        JsLiteralBuilder.new.to_s(lit)
      value = nested_default_value
      if look(/\]/)
        value
      else
        # Otherwise reset parsing position to where we started
        # and rescan up to "]" using simple regex.
        @input.pos = start_pos
        match(/[^\]]*/)
      end
    end

    # Parses default value, attempting to balance "[]" braces
    def nested_default_value
      value = match(/[^\[\]]*/)
      while look(/\[/)
        value += match(/\[/)
        value += nested_default_value
        value += match(/\]/)
        value += match(/[^\[\]]*/)
      end
      value
    end

    # matches {...=} and returns text inside brackets
    def typedef
      match(/\{/)
+16 −3
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ describe JsDuck::Aggregator do
    end
  end

  describe "cfg with bogus array literal as default value" do
  describe "cfg with array literal of idents as default value" do
    before do
      @doc = parse(<<-EOS)[0]
        /**
@@ -260,8 +260,21 @@ describe JsDuck::Aggregator do
         */
      EOS
    end
    it "has everything up to ] as default value" do
      @doc[:default].should == '[ho, ho'
    it "has the full literal as default value" do
      @doc[:default].should == '[ho, ho]'
    end
  end

  describe "cfg with unfinished array literal as default value" do
    before do
      @doc = parse(<<-EOS)[0]
        /**
         * @cfg {Number} [foo=[...] Something
         */
      EOS
    end
    it "has default value up to first ]" do
      @doc[:default].should == '[...'
    end
  end