Commit 1307ebbb authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Split EsprimaParser into Parser and Core parts.

Only the EsprimaCore is now singleton which runs esprima.js, the
EsprimaParser just uses the core and then does additional processing,
but most importantly EsprimaParser now uses the same interface as
JsParser - both of which are instanciated with source and then have
parse method invoked.  This allows for better handling of instance
variables and avoids possible conflicts when we do parallel processing.
parent d43b707e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -6,6 +6,6 @@ $:.unshift File.dirname(File.dirname(__FILE__)) + "/lib"
require 'jsduck/esprima_parser'

ARGV.each do |fname|
  JsDuck::EsprimaParser.instance.parse(IO.read(fname))
  JsDuck::EsprimaParser.new(IO.read(fname)).parse
end
+30 −0
Original line number Diff line number Diff line
require 'v8'
require 'json'
require 'singleton'

module JsDuck

  # Generates AST from JavaScript code by running Esprima.js through V8.
  #
  # Initialized as singleton to avoid loading the esprima.js more
  # than once - otherwise performace will severely suffer.
  class EsprimaCore
    include Singleton

    def initialize
      @v8 = V8::Context.new
      esprima = File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))+"/esprima/esprima.js";
      @v8.load(esprima)
    end

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

  end
end
+12 −21
Original line number Diff line number Diff line
require 'v8'
require 'json'
require 'singleton'
require 'jsduck/esprima_core'

module JsDuck

  # New parser prototype that uses Esprima.js through V8.
  # JavaScript parser that internally uses Esprima.js
  class EsprimaParser
    # Initialize as singleton to avoid loading the esprima.js more
    # than once - otherwise performace will severely suffer.
    include Singleton

    def initialize
      @v8 = V8::Context.new
      esprima = File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))+"/esprima/esprima.js";
      @v8.load(esprima)
    # Initializes the parser with JavaScript source code to be parsed.
    def initialize(input)
      @input = input

      # Initialize line number counting
      @start_index = 0
      @start_linenr = 1
    end

    # Parses JavaScript source code and returns array of hashes like this:
@@ -25,11 +23,8 @@ module JsDuck
    #         :type => :doc_comment, // or :plain_comment
    #     }
    #
    def parse(input)
      @v8['js'] = @input = input

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

      @ast["comments"] = merge_comments(@ast["comments"])
      locate_comments
@@ -76,10 +71,6 @@ module JsDuck
    end

    def locate_comments
      # Initialize line number counting
      @start_index = 0
      @start_linenr = 1

      @ast["comments"].map do |comment|
        # Detect comment type and strip * at the beginning of doc-comment
        value = comment["value"]
+1 −1
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@ require "jsduck/esprima_parser"
describe JsDuck::EsprimaParser do

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

  describe "parsing two comments" do