blob: b542b7a19ee93c1675b557889d09d54a2ba25532 [file] [log] [blame]
// Copyright (c) 2012, 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.
// Patch file for dart:core classes.
import 'dart:_interceptors';
import 'dart:_js_helper' show checkNull,
getRuntimeTypeString,
isJsArray,
JSSyntaxRegExp,
Primitives,
TypeImpl,
stringJoinUnchecked,
JsStringBuffer;
patch void print(var object) {
Primitives.printString(object.toString());
}
// Patch for Object implementation.
patch class Object {
patch int get hashCode => Primitives.objectHashCode(this);
patch String toString() => Primitives.objectToString(this);
patch dynamic noSuchMethod(InvocationMirror invocation) {
throw new NoSuchMethodError(this,
invocation.memberName,
invocation.positionalArguments,
invocation.namedArguments);
}
patch Type get runtimeType {
String type = getRuntimeTypeString(this);
return new TypeImpl(type);
}
}
// Patch for Function implementation.
patch class Function {
patch static apply(Function function,
List positionalArguments,
[Map<String,dynamic> namedArguments]) {
return Primitives.applyFunction(
function, positionalArguments, namedArguments);
}
}
// Patch for Expando implementation.
patch class Expando<T> {
patch Expando([String name]) : this.name = name;
patch T operator[](Object object) {
var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
return (values == null) ? null : Primitives.getProperty(values, _getKey());
}
patch void operator[]=(Object object, T value) {
var values = Primitives.getProperty(object, _EXPANDO_PROPERTY_NAME);
if (values == null) {
values = new Object();
Primitives.setProperty(object, _EXPANDO_PROPERTY_NAME, values);
}
Primitives.setProperty(values, _getKey(), value);
}
String _getKey() {
String key = Primitives.getProperty(this, _KEY_PROPERTY_NAME);
if (key == null) {
key = "expando\$key\$${_keyCount++}";
Primitives.setProperty(this, _KEY_PROPERTY_NAME, key);
}
return key;
}
static const String _KEY_PROPERTY_NAME = 'expando\$key';
static const String _EXPANDO_PROPERTY_NAME = 'expando\$values';
static int _keyCount = 0;
}
patch class int {
patch static int parse(String source,
{ int radix,
int onError(String source) }) {
return Primitives.parseInt(source, radix, onError);
}
}
patch class double {
patch static double parse(String source, [int handleError(String source)]) {
return Primitives.parseDouble(source, handleError);
}
}
patch class Error {
patch static String _objectToString(Object object) {
return Primitives.objectToString(object);
}
}
// Patch for DateTime implementation.
patch class DateTime {
patch DateTime._internal(int year,
int month,
int day,
int hour,
int minute,
int second,
int millisecond,
bool isUtc)
: this.isUtc = checkNull(isUtc),
millisecondsSinceEpoch = Primitives.valueFromDecomposedDate(
year, month, day, hour, minute, second, millisecond, isUtc) {
Primitives.lazyAsJsDate(this);
}
patch DateTime._now()
: isUtc = false,
millisecondsSinceEpoch = Primitives.dateNow() {
Primitives.lazyAsJsDate(this);
}
patch static int _brokenDownDateToMillisecondsSinceEpoch(
int year, int month, int day, int hour, int minute, int second,
int millisecond, bool isUtc) {
return Primitives.valueFromDecomposedDate(
year, month, day, hour, minute, second, millisecond, isUtc);
}
patch String get timeZoneName {
if (isUtc) return "UTC";
return Primitives.getTimeZoneName(this);
}
patch Duration get timeZoneOffset {
if (isUtc) return new Duration();
return new Duration(minutes: Primitives.getTimeZoneOffsetInMinutes(this));
}
patch int get year => Primitives.getYear(this);
patch int get month => Primitives.getMonth(this);
patch int get day => Primitives.getDay(this);
patch int get hour => Primitives.getHours(this);
patch int get minute => Primitives.getMinutes(this);
patch int get second => Primitives.getSeconds(this);
patch int get millisecond => Primitives.getMilliseconds(this);
patch int get weekday => Primitives.getWeekday(this);
}
// Patch for Stopwatch implementation.
patch class Stopwatch {
patch static int _frequency() => 1000000;
patch static int _now() => Primitives.numMicroseconds();
}
// Patch for List implementation.
patch class List<E> {
patch factory List([int length = 0]) {
// Explicit type test is necessary to protect Primitives.newGrowableList in
// unchecked mode.
if ((length is !int) || (length < 0)) {
throw new ArgumentError("Length must be a positive integer: $length.");
}
return Primitives.newGrowableList(length);
}
patch factory List.fixedLength(int length, {E fill: null}) {
// Explicit type test is necessary to protect Primitives.newFixedList in
// unchecked mode.
if ((length is !int) || (length < 0)) {
throw new ArgumentError("Length must be a positive integer: $length.");
}
List result = Primitives.newFixedList(length);
if (length != 0 && fill != null) {
for (int i = 0; i < result.length; i++) {
result[i] = fill;
}
}
return result;
}
}
patch class String {
patch factory String.fromCharCodes(List<int> charCodes) {
if (!isJsArray(charCodes)) {
if (charCodes is !List) throw new ArgumentError(charCodes);
charCodes = new List.from(charCodes);
}
return Primitives.stringFromCharCodes(charCodes);
}
}
// Patch for String implementation.
patch class Strings {
patch static String join(Iterable<String> strings, String separator) {
checkNull(strings);
if (separator is !String) throw new ArgumentError(separator);
return stringJoinUnchecked(_toJsStringArray(strings), separator);
}
patch static String concatAll(Iterable<String> strings) {
return stringJoinUnchecked(_toJsStringArray(strings), "");
}
static List _toJsStringArray(Iterable<String> strings) {
checkNull(strings);
var array;
if (!isJsArray(strings)) {
strings = new List.from(strings);
}
final length = strings.length;
for (int i = 0; i < length; i++) {
final string = strings[i];
if (string is !String) throw new ArgumentError(string);
}
return strings;
}
}
patch class RegExp {
patch factory RegExp(String pattern,
{bool multiLine: false,
bool caseSensitive: true})
=> new JSSyntaxRegExp(pattern,
multiLine: multiLine,
caseSensitive: caseSensitive);
}
// Patch for 'identical' function.
patch bool identical(Object a, Object b) {
return Primitives.identicalImplementation(a, b);
}
patch class StringBuffer {
String _contents = "";
patch StringBuffer([Object content = ""]) {
if (content is String) {
_contents = content;
} else {
write(content);
}
}
patch int get length => _contents.length;
patch void write(Object obj) {
String str = obj is String ? obj : "$obj";
_contents = Primitives.stringConcatUnchecked(_contents, str);
}
patch void clear() {
_contents = "";
}
patch String toString() => _contents;
}