OLD | NEW |
---|---|
1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** @typedef {{startOffset: number, endOffset: number, count: number}} */ | 5 /** @typedef {{startOffset: number, endOffset: number, count: number}} */ |
6 Coverage.RangeUseCount; | 6 Coverage.RangeUseCount; |
7 | 7 |
8 /** @typedef {{end: number, count: (number|undefined), depth: number}} */ | |
alph
2017/03/10 02:05:09
Wouldn't it be more convenient to have a start ins
| |
9 Coverage.CoverageSegment; | |
10 | |
8 /** @typedef {{ | 11 /** @typedef {{ |
9 * contentProvider: !Common.ContentProvider, | 12 * contentProvider: !Common.ContentProvider, |
10 * size: number, | 13 * size: number, |
11 * unusedSize: number, | 14 * unusedSize: number, |
12 * usedSize: number, | 15 * usedSize: number, |
13 * type: !Coverage.CoverageType, | 16 * type: !Coverage.CoverageType, |
14 * lineOffset: number, | 17 * lineOffset: number, |
15 * columnOffset: number, | 18 * columnOffset: number, |
16 * ranges: !Array<!Coverage.RangeUseCount> | 19 * segments: !Array<!Coverage.CoverageSegment> |
17 * }} | 20 * }} |
18 */ | 21 */ |
19 Coverage.CoverageInfo; | 22 Coverage.CoverageInfo; |
20 | 23 |
21 /** | 24 /** |
22 * @enum {number} | 25 * @enum {number} |
23 */ | 26 */ |
24 Coverage.CoverageType = { | 27 Coverage.CoverageType = { |
25 CSS: (1 << 0), | 28 CSS: (1 << 0), |
26 JavaScript: (1 << 1), | 29 JavaScript: (1 << 1), |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
102 * @return {!Array<!Coverage.CoverageInfo>} | 105 * @return {!Array<!Coverage.CoverageInfo>} |
103 */ | 106 */ |
104 static _processJSCoverage(debuggerModel, scriptsCoverage) { | 107 static _processJSCoverage(debuggerModel, scriptsCoverage) { |
105 var result = []; | 108 var result = []; |
106 for (var entry of scriptsCoverage) { | 109 for (var entry of scriptsCoverage) { |
107 var script = debuggerModel.scriptForId(entry.scriptId); | 110 var script = debuggerModel.scriptForId(entry.scriptId); |
108 if (!script) | 111 if (!script) |
109 continue; | 112 continue; |
110 var ranges = []; | 113 var ranges = []; |
111 for (var func of entry.functions) { | 114 for (var func of entry.functions) { |
112 for (var range of func.ranges) | 115 for (var range of func.ranges) |
alph
2017/03/10 02:05:08
slice it?
| |
113 ranges.push({startOffset: range.startOffset, endOffset: range.endOffse t, count: range.count}); | 116 ranges.push(range); |
114 } | 117 } |
118 ranges.sort((a, b) => a.startOffset - b.startOffset); | |
115 result.push(Coverage.CoverageModel._buildCoverageInfo( | 119 result.push(Coverage.CoverageModel._buildCoverageInfo( |
116 script, script.contentLength, script.lineOffset, script.columnOffset, ranges)); | 120 script, script.contentLength, script.lineOffset, script.columnOffset, ranges)); |
117 } | 121 } |
118 return result; | 122 return result; |
119 } | 123 } |
120 | 124 |
121 /** | 125 /** |
126 * @param {!Array<!Coverage.RangeUseCount>} ranges | |
127 * @return {!Array<!Coverage.CoverageSegment>} | |
128 */ | |
129 static _convertToDisjointSegments(ranges) { | |
130 var result = []; | |
131 | |
132 var stack = []; | |
133 for (var entry of ranges) { | |
134 var top = stack.peekLast(); | |
135 while (top && top.endOffset <= entry.startOffset) { | |
136 append(top.endOffset, top.count, stack.length); | |
137 stack.pop(); | |
138 top = stack.peekLast(); | |
139 } | |
140 append(entry.startOffset, top ? top.count : undefined, stack.length); | |
141 stack.push(entry); | |
142 } | |
143 | |
144 while (stack.length) { | |
145 var depth = stack.length; | |
146 var top = stack.pop(); | |
147 append(top.endOffset, top.count, depth); | |
148 } | |
149 | |
150 function append(end, count, depth) { | |
alph
2017/03/10 02:05:08
annotate plz
| |
151 var last = result.peekLast(); | |
152 if (last) { | |
153 if (last.end === end) | |
154 return; | |
155 if (last.count === count && last.depth === depth) { | |
156 last.end = end; | |
157 return; | |
158 } | |
159 } | |
160 result.push({end: end, count: count, depth: depth}); | |
161 } | |
162 | |
163 return result; | |
164 } | |
165 | |
166 /** | |
122 * @return {!Promise<!Array<!Coverage.CoverageInfo>>} | 167 * @return {!Promise<!Array<!Coverage.CoverageInfo>>} |
123 */ | 168 */ |
124 async _stopCSSCoverage() { | 169 async _stopCSSCoverage() { |
125 if (!this._cssModel) | 170 if (!this._cssModel) |
126 return []; | 171 return []; |
127 | 172 |
128 var rawCoverageData = await this._cssModel.ruleListPromise(); | 173 var rawCoverageData = await this._cssModel.ruleListPromise(); |
129 return Coverage.CoverageModel._processCSSCoverage( | 174 return Coverage.CoverageModel._processCSSCoverage( |
130 /** @type !SDK.CSSModel */ (this._cssModel), rawCoverageData); | 175 /** @type !SDK.CSSModel */ (this._cssModel), rawCoverageData); |
131 } | 176 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
165 /** @type Coverage.CoverageType */ | 210 /** @type Coverage.CoverageType */ |
166 var coverageType; | 211 var coverageType; |
167 var url = contentProvider.contentURL(); | 212 var url = contentProvider.contentURL(); |
168 if (contentProvider.contentType().isScript()) | 213 if (contentProvider.contentType().isScript()) |
169 coverageType = Coverage.CoverageType.JavaScript; | 214 coverageType = Coverage.CoverageType.JavaScript; |
170 else if (contentProvider.contentType().isStyleSheet()) | 215 else if (contentProvider.contentType().isStyleSheet()) |
171 coverageType = Coverage.CoverageType.CSS; | 216 coverageType = Coverage.CoverageType.CSS; |
172 else | 217 else |
173 console.assert(false, `Unexpected resource type ${contentProvider.contentT ype().name} for ${url}`); | 218 console.assert(false, `Unexpected resource type ${contentProvider.contentT ype().name} for ${url}`); |
174 | 219 |
175 var stack = []; | 220 var segments = Coverage.CoverageModel._convertToDisjointSegments(ranges); |
176 ranges.sort((a, b) => a.startOffset - b.startOffset); | |
177 for (var entry of ranges) { | |
178 while (stack.length && stack.peekLast().endOffset <= entry.startOffset) | |
179 stack.pop(); | |
180 | |
181 entry.ownSize = entry.endOffset - entry.startOffset; | |
182 var top = stack.peekLast(); | |
183 if (top) { | |
184 if (top.endOffset < entry.endOffset) { | |
185 console.assert( | |
186 false, `Overlapping coverage entries in ${url}: ${top.start}-${top .end} vs. ${entry.start}-${entry.end}`); | |
187 } | |
188 top.ownSize -= entry.ownSize; | |
189 } | |
190 stack.push(entry); | |
191 } | |
192 | |
193 var usedSize = 0; | 221 var usedSize = 0; |
194 var unusedSize = 0; | 222 var unusedSize = 0; |
195 for (var entry of ranges) { | 223 var last = 0; |
196 if (entry.count) | 224 for (var segment of segments) { |
197 usedSize += entry.ownSize; | 225 if (typeof segment.count === 'number') { |
198 else | 226 if (segment.count) |
199 unusedSize += entry.ownSize; | 227 usedSize += segment.end - last; |
228 else | |
229 unusedSize += segment.end - last; | |
230 } | |
231 last = segment.end; | |
200 } | 232 } |
201 | |
202 var coverageInfo = { | 233 var coverageInfo = { |
203 contentProvider: contentProvider, | 234 contentProvider: contentProvider, |
204 ranges: ranges, | 235 segments: segments, |
205 type: coverageType, | 236 type: coverageType, |
206 size: contentLength, | 237 size: contentLength, |
207 usedSize: usedSize, | 238 usedSize: usedSize, |
208 unusedSize: unusedSize, | 239 unusedSize: unusedSize, |
209 lineOffset: startLine, | 240 lineOffset: startLine, |
210 columnOffset: startColumn | 241 columnOffset: startColumn |
211 }; | 242 }; |
212 return coverageInfo; | 243 return coverageInfo; |
213 } | 244 } |
214 }; | 245 }; |
OLD | NEW |