diff --git a/packages/ember-application/lib/ext/controller.js b/packages/ember-application/lib/ext/controller.js index 96e3110e358..eb2d7622ece 100644 --- a/packages/ember-application/lib/ext/controller.js +++ b/packages/ember-application/lib/ext/controller.js @@ -6,7 +6,7 @@ import Ember from "ember-metal/core"; // Ember.assert import { get } from "ember-metal/property_get"; import EmberError from "ember-metal/error"; -import { inspect, meta } from "ember-metal/utils"; +import { inspect } from "ember-metal/utils"; import { computed } from "ember-metal/computed"; import ControllerMixin from "ember-runtime/mixins/controller"; import controllerFor from "ember-routing/system/controller_for"; @@ -131,7 +131,7 @@ ControllerMixin.reopen({ Ember.assert(' `' + inspect(this) + ' specifies `needs`, but does ' + "not have a container. Please ensure this controller was " + "instantiated with a container.", - this.container || meta(this, false).descs.controllers !== defaultControllersComputedProperty); + this.container || this.controllers !== defaultControllersComputedProperty); if (this.container) { verifyNeedsDependencies(this, this.container, needs); diff --git a/packages/ember-htmlbars/lib/system/append-templated-view.js b/packages/ember-htmlbars/lib/system/append-templated-view.js index d6d65573755..9b42b47fbca 100644 --- a/packages/ember-htmlbars/lib/system/append-templated-view.js +++ b/packages/ember-htmlbars/lib/system/append-templated-view.js @@ -22,7 +22,10 @@ export default function appendTemplatedView(parentView, morph, viewClassOrInstan // We only want to override the `_context` computed property if there is // no specified controller. See View#_context for more information. - if (!viewProto.controller && + + var noControllerInProto = !viewProto.controller; + if (viewProto.controller.isDescriptor) { noControllerInProto = true; } + if (noControllerInProto && !viewProto.controllerBinding && !props.controller && !props.controllerBinding) { diff --git a/packages/ember-metal/lib/alias.js b/packages/ember-metal/lib/alias.js index 1ccb8f8a544..124a30e8420 100644 --- a/packages/ember-metal/lib/alias.js +++ b/packages/ember-metal/lib/alias.js @@ -22,6 +22,7 @@ export default function alias(altKey) { } export function AliasedProperty(altKey) { + this.isDescriptor = true; this.altKey = altKey; this._dependentKeys = [altKey]; } diff --git a/packages/ember-metal/lib/chains.js b/packages/ember-metal/lib/chains.js index 7b51fde20e7..7eaf1411421 100644 --- a/packages/ember-metal/lib/chains.js +++ b/packages/ember-metal/lib/chains.js @@ -119,7 +119,8 @@ function lazyGet(obj, key) { } // if a CP only return cached value - var desc = meta && meta.descs[key]; + var possibleDesc = obj[key]; + var desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; if (desc && desc._cacheable) { if (key in meta.cache) { return meta.cache[key]; diff --git a/packages/ember-metal/lib/computed.js b/packages/ember-metal/lib/computed.js index 955eededcaa..3d4743fabc4 100644 --- a/packages/ember-metal/lib/computed.js +++ b/packages/ember-metal/lib/computed.js @@ -113,6 +113,7 @@ function UNDEFINED() { } @constructor */ function ComputedProperty(config, opts) { + this.isDescriptor = true; if (Ember.FEATURES.isEnabled("new-computed-syntax")) { if (typeof config === "function") { config.__ember_arity = config.length; diff --git a/packages/ember-metal/lib/injected_property.js b/packages/ember-metal/lib/injected_property.js index 24d1fe88c12..ea53ac0de42 100644 --- a/packages/ember-metal/lib/injected_property.js +++ b/packages/ember-metal/lib/injected_property.js @@ -3,7 +3,6 @@ import { ComputedProperty } from "ember-metal/computed"; import { AliasedProperty } from "ember-metal/alias"; import { Descriptor } from "ember-metal/properties"; import create from "ember-metal/platform/create"; -import { meta } from "ember-metal/utils"; /** Read-only property that returns the result of a container lookup. @@ -25,7 +24,8 @@ function InjectedProperty(type, name) { } function injectedPropertyGet(keyName) { - var desc = meta(this).descs[keyName]; + var possibleDesc = this[keyName]; + var desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; Ember.assert("Attempting to lookup an injected property on an object " + "without a container, ensure that the object was " + diff --git a/packages/ember-metal/lib/mixin.js b/packages/ember-metal/lib/mixin.js index 686f20f64aa..e08df96dbc0 100644 --- a/packages/ember-metal/lib/mixin.js +++ b/packages/ember-metal/lib/mixin.js @@ -128,7 +128,7 @@ function concatenatedMixinProperties(concatProp, props, values, base) { return concats; } -function giveDescriptorSuper(meta, key, property, values, descs) { +function giveDescriptorSuper(meta, key, property, values, descs, base) { var superProperty; // Computed properties override methods, and do not call super to them @@ -139,7 +139,12 @@ function giveDescriptorSuper(meta, key, property, values, descs) { // If we didn't find the original descriptor in a parent mixin, find // it on the original object. - superProperty = superProperty || meta.descs[key]; + if (!superProperty) { + var possibleDesc = base[key]; + var superDesc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; + + superProperty = superDesc; + } if (superProperty === undefined || !(superProperty instanceof ComputedProperty)) { return property; @@ -256,7 +261,7 @@ function addNormalizedProperty(base, key, value, meta, descs, values, concats, m // Wrap descriptor function to implement // __nextSuper() if needed if (value._getter) { - value = giveDescriptorSuper(meta, key, value, values, descs); + value = giveDescriptorSuper(meta, key, value, values, descs, base); } descs[key] = value; @@ -388,11 +393,12 @@ function finishPartial(obj, m) { function followAlias(obj, desc, m, descs, values) { var altKey = desc.methodName; var value; + var possibleDesc; if (descs[altKey] || values[altKey]) { value = values[altKey]; desc = descs[altKey]; - } else if (m.descs[altKey]) { - desc = m.descs[altKey]; + } else if ((possibleDesc = obj[altKey]) && possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) { + desc = possibleDesc; value = undefined; } else { desc = undefined; @@ -743,6 +749,7 @@ export function required() { } function Alias(methodName) { + this.isDescriptor = true; this.methodName = methodName; } diff --git a/packages/ember-metal/lib/properties.js b/packages/ember-metal/lib/properties.js index a94abd6d4c4..aad6d4d6c53 100644 --- a/packages/ember-metal/lib/properties.js +++ b/packages/ember-metal/lib/properties.js @@ -24,7 +24,9 @@ import { overrideChains } from "ember-metal/property_events"; @private @constructor */ -export function Descriptor() {} +export function Descriptor() { + this.isDescriptor = true; +} // .......................................................... // DEFINING PROPERTIES API @@ -89,42 +91,40 @@ export function DEFAULT_GETTER_FUNCTION(name) { become the explicit value of this property. */ export function defineProperty(obj, keyName, desc, data, meta) { - var descs, existingDesc, watching, value; + var possibleDesc, existingDesc, watching, value; if (!meta) { meta = metaFor(obj); } - descs = meta.descs; - existingDesc = meta.descs[keyName]; var watchEntry = meta.watching[keyName]; + possibleDesc = obj[keyName]; + existingDesc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; watching = watchEntry !== undefined && watchEntry > 0; - if (existingDesc instanceof Descriptor) { + if (existingDesc) { existingDesc.teardown(obj, keyName); } if (desc instanceof Descriptor) { value = desc; - descs[keyName] = desc; if (Ember.FEATURES.isEnabled('mandatory-setter')) { if (watching && hasPropertyAccessors) { objectDefineProperty(obj, keyName, { configurable: true, enumerable: true, writable: true, - value: undefined // make enumerable + value: value }); } else { - obj[keyName] = undefined; // make enumerable + obj[keyName] = value; } } else { - obj[keyName] = undefined; // make enumerable + obj[keyName] = value; } if (desc.setup) { desc.setup(obj, keyName); } } else { - descs[keyName] = undefined; // shadow descriptor in proto if (desc == null) { value = data; diff --git a/packages/ember-metal/lib/property_events.js b/packages/ember-metal/lib/property_events.js index 2da12078e5b..59ddb50e879 100644 --- a/packages/ember-metal/lib/property_events.js +++ b/packages/ember-metal/lib/property_events.js @@ -35,7 +35,8 @@ function propertyWillChange(obj, keyName) { var m = obj['__ember_meta__']; var watching = (m && m.watching[keyName] > 0) || keyName === 'length'; var proto = m && m.proto; - var desc = m && m.descs[keyName]; + var possibleDesc = obj[keyName]; + var desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; if (!watching) { return; @@ -73,7 +74,8 @@ function propertyDidChange(obj, keyName) { var m = obj['__ember_meta__']; var watching = (m && m.watching[keyName] > 0) || keyName === 'length'; var proto = m && m.proto; - var desc = m && m.descs[keyName]; + var possibleDesc = obj[keyName]; + var desc = (possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) ? possibleDesc : undefined; if (proto === obj) { return; @@ -150,7 +152,7 @@ function keysOf(obj) { } function iterDeps(method, obj, deps, depKey, seen, meta) { - var keys, key, i, desc; + var keys, key, i, possibleDesc, desc; var guid = guidFor(obj); var current = seen[guid]; @@ -166,10 +168,10 @@ function iterDeps(method, obj, deps, depKey, seen, meta) { if (deps) { keys = keysOf(deps); - var descs = meta.descs; for (i=0; i