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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/lib/core/errors.dart

Issue 2698353003: unfork DDC's copy of most SDK libraries (Closed)
Patch Set: revert core_patch Created 3 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
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 part of dart.core;
6
7 /**
8 * Error objects thrown in the case of a program failure.
9 *
10 * An `Error` object represents a program failure that the programmer
11 * should have avoided.
12 *
13 * Examples include calling a function with invalid arguments,
14 * or even with the wrong number of arguments,
15 * or calling it at a time when it is not allowed.
16 *
17 * These are not errors that a caller should expect or catch -
18 * if they occur, the program is erroneous,
19 * and terminating the program may be the safest response.
20 *
21 * When deciding that a function throws an error,
22 * the conditions where it happens should be clearly described,
23 * and they should be detectable and predictable,
24 * so the programmer using the function can avoid triggering the error.
25 *
26 * Such descriptions often uses words like
27 * "must" or "must not" to describe the condition,
28 * and if you see words like that in a function's documentation,
29 * then not satisfying the requirement
30 * is very likely to cause an error to be thrown.
31 *
32 * Example (from [String.contains]):
33 *
34 * `startIndex` must not be negative or greater than `length`.
35 *
36 * In this case, an error will be thrown if `startIndex` is negative
37 * or too large.
38 *
39 * If the conditions are not detectable before calling a function,
40 * the called function should not throw an `Error`.
41 * It may still throw a value,
42 * but the caller will have to catch the thrown value,
43 * effectively making it an alternative result rather than an error.
44 * The thrown object can choose to implement [Exception]
45 * to document that it represents an exceptional, but not erroneous, occurrence,
46 * but it has no other effect than documentation.
47 *
48 * All non-`null` values can be thrown in Dart.
49 * Objects extending `Error` are handled specially:
50 * The first time they are thrown,
51 * the stack trace at the throw point is recorded
52 * and stored in the error object.
53 * It can be retrieved using the [stackTrace] getter.
54 * An error object that merely implements `Error`, and doesn't extend it,
55 * will not store the stack trace automatically.
56 *
57 * Error objects are also used for system wide failures
58 * like stack overflow or an out-of-memory situation.
59 *
60 * Since errors are not created to be caught,
61 * there is no need for subclasses to distinguish the errors.
62 * Instead subclasses have been created in order to make groups
63 * of related errors easy to create with consistent error messages.
64 * For example, the [String.contains] method will use a [RangeError]
65 * if its `startIndex` isn't in the range `0..length`,
66 * which is easily created by `new RangeError.range(startIndex, 0, length)`.
67 */
68 class Error {
69 Error(); // Prevent use as mixin.
70
71 /**
72 * Safely convert a value to a [String] description.
73 *
74 * The conversion is guaranteed to not throw, so it won't use the object's
75 * toString method.
76 */
77 static String safeToString(Object object) {
78 if (object is num || object is bool || null == object) {
79 return object.toString();
80 }
81 if (object is String) {
82 return _stringToSafeString(object);
83 }
84 return _objectToString(object);
85 }
86
87 /** Convert string to a valid string literal with no control characters. */
88 external static String _stringToSafeString(String string);
89
90 external static String _objectToString(Object object);
91
92 external StackTrace get stackTrace;
93 }
94
95 /**
96 * Error thrown by the runtime system when an assert statement fails.
97 */
98 class AssertionError extends Error {
99 AssertionError();
100 String toString() => "Assertion failed";
101 }
102
103 /**
104 * Error thrown by the runtime system when a type assertion fails.
105 */
106 class TypeError extends AssertionError {
107 }
108
109 /**
110 * Error thrown by the runtime system when a cast operation fails.
111 */
112 class CastError extends Error {
113 }
114
115 /**
116 * Error thrown when attempting to throw [:null:].
117 */
118 class NullThrownError extends Error {
119 String toString() => "Throw of null.";
120 }
121
122 /**
123 * Error thrown when a function is passed an unacceptable argument.
124 */
125 class ArgumentError extends Error {
126 /** Whether value was provided. */
127 final bool _hasValue;
128 /** The invalid value. */
129 final invalidValue;
130 /** Name of the invalid argument, if available. */
131 final String name;
132 /** Message describing the problem. */
133 final message;
134
135 /**
136 * The [message] describes the erroneous argument.
137 *
138 * Existing code may be using `message` to hold the invalid value.
139 * If the `message` is not a [String], it is assumed to be a value instead
140 * of a message.
141 */
142 ArgumentError([this.message])
143 : invalidValue = null,
144 _hasValue = false,
145 name = null;
146
147 /**
148 * Creates error containing the invalid [value].
149 *
150 * A message is built by suffixing the [message] argument with
151 * the [name] argument (if provided) and the value. Example
152 *
153 * "Invalid argument (foo): null"
154 *
155 * The `name` should match the argument name of the function, but if
156 * the function is a method implementing an interface, and its argument
157 * names differ from the interface, it might be more useful to use the
158 * interface method's argument name (or just rename arguments to match).
159 */
160 ArgumentError.value(value,
161 [String this.name,
162 String this.message])
163 : invalidValue = value,
164 _hasValue = true;
165
166 /**
167 * Create an argument error for a `null` argument that must not be `null`.
168 */
169 ArgumentError.notNull([this.name])
170 : _hasValue = false,
171 message = "Must not be null",
172 invalidValue = null;
173
174 // Helper functions for toString overridden in subclasses.
175 String get _errorName => "Invalid argument${!_hasValue ? "(s)" : ""}";
176 String get _errorExplanation => "";
177
178 String toString() {
179 String nameString = "";
180 if (name != null) {
181 nameString = " ($name)";
182 }
183 var message = (this.message == null) ? "" : ": ${this.message}";
184 String prefix = "$_errorName$nameString$message";
185 if (!_hasValue) return prefix;
186 // If we know the invalid value, we can try to describe the problem.
187 String explanation = _errorExplanation;
188 String errorValue = Error.safeToString(invalidValue);
189 return "$prefix$explanation: $errorValue";
190 }
191 }
192
193 /**
194 * Error thrown due to an index being outside a valid range.
195 */
196 class RangeError extends ArgumentError {
197 /** The minimum value that [value] is allowed to assume. */
198 final num start;
199 /** The maximum value that [value] is allowed to assume. */
200 final num end;
201
202 // TODO(lrn): This constructor should be called only with string values.
203 // It currently isn't in all cases.
204 /**
205 * Create a new [RangeError] with the given [message].
206 */
207 RangeError(var message)
208 : start = null, end = null, super(message);
209
210 /**
211 * Create a new [RangeError] with a message for the given [value].
212 *
213 * An optional [name] can specify the argument name that has the
214 * invalid value, and the [message] can override the default error
215 * description.
216 */
217 RangeError.value(num value, [String name, String message])
218 : start = null, end = null,
219 super.value(value, name,
220 (message != null) ? message : "Value not in range");
221
222 /**
223 * Create a new [RangeError] with for an invalid value being outside a range.
224 *
225 * The allowed range is from [minValue] to [maxValue], inclusive.
226 * If `minValue` or `maxValue` are `null`, the range is infinite in
227 * that direction.
228 *
229 * For a range from 0 to the length of something, end exclusive, use
230 * [RangeError.index].
231 *
232 * An optional [name] can specify the argument name that has the
233 * invalid value, and the [message] can override the default error
234 * description.
235 */
236 RangeError.range(num invalidValue, int minValue, int maxValue,
237 [String name, String message])
238 : start = minValue,
239 end = maxValue,
240 super.value(invalidValue, name,
241 (message != null) ? message : "Invalid value");
242
243 /**
244 * Creates a new [RangeError] stating that [index] is not a valid index
245 * into [indexable].
246 *
247 * An optional [name] can specify the argument name that has the
248 * invalid value, and the [message] can override the default error
249 * description.
250 *
251 * The [length] is the length of [indexable] at the time of the error.
252 * If `length` is omitted, it defaults to `indexable.length`.
253 */
254 factory RangeError.index(int index, indexable,
255 [String name,
256 String message,
257 int length]) = IndexError;
258
259 /**
260 * Check that a [value] lies in a specific interval.
261 *
262 * Throws if [value] is not in the interval.
263 * The interval is from [minValue] to [maxValue], both inclusive.
264 */
265 static void checkValueInInterval(int value, int minValue, int maxValue,
266 [String name, String message]) {
267 if (value < minValue || value > maxValue) {
268 throw new RangeError.range(value, minValue, maxValue, name, message);
269 }
270 }
271
272 /**
273 * Check that a value is a valid index into an indexable object.
274 *
275 * Throws if [index] is not a valid index into [indexable].
276 *
277 * An indexable object is one that has a `length` and a and index-operator
278 * `[]` that accepts an index if `0 <= index < length`.
279 *
280 * If [length] is provided, it is used as the length of the indexable object,
281 * otherwise the length is found as `indexable.length`.
282 */
283 static void checkValidIndex(int index, var indexable,
284 [String name, int length, String message]) {
285 if (length == null) length = indexable.length;
286 // Comparing with `0` as receiver produces better dart2js type inference.
287 if (0 > index || index >= length) {
288 if (name == null) name = "index";
289 throw new RangeError.index(index, indexable, name, message, length);
290 }
291 }
292
293 /**
294 * Check that a range represents a slice of an indexable object.
295 *
296 * Throws if the range is not valid for an indexable object with
297 * the given [length].
298 * A range is valid for an indexable object with a given [length]
299 *
300 * if `0 <= [start] <= [end] <= [length]`.
301 * An `end` of `null` is considered equivalent to `length`.
302 *
303 * The [startName] and [endName] defaults to `"start"` and `"end"`,
304 * respectively.
305 *
306 * Returns the actual `end` value, which is `length` if `end` is `null`,
307 * and `end` otherwise.
308 */
309 static int checkValidRange(int start, int end, int length,
310 [String startName, String endName,
311 String message]) {
312 // Comparing with `0` as receiver produces better dart2js type inference.
313 // Ditto `start > end` below.
314 if (0 > start || start > length) {
315 if (startName == null) startName = "start";
316 throw new RangeError.range(start, 0, length, startName, message);
317 }
318 if (end != null) {
319 if (start > end || end > length) {
320 if (endName == null) endName = "end";
321 throw new RangeError.range(end, start, length, endName, message);
322 }
323 return end;
324 }
325 return length;
326 }
327
328 /**
329 * Check that an integer value isn't negative.
330 *
331 * Throws if the value is negative.
332 */
333 static void checkNotNegative(int value, [String name, String message]) {
334 if (value < 0) throw new RangeError.range(value, 0, null, name, message);
335 }
336
337 String get _errorName => "RangeError";
338 String get _errorExplanation {
339 assert(_hasValue);
340 String explanation = "";
341 if (start == null) {
342 if (end != null) {
343 explanation = ": Not less than or equal to $end";
344 }
345 // If both are null, we don't add a description of the limits.
346 } else if (end == null) {
347 explanation = ": Not greater than or equal to $start";
348 } else if (end > start) {
349 explanation = ": Not in range $start..$end, inclusive";
350 } else if (end < start) {
351 explanation = ": Valid value range is empty";
352 } else {
353 // end == start.
354 explanation = ": Only valid value is $start";
355 }
356 return explanation;
357 }
358 }
359
360 /**
361 * A specialized [RangeError] used when an index is not in the range
362 * `0..indexable.length-1`.
363 *
364 * Also contains the indexable object, its length at the time of the error,
365 * and the invalid index itself.
366 */
367 class IndexError extends ArgumentError implements RangeError {
368 /** The indexable object that [index] was not a valid index into. */
369 final indexable;
370 /** The length of [indexable] at the time of the error. */
371 final int length;
372
373 /**
374 * Creates a new [IndexError] stating that [invalidValue] is not a valid index
375 * into [indexable].
376 *
377 * The [length] is the length of [indexable] at the time of the error.
378 * If `length` is omitted, it defaults to `indexable.length`.
379 *
380 * The message is used as part of the string representation of the error.
381 */
382 IndexError(int invalidValue, indexable,
383 [String name, String message, int length])
384 : this.indexable = indexable,
385 this.length = (length != null) ? length : indexable.length,
386 super.value(invalidValue, name,
387 (message != null) ? message : "Index out of range");
388
389 // Getters inherited from RangeError.
390 int get start => 0;
391 int get end => length - 1;
392
393 String get _errorName => "RangeError";
394 String get _errorExplanation {
395 assert(_hasValue);
396 if (invalidValue < 0) {
397 return ": index must not be negative";
398 }
399 if (length == 0) {
400 return ": no indices are valid";
401 }
402 return ": index should be less than $length";
403 }
404 }
405
406
407 /**
408 * Error thrown when control reaches the end of a switch case.
409 *
410 * The Dart specification requires this error to be thrown when
411 * control reaches the end of a switch case (except the last case
412 * of a switch) without meeting a break or similar end of the control
413 * flow.
414 */
415 class FallThroughError extends Error {
416 FallThroughError();
417 }
418
419 /**
420 * Error thrown when trying to instantiate an abstract class.
421 */
422 class AbstractClassInstantiationError extends Error {
423 final String _className;
424 AbstractClassInstantiationError(String this._className);
425 String toString() => "Cannot instantiate abstract class: '$_className'";
426 }
427
428
429 /**
430 * Error thrown by the default implementation of [:noSuchMethod:] on [Object].
431 */
432 class NoSuchMethodError extends Error {
433 final Object _receiver;
434 final Symbol _memberName;
435 final List _arguments;
436 final Map<Symbol, dynamic> _namedArguments;
437 final List _existingArgumentNames;
438
439 /**
440 * Create a [NoSuchMethodError] corresponding to a failed method call.
441 *
442 * The [receiver] is the receiver of the method call.
443 * That is, the object on which the method was attempted called.
444 * If the receiver is `null`, it is interpreted as a call to a top-level
445 * function of a library.
446 *
447 * The [memberName] is a [Symbol] representing the name of the called method
448 * or accessor. It should not be `null`.
449 *
450 * The [positionalArguments] is a list of the positional arguments that the
451 * method was called with. If `null`, it is considered equivalent to the
452 * empty list.
453 *
454 * The [namedArguments] is a map from [Symbol]s to the values of named
455 * arguments that the method was called with.
456 *
457 * The optional [existingArgumentNames] is the expected parameters of a
458 * method with the same name on the receiver, if available. This is
459 * the signature of the method that would have been called if the parameters
460 * had matched.
461 */
462 NoSuchMethodError(Object receiver,
463 Symbol memberName,
464 List positionalArguments,
465 Map<Symbol ,dynamic> namedArguments,
466 [List existingArgumentNames = null])
467 : _receiver = receiver,
468 _memberName = memberName,
469 _arguments = positionalArguments,
470 _namedArguments = namedArguments,
471 _existingArgumentNames = existingArgumentNames;
472
473 external String toString();
474 }
475
476
477 /**
478 * The operation was not allowed by the object.
479 *
480 * This [Error] is thrown when an instance cannot implement one of the methods
481 * in its signature.
482 */
483 class UnsupportedError extends Error {
484 final String message;
485 UnsupportedError(this.message);
486 String toString() => "Unsupported operation: $message";
487 }
488
489
490 /**
491 * Thrown by operations that have not been implemented yet.
492 *
493 * This [Error] is thrown by unfinished code that hasn't yet implemented
494 * all the features it needs.
495 *
496 * If a class is not intending to implement the feature, it should throw
497 * an [UnsupportedError] instead. This error is only intended for
498 * use during development.
499 */
500 class UnimplementedError extends Error implements UnsupportedError {
501 final String message;
502 UnimplementedError([String this.message]);
503 String toString() => (this.message != null
504 ? "UnimplementedError: $message"
505 : "UnimplementedError");
506 }
507
508
509 /**
510 * The operation was not allowed by the current state of the object.
511 *
512 * This is a generic error used for a variety of different erroneous
513 * actions. The message should be descriptive.
514 */
515 class StateError extends Error {
516 final String message;
517 StateError(this.message);
518 String toString() => "Bad state: $message";
519 }
520
521
522 /**
523 * Error occurring when a collection is modified during iteration.
524 *
525 * Some modifications may be allowed for some collections, so each collection
526 * ([Iterable] or similar collection of values) should declare which operations
527 * are allowed during an iteration.
528 */
529 class ConcurrentModificationError extends Error {
530 /** The object that was modified in an incompatible way. */
531 final Object modifiedObject;
532
533 ConcurrentModificationError([this.modifiedObject]);
534
535 String toString() {
536 if (modifiedObject == null) {
537 return "Concurrent modification during iteration.";
538 }
539 return "Concurrent modification during iteration: "
540 "${Error.safeToString(modifiedObject)}.";
541 }
542 }
543
544
545 class OutOfMemoryError implements Error {
546 const OutOfMemoryError();
547 String toString() => "Out of Memory";
548
549 StackTrace get stackTrace => null;
550 }
551
552
553 class StackOverflowError implements Error {
554 const StackOverflowError();
555 String toString() => "Stack Overflow";
556
557 StackTrace get stackTrace => null;
558 }
559
560 /**
561 * Error thrown when a lazily initialized variable cannot be initialized.
562 *
563 * A static/library variable with an initializer expression is initialized
564 * the first time it is read. If evaluating the initializer expression causes
565 * another read of the variable, this error is thrown.
566 */
567 class CyclicInitializationError extends Error {
568 final String variableName;
569 CyclicInitializationError([this.variableName]);
570 String toString() => variableName == null
571 ? "Reading static variable during its initialization"
572 : "Reading static variable '$variableName' during its initialization";
573 }
OLDNEW
« no previous file with comments | « pkg/dev_compiler/tool/input_sdk/lib/core/duration.dart ('k') | pkg/dev_compiler/tool/input_sdk/lib/core/exceptions.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698