Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove .volatile() #19670

Merged
merged 1 commit into from
Jul 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 4 additions & 84 deletions packages/@ember/-internals/metal/lib/computed.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Meta, meta as metaFor } from '@ember/-internals/meta';
import { inspect, toString } from '@ember/-internals/utils';
import { assert, deprecate, warn } from '@ember/debug';
import { assert, warn } from '@ember/debug';
import EmberError from '@ember/error';
import { isDestroyed } from '@glimmer/destroyable';
import { DEBUG } from '@glimmer/env';
Expand Down Expand Up @@ -249,7 +249,6 @@ function noop(): void {}
@public
*/
export class ComputedProperty extends ComputedDescriptor {
_volatile = false;
_readOnly = false;
protected _hasConfig = false;

Expand Down Expand Up @@ -370,10 +369,6 @@ export class ComputedProperty extends ComputedDescriptor {
}

get(obj: object, keyName: string): any {
if (this._volatile) {
return this._getter!.call(obj, keyName);
}

let meta = metaFor(obj);
let tagMeta = tagMetaFor(obj);

Expand Down Expand Up @@ -435,10 +430,6 @@ export class ComputedProperty extends ComputedDescriptor {
this._setter !== undefined
);

if (this._volatile) {
return this.volatileSet(obj, keyName, value);
}

let meta = metaFor(obj);

// ensure two way binding works when the component has defined a computed
Expand Down Expand Up @@ -500,10 +491,6 @@ export class ComputedProperty extends ComputedDescriptor {
throw new EmberError(`Cannot set read-only property "${keyName}" on object: ${inspect(obj)}`);
}

volatileSet(obj: object, keyName: string, value: any): any {
return this._setter!.call(obj, keyName, value);
}

_set(obj: object, keyName: string, value: unknown, meta: Meta): any {
let hadCachedValue = meta.revisionFor(keyName) !== undefined;
let cachedValue = meta.valueFor(keyName);
Expand Down Expand Up @@ -533,11 +520,9 @@ export class ComputedProperty extends ComputedDescriptor {

/* called before property is overridden */
teardown(obj: object, keyName: string, meta: Meta): void {
if (!this._volatile) {
if (meta.revisionFor(keyName) !== undefined) {
meta.setRevisionFor(keyName, undefined);
meta.setValueFor(keyName, undefined);
}
if (meta.revisionFor(keyName) !== undefined) {
meta.setRevisionFor(keyName, undefined);
meta.setValueFor(keyName, undefined);
}

super.teardown(obj, keyName, meta);
Expand All @@ -546,10 +531,6 @@ export class ComputedProperty extends ComputedDescriptor {

class AutoComputedProperty extends ComputedProperty {
get(obj: object, keyName: string): any {
if (this._volatile) {
return this._getter!.call(obj, keyName);
}

let meta = metaFor(obj);
let tagMeta = tagMetaFor(obj);

Expand Down Expand Up @@ -648,67 +629,6 @@ class ComputedDecoratorImpl extends Function {
return this;
}

/**
Call on a computed property to set it into non-cached mode. When in this
mode the computed property will not automatically cache the return value.
It also does not automatically fire any change events. You must manually notify
any changes if you want to observe this property.

Dependency keys have no effect on volatile properties as they are for cache
invalidation and notification when cached value is invalidated.

Example:

```javascript
import { computed } from '@ember/object';

class CallCounter {
_calledCount = 0;

@computed().volatile()
get calledCount() {
return this._calledCount++;
}
}
```

Classic Class Example:

```javascript
import EmberObject, { computed } from '@ember/object';

let CallCounter = EmberObject.extend({
_calledCount: 0,

value: computed(function() {
return this._calledCount++;
}).volatile()
});
```
@method volatile
@deprecated
@return {ComputedProperty} this
@chainable
@public
*/
volatile(this: Decorator) {
deprecate(
'Setting a computed property as volatile has been deprecated. Instead, consider using a native getter with native class syntax.',
false,
{
id: 'computed-property.volatile',
until: '4.0.0',
url: 'https://deprecations.emberjs.com/v3.x#toc_computed-property-volatile',
for: 'ember-source',
since: {
enabled: '3.9.0-beta.1',
},
}
);
(descriptorForDecorator(this) as ComputedProperty)._volatile = true;
return this;
}

/**
In some cases, you may want to annotate computed properties with additional
metadata about how they function or what values they operate on. For example,
Expand Down
1 change: 0 additions & 1 deletion packages/@ember/-internals/metal/lib/mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ function giveDecoratorSuper(
]);

newProperty._readOnly = property._readOnly;
newProperty._volatile = property._volatile;
newProperty._meta = property._meta;
newProperty.enumerable = property.enumerable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,120 +298,83 @@ moduleFor(
beforeEach() {
lookup = context.lookup = {};

expectDeprecation(() => {
object = ObservableObject.extend({
computed: computed({
get() {
this.computedCalls.push('getter-called');
return 'computed';
},
set(key, value) {
this.computedCalls.push(value);
},
}).volatile(),

computedCached: computed({
get() {
this.computedCachedCalls.push('getter-called');
return 'computedCached';
},
set: function (key, value) {
this.computedCachedCalls.push(value);
},
}),
object = ObservableObject.extend({
computed: computed({
get() {
this.computedCalls.push('getter-called');
return 'computed';
},
set(key, value) {
this.computedCalls.push(value);
},
}),

dependent: computed('changer', {
get() {
this.dependentCalls.push('getter-called');
return 'dependent';
},
set(key, value) {
this.dependentCalls.push(value);
},
}).volatile(),
dependentFront: computed('changer', {
get() {
this.dependentFrontCalls.push('getter-called');
return 'dependentFront';
},
set(key, value) {
this.dependentFrontCalls.push(value);
},
}).volatile(),
dependentCached: computed('changer', {
get() {
this.dependentCachedCalls.push('getter-called!');
return 'dependentCached';
},
set(key, value) {
this.dependentCachedCalls.push(value);
},
}),
dependent: computed('changer', {
get() {
this.dependentCalls.push('getter-called');
return 'dependent';
},
set(key, value) {
this.dependentCalls.push(value);
},
}),

inc: computed('changer', function () {
return this.incCallCount++;
}),
inc: computed('changer', function () {
return this.incCallCount++;
}),

nestedInc: computed('inc', function () {
get(this, 'inc');
return this.nestedIncCallCount++;
}),
nestedInc: computed('inc', function () {
get(this, 'inc');
return this.nestedIncCallCount++;
}),

isOn: computed('state', {
get() {
return this.get('state') === 'on';
},
set() {
this.set('state', 'on');
return this.get('state') === 'on';
},
}).volatile(),

isOff: computed('state', {
get() {
return this.get('state') === 'off';
},
set() {
this.set('state', 'off');
return this.get('state') === 'off';
},
}).volatile(),
}).create({
computedCalls: [],
computedCachedCalls: [],
changer: 'foo',
dependentCalls: [],
dependentFrontCalls: [],
dependentCachedCalls: [],
incCallCount: 0,
nestedIncCallCount: 0,
state: 'on',
});
isOn: computed('state', {
get() {
return this.get('state') === 'on';
},
set() {
this.set('state', 'on');
return this.get('state') === 'on';
},
}),

isOff: computed('state', {
get() {
return this.get('state') === 'off';
},
set() {
this.set('state', 'off');
return this.get('state') === 'off';
},
}),
}).create({
computedCalls: [],
changer: 'foo',
dependentCalls: [],
incCallCount: 0,
nestedIncCallCount: 0,
state: 'on',
});
}

['@test getting values should call function return value'](assert) {
// get each property twice. Verify return.
let keys = w('computed computedCached dependent dependentFront dependentCached');
let keys = w('computed dependent');

keys.forEach(function (key) {
assert.equal(object.get(key), key, `Try #1: object.get(${key}) should run function`);
assert.equal(object.get(key), key, `Try #2: object.get(${key}) should run function`);
});

// verify each call count. cached should only be called once
w('computedCalls dependentFrontCalls dependentCalls').forEach((key) => {
assert.equal(object[key].length, 2, `non-cached property ${key} should be called 2x`);
});

w('computedCachedCalls dependentCachedCalls').forEach((key) => {
// verify each call count. cached should only be called once
w('computedCalls dependentCalls').forEach((key) => {
assert.equal(object[key].length, 1, `non-cached property ${key} should be called 1x`);
});
}

['@test setting values should call function return value'](assert) {
// get each property twice. Verify return.
let keys = w('computed dependent dependentFront computedCached dependentCached');
let keys = w('computed dependent');
let values = w('value1 value2');

keys.forEach((key) => {
Expand Down Expand Up @@ -459,13 +422,13 @@ moduleFor(

['@test notify change should clear cache'](assert) {
// call get several times to collect call count
object.get('computedCached'); // should run func
object.get('computedCached'); // should not run func
object.get('computed'); // should run func
object.get('computed'); // should not run func

object.notifyPropertyChange('computedCached');
object.notifyPropertyChange('computed');

object.get('computedCached'); // should run again
assert.equal(object.computedCachedCalls.length, 2, 'should have invoked method 2x');
object.get('computed'); // should run again
assert.equal(object.computedCalls.length, 2, 'should have invoked method 2x');
}

['@test change dependent should clear cache'](assert) {
Expand Down
1 change: 0 additions & 1 deletion tests/docs/expected.js
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,6 @@ module.exports = {
'validationCache',
'value',
'visit',
'volatile',
'w',
'wait',
'waitForDOMReady',
Expand Down