| // Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| part of 'core_patch.dart'; |
| |
| @patch |
| class Error { |
| @patch |
| static String _objectToString(Object object) => Object._toString(object); |
| |
| @patch |
| static String _stringToSafeString(String string) { |
| return jsonEncode(string); |
| } |
| |
| @pragma('wasm:entry-point') |
| static Never _throwWithCurrentStackTrace(Object object) => |
| Error._throw(object, StackTrace.current); |
| |
| @patch |
| StackTrace? get stackTrace => _stackTrace; |
| |
| @pragma("wasm:entry-point") |
| StackTrace? _stackTrace; |
| |
| @pragma("wasm:entry-point") |
| static void _trySetStackTrace(Object object, StackTrace stackTrace) { |
| // Guard against implementors of [Error] that do not have the stack trace |
| // field by ensuring the error object is a direct/indirect subclass. |
| if (isSubClassOf<Error>(object)) { |
| final error = unsafeCast<Error>(object); |
| error._stackTrace ??= stackTrace; |
| } |
| } |
| |
| @patch |
| @pragma("wasm:intrinsic") |
| external static Never _throw(Object object, StackTrace stackTrace); |
| } |
| |
| class _Error extends Error { |
| final String _message; |
| |
| _Error(this._message); |
| |
| @override |
| String toString() => _message; |
| } |
| |
| // This error is emitted when we catch an opaque object that was thrown from |
| // JavaScript |
| @pragma("wasm:entry-point") |
| class _JavaScriptError extends Error { |
| _JavaScriptError(); |
| |
| @pragma("wasm:entry-point") |
| factory _JavaScriptError._() => _JavaScriptError(); |
| |
| @override |
| String toString() => "JavaScriptError"; |
| } |
| |
| class _TypeError extends _Error implements TypeError { |
| _TypeError(String message) : super(message); |
| |
| factory _TypeError.fromMessageAndStackTrace( |
| String message, |
| StackTrace stackTrace, |
| ) { |
| final typeError = _TypeError(message); |
| typeError._stackTrace = stackTrace; |
| return typeError; |
| } |
| |
| @pragma("wasm:entry-point") |
| @pragma("wasm:never-inline") |
| static Never _throwNullCheckErrorWithCurrentStack() { |
| final stackTrace = StackTrace.current; |
| final typeError = _TypeError.fromMessageAndStackTrace( |
| "Null check operator used on a null value", |
| stackTrace, |
| ); |
| return Error._throw(typeError, stackTrace); |
| } |
| |
| @pragma("wasm:entry-point") |
| static Never _throwAsCheckError(Object? operand, Type? type) { |
| final stackTrace = StackTrace.current; |
| final typeError = _TypeError.fromMessageAndStackTrace( |
| "Type '${operand.runtimeType}' is not a subtype of type '$type'" |
| " in type cast", |
| stackTrace, |
| ); |
| return Error._throw(typeError, stackTrace); |
| } |
| |
| @pragma("wasm:entry-point") |
| static Never _throwWasmRefError(String expected, StackTrace stackTrace) { |
| final typeError = _TypeError.fromMessageAndStackTrace( |
| "The Wasm reference is not $expected", |
| stackTrace, |
| ); |
| return Error._throw(typeError, stackTrace); |
| } |
| |
| @pragma("wasm:entry-point") |
| static Never _throwArgumentTypeCheckError( |
| Object? arg, |
| _Type param, |
| String paramName, |
| StackTrace stackTrace, |
| ) { |
| final typeError = _TypeError.fromMessageAndStackTrace( |
| "type '${arg.runtimeType}' is not a subtype of " |
| "type '$param' of '$paramName'", |
| stackTrace, |
| ); |
| return Error._throw(typeError, stackTrace); |
| } |
| |
| @pragma("wasm:entry-point") |
| static Never _throwTypeArgumentBoundCheckError( |
| _Type param, |
| _Type bound, |
| String paramName, |
| StackTrace stackTrace, |
| ) { |
| final typeError = _TypeError.fromMessageAndStackTrace( |
| "type '$param' is not a subtype of type '$bound' of '$paramName'", |
| stackTrace, |
| ); |
| return Error._throw(typeError, stackTrace); |
| } |
| } |
| |
| @patch |
| class NoSuchMethodError { |
| final Object? _receiver; |
| final Symbol _memberName; |
| final List? _arguments; |
| final Map<Symbol, dynamic>? _namedArguments; |
| final List? _existingArgumentNames; |
| |
| @patch |
| factory NoSuchMethodError.withInvocation( |
| Object? receiver, |
| Invocation invocation, |
| ) => NoSuchMethodError( |
| receiver, |
| invocation.memberName, |
| invocation.positionalArguments, |
| invocation.namedArguments, |
| ); |
| |
| NoSuchMethodError( |
| Object? receiver, |
| Symbol memberName, |
| List? positionalArguments, |
| Map<Symbol, dynamic>? namedArguments, [ |
| List? existingArgumentNames = null, |
| ]) : _receiver = receiver, |
| _memberName = memberName, |
| _arguments = positionalArguments, |
| _namedArguments = namedArguments, |
| _existingArgumentNames = existingArgumentNames; |
| |
| @pragma("wasm:entry-point") |
| static Never _throwWithInvocation(Object? receiver, Invocation invocation) { |
| throw NoSuchMethodError.withInvocation(receiver, invocation); |
| } |
| |
| @pragma("wasm:entry-point") |
| static Never _throwUnimplementedExternalMemberError( |
| Object? receiver, |
| Symbol memberName, |
| ) { |
| throw NoSuchMethodError(receiver, memberName, null, null); |
| } |
| |
| @patch |
| String toString() { |
| StringBuffer sb = StringBuffer(''); |
| String comma = ''; |
| List? arguments = _arguments; |
| if (arguments != null) { |
| for (var argument in arguments) { |
| sb.write(comma); |
| sb.write(Error.safeToString(argument)); |
| comma = ', '; |
| } |
| } |
| Map<Symbol, dynamic>? namedArguments = _namedArguments; |
| if (namedArguments != null) { |
| namedArguments.forEach((Symbol key, var value) { |
| sb.write(comma); |
| sb.write(_symbolToString(key)); |
| sb.write(": "); |
| sb.write(Error.safeToString(value)); |
| comma = ', '; |
| }); |
| } |
| String memberName = _symbolToString(_memberName); |
| String receiverText = Error.safeToString(_receiver); |
| String actualParameters = '$sb'; |
| List? existingArgumentNames = _existingArgumentNames; |
| if (existingArgumentNames == null) { |
| return "NoSuchMethodError: method not found: '$memberName'\n" |
| "Receiver: ${receiverText}\n" |
| "Arguments: [$actualParameters]"; |
| } else { |
| String formalParameters = existingArgumentNames.join(', '); |
| return "NoSuchMethodError: incorrect number of arguments passed to " |
| "method named '$memberName'\n" |
| "Receiver: ${receiverText}\n" |
| "Tried calling: $memberName($actualParameters)\n" |
| "Found: $memberName($formalParameters)"; |
| } |
| } |
| } |
| |
| class _AssertionErrorImpl extends AssertionError { |
| _AssertionErrorImpl( |
| Object? message, |
| this._fileUri, |
| this._line, |
| this._column, |
| this._conditionSource, |
| ) : super(message); |
| |
| final String? _fileUri; |
| final int _line; |
| final int _column; |
| final String? _conditionSource; |
| |
| String toString() { |
| var failureMessage = ""; |
| if (_fileUri != null && _conditionSource != null) { |
| failureMessage += "$_fileUri:${_line}:${_column}\n$_conditionSource\n"; |
| } |
| failureMessage += message != null |
| ? Error.safeToString(message) |
| : "is not true"; |
| |
| return "Assertion failed: $failureMessage"; |
| } |
| } |
| |
| @patch |
| class AssertionError { |
| @pragma("wasm:entry-point") |
| static Never _throwWithMessage( |
| Object? message, |
| String? fileUri, |
| int line, |
| int column, |
| String? conditionSource, |
| ) { |
| throw _AssertionErrorImpl(message, fileUri, line, column, conditionSource); |
| } |
| } |
| |
| /// Used by Fasta to report a runtime error when a final field with an |
| /// initializer is also initialized in a generative constructor. |
| /// |
| /// Note: In strong mode, this is a compile-time error, but the CFE still needs |
| /// this class to exist in `dart:core`. |
| class _DuplicatedFieldInitializerError extends Error { |
| final String _name; |
| |
| _DuplicatedFieldInitializerError(this._name); |
| |
| toString() => "Error: field '$_name' is already initialized."; |
| } |
| |
| @patch |
| class StateError { |
| static _throwNew(String msg) { |
| throw StateError(msg); |
| } |
| } |
| |
| // Implementations needed to implement the `_stackTrace` member added |
| // in the @patch class of [Error]. |
| |
| @patch |
| class OutOfMemoryError { |
| StackTrace? get _stackTrace => |
| throw UnsupportedError('OutOfMemoryError._stackTrace'); |
| void set _stackTrace(StackTrace? _) { |
| throw UnsupportedError('OutOfMemoryError._stackTrace'); |
| } |
| } |
| |
| @patch |
| class StackOverflowError { |
| StackTrace? get _stackTrace => |
| throw UnsupportedError('StackOverflowError._stackTrace'); |
| void set _stackTrace(StackTrace? _) { |
| throw UnsupportedError('StackOverflowError._stackTrace'); |
| } |
| } |
| |
| @patch |
| class IntegerDivisionByZeroException { |
| StackTrace? get _stackTrace => |
| throw UnsupportedError('IntegerDivisionByZeroException._stackTrace'); |
| void set _stackTrace(StackTrace? _) { |
| throw UnsupportedError('IntegerDivisionByZeroException._stackTrace'); |
| } |
| } |