Skip to content

Commit

Permalink
Generate source maps from fragments
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Aug 2, 2013
1 parent b276a9d commit ec91c4c
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 39 deletions.
4 changes: 4 additions & 0 deletions bin/opal
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ parser = OptionParser.new do |opts|
options[:sexp] = true
end

opts.on('-m', '--map', 'Show sourcemap') do
options[:map] = true
end

opts.on('-c', '--compile', 'Compile to JavaScript') do
options[:compile] = true
end
Expand Down
8 changes: 8 additions & 0 deletions lib/opal/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ def initialize _filename, options
case
when options[:sexp]
puts sexp.inspect
when options[:map]
puts map.inspect
when options[:compile]
if File.exist?(filename)
puts sprockets[filename].to_a.last
Expand Down Expand Up @@ -73,6 +75,12 @@ def sexp
Opal::Grammar.new.parse(source)
end

def map
parser = Opal::Parser.new
parser.parse(filename, options)
parser.source_map
end

def source
File.exist?(filename) ? File.read(filename) : filename
end
Expand Down
7 changes: 5 additions & 2 deletions lib/opal/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def to_code
def inspect
"f(#{@code.inspect})"
end

def line
@sexp.line if @sexp
end
end

# Generated code gets indented with two spaces on each scope
Expand Down Expand Up @@ -103,8 +107,7 @@ def version_comment
end

def source_map
# TODO: lazily generate sourcemap
raise "Parser#source_map not yet implemented"
Opal::SourceMap.new(@fragments, '(file)')
end

# This is called when a parsing/processing error occurs. This
Expand Down
44 changes: 15 additions & 29 deletions lib/opal/source_map.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,31 @@

module Opal
class SourceMap
LINE_REGEXP = %r{/\*:(\d+)\*/}.freeze
FILE_REGEXP = %r{/\*-file:(.+?)-\*/}.freeze
attr_reader :fragments
attr_reader :file

attr_reader :generated, :file

def initialize generated, file
@generated = generated
def initialize(fragments, file)
@fragments = fragments
@file = file
end

def map
@map ||= ::SourceMap.new.tap do |map|
source_file = file
generated.lines.each_with_index do |line, index|
generated_line = index+1
if line =~ FILE_REGEXP
source_file = "file://#{$1}"
map.add_mapping(
:generated_line => generated_line,
:generated_col => 0,
:source_line => 1,
:source_col => 0,
:source => source_file
)
end
line, column = 1, 0

pos = 0
while (pos = line.index(LINE_REGEXP, pos))
pos += $~.size
source_line = $1.to_i + 1
source_col = 0 # until column info will be available
generated_col = pos
@fragments.each do |fragment|
if source_line = fragment.line
map.add_mapping(
:generated_line => generated_line,
:generated_col => generated_col,
:generated_line => line,
:generated_col => column,
:source_line => source_line,
:source_col => source_col,
:source => source_file
:source_col => 0,
:source => file
)

new_lines = fragment.code.count "\n"
line += new_lines
column = 0
end
end
end
Expand Down
12 changes: 4 additions & 8 deletions spec/opal/source_map_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@
describe Opal::SourceMap do
before do
pathname = 'foo.rb'
@source = Opal.parse('1 + 1', pathname)
@map = Opal::SourceMap.new(@source, pathname)
parser = Opal::Parser.new
@source = parser.parse("1 + 1", pathname)
@map = Opal::SourceMap.new(parser.fragments, pathname)
end

pending 'source has the magic comments' do
Opal::SourceMap::FILE_REGEXP.should =~ @source
Opal::SourceMap::LINE_REGEXP.should =~ @source
end

it 'does not blow while generating the map' do
pending 'does not blow while generating the map' do
lambda { @map.as_json }.should_not raise_error
end
end

0 comments on commit ec91c4c

Please sign in to comment.