44
55let s: func_aliases = {}
66let s: line_adjuster = {}
7+ let s: source_maps = {}
78
89let s: StackInfo = {
910\ ' stack' : ' ' ,
1011\ ' type' : ' ' ,
11- \ ' line ' : 0 ,
12+ \ ' lnum ' : 0 ,
1213\ ' filled' : 0 ,
1314\ }
1415
@@ -20,13 +21,16 @@ function s:StackInfo.fill_info() abort
2021 if themis#util#is_funcname (self .stack)
2122 call extend (self , themis#util#funcdata (self .stack), ' keep' )
2223 let self .type = ' function'
24+ call self .apply_source_map ()
2325 return
2426 endif
2527 if filereadable (self .stack)
2628 let self .exists = 1
2729 let self .filename = self .stack
2830 let self .funcname = ' '
2931 let self .type = ' file'
32+
33+ call self .apply_source_map ()
3034 return
3135 endif
3236 let matched = matchlist (self .stack, ' ^\(\w\+\) Autocommands for \(.*\)' )
@@ -43,6 +47,25 @@ function s:StackInfo.fill_info() abort
4347 let self .type = ' unknown'
4448endfunction
4549
50+ function s: StackInfo .apply_source_map () abort
51+ let source_map = get (s: source_maps , self .filename, 0 )
52+ if source_map is 0
53+ return
54+ endif
55+ let self .filename = get (source_map, ' original_filename' , self .filename)
56+
57+ let deflnum = self .deflnum
58+ let map_lines = get (source_map, ' map_lines' , [])
59+ if deflnum && len (map_lines) != 0
60+ for [slnum, alnum; _] in map_lines
61+ if slnum <= deflnum
62+ let self .deflnum = alnum + (deflnum - slnum)
63+ break
64+ endif
65+ endfor
66+ endif
67+ endfunction
68+
4669function s: StackInfo .make_signature () abort
4770 let funcname = get (s: func_aliases , self .funcname, self .funcname)
4871 let args = join (self .arguments, ' , ' )
@@ -70,14 +93,14 @@ function s:StackInfo.format() abort
7093 endif
7194
7295 if self .type == # ' file'
73- return printf (' %s Line:%d' , self .filename, self .line )
96+ return printf (' %s Line:%d' , self .filename, self .lnum )
7497 endif
7598 if self .type == # ' function'
7699 let result = self .make_signature ()
77- if self .line
100+ if self .lnum
78101 let result .= ' Line:' . self .adjusted_lnum ()
79102 endif
80- if self .defline
103+ if self .deflnum
81104 let result .= ' [ Absolute Line: ' . self .adjusted_abs_lnum () . ' ]'
82105 endif
83106 return result . ' (' . self .filename . ' )'
@@ -89,7 +112,7 @@ function s:StackInfo.format() abort
89112endfunction
90113
91114function s: StackInfo .get_line (... ) abort
92- let lnum = a: 0 ? a: 1 : self .line
115+ let lnum = a: 0 ? a: 1 : self .lnum
93116 call self .fill_info ()
94117 if self .type == # ' file'
95118 if ! has_key (self , ' body' )
@@ -110,20 +133,17 @@ function s:StackInfo.get_line(...) abort
110133endfunction
111134
112135function s: StackInfo .adjusted_lnum (... ) abort
113- let lnum = a: 0 ? a: 1 : self .line
136+ let lnum = a: 0 ? a: 1 : self .lnum
114137 let adjuster = get (s: line_adjuster , self .funcname, 0 )
115138 return lnum + adjuster
116139endfunction
117140
118- function s: StackInfo .adjusted_abs_lnum (... ) abort
119- let lnum = a: 0 ? a: 1 : self .line
120- let deflnum = self .defline
121- let adjuster = get (s: line_adjuster , self .funcname, 0 )
122- return lnum + deflnum + adjuster
141+ function s: StackInfo .adjusted_abs_lnum () abort
142+ return self .adjusted_lnum () + self .deflnum
123143endfunction
124144
125145function s: StackInfo .get_line_with_lnum (... ) abort
126- let lnum = a: 0 ? a: 1 : self .line
146+ let lnum = a: 0 ? a: 1 : self .lnum
127147 let line = self .get_line (lnum)
128148 return printf (' %3d: %s' , self .adjusted_lnum (lnum), line )
129149endfunction
@@ -141,7 +161,7 @@ function themis#util#stack_info(stack) abort
141161 let matched = matchlist (a: stack , pat)
142162 if ! empty (matched)
143163 let info.stack = matched[1 ]
144- let info.line = matched[2 ] - 0
164+ let info.lnum = matched[2 ] - 0
145165 endif
146166 endfor
147167 endif
@@ -179,6 +199,11 @@ function themis#util#adjust_func_line(target, line) abort
179199 endif
180200endfunction
181201
202+ function themis#util#add_source_map (filename, source_map) abort
203+ let filename = substitute (a: filename , ' [/\\]\+' , ' /' , ' g' )
204+ let s: source_maps [filename] = a: source_map
205+ endfunction
206+
182207function themis#util#callstacklines (throwpoint, ... ) abort
183208 let infos = call (' themis#util#callstack' , [a: throwpoint ] + a: 000 )
184209 return map (infos, ' v:val.format()' )
@@ -228,7 +253,7 @@ function themis#util#funcdata(func) abort
228253 let signature = matchstr (lines [0 ], ' ^\s*\zs.*' )
229254 let file = matchstr (lines [1 ], ' ^\t\%(Last set from\|.\{-}:\)\s*\zs.*$' )
230255 let file = substitute (file , ' [/\\]\+' , ' /' , ' g' )
231- let defline = str2nr (matchstr (file , ' \d\+$' ))
256+ let deflnum = str2nr (matchstr (file , ' \d\+$' ))
232257 " XXX: Remove ' line 10' at tail. But the message may be translated.
233258 " This can fail in some languages.
234259 let file = substitute (file , ' \S\+ \d\+$' , ' ' , ' ' )
@@ -239,7 +264,7 @@ function themis#util#funcdata(func) abort
239264 \ ' exists' : 1 ,
240265 \ ' filename' : file ,
241266 \ ' funcname' : func ,
242- \ ' defline ' : defline ,
267+ \ ' deflnum ' : deflnum ,
243268 \ ' signature' : signature,
244269 \ ' arguments' : arguments,
245270 \ ' arity' : arity,
@@ -255,7 +280,7 @@ endfunction
255280function themis#util#error_info (stacktrace) abort
256281 let tracelines = map (copy (a: stacktrace ), ' v:val.format()' )
257282 let tail = a: stacktrace [-1 ]
258- if tail.line
283+ if tail.lnum
259284 let tracelines += [tail.get_line_with_lnum ()]
260285 endif
261286 return join (tracelines, " \n " )
0 commit comments