forked from angular/angular
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlang.dart
More file actions
397 lines (328 loc) · 10.7 KB
/
lang.dart
File metadata and controls
397 lines (328 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
library angular.core.facade.lang;
export 'dart:core' show Type, RegExp, print, DateTime, Uri;
import 'dart:math' as math;
import 'dart:convert' as convert;
import 'dart:async' show Future, Zone;
String getTypeNameForDebugging(Object type) => type.toString();
class Math {
static final _random = new math.Random();
static int floor(num n) => n.floor();
static double random() => _random.nextDouble();
static num min(num a, num b) => math.min(a, b);
}
class CONST {
const CONST();
}
const IS_DART = true;
scheduleMicroTask(Function fn) {
Zone.current.scheduleMicrotask(fn);
}
bool isPresent(Object obj) => obj != null;
bool isBlank(Object obj) => obj == null;
bool isString(Object obj) => obj is String;
bool isFunction(Object obj) => obj is Function;
bool isType(Object obj) => obj is Type;
bool isStringMap(Object obj) => obj is Map;
bool isArray(Object obj) => obj is List;
bool isPromise(Object obj) => obj is Future;
bool isNumber(Object obj) => obj is num;
bool isBoolean(Object obj) => obj is bool;
bool isDate(Object obj) => obj is DateTime;
String stringify(obj) {
final exp = new RegExp(r"from Function '(\w+)'");
final str = obj.toString();
if (exp.firstMatch(str) != null) {
return exp.firstMatch(str).group(1);
} else {
return str;
}
}
int serializeEnum(val) {
return val.index;
}
/**
* Deserializes an enum
* val should be the indexed value of the enum (sa returned from @Link{serializeEnum})
* values should be a map from indexes to values for the enum that you want to deserialize.
*/
dynamic deserializeEnum(num val, Map<num, dynamic> values) {
return values[val];
}
String resolveEnumToken(enumValue, val) {
// turn Enum.Token -> Token
return val.toString().replaceFirst(new RegExp('^.+\\.'),'');
}
class StringWrapper {
static String fromCharCode(int code) {
return new String.fromCharCode(code);
}
static int charCodeAt(String s, int index) {
return s.codeUnitAt(index);
}
static List<String> split(String s, RegExp regExp) {
var parts = <String>[];
var lastEnd = 0;
regExp.allMatches(s).forEach((match) {
parts.add(s.substring(lastEnd, match.start));
lastEnd = match.end;
for (var i = 0; i < match.groupCount; i++) {
parts.add(match.group(i + 1));
}
});
parts.add(s.substring(lastEnd));
return parts;
}
static bool equals(String s, String s2) {
return s == s2;
}
static String stripLeft(String s, String charVal) {
if (isPresent(s) && s.length > 0) {
var pos = 0;
for (var i = 0; i < s.length; i++) {
if (s[i] != charVal) break;
pos++;
}
s = s.substring(pos);
}
return s;
}
static String stripRight(String s, String charVal) {
if (isPresent(s) && s.length > 0) {
var pos = s.length;
for (var i = s.length - 1; i >= 0; i--) {
if (s[i] != charVal) break;
pos--;
}
s = s.substring(0, pos);
}
return s;
}
static String replace(String s, Pattern from, String replace) {
return s.replaceFirst(from, replace);
}
static String replaceAll(String s, RegExp from, String replace) {
return s.replaceAll(from, replace);
}
static String slice(String s, [int start = 0, int end]) {
start = _startOffset(s, start);
end = _endOffset(s, end);
//in JS if start > end an empty string is returned
if (end != null && start > end) {
return "";
}
return s.substring(start, end);
}
static String replaceAllMapped(String s, RegExp from, Function cb) {
return s.replaceAllMapped(from, cb);
}
static bool contains(String s, String substr) {
return s.contains(substr);
}
static int compare(String a, String b) => a.compareTo(b);
// JS slice function can take start < 0 which indicates a position relative to
// the end of the string
static int _startOffset(String s, int start) {
int len = s.length;
return start < 0 ? math.max(len + start, 0) : math.min(start, len);
}
// JS slice function can take end < 0 which indicates a position relative to
// the end of the string
static int _endOffset(String s, int end) {
int len = s.length;
if (end == null) return len;
return end < 0 ? math.max(len + end, 0) : math.min(end, len);
}
}
class StringJoiner {
final List<String> _parts = <String>[];
void add(String part) {
_parts.add(part);
}
String toString() => _parts.join("");
}
class NumberWrapper {
static String toFixed(num n, int fractionDigits) {
return n.toStringAsFixed(fractionDigits);
}
static bool equal(num a, num b) {
return a == b;
}
static int parseIntAutoRadix(String text) {
return int.parse(text);
}
static int parseInt(String text, int radix) {
return int.parse(text, radix: radix);
}
static double parseFloat(String text) {
return double.parse(text);
}
static double get NaN => double.NAN;
static bool isNaN(num value) => value.isNaN;
static bool isInteger(value) => value is int;
}
class RegExpWrapper {
static RegExp create(regExpStr, [String flags = '']) {
bool multiLine = flags.contains('m');
bool caseSensitive = !flags.contains('i');
return new RegExp(regExpStr,
multiLine: multiLine, caseSensitive: caseSensitive);
}
static Match firstMatch(RegExp regExp, String input) {
return regExp.firstMatch(input);
}
static bool test(RegExp regExp, String input) {
return regExp.hasMatch(input);
}
static Iterator<Match> matcher(RegExp regExp, String input) {
return regExp.allMatches(input).iterator;
}
static String replaceAll(RegExp regExp, String input, Function replace) {
final m = RegExpWrapper.matcher(regExp, input);
var res = "";
var prev = 0;
while(m.moveNext()) {
var c = m.current;
res += input.substring(prev, c.start);
res += replace(c);
prev = c.start + c[0].length;
}
res += input.substring(prev);
return res;
}
}
class RegExpMatcherWrapper {
static _JSLikeMatch next(Iterator<Match> matcher) {
if (matcher.moveNext()) {
return new _JSLikeMatch(matcher.current);
}
return null;
}
}
class _JSLikeMatch {
Match _m;
_JSLikeMatch(this._m);
String operator [](index) => _m[index];
int get index => _m.start;
int get length => _m.groupCount + 1;
}
class FunctionWrapper {
static apply(Function fn, posArgs) {
return Function.apply(fn, posArgs);
}
}
const _NAN_KEY = const Object();
// Dart VM implements `identical` as true reference identity. JavaScript does
// not have this. The closest we have in JS is `===`. However, for strings JS
// would actually compare the contents rather than references. `dart2js`
// compiles `identical` to `===` and therefore there is a discrepancy between
// Dart VM and `dart2js`. The implementation of `looseIdentical` attempts to
// bridge the gap between the two while retaining good performance
// characteristics. In JS we use simple `identical`, which compiles to `===`,
// and in Dart VM we emulate the semantics of `===` by special-casing strings.
// Note that the VM check is a compile-time constant. This allows `dart2js` to
// evaluate the conditional during compilation and inline the entire function.
//
// See: dartbug.com/22496, dartbug.com/25270
const _IS_DART_VM = !identical(1.0, 1); // a hack
bool looseIdentical(a, b) => _IS_DART_VM
? _looseIdentical(a, b)
: identical(a, b);
// This function is intentionally separated from `looseIdentical` to keep the
// number of AST nodes low enough for `dart2js` to inline the code.
bool _looseIdentical(a, b) =>
a is String && b is String ? a == b : identical(a, b);
// Dart compare map keys by equality and we can have NaN != NaN
dynamic getMapKey(value) {
if (value is! num) return value;
return value.isNaN ? _NAN_KEY : value;
}
// TODO: remove with https://github.com/angular/angular/issues/3055
dynamic normalizeBlank(obj) => obj;
bool normalizeBool(bool obj) {
return isBlank(obj) ? false : obj;
}
bool isJsObject(o) {
return false;
}
// Functions below are noop in Dart. Imperatively controlling dev mode kills
// tree shaking. We should only rely on `assertionsEnabled`.
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void lockMode() {}
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void enableDevMode() {}
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void enableProdMode() {}
/// Use this function to guard debugging code. When Dart is compiled in
/// production mode, the code guarded using this function will be tree
/// shaken away, reducing code size.
///
/// WARNING: DO NOT CHANGE THIS METHOD! This method is designed to have no
/// more AST nodes than the maximum allowed by dart2js to inline it. In
/// addition, the use of `assert` allows the compiler to statically compute
/// the value returned by this function and tree shake conditions guarded by
/// it.
///
/// Example:
///
/// if (assertionsEnabled()) {
/// ...code here is tree shaken away in prod mode...
/// }
bool assertionsEnabled() {
var k = false;
assert((k = true));
return k;
}
// Can't be all uppercase as our transpiler would think it is a special directive...
class Json {
static parse(String s) => convert.JSON.decode(s);
static String stringify(data) {
var encoder = new convert.JsonEncoder.withIndent(" ");
return encoder.convert(data);
}
}
class DateWrapper {
static DateTime create(int year,
[int month = 1,
int day = 1,
int hour = 0,
int minutes = 0,
int seconds = 0,
int milliseconds = 0]) {
return new DateTime(year, month, day, hour, minutes, seconds, milliseconds);
}
static DateTime fromISOString(String str) {
return DateTime.parse(str);
}
static DateTime fromMillis(int ms) {
return new DateTime.fromMillisecondsSinceEpoch(ms, isUtc: true);
}
static int toMillis(DateTime date) {
return date.millisecondsSinceEpoch;
}
static DateTime now() {
return new DateTime.now();
}
static String toJson(DateTime date) {
return date.toUtc().toIso8601String();
}
}
bool isPrimitive(Object obj) => obj is num || obj is bool || obj == null || obj is String;
// needed to match the exports from lang.js
var global = null;
dynamic evalExpression(String sourceUrl, String expr, String declarations, Map<String, String> vars) {
throw "Dart does not support evaluating expression during runtime!";
}
bool hasConstructor(Object value, Type type) {
return value.runtimeType == type;
}
num bitWiseOr(List values) {
var val = values.reduce((num a, num b) => (a as int) | (b as int));
return val as num;
}
num bitWiseAnd(List values) {
var val = values.reduce((num a, num b) => (a as int) & (b as int));
return val as num;
}
String escape(String s) {
return Uri.encodeComponent(s);
}