@@ -19,14 +19,18 @@ function s:parse_describe(tokens, lnum, context_stack, scope_id) abort
1919
2020 let funcname = printf (' s:themis_vimspec_scope_%d' , a: scope_id )
2121 call add (a: context_stack , [' describe' , a: lnum , funcname, a: scope_id ])
22- return [
22+ let result = [
2323 \ printf (' function %s() abort' , funcname),
2424 \ printf (' let s:themis_vimspec_bundles += [%s]' , bundle_new),
2525 \ ' let s:themis_vimspec_bundles[-1]._vimspec_hooks = {}' ,
2626 \ ' function s:themis_vimspec_bundles[-1]._vimspec_hooks.start_test()' ,
2727 \ printf (' call s:themis_vimspec_scopes.tmp_scope(%d)' , a: scope_id ),
2828 \ ' endfunction' ,
2929 \ ]
30+ return {
31+ \ ' result' : result,
32+ \ ' map_pos' : 1 ,
33+ \ }
3034endfunction
3135
3236function s: parse_example (tokens, lnum, context_stack, func_id) abort
@@ -42,14 +46,18 @@ function s:parse_example(tokens, lnum, context_stack, func_id) abort
4246 call add (a: context_stack , [' example' , a: lnum ])
4347 let bundle_var = ' s:themis_vimspec_bundles'
4448 let scope_var = ' s:themis_vimspec_scopes'
45- return [
49+ let result = [
4650 \ printf (' let %s[-1].suite_descriptions["T_%05d"] = %s' ,
4751 \ bundle_var, a: func_id , string (example)),
4852 \ printf (' function %s[-1].suite.T_%05d() abort' ,
4953 \ bundle_var, a: func_id ),
5054 \ printf (' execute %s.extend("%s.scope(%d)", 0)' ,
5155 \ scope_var, scope_var, scope_id),
5256 \ ]
57+ return {
58+ \ ' result' : result,
59+ \ ' map_pos' : 2 ,
60+ \ }
5361endfunction
5462
5563function s: parse_hook (tokens, lnum, context_stack) abort
@@ -72,12 +80,16 @@ function s:parse_hook(tokens, lnum, context_stack) abort
7280 call add (a: context_stack , [' hook' , a: lnum , timing])
7381 let bundle_var = ' s:themis_vimspec_bundles'
7482 let scope_var = ' s:themis_vimspec_scopes'
75- return [
83+ let result = [
7684 \ printf (' function %s[-1]._vimspec_hooks.%s() abort' ,
7785 \ bundle_var, hook_point),
7886 \ printf (' execute %s.extend("%s.scope(%d)", %d)' ,
7987 \ scope_var, scope_var, scope_id, copy ),
8088 \ ]
89+ return {
90+ \ ' result' : result,
91+ \ ' map_pos' : 1 ,
92+ \ }
8193endfunction
8294
8395function s: parse_end (tokens, lnum, context_stack) abort
@@ -125,6 +137,8 @@ function s:translate_script(lines) abort
125137 let lnum = 0
126138 let heredoc_endmarker = ' '
127139
140+ let map_lines = []
141+
128142 for line in a: lines
129143 let lnum += 1
130144
@@ -145,24 +159,30 @@ function s:translate_script(lines) abort
145159
146160 let tokens = matchlist (line , ' ^\s*\([Dd]escribe\|[Cc]ontext\)\s*\(.*\)$' )
147161 if ! empty (tokens)
148- let result + =
162+ let parsed =
149163 \ s: parse_describe (tokens, lnum, context_stack, current_scope_id)
150164 let current_scope_id += 1
165+ let map_lines += [[len (result) + parsed.map_pos, lnum, ' desc' ]]
166+ let result += parsed.result
151167 continue
152168 endif
153169
154170 let tokens = matchlist (line , ' ^\s*\([Ii]t\)\s*\(.*\)$' )
155171 if ! empty (tokens)
156- let result + =
172+ let parsed =
157173 \ s: parse_example (tokens, lnum, context_stack, current_func_id)
158174 let current_func_id += 1
175+ let map_lines += [[len (result) + parsed.map_pos, lnum, ' it' ]]
176+ let result += parsed.result
159177 continue
160178 endif
161179
162180 let tokens = matchlist (line ,
163181 \ ' ^\s*\([Bb]efore\|[Aa]fter\)\%(\s\+\(.*\)\)\?$' )
164182 if ! empty (tokens)
165- let result += s: parse_hook (tokens, lnum, context_stack)
183+ let parsed = s: parse_hook (tokens, lnum, context_stack)
184+ let map_lines += [[len (result) + parsed.map_pos, lnum, ' hook' ]]
185+ let result += parsed.result
166186 continue
167187 endif
168188
@@ -180,13 +200,14 @@ function s:translate_script(lines) abort
180200 throw printf (' vimspec:%d:This declaration is not closed.' , opened_lnum)
181201 endif
182202
183- return result
203+ return [ result, map_lines]
184204endfunction
185205
186206function s: compile_specfile (specfile_path, result_path) abort
187207 let slines = readfile (a: specfile_path )
188- let rlines = s: translate_script (slines)
208+ let [ rlines, map_lines] = s: translate_script (slines)
189209 call writefile (rlines, a: result_path )
210+ return map_lines
190211endfunction
191212
192213
@@ -294,8 +315,12 @@ function s:style.load_script(filename, runner) abort
294315 let compiled_specfile_path = tempname ()
295316 call add (self .event ._converted_files, compiled_specfile_path)
296317 try
297- call s: compile_specfile (a: filename , compiled_specfile_path)
318+ let map_lines = s: compile_specfile (a: filename , compiled_specfile_path)
298319 execute ' source' fnameescape (compiled_specfile_path)
320+ call themis#util#add_source_map (compiled_specfile_path, {
321+ \ ' original_filename' : a: filename ,
322+ \ ' map_lines' : reverse (map_lines),
323+ \ })
299324 catch /^vimspec:/
300325 let pat = ' \v^vimspec:(\d+):(.*)'
301326 let [lnum, message] = matchlist (v: exception , pat)[1 : 2 ]
0 commit comments