Chromium Code Reviews| 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 // 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 Loading... | |
| 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 Loading... | |
| 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); | |
|
Cutch
2016/01/15 21:06:02
You're dropping the catch block is that intentiona
turnidge
2016/01/15 22:41:39
Yes.
| |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |