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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/util/util.dart

Issue 208423012: Add helpers library to dart2js. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 library dart2js.util; 5 library dart2js.util;
6 6
7 import "dart:collection";
8 import 'util_implementation.dart'; 7 import 'util_implementation.dart';
9 import 'characters.dart'; 8 import 'characters.dart';
10 9
11 export 'setlet.dart'; 10 export 'setlet.dart';
12 11
13 part 'link.dart'; 12 part 'link.dart';
14 part 'expensive_map.dart';
15 part 'expensive_set.dart';
16 13
17 /** 14 /**
18 * Tagging interface for classes from which source spans can be generated. 15 * Tagging interface for classes from which source spans can be generated.
19 */ 16 */
20 // TODO(johnniwinther): Find a better name. 17 // TODO(johnniwinther): Find a better name.
21 // TODO(ahe): How about "Bolt"? 18 // TODO(ahe): How about "Bolt"?
22 abstract class Spannable {} 19 abstract class Spannable {}
23 20
24 class _SpannableSentinel implements Spannable { 21 class _SpannableSentinel implements Spannable {
25 final String name; 22 final String name;
(...skipping 18 matching lines...) Expand all
44 class SpannableAssertionFailure { 41 class SpannableAssertionFailure {
45 final Spannable node; 42 final Spannable node;
46 final String message; 43 final String message;
47 SpannableAssertionFailure(this.node, this.message); 44 SpannableAssertionFailure(this.node, this.message);
48 45
49 String toString() => 'Assertion failure' 46 String toString() => 'Assertion failure'
50 '${message != null ? ': $message' : ''}'; 47 '${message != null ? ': $message' : ''}';
51 } 48 }
52 49
53 /** 50 /**
54 * Helper method for printing stack traces for debugging.
55 *
56 * [message] is printed as the header of the stack trace.
57 *
58 * If [condition] is provided, the stack trace is only printed if [condition]
59 * returns [:true:] on the stack trace text. This can be used to filter the
60 * printed stack traces based on their content. For instance only print stack
61 * traces that contain specific paths.
62 */
63 void trace(String message, [bool condition(String stackTrace)]) {
64 try {
65 throw '';
66 } catch (e, s) {
67 String stackTrace = prettifyStackTrace(
68 s, rangeStart: 1, filePrefix: stackTraceFilePrefix);
69 if (condition != null) {
70 if (!condition(stackTrace)) return;
71 }
72 print('$message\n$stackTrace');
73 }
74 }
75
76 /**
77 * File name prefix used to shorten the file name in stack traces printed by 51 * File name prefix used to shorten the file name in stack traces printed by
78 * [trace]. 52 * [trace].
79 */ 53 */
80 String stackTraceFilePrefix = null; 54 String stackTraceFilePrefix = null;
81 55
82 /// Helper class for the processing of stack traces in [prettifyStackTrace].
83 class _StackTraceLine {
84 final int index;
85 final String file;
86 final String lineNo;
87 final String columnNo;
88 final String method;
89
90 _StackTraceLine(this.index, this.file, this.lineNo,
91 this.columnNo, this.method);
92
93 String toString() {
94 return 'index=$index, file=$file, '
95 'lineNo=$lineNo, columnNo=$columnNo, method=$method';
96 }
97 }
98
99 // TODO(johnniwinther): Use this format for --throw-on-error.
100 /**
101 * Converts the normal VM stack trace into a more compact and readable format.
102 *
103 * The output format is [: <file> . . . <lineNo>:<columnNo> <method> :] where
104 * [: <file> :] is file name, [: <lineNo> :] is the line number,
105 * [: <columnNo> :] is the column number, and [: <method> :] is the method name.
106 *
107 * If [rangeStart] and/or [rangeEnd] are provided, only the lines within the
108 * range are included.
109 * If [showColumnNo] is [:false:], the [: :<columnNo> :] part is omitted.
110 * If [showDots] is [:true:], the space between [: <file> :] and [: <lineNo> :]
111 * is padded with dots on every other line.
112 * If [filePrefix] is provided, then for every file name thats starts with
113 * [filePrefix] only the remainder is printed.
114 * If [lambda] is non-null, anonymous closures are printed as [lambda].
115 */
116 String prettifyStackTrace(StackTrace s,
117 {int rangeStart,
118 int rangeEnd,
119 bool showColumnNo: false,
120 bool showDots: true,
121 String filePrefix,
122 String lambda: r'?'}) {
123 int index = -1;
124 int maxFileLength = 0;
125 int maxLineNoLength = 0;
126 int maxColumnNoLength = 0;
127
128 String stackTrace = '$s';
129 List<_StackTraceLine> lines = <_StackTraceLine>[];
130 for (String line in stackTrace.split('\n')) {
131 try {
132 index++;
133 if (rangeStart != null && index < rangeStart) continue;
134 if (rangeEnd != null && index > rangeEnd) continue;
135 if (line.isEmpty) continue;
136
137 // Strip index.
138 line = line.replaceFirst(new RegExp(r'#\d+\s*'), '');
139
140 int leftParenPos = line.indexOf('(');
141 int rightParenPos = line.indexOf(')', leftParenPos);
142 int lastColon = line.lastIndexOf(':', rightParenPos);
143 int nextToLastColon = line.lastIndexOf(':', lastColon-1);
144
145 String lineNo;
146 String columnNo;
147 if (nextToLastColon != -1) {
148 lineNo = line.substring(nextToLastColon+1, lastColon);
149 columnNo = line.substring(lastColon+1, rightParenPos);
150 try {
151 int.parse(lineNo);
152 } on FormatException catch (e) {
153 lineNo = columnNo;
154 columnNo = '';
155 nextToLastColon = lastColon;
156 }
157 } else {
158 lineNo = line.substring(lastColon+1, rightParenPos);
159 columnNo = '';
160 nextToLastColon = lastColon;
161 }
162
163 if (lineNo.length > maxLineNoLength) {
164 maxLineNoLength = lineNo.length;
165 }
166 if (columnNo.length > maxColumnNoLength) {
167 maxColumnNoLength = columnNo.length;
168 }
169
170 String file = line.substring(leftParenPos+1, nextToLastColon);
171 if (filePrefix != null && file.startsWith(filePrefix)) {
172 file = file.substring(filePrefix.length);
173 }
174 if (file.length > maxFileLength) {
175 maxFileLength = file.length;
176 }
177 String method = line.substring(0, leftParenPos-1);
178 if (lambda != null) {
179 method = method.replaceAll('<anonymous closure>', lambda);
180 }
181 lines.add(new _StackTraceLine(index, file, lineNo, columnNo, method));
182 } catch (e) {
183 print('Error prettifying "$line": $e');
184 return stackTrace;
185 }
186 }
187
188 StringBuffer sb = new StringBuffer();
189 bool dots = true;
190 for (_StackTraceLine line in lines) {
191 String file = pad('${line.file} ', maxFileLength,
192 dots: showDots && dots ? ' .' : ' ');
193 String lineNo = pad(line.lineNo, maxLineNoLength, padLeft: true);
194 String columnNo =
195 showColumnNo ? ':${pad(line.columnNo, maxColumnNoLength)}' : '';
196 String method = line.method;
197 sb.write(' $file $lineNo$columnNo $method\n');
198 dots = !dots;
199 }
200 return sb.toString();
201 }
202
203 /**
204 * Pads (or truncates) [text] to the [intendedLength].
205 *
206 * If [padLeft] is [:true:] the text is padding inserted to the left of [text].
207 * A repetition of the [dots] text is used for padding.
208 */
209 String pad(String text, int intendedLength,
210 {bool padLeft: false, String dots: ' '}) {
211 if (text.length == intendedLength) return text;
212 if (text.length > intendedLength) return text.substring(0, intendedLength);
213 if (dots == null || dots.isEmpty) dots = ' ';
214 int dotsLength = dots.length;
215 StringBuffer sb = new StringBuffer();
216 if (!padLeft) {
217 sb.write(text);
218 }
219 for (int index = text.length ; index < intendedLength ; index ++) {
220 int dotsIndex = index % dotsLength;
221 sb.write(dots.substring(dotsIndex, dotsIndex + 1));
222 }
223 if (padLeft) {
224 sb.write(text);
225 }
226 return sb.toString();
227 }
228
229 /// Writes the characters of [string] on [buffer]. The characters 56 /// Writes the characters of [string] on [buffer]. The characters
230 /// are escaped as suitable for JavaScript and JSON. [buffer] is 57 /// are escaped as suitable for JavaScript and JSON. [buffer] is
231 /// anything which supports [:write:] and [:writeCharCode:], for example, 58 /// anything which supports [:write:] and [:writeCharCode:], for example,
232 /// [StringBuffer]. Note that JS supports \xnn and \unnnn whereas JSON only 59 /// [StringBuffer]. Note that JS supports \xnn and \unnnn whereas JSON only
233 /// supports the \unnnn notation. Therefore we use the \unnnn notation. 60 /// supports the \unnnn notation. Therefore we use the \unnnn notation.
234 void writeJsonEscapedCharsOn(String string, buffer) { 61 void writeJsonEscapedCharsOn(String string, buffer) {
235 void addCodeUnitEscaped(var buffer, int code) { 62 void addCodeUnitEscaped(var buffer, int code) {
236 assert(code < 0x10000); 63 assert(code < 0x10000);
237 buffer.write(r'\u'); 64 buffer.write(r'\u');
238 if (code < 0x1000) { 65 if (code < 0x1000) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 buffer.write(string); 126 buffer.write(string);
300 } 127 }
301 128
302 int computeHashCode(part1, [part2, part3, part4, part5]) { 129 int computeHashCode(part1, [part2, part3, part4, part5]) {
303 return (part1.hashCode 130 return (part1.hashCode
304 ^ part2.hashCode 131 ^ part2.hashCode
305 ^ part3.hashCode 132 ^ part3.hashCode
306 ^ part4.hashCode 133 ^ part4.hashCode
307 ^ part5.hashCode) & 0x3fffffff; 134 ^ part5.hashCode) & 0x3fffffff;
308 } 135 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698