Skip to content
This repository was archived by the owner on Feb 22, 2018. It is now read-only.

Commit 24a2cf6

Browse files
author
John Messerly
committed
1 parent de5a6da commit 24a2cf6

File tree

12 files changed

+286
-188
lines changed

12 files changed

+286
-188
lines changed

lib/runtime/dart_runtime.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,44 @@ var dart;
132132
}
133133
dart.defineLazyProperties = defineLazyProperties;
134134

135-
function mixin(to, from) {
135+
/**
136+
* Copy properties from source to destination object.
137+
* This operation is commonly called `mixin` in JS.
138+
*/
139+
function copyProperties(to, from) {
136140
var names = getOwnPropertyNames(from);
137141
for (var i = 0; i < names.length; i++) {
138142
var name = names[i];
139143
defineProperty(to, name, getOwnPropertyDescriptor(from, name));
140144
}
141145
return to;
142146
}
147+
dart.copyProperties = copyProperties;
148+
149+
/**
150+
* Returns a new type that mixes members from base and all mixins.
151+
*
152+
* Each mixin applies in sequence, with further to the right ones overriding
153+
* previous entries.
154+
*
155+
* For each mixin, we only take its own properties, not anything from its
156+
* superclass (prototype).
157+
*/
158+
function mixin(base/*, ...mixins*/) {
159+
// Inherit statics from Base to simulate ES6 class inheritance
160+
// Conceptually this is: `class Mixin extends base {}`
161+
function Mixin() {
162+
base.apply(this, arguments);
163+
}
164+
Mixin.__proto__ = base;
165+
Mixin.prototype = Object.create(base.prototype);
166+
// Copy each mixin, with later ones overwriting earlier entires.
167+
for (var i = 1; i < arguments.length; i++) {
168+
var from = arguments[i];
169+
copyProperties(Mixin.prototype, from.prototype);
170+
}
171+
return Mixin;
172+
}
143173
dart.mixin = mixin;
144174

145175
function assert(condition) {

lib/src/codegen/js_codegen.dart

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,31 @@ var $_libraryName;
129129
// typedef?
130130
}
131131

132+
@override
133+
void visitTypeName(TypeName node) {
134+
_visitNode(node.name);
135+
_visitNode(node.typeArguments);
136+
}
137+
138+
@override
139+
void visitTypeParameterList(TypeParameterList node) {
140+
out.write('/* Unimplemented $node */');
141+
}
142+
143+
@override
144+
void visitTypeArgumentList(TypeArgumentList node) {
145+
out.write('/* Unimplemented $node */');
146+
}
147+
148+
@override
149+
void visitClassTypeAlias(ClassTypeAlias node) {
150+
var name = node.name.name;
151+
out.write('class $name extends dart.mixin(');
152+
_visitNodeList(node.withClause.mixinTypes, separator: ', ');
153+
out.write(') {}\n\n');
154+
if (isPublic(name)) _exports.add(name);
155+
}
156+
132157
@override
133158
void visitClassDeclaration(ClassDeclaration node) {
134159
currentClass = node;
@@ -137,9 +162,22 @@ var $_libraryName;
137162
var supertype = node.element.supertype;
138163

139164
out.write('class $name');
140-
if (supertype != null && !supertype.isObject) {
141-
out.write(' extends ${_typeName(supertype)}');
165+
_visitNode(node.typeParameters);
166+
167+
if (node.withClause != null) {
168+
out.write(' extends dart.mixin(');
169+
if (node.extendsClause != null) {
170+
_visitNode(node.extendsClause.superclass);
171+
} else {
172+
out.write('Object');
173+
}
174+
_visitNodeList(node.withClause.mixinTypes, prefix: ', ', separator: ', ');
175+
out.write(')');
176+
} else if (node.extendsClause != null) {
177+
out.write(' extends ');
178+
_visitNode(node.extendsClause.superclass);
142179
}
180+
143181
out.write(' {\n', 2);
144182

145183
var ctors = new List<ConstructorDeclaration>.from(
@@ -706,7 +744,7 @@ var $_libraryName;
706744
void _flushLibraryProperties() {
707745
if (_properties.isEmpty) return;
708746

709-
out.write('dart.mixin($_libraryName, {\n', 2);
747+
out.write('dart.copyProperties($_libraryName, {\n', 2);
710748
for (var node in _properties) {
711749
_writeFunctionDeclaration(node);
712750
out.write(',\n');

test/codegen/expect/_internal/_internal.js

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ var _internal;
55
class EfficientLength {
66
}
77

8-
class ListIterable extends collection.IterableBase {
8+
class ListIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
99
constructor() {
1010
super();
1111
}
@@ -191,7 +191,7 @@ var _internal;
191191
}
192192
}
193193

194-
class SubListIterable extends ListIterable {
194+
class SubListIterable/* Unimplemented <E> */ extends ListIterable/* Unimplemented <E> */ {
195195
constructor(_iterable, _start, _endOrLength) {
196196
this._iterable = _iterable;
197197
this._start = _start;
@@ -265,7 +265,7 @@ var _internal;
265265
}
266266
}
267267

268-
class ListIterator {
268+
class ListIterator/* Unimplemented <E> */ {
269269
constructor(iterable) {
270270
this._iterable = iterable;
271271
this._length = iterable.length;
@@ -288,7 +288,7 @@ var _internal;
288288
}
289289
}
290290

291-
class MappedIterable extends collection.IterableBase {
291+
class MappedIterable/* Unimplemented <S, T> */ extends collection.IterableBase/* Unimplemented <T> */ {
292292
constructor(iterable, /* Unimplemented FunctionTypedFormalParameter: T function(S value) */) {
293293
if (/* Unimplemented IsExpression: iterable is EfficientLength */) {
294294
return new EfficientLengthMappedIterable(iterable, function);
@@ -311,13 +311,13 @@ var _internal;
311311
MappedIterable._ = function(_iterable, _f) { this.__init__(_iterable, _f) };
312312
MappedIterable._.prototype = MappedIterable.prototype;
313313

314-
class EfficientLengthMappedIterable extends MappedIterable {
314+
class EfficientLengthMappedIterable/* Unimplemented <S, T> */ extends MappedIterable/* Unimplemented <S, T> */ {
315315
constructor(iterable, /* Unimplemented FunctionTypedFormalParameter: T function(S value) */) {
316316
super.__init__(/* Unimplemented: DownCastDynamic: Iterable<dynamic> to Iterable<S> */ iterable, function);
317317
}
318318
}
319319

320-
class MappedIterator extends dart_core.Iterator {
320+
class MappedIterator/* Unimplemented <S, T> */ extends dart_core.Iterator/* Unimplemented <T> */ {
321321
constructor(_iterator, _f) {
322322
this._iterator = _iterator;
323323
this._f = _f;
@@ -335,7 +335,7 @@ var _internal;
335335
get current() { return this._current; }
336336
}
337337

338-
class MappedListIterable extends ListIterable {
338+
class MappedListIterable/* Unimplemented <S, T> */ extends ListIterable/* Unimplemented <T> */ {
339339
constructor(_source, _f) {
340340
this._source = _source;
341341
this._f = _f;
@@ -345,7 +345,7 @@ var _internal;
345345
elementAt(index) { return this._f(this._source.elementAt(index)); }
346346
}
347347

348-
class WhereIterable extends collection.IterableBase {
348+
class WhereIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
349349
constructor(_iterable, _f) {
350350
this._iterable = _iterable;
351351
this._f = _f;
@@ -354,7 +354,7 @@ var _internal;
354354
get iterator() { return new WhereIterator(this._iterable.iterator, this._f); }
355355
}
356356

357-
class WhereIterator extends dart_core.Iterator {
357+
class WhereIterator/* Unimplemented <E> */ extends dart_core.Iterator/* Unimplemented <E> */ {
358358
constructor(_iterator, _f) {
359359
this._iterator = _iterator;
360360
this._f = _f;
@@ -371,7 +371,7 @@ var _internal;
371371
get current() { return this._iterator.current; }
372372
}
373373

374-
class ExpandIterable extends collection.IterableBase {
374+
class ExpandIterable/* Unimplemented <S, T> */ extends collection.IterableBase/* Unimplemented <T> */ {
375375
constructor(_iterable, _f) {
376376
this._iterable = _iterable;
377377
this._f = _f;
@@ -380,7 +380,7 @@ var _internal;
380380
get iterator() { return new ExpandIterator(this._iterable.iterator, this._f); }
381381
}
382382

383-
class ExpandIterator {
383+
class ExpandIterator/* Unimplemented <S, T> */ {
384384
constructor(_iterator, _f) {
385385
this._iterator = _iterator;
386386
this._f = _f;
@@ -407,7 +407,7 @@ var _internal;
407407
}
408408
}
409409

410-
class TakeIterable extends collection.IterableBase {
410+
class TakeIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
411411
constructor(iterable, takeCount) {
412412
if (/* Unimplemented IsExpression: takeCount is! int */ || takeCount < 0) {
413413
throw new dart_core.ArgumentError(takeCount);
@@ -429,7 +429,7 @@ var _internal;
429429
TakeIterable._ = function(_iterable, _takeCount) { this.__init__(_iterable, _takeCount) };
430430
TakeIterable._.prototype = TakeIterable.prototype;
431431

432-
class EfficientLengthTakeIterable extends TakeIterable {
432+
class EfficientLengthTakeIterable/* Unimplemented <E> */ extends TakeIterable/* Unimplemented <E> */ {
433433
constructor(iterable, takeCount) {
434434
super.__init__(iterable, takeCount);
435435
}
@@ -440,7 +440,7 @@ var _internal;
440440
}
441441
}
442442

443-
class TakeIterator extends dart_core.Iterator {
443+
class TakeIterator/* Unimplemented <E> */ extends dart_core.Iterator/* Unimplemented <E> */ {
444444
constructor(_iterator, _remaining) {
445445
this._iterator = _iterator;
446446
this._remaining = _remaining;
@@ -461,7 +461,7 @@ var _internal;
461461
}
462462
}
463463

464-
class TakeWhileIterable extends collection.IterableBase {
464+
class TakeWhileIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
465465
constructor(_iterable, _f) {
466466
this._iterable = _iterable;
467467
this._f = _f;
@@ -472,7 +472,7 @@ var _internal;
472472
}
473473
}
474474

475-
class TakeWhileIterator extends dart_core.Iterator {
475+
class TakeWhileIterator/* Unimplemented <E> */ extends dart_core.Iterator/* Unimplemented <E> */ {
476476
constructor(_iterator, _f) {
477477
this._iterator = _iterator;
478478
this._f = _f;
@@ -493,7 +493,7 @@ var _internal;
493493
}
494494
}
495495

496-
class SkipIterable extends collection.IterableBase {
496+
class SkipIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
497497
constructor(iterable, count) {
498498
if (/* Unimplemented IsExpression: iterable is EfficientLength */) {
499499
return new EfficientLengthSkipIterable(iterable, count);
@@ -523,7 +523,7 @@ var _internal;
523523
SkipIterable._ = function(_iterable, _skipCount) { this.__init__(_iterable, _skipCount) };
524524
SkipIterable._.prototype = SkipIterable.prototype;
525525

526-
class EfficientLengthSkipIterable extends SkipIterable {
526+
class EfficientLengthSkipIterable/* Unimplemented <E> */ extends SkipIterable/* Unimplemented <E> */ {
527527
constructor(iterable, skipCount) {
528528
super.__init__(iterable, skipCount);
529529
}
@@ -534,7 +534,7 @@ var _internal;
534534
}
535535
}
536536

537-
class SkipIterator extends dart_core.Iterator {
537+
class SkipIterator/* Unimplemented <E> */ extends dart_core.Iterator/* Unimplemented <E> */ {
538538
constructor(_iterator, _skipCount) {
539539
this._iterator = _iterator;
540540
this._skipCount = _skipCount;
@@ -549,7 +549,7 @@ var _internal;
549549
get current() { return this._iterator.current; }
550550
}
551551

552-
class SkipWhileIterable extends collection.IterableBase {
552+
class SkipWhileIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
553553
constructor(_iterable, _f) {
554554
this._iterable = _iterable;
555555
this._f = _f;
@@ -560,7 +560,7 @@ var _internal;
560560
}
561561
}
562562

563-
class SkipWhileIterator extends dart_core.Iterator {
563+
class SkipWhileIterator/* Unimplemented <E> */ extends dart_core.Iterator/* Unimplemented <E> */ {
564564
constructor(_iterator, _f) {
565565
this._iterator = _iterator;
566566
this._f = _f;
@@ -579,7 +579,7 @@ var _internal;
579579
get current() { return this._iterator.current; }
580580
}
581581

582-
class EmptyIterable extends collection.IterableBase {
582+
class EmptyIterable/* Unimplemented <E> */ extends collection.IterableBase/* Unimplemented <E> */ {
583583
constructor() {
584584
super();
585585
}
@@ -647,17 +647,17 @@ var _internal;
647647
toSet() { return new dart_core.Set(); }
648648
}
649649

650-
class EmptyIterator {
650+
class EmptyIterator/* Unimplemented <E> */ {
651651
constructor() {
652652
}
653653
moveNext() { return false; }
654654
get current() { return null; }
655655
}
656656

657-
class BidirectionalIterator {
657+
class BidirectionalIterator/* Unimplemented <T> */ {
658658
}
659659

660-
class IterableMixinWorkaround {
660+
class IterableMixinWorkaround/* Unimplemented <T> */ {
661661
static contains(iterable, element) {
662662
/* Unimplemented ForEachStatement: for (final e in iterable) {if (e == element) return true;} */return false;
663663
}
@@ -939,7 +939,7 @@ var _internal;
939939
static tooFew() { return new dart_core.StateError("Too few elements"); }
940940
}
941941

942-
class FixedLengthListMixin {
942+
class FixedLengthListMixin/* Unimplemented <E> */ {
943943
set length(newLength) {
944944
throw new dart_core.UnsupportedError("Cannot change the length of a fixed-length list");
945945
}
@@ -981,7 +981,7 @@ var _internal;
981981
}
982982
}
983983

984-
class UnmodifiableListMixin {
984+
class UnmodifiableListMixin/* Unimplemented <E> */ {
985985
[]=(index, value) {
986986
throw new dart_core.UnsupportedError("Cannot modify an unmodifiable list");
987987
}
@@ -1045,7 +1045,11 @@ var _internal;
10451045
}
10461046
}
10471047

1048-
/* Unimplemented ClassTypeAlias: abstract class FixedLengthListBase<E> = ListBase<E> with FixedLengthListMixin<E>; *//* Unimplemented ClassTypeAlias: abstract class UnmodifiableListBase<E> = ListBase<E> with UnmodifiableListMixin<E>; */class _ListIndicesIterable extends ListIterable {
1048+
class FixedLengthListBase extends dart.mixin(FixedLengthListMixin/* Unimplemented <E> */) {}
1049+
1050+
class UnmodifiableListBase extends dart.mixin(UnmodifiableListMixin/* Unimplemented <E> */) {}
1051+
1052+
class _ListIndicesIterable extends ListIterable/* Unimplemented <int> */ {
10491053
constructor(_backedList) {
10501054
this._backedList = _backedList;
10511055
super();
@@ -1057,7 +1061,7 @@ var _internal;
10571061
}
10581062
}
10591063

1060-
class ListMapView {
1064+
class ListMapView/* Unimplemented <E> */ {
10611065
constructor(_values) {
10621066
this._values = _values;
10631067
}
@@ -1096,7 +1100,7 @@ var _internal;
10961100
toString() { return collection.Maps.mapToString(this); }
10971101
}
10981102

1099-
class ReversedListIterable extends ListIterable {
1103+
class ReversedListIterable/* Unimplemented <E> */ extends ListIterable/* Unimplemented <E> */ {
11001104
constructor(_source) {
11011105
this._source = _source;
11021106
super();
@@ -1497,6 +1501,8 @@ var _internal;
14971501
_internal.IterableElementError = IterableElementError;
14981502
_internal.FixedLengthListMixin = FixedLengthListMixin;
14991503
_internal.UnmodifiableListMixin = UnmodifiableListMixin;
1504+
_internal.FixedLengthListBase = FixedLengthListBase;
1505+
_internal.UnmodifiableListBase = UnmodifiableListBase;
15001506
_internal.ListMapView = ListMapView;
15011507
_internal.ReversedListIterable = ReversedListIterable;
15021508
_internal.UnmodifiableListError = UnmodifiableListError;

0 commit comments

Comments
 (0)