@@ -44,24 +44,78 @@ enum LogLevel {
4444 Error
4545}
4646
47+ function getCallerLocation ( stack ?: string ) {
48+ if ( ! stack ) {
49+ return
50+ }
51+
52+ if ( stack . startsWith ( 'Error' ) ) {
53+ // Assume it's Chromium V8
54+ //
55+ // Error
56+ // at baz (filename.js:10:15)
57+ // at bar (filename.js:6:3)
58+ // at foo (filename.js:2:3)
59+ // at filename.js:13:1
60+
61+ const lines = stack . split ( '\n' )
62+ // Find the third line (caller's caller of the current location)
63+ const callerLine = lines [ 3 ] . trim ( )
64+
65+ const regex =
66+ / a t \s + (?< functionName > .* ?) \s + \( (?< fileName > .* ?) : (?< lineNumber > \d + ) : (?< columnNumber > \d + ) \) /
67+ const match = callerLine . match ( regex )
68+
69+ if ( match ) {
70+ const { functionName, fileName, lineNumber, columnNumber } =
71+ match . groups as {
72+ functionName : string
73+ fileName : string
74+ lineNumber : string
75+ columnNumber : string
76+ }
77+ return `${ functionName } @${ fileName } :${ lineNumber } :${ columnNumber } `
78+ } else {
79+ // Handle cases where the regex does not match (e.g., last line without function name)
80+ const regexNoFunction =
81+ / a t \s + (?< fileName > .* ?) : (?< lineNumber > \d + ) : (?< columnNumber > \d + ) /
82+ const matchNoFunction = callerLine . match ( regexNoFunction )
83+ if ( matchNoFunction ) {
84+ const { fileName, lineNumber, columnNumber } =
85+ matchNoFunction . groups as {
86+ fileName : string
87+ lineNumber : string
88+ columnNumber : string
89+ }
90+ return `<anonymous>@${ fileName } :${ lineNumber } :${ columnNumber } `
91+ }
92+ }
93+ } else {
94+ // Assume it's Webkit JavaScriptCore, example:
95+ //
96+ // baz@filename .js:10:24
97+ // bar@filename .js:6:6
98+ // foo@filename .js:2:6
99+ // global code@filename .js:13:4
100+
101+ const traces = stack . split ( '\n' ) . map ( ( line ) => line . split ( '@' ) )
102+ const filtered = traces . filter ( ( [ name , location ] ) => {
103+ return name . length > 0 && location !== '[native code]'
104+ } )
105+ // Find the third line (caller's caller of the current location)
106+ return filtered [ 2 ] . filter ( ( v ) => v . length > 0 ) . join ( '@' )
107+ }
108+ }
109+
47110async function log (
48111 level : LogLevel ,
49112 message : string ,
50113 options ?: LogOptions
51114) : Promise < void > {
52- const traces = new Error ( ) . stack ?. split ( '\n' ) . map ( ( line ) => line . split ( '@' ) )
53-
54- const filtered = traces ?. filter ( ( [ name , location ] ) => {
55- return name . length > 0 && location !== '[native code]'
56- } )
115+ const location = getCallerLocation ( new Error ( ) . stack )
57116
58117 const { file, line, keyValues } = options ?? { }
59118
60- let location = filtered ?. [ 0 ] ?. filter ( ( v ) => v . length > 0 ) . join ( '@' )
61- if ( location === 'Error' ) {
62- location = 'webview::unknown'
63- }
64-
65119 await invoke ( 'plugin:log|log' , {
66120 level,
67121 message,
0 commit comments