55WebInspector . SourceMapNamesResolver = { } ;
66
77WebInspector . SourceMapNamesResolver . _cachedMapSymbol = Symbol ( "cache" ) ;
8- WebInspector . SourceMapNamesResolver . _cachedPromiseSymbol = Symbol ( "cachePromise " ) ;
8+ WebInspector . SourceMapNamesResolver . _cachedIdentifiersSymbol = Symbol ( "cachedIdentifiers " ) ;
99
1010/**
11- * @param {!WebInspector.DebuggerModel.Scope } scope
12- * @return {!Promise.<!Map<string, string>> }
11+ * @constructor
12+ * @param {string } name
13+ * @param {number } lineNumber
14+ * @param {number } columnNumber
1315 */
14- WebInspector . SourceMapNamesResolver . _resolveScope = function ( scope )
16+ WebInspector . SourceMapNamesResolver . Identifier = function ( name , lineNumber , columnNumber )
1517{
16- var cachedMap = scope [ WebInspector . SourceMapNamesResolver . _cachedMapSymbol ] ;
17- if ( cachedMap )
18- return Promise . resolve ( cachedMap ) ;
19-
20- var cachedPromise = scope [ WebInspector . SourceMapNamesResolver . _cachedPromiseSymbol ] ;
21- if ( cachedPromise )
22- return cachedPromise ;
18+ this . name = name ;
19+ this . lineNumber = lineNumber ;
20+ this . columnNumber = columnNumber ;
21+ }
2322
23+ /**
24+ * @param {!WebInspector.DebuggerModel.Scope } scope
25+ * @return {!Promise<!Array<!WebInspector.SourceMapNamesResolver.Identifier>> }
26+ */
27+ WebInspector . SourceMapNamesResolver . _scopeIdentifiers = function ( scope )
28+ {
2429 var startLocation = scope . startLocation ( ) ;
2530 var endLocation = scope . endLocation ( ) ;
2631
2732 if ( scope . type ( ) === DebuggerAgent . ScopeType . Global || ! startLocation || ! endLocation || ! startLocation . script ( ) . sourceMapURL || ( startLocation . script ( ) !== endLocation . script ( ) ) )
28- return Promise . resolve ( new Map ( ) ) ;
33+ return Promise . resolve ( /** @type { !Array<!WebInspector.SourceMapNamesResolver.Identifier> }*/ ( [ ] ) ) ;
2934
3035 var script = startLocation . script ( ) ;
31- var sourceMap = WebInspector . debuggerWorkspaceBinding . sourceMapForScript ( script ) ;
32- if ( ! sourceMap )
33- return Promise . resolve ( new Map ( ) ) ;
34-
35- var promise = script . requestContent ( ) . then ( onContent ) ;
36- scope [ WebInspector . SourceMapNamesResolver . _cachedPromiseSymbol ] = promise ;
37- return promise ;
36+ return script . requestContent ( ) . then ( onContent ) ;
3837
3938 /**
4039 * @param {?string } content
41- * @return {!Promise<!Map<string, string >> }
40+ * @return {!Promise<!Array<!WebInspector.SourceMapNamesResolver.Identifier >> }
4241 */
4342 function onContent ( content )
4443 {
4544 if ( ! content )
46- return Promise . resolve ( new Map ( ) ) ;
47-
48- var startLocation = scope . startLocation ( ) ;
49- var endLocation = scope . endLocation ( ) ;
50- var textRange = new WebInspector . TextRange ( startLocation . lineNumber , startLocation . columnNumber , endLocation . lineNumber , endLocation . columnNumber ) ;
45+ return Promise . resolve ( /** @type {!Array<!WebInspector.SourceMapNamesResolver.Identifier> }*/ ( [ ] ) ) ;
5146
5247 var text = new WebInspector . Text ( content ) ;
53- var scopeText = text . extract ( textRange ) ;
54- var scopeStart = text . toSourceRange ( textRange ) . offset ;
48+ var scopeRange = new WebInspector . TextRange ( startLocation . lineNumber , startLocation . columnNumber , endLocation . lineNumber , endLocation . columnNumber )
49+ var scopeText = text . extract ( scopeRange ) ;
50+ var scopeStart = text . toSourceRange ( scopeRange ) . offset ;
5551 var prefix = "function fui" ;
5652
5753 return WebInspector . SourceMapNamesResolverWorker . _instance ( ) . javaScriptIdentifiers ( prefix + scopeText )
@@ -63,28 +59,124 @@ WebInspector.SourceMapNamesResolver._resolveScope = function(scope)
6359 * @param {number } scopeStart
6460 * @param {string } prefix
6561 * @param {!Array<!{name: string, offset: number}> } identifiers
66- * @return {!Map<string, string > }
62+ * @return {!Array<!WebInspector.SourceMapNamesResolver.Identifier > }
6763 */
6864 function onIdentifiers ( text , scopeStart , prefix , identifiers )
6965 {
70- var namesMapping = new Map ( ) ;
71- var lineEndings = text . lineEndings ( ) ;
72-
66+ var result = [ ] ;
67+ var cursor = new WebInspector . TextCursor ( text . lineEndings ( ) ) ;
68+ var promises = [ ] ;
7369 for ( var i = 0 ; i < identifiers . length ; ++ i ) {
7470 var id = identifiers [ i ] ;
71+ if ( id . offset < prefix . length )
72+ continue ;
7573 var start = scopeStart + id . offset - prefix . length ;
74+ cursor . resetTo ( start ) ;
75+ result . push ( new WebInspector . SourceMapNamesResolver . Identifier ( id . name , cursor . lineNumber ( ) , cursor . columnNumber ( ) ) ) ;
76+ }
77+ return result ;
78+ }
79+ }
80+
81+ /**
82+ * @param {!WebInspector.DebuggerModel.Scope } scope
83+ * @return {!Promise.<!Map<string, string>> }
84+ */
85+ WebInspector . SourceMapNamesResolver . _resolveScope = function ( scope )
86+ {
87+ var identifiersPromise = scope [ WebInspector . SourceMapNamesResolver . _cachedIdentifiersSymbol ] ;
88+ if ( identifiersPromise )
89+ return identifiersPromise ;
90+
91+ var script = scope . callFrame ( ) . script ;
92+ var sourceMap = WebInspector . debuggerWorkspaceBinding . sourceMapForScript ( script ) ;
93+ if ( ! sourceMap )
94+ return Promise . resolve ( new Map ( ) ) ;
7695
77- var lineNumber = lineEndings . lowerBound ( start ) ;
78- var columnNumber = start - ( lineNumber === 0 ? 0 : ( lineEndings [ lineNumber - 1 ] + 1 ) ) ;
79- var entry = sourceMap . findEntry ( lineNumber , columnNumber ) ;
80- if ( entry )
96+ /** @type {!Map<string, !WebInspector.Text> } */
97+ var textCache = new Map ( ) ;
98+ identifiersPromise = WebInspector . SourceMapNamesResolver . _scopeIdentifiers ( scope ) . then ( onIdentifiers ) ;
99+ scope [ WebInspector . SourceMapNamesResolver . _cachedIdentifiersSymbol ] = identifiersPromise ;
100+ return identifiersPromise ;
101+
102+ /**
103+ * @param {!Array<!WebInspector.SourceMapNamesResolver.Identifier> } identifiers
104+ * @return {!Promise<!Map<string, string>> }
105+ */
106+ function onIdentifiers ( identifiers )
107+ {
108+ var namesMapping = new Map ( ) ;
109+ // Extract as much as possible from SourceMap.
110+ for ( var i = 0 ; i < identifiers . length ; ++ i ) {
111+ var id = identifiers [ i ] ;
112+ var entry = sourceMap . findEntry ( id . lineNumber , id . columnNumber ) ;
113+ if ( entry && entry . name )
81114 namesMapping . set ( id . name , entry . name ) ;
82115 }
83116
84- scope [ WebInspector . SourceMapNamesResolver . _cachedMapSymbol ] = namesMapping ;
85- delete scope [ WebInspector . SourceMapNamesResolver . _cachedPromiseSymbol ] ;
86- WebInspector . SourceMapNamesResolver . _scopeResolvedForTest ( ) ;
87- return namesMapping ;
117+ // Resolve missing identifier names from sourcemap ranges.
118+ var promises = [ ] ;
119+ for ( var i = 0 ; i < identifiers . length ; ++ i ) {
120+ var id = identifiers [ i ] ;
121+ if ( namesMapping . has ( id . name ) )
122+ continue ;
123+ var promise = resolveSourceName ( id ) . then ( onSourceNameResolved . bind ( null , namesMapping , id ) ) ;
124+ promises . push ( promise ) ;
125+ }
126+ return Promise . all ( promises )
127+ . then ( ( ) => WebInspector . SourceMapNamesResolver . _scopeResolvedForTest ( ) )
128+ . then ( ( ) => namesMapping )
129+ }
130+
131+ /**
132+ * @param {!Map<string, string> } namesMapping
133+ * @param {!WebInspector.SourceMapNamesResolver.Identifier } id
134+ * @param {?string } sourceName
135+ */
136+ function onSourceNameResolved ( namesMapping , id , sourceName )
137+ {
138+ if ( ! sourceName )
139+ return ;
140+ namesMapping . set ( id . name , sourceName ) ;
141+ }
142+
143+ /**
144+ * @param {!WebInspector.SourceMapNamesResolver.Identifier } id
145+ * @return {!Promise<?string> }
146+ */
147+ function resolveSourceName ( id )
148+ {
149+ var startEntry = sourceMap . findEntry ( id . lineNumber , id . columnNumber ) ;
150+ var endEntry = sourceMap . findEntry ( id . lineNumber , id . columnNumber + id . name . length ) ;
151+ if ( ! startEntry || ! endEntry || ! startEntry . sourceURL || startEntry . sourceURL !== endEntry . sourceURL
152+ || ! startEntry . sourceLineNumber || ! startEntry . sourceColumnNumber
153+ || ! endEntry . sourceLineNumber || ! endEntry . sourceColumnNumber )
154+ return Promise . resolve ( /** @type {?string } */ ( null ) ) ;
155+ var sourceTextRange = new WebInspector . TextRange ( startEntry . sourceLineNumber , startEntry . sourceColumnNumber , endEntry . sourceLineNumber , endEntry . sourceColumnNumber ) ;
156+ var uiSourceCode = WebInspector . networkMapping . uiSourceCodeForScriptURL ( startEntry . sourceURL , script ) ;
157+ if ( ! uiSourceCode )
158+ return Promise . resolve ( /** @type {?string } */ ( null ) ) ;
159+
160+ return uiSourceCode . requestContent ( )
161+ . then ( onSourceContent . bind ( null , sourceTextRange ) ) ;
162+ }
163+
164+ /**
165+ * @param {!WebInspector.TextRange } sourceTextRange
166+ * @param {?string } content
167+ * @return {?string }
168+ */
169+ function onSourceContent ( sourceTextRange , content )
170+ {
171+ if ( ! content )
172+ return null ;
173+ var text = textCache . get ( content ) ;
174+ if ( ! text ) {
175+ text = new WebInspector . Text ( content ) ;
176+ textCache . set ( content , text ) ;
177+ }
178+ var originalIdentifier = text . extract ( sourceTextRange ) . trim ( ) ;
179+ return / [ a - z A - Z 0 - 9 _ $ ] + / . test ( originalIdentifier ) ? originalIdentifier : null ;
88180 }
89181}
90182
@@ -151,7 +243,7 @@ WebInspector.SourceMapNamesResolver.resolveExpression = function(callFrame, orig
151243 if ( reverseMapping . has ( originalText ) )
152244 return Promise . resolve ( reverseMapping . get ( originalText ) || "" ) ;
153245
154- return WebInspector . SourceMapNamesResolver . _resolveExpression ( callFrame , uiSourceCode , lineNumber , startColumnNumber , endColumnNumber )
246+ return WebInspector . SourceMapNamesResolver . _resolveExpression ( callFrame , uiSourceCode , lineNumber , startColumnNumber , endColumnNumber ) ;
155247 }
156248}
157249
0 commit comments