lib/uglifier.rb in uglifier-4.1.20 vs lib/uglifier.rb in uglifier-4.2.0
- old
+ new
@@ -96,10 +96,11 @@
:define => {}, # Define values for symbol replacement
:keep_fnames => false, # Generate code safe for the poor souls relying on Function.prototype.name at run-time. Sets both compress and mangle keep_fanems to true.
:toplevel => false,
:ie8 => true, # Generate safe code for IE8
:source_map => false, # Generate source map
+ :error_context_lines => 8, # How many lines surrounding the error line
:harmony => false # Enable ES6/Harmony mode (experimental). Disabling mangling and compressing is recommended with Harmony mode.
}
EXTRA_OPTIONS = [:comments, :mangle_properties]
@@ -147,13 +148,10 @@
def initialize(options = {})
(options.keys - DEFAULTS.keys - EXTRA_OPTIONS)[0..1].each do |missing|
raise ArgumentError, "Invalid option: #{missing}"
end
@options = options
-
- source = harmony? ? source_with(HarmonySourcePath) : source_with(SourcePath)
- @context = ExecJS.compile(source)
end
# Minifies JavaScript code
#
# @param source [IO, String] valid JS source code.
@@ -178,10 +176,17 @@
run_uglifyjs(source, true)
end
private
+ def context
+ @context ||= begin
+ source = harmony? ? source_with(HarmonySourcePath) : source_with(SourcePath)
+ ExecJS.compile(source)
+ end
+ end
+
def source_map_comments
return '' unless @options[:source_map].respond_to?(:[])
suffix = ''
if @options[:source_map][:map_url]
@@ -211,28 +216,80 @@
:parse => parse_options,
:sourceMap => source_map_options(input_map),
:ie8 => ie8?
}
- parse_result(@context.call("uglifier", options), generate_map)
+ parse_result(context.call("uglifier", options), generate_map, options)
end
def harmony?
@options[:harmony]
end
- def error_message(result)
- result['error']['message'] +
- if result['error']['message'].start_with?("Unexpected token") && !harmony?
- ". To use ES6 syntax, harmony mode must be enabled with " \
- "Uglifier.new(:harmony => true)."
+ def harmony_error_message(message)
+ if message.start_with?("Unexpected token")
+ ". To use ES6 syntax, harmony mode must be enabled with " \
+ "Uglifier.new(:harmony => true)."
+ else
+ ""
+ end
+ end
+
+ def error_context_lines
+ @options.fetch(:error_context_lines, DEFAULTS[:error_context_lines]).to_i
+ end
+
+ def error_context_format_options(low, high, line_index, column)
+ line_width = high.to_s.size
+ {
+ :line_index => line_index,
+ :base_index => low,
+ :line_width => line_width,
+ :line_format => "\e[36m%#{line_width + 1}d\e[0m ", # cyan
+ :col => column
+ }
+ end
+
+ def format_error_line(line, options)
+ # light red
+ indicator = ' => '.rjust(options[:line_width] + 2)
+ colored_line = "#{line[0...options[:col]]}\e[91m#{line[options[:col]..-1]}"
+ "\e[91m#{indicator}\e[0m#{colored_line}\e[0m"
+ end
+
+ def format_lines(lines, options)
+ lines.map.with_index do |line, index|
+ if options[:base_index] + index == options[:line_index]
+ format_error_line(line, options)
else
- ""
+ "#{options[:line_format] % (options[:base_index] + index + 1)}#{line}"
end
+ end
end
- def parse_result(result, generate_map)
- raise Error, error_message(result) if result.has_key?('error')
+ def context_lines_message(source, line_number, column)
+ return if line_number.nil?
+
+ line_index = line_number - 1
+ lines = source.split("\n")
+
+ first_line = [line_index - error_context_lines, 0].max
+ last_line = [line_number + error_context_lines, lines.size].min
+ options = error_context_format_options(first_line, last_line, line_index, column)
+ context_lines = lines[first_line...last_line]
+
+ "--\n#{format_lines(context_lines, options).join("\n")}\n=="
+ end
+
+ def error_message(result, options)
+ err = result['error']
+ harmony_msg = harmony? ? '' : harmony_error_message(err['message'].to_s)
+ src_ctx = context_lines_message(options[:source], err['line'], err['col'])
+ "#{err['message']}#{harmony_msg}\n#{src_ctx}"
+ end
+
+ def parse_result(result, generate_map, options)
+ raise Error, error_message(result, options) if result.has_key?('error')
if generate_map
[result['code'] + source_map_comments, result['map']]
else
result['code'] + source_map_comments