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

Proper RegExp parsing support.

Previously regexer got just lost, now they are transformed into:

    {regex: "/regex string/g"}

Unfortunately adding the callback parameter to JSON.stringify has
quite a performance penalty.

Again, parsing of Sencha Touch source:

    before: 4.5s
    after:  5.4s
parent 89f7791e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -156,7 +156,7 @@ module JsDuck
      when "Identifier"
        ast["name"]
      when "Literal"
        ast["value"].to_s
        ast["value"].is_a?(Hash) ? ast["value"]["regex"].to_s : ast["value"].to_s
      else
        @serializer.to_s(ast)
      end
+9 −1
Original line number Diff line number Diff line
@@ -15,6 +15,14 @@ module JsDuck
      @v8 = V8::Context.new
      esprima = File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))+"/esprima/esprima.js";
      @v8.load(esprima)
      @v8.eval(<<-EOS)
        function adjustRegexLiteral(key, value) {
            if (key === 'value' && value instanceof RegExp) {
                value = {regex: value.toString()};
            }
            return value;
        }
      EOS
    end

    # Parses JavaScript source code using Esprima.js
@@ -22,7 +30,7 @@ module JsDuck
    # Returns the resulting AST
    def parse(input)
      @v8['js'] = input
      json = @v8.eval("JSON.stringify(esprima.parse(js, {comment: true, range: true}))")
      json = @v8.eval("JSON.stringify(esprima.parse(js, {comment: true, range: true}), adjustRegexLiteral)")
      return JSON.parse(json, :max_nesting => false)
    end

+2 −0
Original line number Diff line number Diff line
@@ -159,6 +159,8 @@ module JsDuck
          "null"
        elsif ast["value"].is_a? String
          '"' + ast["value"] + '"'
        elsif ast["value"].is_a? Hash
          ast["value"]["regex"]
        else
          ast["value"].to_s
        end
+4 −0
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@ describe JsDuck::Serializer do
      test('null;')
    end

    it "regex" do
      test('/abc/g;')
    end

    it "function declaration" do
      test("function foo(a, b, c) {return 0;}")
    end