OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of service; | 5 part of service; |
6 | 6 |
7 /// A [ServiceObject] represents a persistent object within the vm. | 7 /// A [ServiceObject] represents a persistent object within the vm. |
8 abstract class ServiceObject extends Observable { | 8 abstract class ServiceObject extends Observable { |
9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { | 9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { |
10 return o1.name.compareTo(o2.name); | 10 return o1.name.compareTo(o2.name); |
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1823 typeClass = map['type_class']; | 1823 typeClass = map['type_class']; |
1824 userName = map['user_name']; | 1824 userName = map['user_name']; |
1825 referent = map['referent']; | 1825 referent = map['referent']; |
1826 key = map['key']; | 1826 key = map['key']; |
1827 value = map['value']; | 1827 value = map['value']; |
1828 | 1828 |
1829 // We are fully loaded. | 1829 // We are fully loaded. |
1830 _loaded = true; | 1830 _loaded = true; |
1831 } | 1831 } |
1832 | 1832 |
1833 String get shortName => valueAsString != null ? valueAsString : 'a ${clazz.nam
e}'; | 1833 String get shortName { |
| 1834 if (isClosure) { |
| 1835 return closureFunc.qualifiedName; |
| 1836 } |
| 1837 if (valueAsString != null) { |
| 1838 return valueAsString; |
| 1839 } |
| 1840 return 'a ${clazz.name}'; |
| 1841 } |
1834 | 1842 |
1835 String toString() => 'Instance($shortName)'; | 1843 String toString() => 'Instance($shortName)'; |
1836 } | 1844 } |
1837 | 1845 |
1838 | 1846 |
1839 class Context extends ServiceObject { | 1847 class Context extends ServiceObject { |
1840 @observable Class clazz; | 1848 @observable Class clazz; |
1841 @observable int size; | 1849 @observable int size; |
1842 | 1850 |
1843 @observable var parentContext; | 1851 @observable var parentContext; |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2061 | 2069 |
2062 bool get isBlank { | 2070 bool get isBlank { |
2063 // Compute isBlank on demand. | 2071 // Compute isBlank on demand. |
2064 if (_isBlank == null) { | 2072 if (_isBlank == null) { |
2065 _isBlank = text.trim().isEmpty; | 2073 _isBlank = text.trim().isEmpty; |
2066 } | 2074 } |
2067 return _isBlank; | 2075 return _isBlank; |
2068 } | 2076 } |
2069 bool _isBlank; | 2077 bool _isBlank; |
2070 | 2078 |
| 2079 bool get isTrivialLine => !possibleBpt; |
| 2080 |
2071 static bool _isTrivialToken(String token) { | 2081 static bool _isTrivialToken(String token) { |
2072 if (token == 'else') { | 2082 if (token == 'else') { |
2073 return true; | 2083 return true; |
2074 } | 2084 } |
2075 for (var c in token.split('')) { | 2085 for (var c in token.split('')) { |
2076 switch (c) { | 2086 switch (c) { |
2077 case '{': | 2087 case '{': |
2078 case '}': | 2088 case '}': |
2079 case '(': | 2089 case '(': |
2080 case ')': | 2090 case ')': |
2081 case ';': | 2091 case ';': |
2082 break; | 2092 break; |
2083 default: | 2093 default: |
2084 return false; | 2094 return false; |
2085 } | 2095 } |
2086 } | 2096 } |
2087 return true; | 2097 return true; |
2088 } | 2098 } |
2089 | 2099 |
2090 static bool _isTrivialLine(String text) { | 2100 static bool _isTrivialLine(String text) { |
| 2101 if (text.trimLeft().startsWith('//')) { |
| 2102 return true; |
| 2103 } |
2091 var wsTokens = text.split(new RegExp(r"(\s)+")); | 2104 var wsTokens = text.split(new RegExp(r"(\s)+")); |
2092 for (var wsToken in wsTokens) { | 2105 for (var wsToken in wsTokens) { |
2093 var tokens = wsToken.split(new RegExp(r"(\b)")); | 2106 var tokens = wsToken.split(new RegExp(r"(\b)")); |
2094 for (var token in tokens) { | 2107 for (var token in tokens) { |
2095 if (!_isTrivialToken(token)) { | 2108 if (!_isTrivialToken(token)) { |
2096 return false; | 2109 return false; |
2097 } | 2110 } |
2098 } | 2111 } |
2099 } | 2112 } |
2100 return true; | 2113 return true; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2168 | 2181 |
2169 factory CallSiteEntry.fromMap(Map entryMap) { | 2182 factory CallSiteEntry.fromMap(Map entryMap) { |
2170 return new CallSiteEntry(entryMap['receiverContainer'], | 2183 return new CallSiteEntry(entryMap['receiverContainer'], |
2171 entryMap['count'], | 2184 entryMap['count'], |
2172 entryMap['target']); | 2185 entryMap['target']); |
2173 } | 2186 } |
2174 | 2187 |
2175 String toString() => "CallSiteEntry(${receiverContainer.name}, $count)"; | 2188 String toString() => "CallSiteEntry(${receiverContainer.name}, $count)"; |
2176 } | 2189 } |
2177 | 2190 |
| 2191 /// The location of a local variable reference in a script. |
| 2192 class LocalVarLocation { |
| 2193 final int line; |
| 2194 final int column; |
| 2195 final int endColumn; |
| 2196 LocalVarLocation(this.line, this.column, this.endColumn); |
| 2197 } |
| 2198 |
2178 class Script extends ServiceObject with Coverage { | 2199 class Script extends ServiceObject with Coverage { |
2179 Set<CallSite> callSites = new Set<CallSite>(); | 2200 Set<CallSite> callSites = new Set<CallSite>(); |
2180 final lines = new ObservableList<ScriptLine>(); | 2201 final lines = new ObservableList<ScriptLine>(); |
2181 final _hits = new Map<int, int>(); | 2202 final _hits = new Map<int, int>(); |
2182 @observable String kind; | 2203 @observable String kind; |
2183 @observable int firstTokenPos; | 2204 @observable int firstTokenPos; |
2184 @observable int lastTokenPos; | 2205 @observable int lastTokenPos; |
2185 @observable int lineOffset; | 2206 @observable int lineOffset; |
2186 @observable int columnOffset; | 2207 @observable int columnOffset; |
2187 @observable Library library; | 2208 @observable Library library; |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2324 var line = tokenToLine(bpt.tokenPos); | 2345 var line = tokenToLine(bpt.tokenPos); |
2325 getLine(line).addBreakpoint(bpt); | 2346 getLine(line).addBreakpoint(bpt); |
2326 } | 2347 } |
2327 | 2348 |
2328 void _removeBreakpoint(Breakpoint bpt) { | 2349 void _removeBreakpoint(Breakpoint bpt) { |
2329 var line = tokenToLine(bpt.tokenPos); | 2350 var line = tokenToLine(bpt.tokenPos); |
2330 if (line != null) { | 2351 if (line != null) { |
2331 getLine(line).removeBreakpoint(bpt); | 2352 getLine(line).removeBreakpoint(bpt); |
2332 } | 2353 } |
2333 } | 2354 } |
| 2355 |
| 2356 List<LocalVarLocation> scanLineForLocalVariableLocations(Pattern pattern, |
| 2357 String name, |
| 2358 String lineContents, |
| 2359 int lineNumber, |
| 2360 int columnOffset) { |
| 2361 var r = <LocalVarLocation>[]; |
| 2362 |
| 2363 pattern.allMatches(lineContents).forEach((Match match) { |
| 2364 // We have a match but our regular expression may have matched extra |
| 2365 // characters on either side of the name. Tighten the location. |
| 2366 var nameStart = match.input.indexOf(name, match.start); |
| 2367 var column = nameStart + columnOffset; |
| 2368 var endColumn = column + name.length; |
| 2369 var localVarLocation = new LocalVarLocation(lineNumber, |
| 2370 column, |
| 2371 endColumn); |
| 2372 r.add(localVarLocation); |
| 2373 }); |
| 2374 |
| 2375 return r; |
| 2376 } |
| 2377 |
| 2378 List<LocalVarLocation> scanForLocalVariableLocations(String name, |
| 2379 int tokenPos, |
| 2380 int endTokenPos) { |
| 2381 // A pattern that matches: |
| 2382 // start of line OR non-(alpha numeric OR period) character followed by |
| 2383 // name followed by |
| 2384 // a non-alpha numerc character. |
| 2385 // |
| 2386 // NOTE: This pattern can over match on both ends. This is corrected for |
| 2387 // [scanLineForLocalVariableLocationse]. |
| 2388 var pattern = new RegExp("(^|[^A-Za-z0-9\.])$name[^A-Za-z0-9]"); |
| 2389 |
| 2390 // Result. |
| 2391 var r = <LocalVarLocation>[]; |
| 2392 |
| 2393 // Limits. |
| 2394 final lastLine = tokenToLine(endTokenPos); |
| 2395 if (lastLine == null) { |
| 2396 return r; |
| 2397 } |
| 2398 |
| 2399 final lastColumn = tokenToCol(endTokenPos); |
| 2400 if (lastColumn == null) { |
| 2401 return r; |
| 2402 } |
| 2403 // Current scan position. |
| 2404 var line = tokenToLine(tokenPos); |
| 2405 if (line == null) { |
| 2406 return r; |
| 2407 } |
| 2408 var column = tokenToCol(tokenPos); |
| 2409 if (column == null) { |
| 2410 return r; |
| 2411 } |
| 2412 |
| 2413 // Move back by name length. |
| 2414 // TODO(johnmccutchan): Fix LocalVarDescriptor to set column before the |
| 2415 // identifier name. |
| 2416 column = math.max(0, column - name.length); |
| 2417 |
| 2418 var lineContents; |
| 2419 |
| 2420 if (line == lastLine) { |
| 2421 // Only one line. |
| 2422 if (!getLine(line).isTrivialLine) { |
| 2423 lineContents = getLine(line).text.substring(column, lastColumn - 1); |
| 2424 return scanLineForLocalVariableLocations(pattern, |
| 2425 name, |
| 2426 lineContents, |
| 2427 line, |
| 2428 column); |
| 2429 } |
| 2430 } |
| 2431 |
| 2432 // Scan first line. |
| 2433 if (!getLine(line).isTrivialLine) { |
| 2434 lineContents = getLine(line).text.substring(column); |
| 2435 r.addAll(scanLineForLocalVariableLocations(pattern, |
| 2436 name, |
| 2437 lineContents, |
| 2438 line++, |
| 2439 column)); |
| 2440 } |
| 2441 |
| 2442 // Scan middle lines. |
| 2443 while (line < (lastLine - 1)) { |
| 2444 if (getLine(line).isTrivialLine) { |
| 2445 line++; |
| 2446 continue; |
| 2447 } |
| 2448 lineContents = getLine(line).text; |
| 2449 r.addAll( |
| 2450 scanLineForLocalVariableLocations(pattern, |
| 2451 name, |
| 2452 lineContents, |
| 2453 line++, |
| 2454 0)); |
| 2455 } |
| 2456 |
| 2457 // Scan last line. |
| 2458 if (!getLine(line).isTrivialLine) { |
| 2459 lineContents = getLine(line).text.substring(0, lastColumn - 1); |
| 2460 r.addAll( |
| 2461 scanLineForLocalVariableLocations(pattern, |
| 2462 name, |
| 2463 lineContents, |
| 2464 line, |
| 2465 0)); |
| 2466 } |
| 2467 return r; |
| 2468 } |
2334 } | 2469 } |
2335 | 2470 |
2336 class PcDescriptor extends Observable { | 2471 class PcDescriptor extends Observable { |
2337 final int pcOffset; | 2472 final int pcOffset; |
2338 @reflectable final int deoptId; | 2473 @reflectable final int deoptId; |
2339 @reflectable final int tokenPos; | 2474 @reflectable final int tokenPos; |
2340 @reflectable final int tryIndex; | 2475 @reflectable final int tryIndex; |
2341 @reflectable final String kind; | 2476 @reflectable final String kind; |
2342 @observable Script script; | 2477 @observable Script script; |
2343 @observable String formattedLine; | 2478 @observable String formattedLine; |
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3001 var v = list[i]; | 3136 var v = list[i]; |
3002 if ((v is ObservableMap) && _isServiceMap(v)) { | 3137 if ((v is ObservableMap) && _isServiceMap(v)) { |
3003 list[i] = owner.getFromMap(v); | 3138 list[i] = owner.getFromMap(v); |
3004 } else if (v is ObservableList) { | 3139 } else if (v is ObservableList) { |
3005 _upgradeObservableList(v, owner); | 3140 _upgradeObservableList(v, owner); |
3006 } else if (v is ObservableMap) { | 3141 } else if (v is ObservableMap) { |
3007 _upgradeObservableMap(v, owner); | 3142 _upgradeObservableMap(v, owner); |
3008 } | 3143 } |
3009 } | 3144 } |
3010 } | 3145 } |
OLD | NEW |