| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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 dart.core; | 5 part of dart.core; |
| 6 | 6 |
| 7 /** | 7 /** |
| 8 * Error objects thrown in the case of a program failure. | 8 * Error objects thrown in the case of a program failure. |
| 9 * | 9 * |
| 10 * An `Error` object represents a program failure that the programmer | 10 * An `Error` object represents a program failure that the programmer |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 * | 150 * |
| 151 * "Invalid argument (foo): null" | 151 * "Invalid argument (foo): null" |
| 152 * | 152 * |
| 153 * The `name` should match the argument name of the function, but if | 153 * The `name` should match the argument name of the function, but if |
| 154 * the function is a method implementing an interface, and its argument | 154 * the function is a method implementing an interface, and its argument |
| 155 * names differ from the interface, it might be more useful to use the | 155 * names differ from the interface, it might be more useful to use the |
| 156 * interface method's argument name (or just rename arguments to match). | 156 * interface method's argument name (or just rename arguments to match). |
| 157 */ | 157 */ |
| 158 ArgumentError.value(value, | 158 ArgumentError.value(value, |
| 159 [String this.name, | 159 [String this.name, |
| 160 String this.message = "Invalid argument"]) | 160 String this.message]) |
| 161 : invalidValue = value, | 161 : invalidValue = value, |
| 162 _hasValue = true; | 162 _hasValue = true; |
| 163 | 163 |
| 164 /** | 164 /** |
| 165 * Create an argument error for a `null` argument that must not be `null`. | 165 * Create an argument error for a `null` argument that must not be `null`. |
| 166 * | |
| 167 * Shorthand for calling [ArgumentError.value] with a `null` value and a | |
| 168 * message of `"Must not be null"`. | |
| 169 */ | 166 */ |
| 170 ArgumentError.notNull([String name]) | 167 ArgumentError.notNull([this.name]) |
| 171 : this.value(null, name, "Must not be null"); | 168 : _hasValue = false, |
| 169 message = "Must not be null", |
| 170 invalidValue = null; |
| 171 |
| 172 // Helper functions for toString overridden in subclasses. |
| 173 String get _errorName => "Invalid argument${!_hasValue ? "(s)" : ""}"; |
| 174 String get _errorExplanation => ""; |
| 172 | 175 |
| 173 String toString() { | 176 String toString() { |
| 174 if (!_hasValue) { | |
| 175 var result = "Invalid arguments(s)"; | |
| 176 if (message != null) { | |
| 177 result = "$result: $message"; | |
| 178 } | |
| 179 return result; | |
| 180 } | |
| 181 String nameString = ""; | 177 String nameString = ""; |
| 182 if (name != null) { | 178 if (name != null) { |
| 183 nameString = " ($name)"; | 179 nameString = " ($name)"; |
| 184 } | 180 } |
| 185 return "$message$nameString: ${Error.safeToString(invalidValue)}"; | 181 var message = (this.message == null) ? "" : ": ${this.message}"; |
| 182 String prefix = "$_errorName$nameString$message"; |
| 183 if (!_hasValue) return prefix; |
| 184 // If we know the invalid value, we can try to describe the problem. |
| 185 String explanation = _errorExplanation; |
| 186 String errorValue = Error.safeToString(invalidValue); |
| 187 return "$prefix$explanation: $errorValue"; |
| 186 } | 188 } |
| 187 } | 189 } |
| 188 | 190 |
| 189 /** | 191 /** |
| 190 * Error thrown due to an index being outside a valid range. | 192 * Error thrown due to an index being outside a valid range. |
| 191 */ | 193 */ |
| 192 class RangeError extends ArgumentError { | 194 class RangeError extends ArgumentError { |
| 193 /** The minimum value that [value] is allowed to assume. */ | 195 /** The minimum value that [value] is allowed to assume. */ |
| 194 final num start; | 196 final num start; |
| 195 /** The maximum value that [value] is allowed to assume. */ | 197 /** The maximum value that [value] is allowed to assume. */ |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 | 269 |
| 268 /** | 270 /** |
| 269 * Check that a value is a valid index into an indexable object. | 271 * Check that a value is a valid index into an indexable object. |
| 270 * | 272 * |
| 271 * Throws if [index] is not a valid index into [indexable]. | 273 * Throws if [index] is not a valid index into [indexable]. |
| 272 * | 274 * |
| 273 * An indexable object is one that has a `length` and a and index-operator | 275 * An indexable object is one that has a `length` and a and index-operator |
| 274 * `[]` that accepts an index if `0 <= index < length`. | 276 * `[]` that accepts an index if `0 <= index < length`. |
| 275 * | 277 * |
| 276 * If [length] is provided, it is used as the length of the indexable object, | 278 * If [length] is provided, it is used as the length of the indexable object, |
| 277 * otherwise the length is found as `idexable.length`. | 279 * otherwise the length is found as `indexable.length`. |
| 278 */ | 280 */ |
| 279 static void checkValidIndex(int index, var indexable, | 281 static void checkValidIndex(int index, var indexable, |
| 280 [String name, int length, String message]) { | 282 [String name, int length, String message]) { |
| 281 if (length == null) length = indexable.length; | 283 if (length == null) length = indexable.length; |
| 282 if (index < 0 || index >= length) { | 284 // Comparing with `0` as receiver produces better dart2js type inference. |
| 285 if (0 > index || index >= length) { |
| 283 if (name == null) name = "index"; | 286 if (name == null) name = "index"; |
| 284 throw new RangeError.index(index, indexable, name, message, length); | 287 throw new RangeError.index(index, indexable, name, message, length); |
| 285 } | 288 } |
| 286 } | 289 } |
| 287 | 290 |
| 288 /** | 291 /** |
| 289 * Check that a range represents a slice of an indexable object. | 292 * Check that a range represents a slice of an indexable object. |
| 290 * | 293 * |
| 291 * Throws if the range is not valid for an indexable object with | 294 * Throws if the range is not valid for an indexable object with |
| 292 * the given [length]. | 295 * the given [length]. |
| 293 * A range is valid for an indexable object with a given [length] | 296 * A range is valid for an indexable object with a given [length] |
| 294 * | 297 * |
| 295 * if `0 <= [start] <= [end] <= [length]`. | 298 * if `0 <= [start] <= [end] <= [length]`. |
| 296 * An `end` of `null` is considered equivalent to `length`. | 299 * An `end` of `null` is considered equivalent to `length`. |
| 297 * | 300 * |
| 298 * The [startName] and [endName] defaults to `"start"` and `"end"`, | 301 * The [startName] and [endName] defaults to `"start"` and `"end"`, |
| 299 * respectively. | 302 * respectively. |
| 303 * |
| 304 * Returns the actual `end` value, which is `length` if `end` is `null`, |
| 305 * and `end` otherwise. |
| 300 */ | 306 */ |
| 301 static void checkValidRange(int start, int end, int length, | 307 static int checkValidRange(int start, int end, int length, |
| 302 [String startName, String endName, | 308 [String startName, String endName, |
| 303 String message]) { | 309 String message]) { |
| 304 if (start < 0 || start > length) { | 310 // Comparing with `0` as receiver produces better dart2js type inference. |
| 311 // Ditto `start > end` below. |
| 312 if (0 > start || start > length) { |
| 305 if (startName == null) startName = "start"; | 313 if (startName == null) startName = "start"; |
| 306 throw new RangeError.range(start, 0, length, startName, message); | 314 throw new RangeError.range(start, 0, length, startName, message); |
| 307 } | 315 } |
| 308 if (end != null && (end < start || end > length)) { | 316 if (end != null) { |
| 309 if (endName == null) endName = "end"; | 317 if (start > end || end > length) { |
| 310 throw new RangeError.range(end, start, length, endName, message); | 318 if (endName == null) endName = "end"; |
| 319 throw new RangeError.range(end, start, length, endName, message); |
| 320 } |
| 321 return end; |
| 311 } | 322 } |
| 323 return length; |
| 312 } | 324 } |
| 313 | 325 |
| 314 /** | 326 /** |
| 315 * Check that an integer value isn't negative. | 327 * Check that an integer value isn't negative. |
| 316 * | 328 * |
| 317 * Throws if the value is negative. | 329 * Throws if the value is negative. |
| 318 */ | 330 */ |
| 319 static void checkNotNegative(int value, [String name, String message]) { | 331 static void checkNotNegative(int value, [String name, String message]) { |
| 320 if (value < 0) throw new RangeError.range(value, 0, null, name, message); | 332 if (value < 0) throw new RangeError.range(value, 0, null, name, message); |
| 321 } | 333 } |
| 322 | 334 |
| 323 String toString() { | 335 String get _errorName => "RangeError"; |
| 324 if (!_hasValue) return "RangeError: $message"; | 336 String get _errorExplanation { |
| 325 String value = Error.safeToString(invalidValue); | 337 assert(_hasValue); |
| 326 String explanation = ""; | 338 String explanation = ""; |
| 327 if (start == null) { | 339 if (start == null) { |
| 328 if (end != null) { | 340 if (end != null) { |
| 329 explanation = ": Not less than or equal to $end"; | 341 explanation = ": Not less than or equal to $end"; |
| 330 } | 342 } |
| 331 // If both are null, we don't add a description of the limits. | 343 // If both are null, we don't add a description of the limits. |
| 332 } else if (end == null) { | 344 } else if (end == null) { |
| 333 explanation = ": Not greater than or equal to $start"; | 345 explanation = ": Not greater than or equal to $start"; |
| 334 } else if (end > start) { | 346 } else if (end > start) { |
| 335 explanation = ": Not in range $start..$end, inclusive."; | 347 explanation = ": Not in range $start..$end, inclusive"; |
| 336 } else if (end < start) { | 348 } else if (end < start) { |
| 337 explanation = ": Valid value range is empty"; | 349 explanation = ": Valid value range is empty"; |
| 338 } else { | 350 } else { |
| 339 // end == start. | 351 // end == start. |
| 340 explanation = ": Only valid value is $start"; | 352 explanation = ": Only valid value is $start"; |
| 341 } | 353 } |
| 342 return "RangeError: $message ($value)$explanation"; | 354 return explanation; |
| 343 } | 355 } |
| 344 } | 356 } |
| 345 | 357 |
| 346 /** | 358 /** |
| 347 * A specialized [RangeError] used when an index is not in the range | 359 * A specialized [RangeError] used when an index is not in the range |
| 348 * `0..indexable.length-1`. | 360 * `0..indexable.length-1`. |
| 349 * | 361 * |
| 350 * Also contains the indexable object, its length at the time of the error, | 362 * Also contains the indexable object, its length at the time of the error, |
| 351 * and the invalid index itself. | 363 * and the invalid index itself. |
| 352 */ | 364 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 369 [String name, String message, int length]) | 381 [String name, String message, int length]) |
| 370 : this.indexable = indexable, | 382 : this.indexable = indexable, |
| 371 this.length = (length != null) ? length : indexable.length, | 383 this.length = (length != null) ? length : indexable.length, |
| 372 super.value(invalidValue, name, | 384 super.value(invalidValue, name, |
| 373 (message != null) ? message : "Index out of range"); | 385 (message != null) ? message : "Index out of range"); |
| 374 | 386 |
| 375 // Getters inherited from RangeError. | 387 // Getters inherited from RangeError. |
| 376 int get start => 0; | 388 int get start => 0; |
| 377 int get end => length - 1; | 389 int get end => length - 1; |
| 378 | 390 |
| 379 String toString() { | 391 String get _errorName => "RangeError"; |
| 392 String get _errorExplanation { |
| 380 assert(_hasValue); | 393 assert(_hasValue); |
| 381 String target = Error.safeToString(indexable); | |
| 382 var explanation = "index should be less than $length"; | |
| 383 if (invalidValue < 0) { | 394 if (invalidValue < 0) { |
| 384 explanation = "index must not be negative"; | 395 return ": index must not be negative"; |
| 385 } | 396 } |
| 386 return "RangeError: $message ($target[$invalidValue]): $explanation"; | 397 if (length == 0) { |
| 398 return ": no indices are valid"; |
| 399 } |
| 400 return ": index should be less than $length"; |
| 387 } | 401 } |
| 388 } | 402 } |
| 389 | 403 |
| 390 | 404 |
| 391 /** | 405 /** |
| 392 * Error thrown when control reaches the end of a switch case. | 406 * Error thrown when control reaches the end of a switch case. |
| 393 * | 407 * |
| 394 * The Dart specification requires this error to be thrown when | 408 * The Dart specification requires this error to be thrown when |
| 395 * control reaches the end of a switch case (except the last case | 409 * control reaches the end of a switch case (except the last case |
| 396 * of a switch) without meeting a break or similar end of the control | 410 * of a switch) without meeting a break or similar end of the control |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 * the first time it is read. If evaluating the initializer expression causes | 562 * the first time it is read. If evaluating the initializer expression causes |
| 549 * another read of the variable, this error is thrown. | 563 * another read of the variable, this error is thrown. |
| 550 */ | 564 */ |
| 551 class CyclicInitializationError extends Error { | 565 class CyclicInitializationError extends Error { |
| 552 final String variableName; | 566 final String variableName; |
| 553 CyclicInitializationError([this.variableName]); | 567 CyclicInitializationError([this.variableName]); |
| 554 String toString() => variableName == null | 568 String toString() => variableName == null |
| 555 ? "Reading static variable during its initialization" | 569 ? "Reading static variable during its initialization" |
| 556 : "Reading static variable '$variableName' during its initialization"; | 570 : "Reading static variable '$variableName' during its initialization"; |
| 557 } | 571 } |
| OLD | NEW |