module PluginTool @@syntax_check_queue = [] @@syntax_check_queue_lock = Mutex.new @@syntax_check_queue_semaphore = Mutex.new @@syntax_check_queue_semaphore_var = ConditionVariable.new Context = Java::OrgMozillaJavascript::Context def self.start_syntax_check Thread.new do begin do_syntax_checking rescue => e puts "EXCEPTION IN SYNTAX CHECKER\n#{e.inspect}" exit 1 end end end def self.init_syntax_checking # Set up interpreter and get a syntax checker function raise "Another JS Context is active" unless nil == Context.getCurrentContext() @@cx = Context.enter(); @@javascript_scope = @@cx.initStandardObjects(); jshint = File.open("#{File.dirname(__FILE__)}/jshint.js") { |f| f.read } @@cx.evaluateString(@@javascript_scope, jshint, "", 1, nil); testerfn = File.open("#{File.dirname(__FILE__)}/js_syntax_test.js") { |f| f.read } @@cx.evaluateString(@@javascript_scope, testerfn, "", 1, nil); @@syntax_tester = @@javascript_scope.get("syntax_tester", @@javascript_scope); end def self.syntax_check_one_file(plugin, file) # Load the plugin.json file plugin_dir = plugin.plugin_dir plugin_json = File.open("#{plugin_dir}/plugin.json") { |f| JSON.parse(f.read) } # Determine kind of file file =~ /\A(\w+)\// kind = $1 # Is this file referenced? report = nil unless kind != 'js' || plugin_json['load'].include?(file) puts "\nWARNING: #{plugin_dir}/plugin.json doesn't mention #{file} in the load directive.\n" report = "Couldn't check file - not mentioned in plugin.json" else # Load the file js = File.open("#{plugin_dir}/#{file}") { |f| f.read } # If it's not the first the file, need to tell JSHint about the extra var unless plugin_json['load'].first == file js = "/*global #{plugin_json["pluginName"]}: false */#{js}" end # Do syntax checking report = @@syntax_tester.call(@@cx, @@javascript_scope, @@javascript_scope, [js, kind]) end report end def self.do_syntax_checking init_syntax_checking while(true) plugin, file = @@syntax_check_queue_lock.synchronize do @@syntax_check_queue.shift end if file == nil # Wait for another file @@syntax_check_queue_semaphore.synchronize { @@syntax_check_queue_semaphore_var.wait(@@syntax_check_queue_semaphore) } else report = syntax_check_one_file(plugin, file) if report != nil puts "\nJavaScript file #{plugin.plugin_dir}/#{file} has syntax errors:\n#{report}\n\n" beep end end end end def self.syntax_check(plugin, filename) @@syntax_check_queue_lock.synchronize do @@syntax_check_queue << [plugin, filename] @@syntax_check_queue.uniq! end @@syntax_check_queue_semaphore.synchronize { @@syntax_check_queue_semaphore_var.signal } end end