Skip to content

Commit

Permalink
[bugfix] Fix proto return value for native classes
Browse files Browse the repository at this point in the history
Native classes end up calling the nearest class constructor, and with
the recent refactor those class constructors return their own prototype
instead of the class instance's. This breaks certain functions that
currently rely on the `proto` function return the prototype of the
instance itself. We're seeing failures in `@ember-decorators/data`
due to this bug.

This reverts to returning the protoype on the instance directly.
  • Loading branch information
pzuraq committed Apr 13, 2018
1 parent c58044b commit c93adc0
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
9 changes: 6 additions & 3 deletions packages/ember-runtime/lib/system/core_object.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,15 +241,15 @@ function makeCtor(base) {
};
}

Class.willReopen = () => {
Class.willReopen = function() {
if (wasApplied) {
Class.PrototypeMixin = Mixin.create(Class.PrototypeMixin);
}

wasApplied = false;
};

Class.proto = () => {
Class.proto = function() {
let superclass = Class.superclass;
if (superclass) {
superclass.proto();
Expand All @@ -260,7 +260,10 @@ function makeCtor(base) {
Class.PrototypeMixin.applyPartial(Class.prototype);
}

return Class.prototype;
// Native classes will call the nearest superclass's proto function,
// and proto is expected to return the current instance's prototype,
// so we need to return it from `this` instead
return this.prototype;
};

return Class;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import EmberObject from '../../../lib/system/object';
import { Mixin } from 'ember-metal';
import { Mixin, defineProperty, computed } from 'ember-metal';
import { moduleFor, AbstractTestCase } from 'internal-test-helpers';

moduleFor(
Expand Down Expand Up @@ -277,5 +277,24 @@ moduleFor(
assert.equal(obj.foo, 123, 'sets class fields on instance correctly');
assert.equal(obj.bar, 789, 'sets passed in properties on instance correctly');
}

['@test calling metaForProperty on a native class works'](assert) {
assert.expect(0);

class SubEmberObject extends EmberObject {}

defineProperty(
SubEmberObject.prototype,
'foo',
computed('foo', {
get() {
return 'bar';
},
})
);

// able to get meta without throwing an error
SubEmberObject.metaForProperty('foo');
}
}
);

0 comments on commit c93adc0

Please sign in to comment.