Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: runtime/observatory/lib/src/service/object.dart

Issue 1590353002: Only show breakpoints at possible breakpoint positions in Observatory. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fix tests Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // Some value smaller than the object ring, so requesting a large array 7 // Some value smaller than the object ring, so requesting a large array
8 // doesn't result in an expired ref because the elements lapped it in the 8 // doesn't result in an expired ref because the elements lapped it in the
9 // object ring. 9 // object ring.
10 const int kDefaultFieldLimit = 100; 10 const int kDefaultFieldLimit = 100;
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1154 Code code = value; 1154 Code code = value;
1155 code.profile = null; 1155 code.profile = null;
1156 } else if (value is ServiceFunction) { 1156 } else if (value is ServiceFunction) {
1157 ServiceFunction function = value; 1157 ServiceFunction function = value;
1158 function.profile = null; 1158 function.profile = null;
1159 } 1159 }
1160 }); 1160 });
1161 } 1161 }
1162 1162
1163 static const kCallSitesReport = '_CallSites'; 1163 static const kCallSitesReport = '_CallSites';
1164 static const kPossibleBreakpointsReport = 'PossibleBreakpoints';
1164 1165
1165 Future<ServiceMap> getSourceReport(List<String> report_kinds, 1166 Future<ServiceMap> getSourceReport(List<String> report_kinds,
1166 [Script script, 1167 [Script script,
1167 int startPos, 1168 int startPos,
1168 int endPos]) { 1169 int endPos]) {
1169 var params = { 'reports' : report_kinds }; 1170 var params = { 'reports' : report_kinds };
1170 if (script != null) { 1171 if (script != null) {
1171 params['scriptId'] = script.id; 1172 params['scriptId'] = script.id;
1172 } 1173 }
1173 if (startPos != null) { 1174 if (startPos != null) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
1514 // Ignore GC events for now. 1515 // Ignore GC events for now.
1515 break; 1516 break;
1516 1517
1517 default: 1518 default:
1518 // Log unexpected events. 1519 // Log unexpected events.
1519 Logger.root.severe('Unexpected event: $event'); 1520 Logger.root.severe('Unexpected event: $event');
1520 break; 1521 break;
1521 } 1522 }
1522 } 1523 }
1523 1524
1524 Future<ServiceObject> addBreakpoint( 1525 Future<ServiceObject> addBreakpoint(Script script, int line, [int col]) {
1525 Script script, int line, [int col]) async { 1526 Map params = {
1526 // TODO(turnidge): Pass line as an int instead of a string. 1527 'scriptId': script.id,
1527 try { 1528 'line': line,
1528 Map params = { 1529 };
1529 'scriptId': script.id, 1530 if (col != null) {
1530 'line': line.toString(), 1531 params['column'] = col;
1531 };
1532 if (col != null) {
1533 params['column'] = col.toString();
1534 }
1535 Breakpoint bpt = await invokeRpc('addBreakpoint', params);
1536 if (bpt.resolved && script.loaded) {
1537 SourceLocation loc = bpt.location;
1538 if (script.tokenToLine(loc.tokenPos) != line) {
1539 script.getLine(line).possibleBpt = false;
1540 }
1541 }
1542 return bpt;
1543 } on ServerRpcException catch(e) {
1544 if (e.code == ServerRpcException.kCannotAddBreakpoint) {
1545 // Unable to set a breakpoint at the desired line.
1546 if (script.loaded) {
1547 script.getLine(line).possibleBpt = false;
1548 }
1549 }
1550 rethrow;
1551 } 1532 }
1533 return invokeRpc('addBreakpoint', params);
1552 } 1534 }
1553 1535
1554 Future<ServiceObject> addBreakpointByScriptUri( 1536 Future<ServiceObject> addBreakpointByScriptUri(
1555 String uri, int line, [int col]) { 1537 String uri, int line, [int col]) {
1556 Map params = { 1538 Map params = {
1557 'scriptUri': uri, 1539 'scriptUri': uri,
1558 'line': line.toString(), 1540 'line': line.toString(),
1559 }; 1541 };
1560 if (col != null) { 1542 if (col != null) {
1561 params['column'] = col.toString(); 1543 params['column'] = col.toString();
(...skipping 1154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2716 } 2698 }
2717 2699
2718 String toString() => 'Field(${dartOwner.name}.$name)'; 2700 String toString() => 'Field(${dartOwner.name}.$name)';
2719 } 2701 }
2720 2702
2721 2703
2722 class ScriptLine extends Observable { 2704 class ScriptLine extends Observable {
2723 final Script script; 2705 final Script script;
2724 final int line; 2706 final int line;
2725 final String text; 2707 final String text;
2726 @observable bool possibleBpt = true;
2727 @observable bool breakpointResolved = false;
2728 @observable Set<Breakpoint> breakpoints; 2708 @observable Set<Breakpoint> breakpoints;
2729 2709
2710 ScriptLine(this.script, this.line, this.text);
2711
2730 bool get isBlank { 2712 bool get isBlank {
2731 // Compute isBlank on demand. 2713 return text.isEmpty || text.trim().isEmpty;
2732 if (_isBlank == null) { 2714 }
2733 _isBlank = text.trim().isEmpty; 2715
2716 bool _isTrivial = null;
2717 bool get isTrivial {
2718 if (_isTrivial == null) {
2719 _isTrivial = _isTrivialLine(text);
2734 } 2720 }
2735 return _isBlank; 2721 return _isTrivial;
2736 } 2722 }
2737 bool _isBlank;
2738
2739 bool get isTrivialLine => !possibleBpt;
2740 2723
2741 static bool _isTrivialToken(String token) { 2724 static bool _isTrivialToken(String token) {
2742 if (token == 'else') { 2725 if (token == 'else') {
2743 return true; 2726 return true;
2744 } 2727 }
2745 for (var c in token.split('')) { 2728 for (var c in token.split('')) {
2746 switch (c) { 2729 switch (c) {
2747 case '{': 2730 case '{':
2748 case '}': 2731 case '}':
2749 case '(': 2732 case '(':
(...skipping 16 matching lines...) Expand all
2766 var tokens = wsToken.split(new RegExp(r"(\b)")); 2749 var tokens = wsToken.split(new RegExp(r"(\b)"));
2767 for (var token in tokens) { 2750 for (var token in tokens) {
2768 if (!_isTrivialToken(token)) { 2751 if (!_isTrivialToken(token)) {
2769 return false; 2752 return false;
2770 } 2753 }
2771 } 2754 }
2772 } 2755 }
2773 return true; 2756 return true;
2774 } 2757 }
2775 2758
2776 ScriptLine(this.script, this.line, this.text) {
2777 possibleBpt = !_isTrivialLine(text);
2778 }
2779
2780 void addBreakpoint(Breakpoint bpt) { 2759 void addBreakpoint(Breakpoint bpt) {
2781 if (breakpoints == null) { 2760 if (breakpoints == null) {
2782 breakpoints = new Set<Breakpoint>(); 2761 breakpoints = new Set<Breakpoint>();
2783 } 2762 }
2784 breakpoints.add(bpt); 2763 breakpoints.add(bpt);
2785 breakpointResolved = breakpointResolved || bpt.resolved;
2786 } 2764 }
2787 2765
2788 void removeBreakpoint(Breakpoint bpt) { 2766 void removeBreakpoint(Breakpoint bpt) {
2789 assert(breakpoints != null && breakpoints.contains(bpt)); 2767 assert(breakpoints != null && breakpoints.contains(bpt));
2790 breakpoints.remove(bpt); 2768 breakpoints.remove(bpt);
2791 if (breakpoints.isEmpty) { 2769 if (breakpoints.isEmpty) {
2792 breakpoints = null; 2770 breakpoints = null;
2793 breakpointResolved = false;
2794 } 2771 }
2795 } 2772 }
2796 } 2773 }
2797 2774
2798 class CallSite { 2775 class CallSite {
2799 final String name; 2776 final String name;
2800 // TODO(turnidge): Use SourceLocation here instead. 2777 // TODO(turnidge): Use SourceLocation here instead.
2801 final Script script; 2778 final Script script;
2802 final int tokenPos; 2779 final int tokenPos;
2803 final List<CallSiteEntry> entries; 2780 final List<CallSiteEntry> entries;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2996 // Keep track of max and min token positions. 2973 // Keep track of max and min token positions.
2997 firstTokenPos = (firstTokenPos <= tokenOffset) ? 2974 firstTokenPos = (firstTokenPos <= tokenOffset) ?
2998 firstTokenPos : tokenOffset; 2975 firstTokenPos : tokenOffset;
2999 lastTokenPos = (lastTokenPos >= tokenOffset) ? 2976 lastTokenPos = (lastTokenPos >= tokenOffset) ?
3000 lastTokenPos : tokenOffset; 2977 lastTokenPos : tokenOffset;
3001 } 2978 }
3002 _tokenToLine[tokenOffset] = lineNumber; 2979 _tokenToLine[tokenOffset] = lineNumber;
3003 _tokenToCol[tokenOffset] = colNumber; 2980 _tokenToCol[tokenOffset] = colNumber;
3004 } 2981 }
3005 } 2982 }
3006
3007 for (var line in lines) {
3008 // Remove possible breakpoints on lines with no tokens.
3009 if (!lineSet.contains(line.line)) {
3010 line.possibleBpt = false;
3011 }
3012 }
3013 } 2983 }
3014 2984
3015 void _processSource(String source) { 2985 void _processSource(String source) {
3016 if (source == null) { 2986 if (source == null) {
3017 return; 2987 return;
3018 } 2988 }
3019 var sourceLines = source.split('\n'); 2989 var sourceLines = source.split('\n');
3020 if (sourceLines.length == 0) { 2990 if (sourceLines.length == 0) {
3021 return; 2991 return;
3022 } 2992 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
3118 3088
3119 // Move back by name length. 3089 // Move back by name length.
3120 // TODO(johnmccutchan): Fix LocalVarDescriptor to set column before the 3090 // TODO(johnmccutchan): Fix LocalVarDescriptor to set column before the
3121 // identifier name. 3091 // identifier name.
3122 column = math.max(0, column - name.length); 3092 column = math.max(0, column - name.length);
3123 3093
3124 var lineContents; 3094 var lineContents;
3125 3095
3126 if (line == lastLine) { 3096 if (line == lastLine) {
3127 // Only one line. 3097 // Only one line.
3128 if (!getLine(line).isTrivialLine) { 3098 if (!getLine(line).isTrivial) {
3129 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted 3099 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted
3130 // code. e.g.: 3100 // code. e.g.:
3131 // io_sink.dart source line 23 ends at column 39 3101 // io_sink.dart source line 23 ends at column 39
3132 // io_sink.dart snapshotted source line 23 ends at column 35. 3102 // io_sink.dart snapshotted source line 23 ends at column 35.
3133 lastColumn = math.min(getLine(line).text.length, lastColumn); 3103 lastColumn = math.min(getLine(line).text.length, lastColumn);
3134 lineContents = getLine(line).text.substring(column, lastColumn - 1); 3104 lineContents = getLine(line).text.substring(column, lastColumn - 1);
3135 return scanLineForLocalVariableLocations(pattern, 3105 return scanLineForLocalVariableLocations(pattern,
3136 name, 3106 name,
3137 lineContents, 3107 lineContents,
3138 line, 3108 line,
3139 column); 3109 column);
3140 } 3110 }
3141 } 3111 }
3142 3112
3143 // Scan first line. 3113 // Scan first line.
3144 if (!getLine(line).isTrivialLine) { 3114 if (!getLine(line).isTrivial) {
3145 lineContents = getLine(line).text.substring(column); 3115 lineContents = getLine(line).text.substring(column);
3146 r.addAll(scanLineForLocalVariableLocations(pattern, 3116 r.addAll(scanLineForLocalVariableLocations(pattern,
3147 name, 3117 name,
3148 lineContents, 3118 lineContents,
3149 line++, 3119 line++,
3150 column)); 3120 column));
3151 } 3121 }
3152 3122
3153 // Scan middle lines. 3123 // Scan middle lines.
3154 while (line < (lastLine - 1)) { 3124 while (line < (lastLine - 1)) {
3155 if (getLine(line).isTrivialLine) { 3125 if (getLine(line).isTrivial) {
3156 line++; 3126 line++;
3157 continue; 3127 continue;
3158 } 3128 }
3159 lineContents = getLine(line).text; 3129 lineContents = getLine(line).text;
3160 r.addAll( 3130 r.addAll(
3161 scanLineForLocalVariableLocations(pattern, 3131 scanLineForLocalVariableLocations(pattern,
3162 name, 3132 name,
3163 lineContents, 3133 lineContents,
3164 line++, 3134 line++,
3165 0)); 3135 0));
3166 } 3136 }
3167 3137
3168 // Scan last line. 3138 // Scan last line.
3169 if (!getLine(line).isTrivialLine) { 3139 if (!getLine(line).isTrivial) {
3170 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted 3140 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted
3171 // code. e.g.: 3141 // code. e.g.:
3172 // io_sink.dart source line 23 ends at column 39 3142 // io_sink.dart source line 23 ends at column 39
3173 // io_sink.dart snapshotted source line 23 ends at column 35. 3143 // io_sink.dart snapshotted source line 23 ends at column 35.
3174 lastColumn = math.min(getLine(line).text.length, lastColumn); 3144 lastColumn = math.min(getLine(line).text.length, lastColumn);
3175 lineContents = getLine(line).text.substring(0, lastColumn - 1); 3145 lineContents = getLine(line).text.substring(0, lastColumn - 1);
3176 r.addAll( 3146 r.addAll(
3177 scanLineForLocalVariableLocations(pattern, 3147 scanLineForLocalVariableLocations(pattern,
3178 name, 3148 name,
3179 lineContents, 3149 lineContents,
(...skipping 789 matching lines...) Expand 10 before | Expand all | Expand 10 after
3969 _upgradeCollection(map, owner); 3939 _upgradeCollection(map, owner);
3970 this.messageObjectId = map['messageObjectId']; 3940 this.messageObjectId = map['messageObjectId'];
3971 this.index = map['index']; 3941 this.index = map['index'];
3972 this.size = map['size']; 3942 this.size = map['size'];
3973 this.handler = map['handler']; 3943 this.handler = map['handler'];
3974 this.location = map['location']; 3944 this.location = map['location'];
3975 } 3945 }
3976 } 3946 }
3977 3947
3978 3948
3949 // Helper function to extract possible breakpoint locations from a
3950 // SourceReport for some script.
3951 Set<int> getPossibleBreakpointLines(ServiceMap report, Script script) {
3952 var result = new Set<int>();
3953 int scriptIndex;
3954 int numScripts = report['scripts'].length;
3955 for (scriptIndex = 0; scriptIndex < numScripts; scriptIndex++) {
3956 if (report['scripts'][scriptIndex].id == script.id) {
3957 break;
3958 }
3959 }
3960 if (scriptIndex == numScripts) {
3961 return result;
3962 }
3963 var ranges = report['ranges'];
3964 if (ranges != null) {
3965 for (var range in ranges) {
3966 if (range['scriptIndex'] != scriptIndex) {
3967 continue;
3968 }
3969 if (range['compiled']) {
3970 var possibleBpts = range['possibleBreakpoints'];
3971 if (possibleBpts != null) {
3972 for (var tokenPos in possibleBpts) {
3973 result.add(script.tokenToLine(tokenPos));
3974 }
3975 }
3976 } else {
3977 int startLine = script.tokenToLine(range['startPos']);
3978 int endLine = script.tokenToLine(range['endPos']);
3979 for (int line = startLine; line <= endLine; line++) {
3980 if (!script.getLine(line).isTrivial) {
3981 result.add(line);
3982 }
3983 }
3984 }
3985 }
3986 }
3987 return result;
3988 }
3989
3990
3979 // Returns true if [map] is a service map. i.e. it has the following keys: 3991 // Returns true if [map] is a service map. i.e. it has the following keys:
3980 // 'id' and a 'type'. 3992 // 'id' and a 'type'.
3981 bool _isServiceMap(ObservableMap m) { 3993 bool _isServiceMap(ObservableMap m) {
3982 return (m != null) && (m['type'] != null); 3994 return (m != null) && (m['type'] != null);
3983 } 3995 }
3984 3996
3985 bool _hasRef(String type) => type.startsWith('@'); 3997 bool _hasRef(String type) => type.startsWith('@');
3986 String _stripRef(String type) => (_hasRef(type) ? type.substring(1) : type); 3998 String _stripRef(String type) => (_hasRef(type) ? type.substring(1) : type);
3987 3999
3988 /// Recursively upgrades all [ServiceObject]s inside [collection] which must 4000 /// Recursively upgrades all [ServiceObject]s inside [collection] which must
(...skipping 27 matching lines...) Expand all
4016 var v = list[i]; 4028 var v = list[i];
4017 if ((v is ObservableMap) && _isServiceMap(v)) { 4029 if ((v is ObservableMap) && _isServiceMap(v)) {
4018 list[i] = owner.getFromMap(v); 4030 list[i] = owner.getFromMap(v);
4019 } else if (v is ObservableList) { 4031 } else if (v is ObservableList) {
4020 _upgradeObservableList(v, owner); 4032 _upgradeObservableList(v, owner);
4021 } else if (v is ObservableMap) { 4033 } else if (v is ObservableMap) {
4022 _upgradeObservableMap(v, owner); 4034 _upgradeObservableMap(v, owner);
4023 } 4035 }
4024 } 4036 }
4025 } 4037 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/script_inset.dart ('k') | runtime/observatory/tests/service/debugger_location_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698