From 0cdc8c28fbeef5688d0d4667bf0431656bdfcf03 Mon Sep 17 00:00:00 2001 From: John Messerly Date: Fri, 25 Sep 2015 11:31:25 -0700 Subject: [PATCH] Revert "Qualified exports and inheritance for Closure" --- .../lib/runtime/dart/_interceptors.js | 10 +- .../lib/runtime/dart/_native_typed_data.js | 4 +- pkg/dev_compiler/lib/runtime/dart/async.js | 58 +- .../lib/runtime/dart/collection.js | 16 +- pkg/dev_compiler/lib/runtime/dart/convert.js | 8 +- pkg/dev_compiler/lib/runtime/dart/core.js | 26 +- .../lib/src/codegen/js_codegen.dart | 545 +++++++----------- pkg/dev_compiler/test/codegen/closure.dart | 6 +- .../test/codegen/expect/closure.js | 53 +- 9 files changed, 299 insertions(+), 427 deletions(-) diff --git a/pkg/dev_compiler/lib/runtime/dart/_interceptors.js b/pkg/dev_compiler/lib/runtime/dart/_interceptors.js index 800b1f7852fb..4d81b095de5c 100644 --- a/pkg/dev_compiler/lib/runtime/dart/_interceptors.js +++ b/pkg/dev_compiler/lib/runtime/dart/_interceptors.js @@ -476,11 +476,6 @@ dart_library.library('dart/_interceptors', null, /* Imports */[ return JSExtendableArray; }); let JSExtendableArray = JSExtendableArray$(); - let _isInt32 = Symbol('_isInt32'); - let _tdivSlow = Symbol('_tdivSlow'); - let _shlPositive = Symbol('_shlPositive'); - let _shrOtherPositive = Symbol('_shrOtherPositive'); - let _shrBothPositive = Symbol('_shrBothPositive'); class Interceptor extends core.Object { Interceptor() { } @@ -488,6 +483,11 @@ dart_library.library('dart/_interceptors', null, /* Imports */[ dart.setSignature(Interceptor, { constructors: () => ({Interceptor: [Interceptor, []]}) }); + let _isInt32 = Symbol('_isInt32'); + let _tdivSlow = Symbol('_tdivSlow'); + let _shlPositive = Symbol('_shlPositive'); + let _shrOtherPositive = Symbol('_shrOtherPositive'); + let _shrBothPositive = Symbol('_shrBothPositive'); dart.defineExtensionNames([ 'compareTo', 'isNegative', diff --git a/pkg/dev_compiler/lib/runtime/dart/_native_typed_data.js b/pkg/dev_compiler/lib/runtime/dart/_native_typed_data.js index 34f89fd65e3d..18d46c5e0459 100644 --- a/pkg/dev_compiler/lib/runtime/dart/_native_typed_data.js +++ b/pkg/dev_compiler/lib/runtime/dart/_native_typed_data.js @@ -1,14 +1,14 @@ dart_library.library('dart/_native_typed_data', null, /* Imports */[ "dart_runtime/dart", - 'dart/typed_data', 'dart/core', + 'dart/typed_data', 'dart/_js_helper', 'dart/collection', 'dart/_internal', 'dart/_interceptors', 'dart/math' ], /* Lazy imports */[ -], function(exports, dart, typed_data, core, _js_helper, collection, _internal, _interceptors, math) { +], function(exports, dart, core, typed_data, _js_helper, collection, _internal, _interceptors, math) { 'use strict'; let dartx = dart.dartx; class NativeByteBuffer extends core.Object { diff --git a/pkg/dev_compiler/lib/runtime/dart/async.js b/pkg/dev_compiler/lib/runtime/dart/async.js index 98ad23595708..1e43afd29648 100644 --- a/pkg/dev_compiler/lib/runtime/dart/async.js +++ b/pkg/dev_compiler/lib/runtime/dart/async.js @@ -63,10 +63,6 @@ dart_library.library('dart/async', null, /* Imports */[ names: ['_getBestStackTrace'] }); let __CastType0 = dart.typedef('__CastType0', () => dart.functionType(dart.dynamic, [dart.dynamic])); - let _controller = Symbol('_controller'); - let _subscribe = Symbol('_subscribe'); - let _createSubscription = Symbol('_createSubscription'); - let _onListen = Symbol('_onListen'); let _add = Symbol('_add'); let _closeUnchecked = Symbol('_closeUnchecked'); let _addError = Symbol('_addError'); @@ -767,6 +763,8 @@ dart_library.library('dart/async', null, /* Imports */[ return Stream; }); let Stream = Stream$(); + let _createSubscription = Symbol('_createSubscription'); + let _onListen = Symbol('_onListen'); let _StreamImpl$ = dart.generic(function(T) { class _StreamImpl extends Stream$(T) { _StreamImpl() { @@ -800,6 +798,8 @@ dart_library.library('dart/async', null, /* Imports */[ return _StreamImpl; }); let _StreamImpl = _StreamImpl$(); + let _controller = Symbol('_controller'); + let _subscribe = Symbol('_subscribe'); let _ControllerStream$ = dart.generic(function(T) { class _ControllerStream extends _StreamImpl$(T) { _ControllerStream(controller) { @@ -855,18 +855,6 @@ dart_library.library('dart/async', null, /* Imports */[ this[_previous] = null; } } - let _eventState = Symbol('_eventState'); - let _expectsEvent = Symbol('_expectsEvent'); - let _toggleEventId = Symbol('_toggleEventId'); - let _isFiring = Symbol('_isFiring'); - let _setRemoveAfterFiring = Symbol('_setRemoveAfterFiring'); - let _removeAfterFiring = Symbol('_removeAfterFiring'); - let _onPause = Symbol('_onPause'); - let _onResume = Symbol('_onResume'); - let _recordCancel = Symbol('_recordCancel'); - let _onCancel = Symbol('_onCancel'); - let _recordPause = Symbol('_recordPause'); - let _recordResume = Symbol('_recordResume'); let _zone = Symbol('_zone'); let _state = Symbol('_state'); let _onData = Symbol('_onData'); @@ -881,14 +869,17 @@ dart_library.library('dart/async', null, /* Imports */[ let _isInputPaused = Symbol('_isInputPaused'); let _inCallback = Symbol('_inCallback'); let _guardCallback = Symbol('_guardCallback'); + let _onPause = Symbol('_onPause'); let _decrementPauseCount = Symbol('_decrementPauseCount'); let _hasPending = Symbol('_hasPending'); let _mayResumeInput = Symbol('_mayResumeInput'); + let _onResume = Symbol('_onResume'); let _cancel = Symbol('_cancel'); let _isClosed = Symbol('_isClosed'); let _waitsForCancel = Symbol('_waitsForCancel'); let _canFire = Symbol('_canFire'); let _cancelOnError = Symbol('_cancelOnError'); + let _onCancel = Symbol('_onCancel'); let _incrementPauseCount = Symbol('_incrementPauseCount'); let _sendData = Symbol('_sendData'); let _addPending = Symbol('_addPending'); @@ -1229,6 +1220,9 @@ dart_library.library('dart/async', null, /* Imports */[ return _BufferingStreamSubscription; }); let _BufferingStreamSubscription = _BufferingStreamSubscription$(); + let _recordCancel = Symbol('_recordCancel'); + let _recordPause = Symbol('_recordPause'); + let _recordResume = Symbol('_recordResume'); let _ControllerSubscription$ = dart.generic(function(T) { class _ControllerSubscription extends _BufferingStreamSubscription$(T) { _ControllerSubscription(controller, onData, onError, onDone, cancelOnError) { @@ -1251,6 +1245,12 @@ dart_library.library('dart/async', null, /* Imports */[ return _ControllerSubscription; }); let _ControllerSubscription = _ControllerSubscription$(); + let _eventState = Symbol('_eventState'); + let _expectsEvent = Symbol('_expectsEvent'); + let _toggleEventId = Symbol('_toggleEventId'); + let _isFiring = Symbol('_isFiring'); + let _setRemoveAfterFiring = Symbol('_setRemoveAfterFiring'); + let _removeAfterFiring = Symbol('_removeAfterFiring'); let _BroadcastSubscription$ = dart.generic(function(T) { class _BroadcastSubscription extends _ControllerSubscription$(T) { _BroadcastSubscription(controller, onData, onError, onDone, cancelOnError) { @@ -3543,7 +3543,6 @@ dart_library.library('dart/async', null, /* Imports */[ return _GeneratedStreamImpl; }); let _GeneratedStreamImpl = _GeneratedStreamImpl$(); - let _iterator = Symbol('_iterator'); let _eventScheduled = Symbol('_eventScheduled'); class _PendingEvents extends core.Object { _PendingEvents() { @@ -3584,6 +3583,7 @@ dart_library.library('dart/async', null, /* Imports */[ cancelSchedule: [dart.void, []] }) }); + let _iterator = Symbol('_iterator'); let _IterablePendingEvents$ = dart.generic(function(T) { class _IterablePendingEvents extends _PendingEvents { _IterablePendingEvents(data) { @@ -5133,6 +5133,18 @@ dart_library.library('dart/async', null, /* Imports */[ }), names: ['_enter', '_leave'] }); + class _Zone extends core.Object { + _Zone() { + } + inSameErrorZone(otherZone) { + return dart.notNull(core.identical(this, otherZone)) || dart.notNull(core.identical(this.errorZone, otherZone.errorZone)); + } + } + _Zone[dart.implements] = () => [Zone]; + dart.setSignature(_Zone, { + constructors: () => ({_Zone: [_Zone, []]}), + methods: () => ({inSameErrorZone: [core.bool, [Zone]]}) + }); let _run = Symbol('_run'); let _runUnary = Symbol('_runUnary'); let _runBinary = Symbol('_runBinary'); @@ -5148,18 +5160,6 @@ dart_library.library('dart/async', null, /* Imports */[ let _handleUncaughtError = Symbol('_handleUncaughtError'); let _map = Symbol('_map'); let _delegate = Symbol('_delegate'); - class _Zone extends core.Object { - _Zone() { - } - inSameErrorZone(otherZone) { - return dart.notNull(core.identical(this, otherZone)) || dart.notNull(core.identical(this.errorZone, otherZone.errorZone)); - } - } - _Zone[dart.implements] = () => [Zone]; - dart.setSignature(_Zone, { - constructors: () => ({_Zone: [_Zone, []]}), - methods: () => ({inSameErrorZone: [core.bool, [Zone]]}) - }); class _RootZone extends _Zone { _RootZone() { super._Zone(); diff --git a/pkg/dev_compiler/lib/runtime/dart/collection.js b/pkg/dev_compiler/lib/runtime/dart/collection.js index 8d5b41d6cc91..f67f3e3b0010 100644 --- a/pkg/dev_compiler/lib/runtime/dart/collection.js +++ b/pkg/dev_compiler/lib/runtime/dart/collection.js @@ -22,7 +22,7 @@ dart_library.library('dart/collection', null, /* Imports */[ } } dart.setSignature(UnmodifiableListView, { - constructors: () => ({UnmodifiableListView: [UnmodifiableListView$(E), [core.Iterable$(E)]]}), + constructors: () => ({UnmodifiableListView: [exports.UnmodifiableListView$(E), [core.Iterable$(E)]]}), methods: () => ({get: [E, [core.int]]}) }); dart.defineExtensionMembers(UnmodifiableListView, ['get', 'length']); @@ -113,9 +113,11 @@ dart_library.library('dart/collection', null, /* Imports */[ return HashMap; }); let HashMap = HashMap$(); - let _newSet = Symbol('_newSet'); let SetMixin$ = dart.generic(function(E) { class SetMixin extends core.Object { + [Symbol.iterator]() { + return new dart.JsIterator(this.iterator); + } get isEmpty() { return this.length == 0; } @@ -379,9 +381,6 @@ dart_library.library('dart/collection', null, /* Imports */[ } dart.throw(core.RangeError.index(index, this, "index", null, elementIndex)); } - [Symbol.iterator]() { - return new dart.JsIterator(this.iterator); - } } SetMixin[dart.implements] = () => [core.Set$(E)]; dart.setSignature(SetMixin, { @@ -457,6 +456,7 @@ dart_library.library('dart/collection', null, /* Imports */[ return SetBase; }); let SetBase = SetBase$(); + let _newSet = Symbol('_newSet'); let _HashSetBase$ = dart.generic(function(E) { class _HashSetBase extends SetBase$(E) { difference(other) { @@ -1624,6 +1624,9 @@ dart_library.library('dart/collection', null, /* Imports */[ get iterator() { return new (_internal.ListIterator$(E))(this); } + [Symbol.iterator]() { + return new dart.JsIterator(this.iterator); + } elementAt(index) { return this.get(index); } @@ -2098,9 +2101,6 @@ dart_library.library('dart/collection', null, /* Imports */[ toString() { return IterableBase.iterableToFullString(this, '[', ']'); } - [Symbol.iterator]() { - return new dart.JsIterator(this.iterator); - } } ListMixin[dart.implements] = () => [core.List$(E)]; dart.setSignature(ListMixin, { diff --git a/pkg/dev_compiler/lib/runtime/dart/convert.js b/pkg/dev_compiler/lib/runtime/dart/convert.js index 7646976c8ead..03a825aa066c 100644 --- a/pkg/dev_compiler/lib/runtime/dart/convert.js +++ b/pkg/dev_compiler/lib/runtime/dart/convert.js @@ -9,7 +9,6 @@ dart_library.library('dart/convert', null, /* Imports */[ ], function(exports, dart, core, async, typed_data, _internal, collection) { 'use strict'; let dartx = dart.dartx; - let _allowInvalid = Symbol('_allowInvalid'); let Codec$ = dart.generic(function(S, T) { class Codec extends core.Object { Codec() { @@ -64,6 +63,7 @@ dart_library.library('dart/convert', null, /* Imports */[ statics: () => ({getByName: [Encoding, [core.String]]}), names: ['getByName'] }); + let _allowInvalid = Symbol('_allowInvalid'); class AsciiCodec extends Encoding { AsciiCodec(opts) { let allowInvalid = opts && 'allowInvalid' in opts ? opts.allowInvalid : false; @@ -96,7 +96,6 @@ dart_library.library('dart/convert', null, /* Imports */[ }); let ASCII = dart.const(new AsciiCodec()); let _ASCII_MASK = 127; - let _subsetMask = Symbol('_subsetMask'); let Converter$ = dart.generic(function(S, T) { class Converter extends core.Object { Converter() { @@ -126,6 +125,7 @@ dart_library.library('dart/convert', null, /* Imports */[ return Converter; }); let Converter = Converter$(); + let _subsetMask = Symbol('_subsetMask'); class _UnicodeSubsetEncoder extends Converter$(core.String, core.List$(core.int)) { _UnicodeSubsetEncoder(subsetMask) { this[_subsetMask] = subsetMask; @@ -177,7 +177,6 @@ dart_library.library('dart/convert', null, /* Imports */[ dart.setSignature(AsciiEncoder, { constructors: () => ({AsciiEncoder: [AsciiEncoder, []]}) }); - let _sink = Symbol('_sink'); class StringConversionSinkMixin extends core.Object { add(str) { return this.addSlice(str, 0, str[dartx.length], false); @@ -198,6 +197,7 @@ dart_library.library('dart/convert', null, /* Imports */[ }) }); class StringConversionSinkBase extends StringConversionSinkMixin {} + let _sink = Symbol('_sink'); class _UnicodeSubsetEncoderSink extends StringConversionSinkBase { _UnicodeSubsetEncoderSink(subsetMask, sink) { this[_subsetMask] = subsetMask; @@ -300,7 +300,6 @@ dart_library.library('dart/convert', null, /* Imports */[ constructors: () => ({AsciiDecoder: [AsciiDecoder, [], {allowInvalid: core.bool}]}), methods: () => ({startChunkedConversion: [ByteConversionSink, [core.Sink$(core.String)]]}) }); - let _utf8Sink = Symbol('_utf8Sink'); let ChunkedConversionSink$ = dart.generic(function(T) { class ChunkedConversionSink extends core.Object { ChunkedConversionSink() { @@ -350,6 +349,7 @@ dart_library.library('dart/convert', null, /* Imports */[ dart.setSignature(ByteConversionSinkBase, { methods: () => ({addSlice: [dart.void, [core.List$(core.int), core.int, core.int, core.bool]]}) }); + let _utf8Sink = Symbol('_utf8Sink'); class _ErrorHandlingAsciiDecoderSink extends ByteConversionSinkBase { _ErrorHandlingAsciiDecoderSink(utf8Sink) { this[_utf8Sink] = utf8Sink; diff --git a/pkg/dev_compiler/lib/runtime/dart/core.js b/pkg/dev_compiler/lib/runtime/dart/core.js index b10088008047..b104bb5b4ccf 100644 --- a/pkg/dev_compiler/lib/runtime/dart/core.js +++ b/pkg/dev_compiler/lib/runtime/dart/core.js @@ -1270,7 +1270,10 @@ dart_library.library('dart/core', null, /* Imports */[ generator = null; if (dart.notNull(count) <= 0) return new (_internal.EmptyIterable$(E))(); - return new (_GeneratorIterable$(E))(count, generator); + return new (exports._GeneratorIterable$(E))(count, generator); + } + [dart.JsSymbol.iterator]() { + return new dart.JsIterator(this[dartx.iterator]); } [dartx.join](separator) { if (separator === void 0) @@ -1279,9 +1282,6 @@ dart_library.library('dart/core', null, /* Imports */[ buffer.writeAll(this, separator); return dart.toString(buffer); } - [dart.JsSymbol.iterator]() { - return new dart.JsIterator(this[dartx.iterator]); - } } dart.setSignature(Iterable, { constructors: () => ({ @@ -1306,7 +1306,7 @@ dart_library.library('dart/core', null, /* Imports */[ _GeneratorIterable(end, generator) { this[_end] = end; this[_start] = 0; - this[_generator] = dart.as(generator != null ? generator : _GeneratorIterable$()._id, _Generator$(E)); + this[_generator] = dart.as(generator != null ? generator : exports._GeneratorIterable$()._id, _Generator$(E)); super.IterableBase(); } slice(start, end, generator) { @@ -1328,7 +1328,7 @@ dart_library.library('dart/core', null, /* Imports */[ let newStart = dart.notNull(this[_start]) + dart.notNull(count); if (dart.notNull(newStart) >= dart.notNull(this[_end])) return new (_internal.EmptyIterable$(E))(); - return new (_GeneratorIterable$(E)).slice(newStart, this[_end], this[_generator]); + return new (exports._GeneratorIterable$(E)).slice(newStart, this[_end], this[_generator]); } take(count) { RangeError.checkNotNegative(count, "count"); @@ -1337,7 +1337,7 @@ dart_library.library('dart/core', null, /* Imports */[ let newEnd = dart.notNull(this[_start]) + dart.notNull(count); if (dart.notNull(newEnd) >= dart.notNull(this[_end])) return this; - return new (_GeneratorIterable$(E)).slice(this[_start], newEnd, this[_generator]); + return new (exports._GeneratorIterable$(E)).slice(this[_start], newEnd, this[_generator]); } static _id(n) { return n; @@ -1347,8 +1347,8 @@ dart_library.library('dart/core', null, /* Imports */[ dart.defineNamedConstructor(_GeneratorIterable, 'slice'); dart.setSignature(_GeneratorIterable, { constructors: () => ({ - _GeneratorIterable: [_GeneratorIterable$(E), [int, dart.functionType(E, [int])]], - slice: [_GeneratorIterable$(E), [int, int, _Generator$(E)]] + _GeneratorIterable: [exports._GeneratorIterable$(E), [int, dart.functionType(E, [int])]], + slice: [exports._GeneratorIterable$(E), [int, int, _Generator$(E)]] }), methods: () => ({ skip: [Iterable$(E), [int]], @@ -1548,9 +1548,9 @@ dart_library.library('dart/core', null, /* Imports */[ Set[dart.implements] = () => [_internal.EfficientLength]; dart.setSignature(Set, { constructors: () => ({ - new: [Set$(E), []], - identity: [Set$(E), []], - from: [Set$(E), [Iterable]] + new: [exports.Set$(E), []], + identity: [exports.Set$(E), []], + from: [exports.Set$(E), [Iterable]] }) }); return Set; @@ -1729,7 +1729,7 @@ dart_library.library('dart/core', null, /* Imports */[ } } dart.setSignature(Runes, { - constructors: () => ({Runes: [Runes, [String]]}) + constructors: () => ({Runes: [exports.Runes, [String]]}) }); dart.defineExtensionMembers(Runes, ['iterator', 'last']); return Runes; diff --git a/pkg/dev_compiler/lib/src/codegen/js_codegen.dart b/pkg/dev_compiler/lib/src/codegen/js_codegen.dart index 4728cd4d9d47..2cc5145cd91e 100644 --- a/pkg/dev_compiler/lib/src/codegen/js_codegen.dart +++ b/pkg/dev_compiler/lib/src/codegen/js_codegen.dart @@ -49,54 +49,6 @@ const DSETINDEX = 'dsetindex'; const DCALL = 'dcall'; const DSEND = 'dsend'; -/// Type for builder of statements that need to refer to a companion class. -/// [classRef] will either be a simple identifier or a qualified one, depending -/// on the context in which the class is emitted (generics or not, exported or -/// not...). -typedef JS.Statement _ClassRefStatementBuilder(JS.Expression classRef); - -/// Helper class used to build class declarations. -class _ClassBuilder { - final _ClassInfo info; - - /// Statements that should appear before the class declaration. - final List prelude = []; - /// Members of the class declaration. - final List body = []; - /// Builders for statements that should appear just after the class - /// declaration. These builders will get a local or qualified reference to the - /// class as argument so they can refer to it if they so wish. - /// - /// Note that these statements may be wrapped in generic or lazy classes - /// definitions, so they might not be top-level. - final List<_ClassRefStatementBuilder> statements = []; - /// Statements for extension classes are treated separately, as they need to - /// be at the top-level. - final List topLevelStatements = []; - - _ClassBuilder(this.info); -} - -/// Class info helper that provides member declarations. -class _ClassInfo { - final ClassElement element; - final ClassDeclaration declaration; - final String jsPeerName; - final List ctors = []; - final List instanceFields = []; - final List methods = []; - - _ClassInfo(this.element, [this.declaration, this.jsPeerName]) { - if (declaration != null) { - for (var m in declaration.members) { - if (m is ConstructorDeclaration) ctors.add(m); - else if (m is FieldDeclaration && !m.isStatic) instanceFields.add(m); - else if (m is MethodDeclaration) methods.add(m); - } - } - } -} - class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { final AbstractCompiler compiler; final CodegenOptions options; @@ -134,8 +86,9 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { final _qualifiedGenericIds = new HashMap(); /// The name for the library's exports inside itself. - var _exportsVar; + /// `exports` was chosen as the most similar to ES module patterns. final _dartxVar = new JS.Identifier('dartx'); + final _exportsVar = new JS.TemporaryId('exports'); final _runtimeLibVar = new JS.Identifier('dart'); final _namedArgTemp = new JS.TemporaryId('opts'); @@ -164,22 +117,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { _jsArray = interceptors.getType('JSArray'); _objectMembers = getObjectMemberMap(types); - // `exports` was chosen as the most similar to ES module patterns. - _exportsVar = new JS.TemporaryId( - _qualifyExports ? jsLibraryName(currentLibrary) : 'exports'); } - /// Whether to always refer to current library's exported types as if they - /// were external types (i.e. within library 'foo', refer to local class 'Bar' - /// as 'foo.Bar'). This helps compile the 'core' library with Closure, as it - /// defines classes such as 'Object' or 'Error' that conflict with their JS - /// homonyms. - bool get _qualifyExports => options.closure; - - /// Whether class parent needs to be a qualified identifier - /// (as opposed to an expression such as `dart.mixin(...)`). - bool get _needsQualifiedHeritage => options.closure; - TypeProvider get types => rules.provider; JS.Program emitLibrary(LibraryUnit library) { @@ -434,16 +373,15 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { var type = element.type; var name = element.name; - return annotateTypeDef( - _finishType(type, ({bool isExportable}) { - return _emitDecl(name, - js.call('dart.typedef(#, () => #)', [ - js.string(name, "'"), - _emitTypeName(type, lowerTypedef: true) - ]), - isExportable: isExportable); - }), + var fnType = annotateTypeDef( + js.statement('let # = dart.typedef(#, () => #);', [ + name, + js.string(name, "'"), + _emitTypeName(type, lowerTypedef: true) + ]), node.element); + + return _finishClassDef(type, fnType); } @override @@ -454,7 +392,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { var element = node.element; // Forward all generative constructors from the base class. - var builder = new _ClassBuilder(new _ClassInfo(element)); + var body = []; var supertype = element.supertype; if (!supertype.isObject) { @@ -462,11 +400,14 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { var parentCtor = supertype.lookUpConstructor(ctor.name, ctor.library); var fun = js.call('function() { super.#(...arguments); }', [_constructorName(parentCtor)]) as JS.Fun; - builder.body.add(new JS.Method(_constructorName(ctor), fun)); + body.add(new JS.Method(_constructorName(ctor), fun)); } } - return _finishClass(builder); + var classDecl = new JS.ClassDeclaration(new JS.ClassExpression( + new JS.Identifier(element.name), _classHeritage(element), body)); + + return _finishClassDef(element.type, classDecl); } JS.Statement _emitJsType(String dartClassName, DartObjectImpl jsName) { @@ -477,118 +418,64 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { // `dom.InputElement` to actually be HTMLInputElement. // TODO(jmesserly): if we had the JsName on the Element, we could just // generate it correctly when we refer to it. - return _emitDecl(dartClassName, new JS.Identifier(jsTypeName)); + if (isPublic(dartClassName)) _addExport(dartClassName); + return js.statement('let # = #;', [dartClassName, jsTypeName]); } return null; } - /// Emit declaration, exporting it if [isExportable] and if the name is - /// public. - JS.Statement _emitDecl(String name, JS.Expression expr, - {bool isExportable: true}) { - var shouldExport = isExportable && isPublic(name); - if (shouldExport && _qualifyExports) { - return js.statement('#.# = #;', [_exportsVar, name, expr]); - } else { - if (shouldExport) _addExport(name); - - if (expr is JS.ClassExpression) { - return new JS.ClassDeclaration(expr); - } else { - return js.statement('let # = #;', [name, expr]); - } - } - } - @override JS.Statement visitClassDeclaration(ClassDeclaration node) { var classElem = node.element; - var classType = classElem.type; + var type = classElem.type; var jsName = findAnnotation(classElem, _isJsNameAnnotation); - if (jsName != null) return _emitJsType(node.name.name, jsName); - - var info = new _ClassInfo(classElem, node, _getJsPeerName(classElem)); - var builder = new _ClassBuilder(info); - _addClassJsPeerSetup(builder); - _addClassInterfaces(builder); - - // Iff no constructor is specified for a class C, it implicitly has a - // default constructor `C() : super() {}`, unless C is class Object. - if (info.ctors.isEmpty && !classType.isObject) { - builder.body.add(_emitImplicitConstructor(node, info.instanceFields)); - } + if (jsName != null) return _emitJsType(node.name.name, jsName); + var ctors = []; + var fields = []; + var methods = []; for (var member in node.members) { if (member is ConstructorDeclaration) { - builder.body.add(_emitConstructor( - member, classType, info.instanceFields, classType.isObject)); - // Named constructors - if (member.name != null && member.factoryKeyword == null) { - builder.statements.add((classRef) => - js.statement('dart.defineNamedConstructor(#, #);', [ - classRef, - _emitMemberName(member.name.name, isStatic: true) - ])); - } + ctors.add(member); } else if (member is FieldDeclaration && !member.isStatic) { - /// Instance fields, if they override getter/setter pairs - for (VariableDeclaration fieldDecl in member.fields.variables) { - var field = fieldDecl.element as FieldElement; - if (_fieldsNeedingStorage.contains(field)) { - builder.statements.add((classRef) => - js.statement('dart.virtualField(#, #)', - [classRef, _emitMemberName(field.name, type: classType)])); - } - } + fields.add(member); } else if (member is MethodDeclaration) { - builder.body.add(_emitMethodDeclaration(classType, member)); + methods.add(member); } } - _addClassExtensionNames(builder); - _addClassIterableSupport(builder); - _addClassMemberSignatures(builder); - _addClassMetadata(builder); - - return _finishClass(builder); - } + var classExpr = new JS.ClassExpression(new JS.Identifier(type.name), + _classHeritage(classElem), _emitClassMethods(node, ctors, fields)); - void _addClassExtensionNames(_ClassBuilder builder) { - var classElem = builder.info.element; - if (!_extensionTypes.contains(classElem)) return; - - var dartxNames = []; - for (MethodDeclaration m in builder.info.methods) { - if (!m.isAbstract && !m.isStatic && m.element.isPublic) { - dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); - } + String jsPeerName; + var jsPeer = findAnnotation(classElem, _isJsPeerInterface); + if (jsPeer != null) { + jsPeerName = getConstantField(jsPeer, 'name', types.stringType) as String; } - if (dartxNames.isNotEmpty) { - builder.prelude.add(js.statement('dart.defineExtensionNames(#)', - [new JS.ArrayInitializer(dartxNames, multiline: true)])); - } - } + var body = _finishClassMembers(classElem, classExpr, ctors, fields, methods, + node.metadata, jsPeerName); - void _addClassIterableSupport(_ClassBuilder builder) { - if (builder.info.jsPeerName != null) return; + var result = _finishClassDef(type, body); - var classType = builder.info.element.type; - bool hasIteratorMethod = builder.info.methods - .any((m) => m.isGetter && m.name.name == 'iterator'); + if (jsPeerName != null) { + // This class isn't allowed to be lazy, because we need to set up + // the native JS type eagerly at this point. + // If we wanted to support laziness, we could defer the hookup until + // the end of the Dart library cycle load. + assert(_loader.isLoaded(classElem)); - // If the type doesn't have an `iterator`, but claims to implement Iterable, - // we inject the adaptor method here, as it's less code size to put the - // helper on a parent class. This pattern is common in the core libraries - // (e.g. IterableMixin and IterableBase). - // - // (We could do this same optimization for any interface with an `iterator` - // method, but that's more expensive to check for, so it doesn't seem worth - // it. The above case for an explicit `iterator` method will catch those.) - if (hasIteratorMethod || _implementsIterable(classType)) { - builder.body.add(_emitIterable(classType)); + // TODO(jmesserly): this copies the dynamic members. + // Probably fine for objects coming from JS, but not if we actually + // want to support construction of instances with generic types other + // than dynamic. See issue #154 for Array and List related bug. + var copyMembers = js.statement( + 'dart.registerExtension(dart.global.#, #);', + [_propertyName(jsPeerName), classElem.name]); + return _statement([result, copyMembers]); } + return result; } @override @@ -638,95 +525,51 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { return _statement(result); } - static bool _isQualifiedName(JS.Expression expr) => - expr is JS.Identifier - || (expr is JS.PropertyAccess - && expr.selector is JS.LiteralString - && _isQualifiedName(expr.receiver)); - - /// Builds the class. - JS.Statement _finishClass(_ClassBuilder builder) { - var element = builder.info.element; - var name = element.name; + /// Given a class element and body, complete the class declaration. + /// This handles generic type parameters, laziness (in library-cycle cases), + /// and ensuring dependencies are loaded first. + JS.Statement _finishClassDef(ParameterizedType type, JS.Statement body) { + var name = type.name; + var genericName = '$name\$'; - var heritage = _classHeritage(element); - /// Closure expects qualified identifiers for superclasses. - if (_needsQualifiedHeritage && !_isQualifiedName(heritage)) { - var alias = new JS.TemporaryId("$name\$super"); - builder.prelude.add(js.statement('let # = #', [alias, heritage])); - heritage = alias; + JS.Statement genericDef = null; + if (type.typeParameters.isNotEmpty) { + genericDef = _emitGenericClassDef(type, body); } - var classExpr = new JS.ClassExpression( - new JS.Identifier(name), - heritage, - builder.body.where((m) => m != null).toList(growable: false)); - var result = _finishType(element.type, ({bool isExportable}) { - var classRef = isExportable - ? _maybeQualifiedLocalType(name) - : new JS.Identifier(name); - - return _statement([] - ..addAll(builder.prelude) - ..add(_emitDecl(name, classExpr, isExportable: isExportable)) - ..addAll(builder.statements.map((statementBuilder) { - return statementBuilder(classRef); - }))); - }); - return _statement([result]..addAll(builder.topLevelStatements)); - } - - /// Given a class definition statement factory, completes its declaration. - /// This handles generic type parameters, laziness (in library-cycle cases), - /// and ensuring dependencies are loaded first. - JS.Statement _finishType(ParameterizedType type, - JS.Statement getStatement({bool isExportable})) { // The base class and all mixins must be declared before this class. - // TODO(jmesserly): the lazy class def is a simple solution for now. - // We may want to consider other options in the future. - bool isLoaded = _loader.isLoaded(type.element); - var name = type.name; + if (!_loader.isLoaded(type.element)) { + // TODO(jmesserly): the lazy class def is a simple solution for now. + // We may want to consider other options in the future. - if (type.typeParameters.isEmpty) { - if (isLoaded) { - return getStatement(isExportable: true); - } else { - return js.statement( - 'dart.defineLazyClass(#, { get #() { #; return #; } });', [ - _exportsVar, - _propertyName(name), - getStatement(isExportable: false), - name - ]); - } - } else { - var genericName = '$name\$'; - var genericDef = _emitDecl( - genericName, - js.call('dart.generic(function(#) { #; return #; })', [ - type.typeParameters.map((p) => p.name), - getStatement(isExportable: false), - name - ]), - isExportable: true); - - if (isLoaded) { - var genericInst = _emitTypeName( - fillDynamicTypeArgs(type, types), lowerGeneric: true); - return js.statement('{ #; #; }', [ - genericDef, - _emitDecl(name, genericInst) - ]); - } else { + if (genericDef != null) { return js.statement( - '{ #; dart.defineLazyClassGeneric(#, #, { get: # }); }', [ - genericDef, - _exportsVar, - _propertyName(name), - _maybeQualifiedLocalType(genericName) - ]); + '{ #; dart.defineLazyClassGeneric(#, #, { get: # }); }', + [genericDef, _exportsVar, _propertyName(name), genericName]); } + + return js.statement( + 'dart.defineLazyClass(#, { get #() { #; return #; } });', + [_exportsVar, _propertyName(name), body, name]); + } + + if (isPublic(name)) _addExport(name); + + if (genericDef != null) { + var dynType = fillDynamicTypeArgs(type, types); + var genericInst = _emitTypeName(dynType, lowerGeneric: true); + return js.statement('{ #; let # = #; }', [genericDef, name, genericInst]); } + return body; + } + + JS.Statement _emitGenericClassDef(ParameterizedType type, JS.Statement body) { + var name = type.name; + var genericName = '$name\$'; + var typeParams = type.typeParameters.map((p) => p.name); + if (isPublic(name)) _exports.add(genericName); + return js.statement('let # = dart.generic(function(#) { #; return #; });', + [genericName, typeParams, body, name]); } JS.Expression _classHeritage(ClassElement element) { @@ -747,6 +590,50 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { return heritage; } + List _emitClassMethods(ClassDeclaration node, + List ctors, List fields) { + var element = node.element; + var type = element.type; + var isObject = type.isObject; + + // Iff no constructor is specified for a class C, it implicitly has a + // default constructor `C() : super() {}`, unless C is class Object. + var jsMethods = []; + if (ctors.isEmpty && !isObject) { + jsMethods.add(_emitImplicitConstructor(node, fields)); + } + + bool hasJsPeer = findAnnotation(element, _isJsPeerInterface) != null; + + bool hasIterator = false; + for (var m in node.members) { + if (m is ConstructorDeclaration) { + jsMethods.add(_emitConstructor(m, type, fields, isObject)); + } else if (m is MethodDeclaration) { + jsMethods.add(_emitMethodDeclaration(type, m)); + + if (!hasJsPeer && m.isGetter && m.name.name == 'iterator') { + hasIterator = true; + jsMethods.add(_emitIterable(type)); + } + } + } + + // If the type doesn't have an `iterator`, but claims to implement Iterable, + // we inject the adaptor method here, as it's less code size to put the + // helper on a parent class. This pattern is common in the core libraries + // (e.g. IterableMixin and IterableBase). + // + // (We could do this same optimization for any interface with an `iterator` + // method, but that's more expensive to check for, so it doesn't seem worth + // it. The above case for an explicit `iterator` method will catch those.) + if (!hasJsPeer && !hasIterator && _implementsIterable(type)) { + jsMethods.add(_emitIterable(type)); + } + + return jsMethods.where((m) => m != null).toList(growable: false); + } + bool _implementsIterable(InterfaceType t) => t.interfaces.any((i) => i.element.type == types.iterableType); @@ -785,63 +672,67 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { } } - String _getJsPeerName(ClassElement classElem) { - var jsPeer = findAnnotation(classElem, _isJsPeerInterface); - return jsPeer == null ? null - : getConstantField(jsPeer, 'name', types.stringType) as String; - } + /// Emit class members that need to come after the class declaration, such + /// as static fields. See [_emitClassMethods] for things that are emitted + /// inside the ES6 `class { ... }` node. + JS.Statement _finishClassMembers( + ClassElement classElem, + JS.ClassExpression cls, + List ctors, + List fields, + List methods, + List metadata, + String jsPeerName) { + var name = classElem.name; + var body = []; - void _addClassJsPeerSetup(_ClassBuilder builder) { - var jsPeerName = builder.info.jsPeerName; - if (jsPeerName == null) return; + if (_extensionTypes.contains(classElem)) { + var dartxNames = []; + for (var m in methods) { + if (!m.isAbstract && !m.isStatic && m.element.isPublic) { + dartxNames.add(_elementMemberName(m.element, allowExtensions: false)); + } + } + if (dartxNames.isNotEmpty) { + body.add(js.statement('dart.defineExtensionNames(#)', + [new JS.ArrayInitializer(dartxNames, multiline: true)])); + } + } - ClassElement classElem = builder.info.element; + body.add(new JS.ClassDeclaration(cls)); // TODO(jmesserly): we should really just extend native Array. - if (classElem.typeParameters.isNotEmpty) { - builder.statements.add((classRef) => - js.statement('dart.setBaseClass(#, dart.global.#);', - [classRef, _propertyName(jsPeerName)])); - } - - // This class isn't allowed to be lazy, because we need to set up - // the native JS type eagerly at this point. - // If we wanted to support laziness, we could defer the hookup until - // the end of the Dart library cycle load. - assert(_loader.isLoaded(classElem)); - - // TODO(jmesserly): this copies the dynamic members. - // Probably fine for objects coming from JS, but not if we actually - // want to support construction of instances with generic types other - // than dynamic. See issue #154 for Array and List related bug. - builder.topLevelStatements.add( - js.statement( - 'dart.registerExtension(dart.global.#, #);', [ - _propertyName(jsPeerName), - classElem.name - ])); - } - void _addClassInterfaces(_ClassBuilder builder) { - ClassElement classElem = builder.info.element; - if (classElem.interfaces.isNotEmpty) { - builder.statements.add((classRef) => - js.statement('#[dart.implements] = () => #;', [ - classRef, - new JS.ArrayInitializer(new List.from( - classElem.interfaces.map(_emitTypeName))) - ])); + if (jsPeerName != null && classElem.typeParameters.isNotEmpty) { + body.add(js.statement('dart.setBaseClass(#, dart.global.#);', + [classElem.name, _propertyName(jsPeerName)])); } - } - /// Emit statements for members that need to come after the class declaration, - /// such as static fields. See [_emitClassMethods] for things that are emitted - /// inside the ES6 `class { ... }` node. - void _addClassMemberSignatures(_ClassBuilder builder) { - - var ctors = builder.info.ctors; - var methods = builder.info.methods; + // Interfaces + if (classElem.interfaces.isNotEmpty) { + body.add(js.statement('#[dart.implements] = () => #;', [ + name, + new JS.ArrayInitializer(new List.from( + classElem.interfaces.map(_emitTypeName))) + ])); + } + + // Named constructors + for (ConstructorDeclaration member in ctors) { + if (member.name != null && member.factoryKeyword == null) { + body.add(js.statement('dart.defineNamedConstructor(#, #);', + [name, _emitMemberName(member.name.name, isStatic: true)])); + } + } - ClassElement classElem = builder.info.element; + // Instance fields, if they override getter/setter pairs + for (FieldDeclaration member in fields) { + for (VariableDeclaration fieldDecl in member.fields.variables) { + var field = fieldDecl.element as FieldElement; + if (_fieldsNeedingStorage.contains(field)) { + body.add(_overrideField(field)); + } + } + } // Emit the signature on the class recording the runtime type information { @@ -897,8 +788,8 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { } if (!sigFields.isEmpty) { var sig = new JS.ObjectInitializer(sigFields); - builder.statements.add((classRef) => - js.statement('dart.setSignature(#, #);', [classRef, sig])); + var classExpr = new JS.Identifier(name); + body.add(js.statement('dart.setSignature(#, #);', [classExpr, sig])); } } @@ -910,27 +801,23 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { for (var e in extensions) { methodNames.add(_elementMemberName(e)); } - builder.statements.add((classRef) => - js.statement('dart.defineExtensionMembers(#, #);', [ - classRef, - new JS.ArrayInitializer(methodNames, - multiline: methodNames.length > 4) - ])); + body.add(js.statement('dart.defineExtensionMembers(#, #);', [ + name, + new JS.ArrayInitializer(methodNames, multiline: methodNames.length > 4) + ])); } - } - void _addClassMetadata(_ClassBuilder builder) { - var metadata = builder.info.declaration?.metadata ?? const []; // TODO(vsm): Make this optional per #268. // Metadata if (metadata.isNotEmpty) { - builder.statements.add((classRef) => - js.statement('#[dart.metadata] = () => #;', [ - classRef, - new JS.ArrayInitializer( - new List.from(metadata.map(_instantiateAnnotation))) - ])); + body.add(js.statement('#[dart.metadata] = () => #;', [ + name, + new JS.ArrayInitializer( + new List.from(metadata.map(_instantiateAnnotation))) + ])); } + + return _statement(body); } List _extensionsToImplement(ClassElement element) { @@ -975,6 +862,12 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { _collectExtensions(type.superclass, types); } + JS.Statement _overrideField(FieldElement e) { + var cls = e.enclosingElement; + return js.statement('dart.virtualField(#, #)', + [cls.name, _emitMemberName(e.name, type: cls.type)]); + } + /// Generates the implicit default constructor for class C of the form /// `C() : super() {}`. JS.Method _emitImplicitConstructor( @@ -1184,7 +1077,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { /// 3. constructor field initializers, /// 4. initialize fields not covered in 1-3 JS.Statement _initializeFields( - ClassDeclaration cls, Iterable fieldDecls, + ClassDeclaration cls, List fieldDecls, [ConstructorDeclaration ctor]) { var unit = cls.getAncestor((a) => a is CompilationUnit) as CompilationUnit; var constField = new ConstFieldVisitor(types, unit); @@ -1757,36 +1650,18 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { return _maybeQualifiedName(element, _propertyName(name)); } - JS.Expression _maybeQualifiedLocalType(String name) => - isPublic(name) && _qualifyExports - ? _maybeQualifiedName(currentLibrary, _propertyName(name)) - : new JS.Identifier(name); - JS.Expression _maybeQualifiedName(Element e, JS.Expression name, [Map idTable]) { - bool isPrivate = name is JS.LiteralString - && !isPublic(name.valueWithoutQuotes); - bool isCurrentLibrary = e.library == currentLibrary; + var libName = _libraryName(e.library); + if (idTable == null) idTable = _qualifiedIds; // Mutable top-level fields should always be qualified. bool mutableTopLevel = e is TopLevelVariableElement && !e.isConst; - - if (name is JS.LiteralString - && isCurrentLibrary - && !mutableTopLevel - && (isPrivate || !_qualifyExports)) { - return new JS.Identifier(name.valueWithoutQuotes); - } - var libName = _libraryName(e.library); - - if (!isCurrentLibrary - || _qualifyExports && !isPrivate - || mutableTopLevel) { + if (e.library != currentLibrary || mutableTopLevel) { return new JS.PropertyAccess(libName, name); } - return (idTable ?? _qualifiedIds) - .putIfAbsent(e, () => new JS.MaybeQualifiedId(libName, name)); + return idTable.putIfAbsent(e, () => new JS.MaybeQualifiedId(libName, name)); } @override @@ -2208,7 +2083,7 @@ class JSCodegenVisitor extends GeneralizingAstVisitor with ClosureAnnotator { JS.Expression objExpr = _exportsVar; var target = _lazyFields[0].element.enclosingElement; if (target is ClassElement) { - objExpr = _maybeQualifiedLocalType(target.type.name); + objExpr = new JS.Identifier(target.type.name); } return js.statement( diff --git a/pkg/dev_compiler/test/codegen/closure.dart b/pkg/dev_compiler/test/codegen/closure.dart index dea593d9c37f..d40e8a759476 100644 --- a/pkg/dev_compiler/test/codegen/closure.dart +++ b/pkg/dev_compiler/test/codegen/closure.dart @@ -15,7 +15,7 @@ class Foo { factory Foo.build() => new Foo(1, null); untyped_method(a, b) {} - + T pass(T t) => t; String typed_method( @@ -52,10 +52,8 @@ class Baz extends Foo with Bar { Baz(int i) : super(i, 123); } -class _Bam {} - void main(args) {} const String some_top_level_constant = "abc"; final String some_top_level_final = "abc"; -String some_top_level_var = "abc"; +String some_top_level_var = "abc"; \ No newline at end of file diff --git a/pkg/dev_compiler/test/codegen/expect/closure.js b/pkg/dev_compiler/test/codegen/expect/closure.js index 64b42127b957..0dbfa3770c32 100644 --- a/pkg/dev_compiler/test/codegen/expect/closure.js +++ b/pkg/dev_compiler/test/codegen/expect/closure.js @@ -3,12 +3,12 @@ dart_library.library('closure', null, /* Imports */[ 'dart/core', 'dart/js' ], /* Lazy imports */[ -], function(closure, dart, core, js) { +], function(exports, dart, core, js) { 'use strict'; let dartx = dart.dartx; /** @typedef {function({i: (?number|undefined)}=)} */ - closure.Callback = dart.typedef('Callback', () => dart.functionType(dart.void, [], {i: core.int})); - closure.Foo$ = dart.generic(function(T) { + let Callback = dart.typedef('Callback', () => dart.functionType(dart.void, [], {i: core.int})); + let Foo$ = dart.generic(function(T) { class Foo extends core.Object { /** * @param {?number} i @@ -22,7 +22,7 @@ dart_library.library('closure', null, /* Imports */[ } /** @return {Foo} */ static build() { - return new (closure.Foo$(T))(1, null); + return new (Foo$(T))(1, null); } /** * @param {?} a @@ -95,45 +95,39 @@ dart_library.library('closure', null, /* Imports */[ } dart.setSignature(Foo, { constructors: () => ({ - Foo: [closure.Foo$(T), [core.int, T]], - build: [closure.Foo$(T), []] + Foo: [Foo$(T), [core.int, T]], + build: [Foo$(T), []] }), methods: () => ({ untyped_method: [dart.dynamic, [dart.dynamic, dart.dynamic]], pass: [T, [T]], - typed_method: [core.String, [closure.Foo$(), core.List, core.int, core.num, core.double, core.bool, core.String, js.JsArray, js.JsObject, js.JsFunction]], + typed_method: [core.String, [Foo$(), core.List, core.int, core.num, core.double, core.bool, core.String, js.JsArray, js.JsObject, js.JsFunction]], optional_params: [dart.dynamic, [dart.dynamic], [dart.dynamic, dart.dynamic]], nullary_method: [dart.dynamic, []], - function_params: [dart.dynamic, [dart.functionType(core.int, [dart.dynamic], [dart.dynamic]), dart.functionType(dart.dynamic, [dart.dynamic], {y: core.String, z: dart.dynamic}), closure.Callback]] + function_params: [dart.dynamic, [dart.functionType(core.int, [dart.dynamic], [dart.dynamic]), dart.functionType(dart.dynamic, [dart.dynamic], {y: core.String, z: dart.dynamic}), Callback]] }), statics: () => ({named_params: [dart.dynamic, [dart.dynamic], {b: dart.dynamic, c: dart.dynamic}]}), names: ['named_params'] }); return Foo; }); - closure.Foo = closure.Foo$(); + let Foo = Foo$(); /** @final {string} */ - closure.Foo.some_static_constant = "abc"; + Foo.some_static_constant = "abc"; /** @final {string} */ - closure.Foo.some_static_final = "abc"; + Foo.some_static_final = "abc"; /** @type {string} */ - closure.Foo.some_static_var = "abc"; - closure.Bar = class Bar extends core.Object {}; - let Baz$super = dart.mixin(closure.Foo$(core.int), closure.Bar); - closure.Baz = class Baz extends Baz$super { + Foo.some_static_var = "abc"; + class Bar extends core.Object {} + class Baz extends dart.mixin(Foo$(core.int), Bar) { /** @param {?number} i */ Baz(i) { super.Foo(i, 123); } - }; - dart.setSignature(closure.Baz, { - constructors: () => ({Baz: [closure.Baz, [core.int]]}) - }); - let _Bam$ = dart.generic(function(M) { - class _Bam extends core.Object {} - return _Bam; + } + dart.setSignature(Baz, { + constructors: () => ({Baz: [Baz, [core.int]]}) }); - let _Bam = _Bam$(); /** @param {?} args */ function main(args) { } @@ -141,10 +135,15 @@ dart_library.library('closure', null, /* Imports */[ /** @final {string} */ let some_top_level_constant = "abc"; /** @final {string} */ - closure.some_top_level_final = "abc"; + exports.some_top_level_final = "abc"; /** @type {string} */ - closure.some_top_level_var = "abc"; + exports.some_top_level_var = "abc"; // Exports: - closure.main = main; - closure.some_top_level_constant = some_top_level_constant; + exports.Callback = Callback; + exports.Foo$ = Foo$; + exports.Foo = Foo; + exports.Bar = Bar; + exports.Baz = Baz; + exports.main = main; + exports.some_top_level_constant = some_top_level_constant; });