Skip to content

Commit

Permalink
[FEATURE beta] Passes the owner through to classic classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Garrett committed Apr 4, 2019
1 parent 02925ad commit 791b80b
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 5 deletions.
25 changes: 20 additions & 5 deletions packages/@ember/-internals/runtime/lib/system/core_object.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import { FACTORY_FOR } from '@ember/-internals/container';
import { assign, _WeakSet as WeakSet } from '@ember/polyfills';
import { getOwner, setOwner } from '@ember/-internals/owner';
import {
guidFor,
getName,
Expand Down Expand Up @@ -38,12 +39,12 @@ const factoryMap = new WeakMap();

const prototypeMixinMap = new WeakMap();

let PASSED_FROM_CREATE;
let passedFromCreate;
let initCalled; // only used in debug builds to enable the proxy trap

// using DEBUG here to avoid the extraneous variable when not needed
if (DEBUG) {
PASSED_FROM_CREATE = Symbol();
passedFromCreate = new WeakSet();
initCalled = new WeakSet();
}

Expand Down Expand Up @@ -201,7 +202,7 @@ class CoreObject {
factoryMap.set(this, factory);
}

constructor(properties) {
constructor(owner) {
// pluck off factory
let initFactory = factoryMap.get(this.constructor);
if (initFactory !== undefined) {
Expand Down Expand Up @@ -273,9 +274,11 @@ class CoreObject {
`An EmberObject based class, ${
this.constructor
}, was not instantiated correctly. You may have either used \`new\` instead of \`.create()\`, or not passed arguments to your call to super in the constructor: \`super(...arguments)\`. If you are trying to use \`new\`, consider using native classes without extending from EmberObject.`,
properties[PASSED_FROM_CREATE]
passedFromCreate.has(owner)
);

setOwner(this, owner);

// only return when in debug builds and `self` is the proxy created above
if (DEBUG && self !== this) {
return self;
Expand Down Expand Up @@ -749,7 +752,19 @@ class CoreObject {
*/
static create(props, extra) {
let C = this;
let instance = DEBUG ? new C(Object.freeze({ [PASSED_FROM_CREATE]: true })) : new C();

let owner = typeof props === 'object' && props !== null ? getOwner(props) : undefined;

if (DEBUG) {
owner = owner || {};
passedFromCreate.add(owner);
}

let instance = new C(owner);

if (DEBUG) {
passedFromCreate.delete(owner);
}

if (extra === undefined) {
initialize(instance, props);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,31 @@ moduleFor(
}, /You may have either used `new` instead of `.create\(\)`/);
}

['@test tunnels the owner through to the base constructor'](assert) {
assert.expect(2);

let owner = {};
let props = {
someOtherProp: 'foo',
};

setOwner(props, owner);

class Route extends CoreObject {
constructor() {
super(...arguments);
assert.equal(
getOwner(this),
owner,
'owner was assigned properly in the root constructor'
);
assert.equal(this.someOtherProp, undefined, 'other props were not yet assigned');
}
}

Route.create(props);
}

['@test toString should be not be added as a property when calling toString()'](assert) {
let obj = CoreObject.create({
firstName: 'Foo',
Expand Down

0 comments on commit 791b80b

Please sign in to comment.