diff --git a/closure.log b/closure.log index 0d8578eca4..994df1c3d1 100644 --- a/closure.log +++ b/closure.log @@ -5,43 +5,11 @@ Found : undefined return window.Polymer._polymerFn(info); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -/polymer.html_script_1.js:44: WARNING - The right side in the assignment is not a subtype of the left side. -Expected : T -Found : Function|null -More details: -The found type is a union that includes an unexpected type: null - mixin = cachingMixin(mixin); - ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -/polymer.html_script_1.js:44: WARNING - Invalid type for parameter 1 of function cachingMixin. -Expected : Function|null -Found : T - - mixin = cachingMixin(mixin); - ^^^^^ - -/polymer.html_script_1.js:46: WARNING - Cannot create property __dedupeId on non-object type T. - mixin.__dedupeId = ++dedupeId; - ^^^^^ - -/polymer.html_script_1.js:47: WARNING - Returned type does not match declared return type. -Expected : T -Found : function({__mixinSet:?} (loose)):{__mixinSet:?} (loose) - - return function(base) { - ^^^^^^^^^^^^^^^^^^^^^^^ - -/polymer.html_script_1.js:49: WARNING - Cannot access property __dedupeId of non-object type T. - if (baseSet && baseSet[mixin.__dedupeId]) { - ^^^^^ - -/polymer.html_script_1.js:52: WARNING - Cannot call non-function type T - let extended = mixin(base); - ^^^^^^^^^^^ - -/polymer.html_script_1.js:58: WARNING - Cannot access property __dedupeId of non-object type T. - extended.__mixinSet[mixin.__dedupeId] = true; - ^^^^^ +/polymer.html_script_1.js:59: WARNING - invalid cast - the types do not have a common subtype +from: function(?=):? +to : T + return /** @type {T} */(dedupingMixin); + ^^^^^^^^^^^^^^^ /polymer.html_script_10.js:144: WARNING - Property name never defined on trigger of type Object let triggerPath = trigger.name; @@ -1378,4 +1346,4 @@ externs/closure-types.js:762: WARNING - property toggle on interface Polymer_Arr Polymer_ArraySelectorMixin.prototype.toggle; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -0 error(s), 299 warning(s), 72.7% typed +0 error(s), 293 warning(s), 72.8% typed diff --git a/lib/utils/mixin.html b/lib/utils/mixin.html index 9ed0237663..b0f8fb1c62 100644 --- a/lib/utils/mixin.html +++ b/lib/utils/mixin.html @@ -20,26 +20,14 @@ let dedupeId = 0; /** - * Given a mixin producing function, memoize applications of mixin to base - * @private - * @param {Function} mixin Mixin for which to create a caching mixin. - * @return {Function} Returns a mixin which when applied multiple times to the - * same base will always return the same extended class. + * @constructor + * @extends {Function} */ - function cachingMixin(mixin) { - return function(base) { - if (!mixin.__mixinApplications) { - mixin.__mixinApplications = new WeakMap(); - } - let map = mixin.__mixinApplications; - let application = map.get(base); - if (!application) { - application = mixin(base); - map.set(base, application); - } - return application; - }; - } + function MixinFunction(){} + /** @type {(WeakMap | undefined)} */ + MixinFunction.prototype.__mixinApplications; + /** @type {(Object | undefined)} */ + MixinFunction.prototype.__mixinSet; /** * Wraps an ES6 class expression mixin such that the mixin is only applied @@ -53,23 +41,34 @@ * mixin applications to base */ Polymer.dedupingMixin = function(mixin) { - mixin = cachingMixin(mixin); + let mixinApplications = /** @type {!MixinFunction} */(mixin).__mixinApplications; + if (!mixinApplications) { + mixinApplications = new WeakMap(); + /** @type {!MixinFunction} */(mixin).__mixinApplications = mixinApplications; + } // maintain a unique id for each mixin - mixin.__dedupeId = ++dedupeId; - return function(base) { - let baseSet = base.__mixinSet; - if (baseSet && baseSet[mixin.__dedupeId]) { + let mixinDedupeId = dedupeId++; + function dedupingMixin(base) { + let baseSet = /** @type {!MixinFunction} */(base).__mixinSet; + if (baseSet && baseSet[mixinDedupeId]) { return base; } - let extended = mixin(base); + let map = mixinApplications; + let extended = map.get(base); + if (!extended) { + extended = /** @type {!Function} */(mixin)(base); + map.set(base, extended); + } // copy inherited mixin set from the extended class, or the base class // NOTE: we avoid use of Set here because some browser (IE11) // cannot extend a base Set via the constructor. - extended.__mixinSet = - Object.create(extended.__mixinSet || baseSet || null); - extended.__mixinSet[mixin.__dedupeId] = true; + let mixinSet = Object.create(/** @type {!MixinFunction} */(extended).__mixinSet || baseSet || null); + mixinSet[mixinDedupeId] = true; + /** @type {!MixinFunction} */(extended).__mixinSet = mixinSet; return extended; } + + return /** @type {T} */(dedupingMixin); }; })();