@@ -44,24 +44,78 @@ enum LogLevel {
44
44
Error
45
45
}
46
46
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
+
47
110
async function log (
48
111
level : LogLevel ,
49
112
message : string ,
50
113
options ?: LogOptions
51
114
) : 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 )
57
116
58
117
const { file, line, keyValues } = options ?? { }
59
118
60
- let location = filtered ?. [ 0 ] ?. filter ( ( v ) => v . length > 0 ) . join ( '@' )
61
- if ( location === 'Error' ) {
62
- location = 'webview::unknown'
63
- }
64
-
65
119
await invoke ( 'plugin:log|log' , {
66
120
level,
67
121
message,
0 commit comments