Skip to content

Commit 55944fb

Browse files
author
Suchita Doshi
committed
Handle non computed decorators
1 parent 268f664 commit 55944fb

File tree

5 files changed

+141
-40
lines changed

5 files changed

+141
-40
lines changed

transforms/tracked-properties/README.md

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@ npx ember-tracked-properties-codemod path/of/files/ or/some**/*glob.js
99
## Input / Output
1010

1111
<!--FIXTURES_TOC_START-->
12-
* [basic-with-prefix-false](#basic-with-prefix-false)
13-
* [basic](#basic)
14-
* [chained-complex-computed](#chained-complex-computed)
15-
* [chained-computed](#chained-computed)
16-
* [complex](#complex)
17-
* [with-tracked](#with-tracked)
18-
<!--FIXTURES_TOC_END-->
12+
13+
- [basic-with-prefix-false](#basic-with-prefix-false)
14+
- [basic](#basic)
15+
- [chained-complex-computed](#chained-complex-computed)
16+
- [chained-computed](#chained-computed)
17+
- [complex](#complex)
18+
- [non-computed-decorators](#non-computed-decorators)
19+
- [with-tracked](#with-tracked)
20+
<!--FIXTURES_TOC_END-->
1921

2022
## <!--FIXTURES_CONTENT_START-->
2123

@@ -269,6 +271,63 @@ export default class AddTeamComponent extends Component {
269271

270272
---
271273

274+
<a id="non-computed-decorators">**non-computed-decorators**</a>
275+
276+
**Input** (<small>[non-computed-decorators.input.js](__testfixtures__/non-computed-decorators.input.js)</small>):
277+
278+
```js
279+
import Component from '@ember/component';
280+
import { computed, get } from '@ember/object';
281+
import { alias } from '@ember/object/computed';
282+
283+
export default class Foo extends Component {
284+
bar;
285+
baz = 'barBaz';
286+
287+
@alias('model.isFoo')
288+
isFoo;
289+
290+
@computed('baz', 'isFoo')
291+
get bazInfo() {
292+
return get(this, 'isFoo') ? `Name: ${get(this, 'baz')}` : 'Baz';
293+
}
294+
295+
@computed('bar', 'isFoo').readOnly()
296+
get barInfo() {
297+
return get(this, 'isFoo') ? `Name: ${get(this, 'bab')}` : 'Bar';
298+
}
299+
}
300+
```
301+
302+
**Output** (<small>[non-computed-decorators.output.js](__testfixtures__/non-computed-decorators.output.js)</small>):
303+
304+
```js
305+
import { tracked } from '@glimmer/tracking';
306+
import Component from '@ember/component';
307+
import { computed, get } from '@ember/object';
308+
import { alias } from '@ember/object/computed';
309+
310+
export default class Foo extends Component {
311+
bar;
312+
@tracked baz = 'barBaz';
313+
314+
@alias('model.isFoo')
315+
isFoo;
316+
317+
@computed('isFoo')
318+
get bazInfo() {
319+
return get(this, 'isFoo') ? `Name: ${get(this, 'baz')}` : 'Baz';
320+
}
321+
322+
@computed('bar', 'isFoo').readOnly()
323+
get barInfo() {
324+
return get(this, 'isFoo') ? `Name: ${get(this, 'bab')}` : 'Bar';
325+
}
326+
}
327+
```
328+
329+
---
330+
272331
<a id="with-tracked">**with-tracked**</a>
273332

274333
**Input** (<small>[with-tracked.input.js](__testfixtures__/with-tracked.input.js)</small>):
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import Component from '@ember/component';
2+
import { computed, get } from '@ember/object';
3+
import { alias } from '@ember/object/computed';
4+
5+
export default class Foo extends Component {
6+
bar;
7+
baz = 'barBaz';
8+
9+
@alias('model.isFoo')
10+
isFoo;
11+
12+
@computed('baz', 'isFoo')
13+
get bazInfo() {
14+
return get(this, 'isFoo') ? `Name: ${get(this, 'baz')}` : 'Baz';
15+
}
16+
17+
@computed('bar', 'isFoo').readOnly()
18+
get barInfo() {
19+
return get(this, 'isFoo') ? `Name: ${get(this, 'bab')}` : 'Bar';
20+
}
21+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { tracked } from '@glimmer/tracking';
2+
import Component from '@ember/component';
3+
import { computed, get } from '@ember/object';
4+
import { alias } from '@ember/object/computed';
5+
6+
export default class Foo extends Component {
7+
bar;
8+
@tracked baz = 'barBaz';
9+
10+
@alias('model.isFoo')
11+
isFoo;
12+
13+
@computed('isFoo')
14+
get bazInfo() {
15+
return get(this, 'isFoo') ? `Name: ${get(this, 'baz')}` : 'Baz';
16+
}
17+
18+
@computed('bar', 'isFoo').readOnly()
19+
get barInfo() {
20+
return get(this, 'isFoo') ? `Name: ${get(this, 'bab')}` : 'Bar';
21+
}
22+
}

transforms/tracked-properties/index.js

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,28 @@ module.exports = function transformer(file, api) {
2525
path.node.body.forEach(classItem => {
2626
// Collect all the class properties in the file and add it to the
2727
// classProps array.
28-
if (classItem.type === 'ClassProperty') {
28+
if (classItem.type === 'ClassProperty' && !classItem.decorators) {
2929
classProps.push(classItem.key.name);
3030
}
3131
// Collect all the dependent keys of the computed properties present in the file
3232
// and add it to the computedProps array.
33-
if (classItem.type === 'ClassMethod') {
34-
if (classItem.kind === 'get') {
35-
classProps.push(classItem.key.name);
36-
}
37-
if (classItem.decorators) {
38-
classItem.decorators.forEach(decoratorItem => {
39-
if (
40-
decoratorItem.expression.callee &&
41-
decoratorItem.expression.callee.name === 'computed'
42-
) {
43-
const argValues = decoratorItem.expression.arguments.map(
44-
item => item.value
45-
);
46-
computedPropsMap[classItem.key.name] = argValues;
47-
computedProps = computedProps.concat(argValues);
48-
}
49-
});
50-
}
33+
if (
34+
classItem.type === 'ClassMethod' &&
35+
classItem.kind === 'get' &&
36+
classItem.decorators
37+
) {
38+
classItem.decorators.forEach(decoratorItem => {
39+
if (
40+
decoratorItem.expression.callee &&
41+
decoratorItem.expression.callee.name === 'computed'
42+
) {
43+
const argValues = decoratorItem.expression.arguments.map(
44+
item => item.value
45+
);
46+
computedPropsMap[classItem.key.name] = argValues;
47+
computedProps = computedProps.concat(argValues);
48+
}
49+
});
5150
}
5251
});
5352
});
@@ -61,14 +60,14 @@ module.exports = function transformer(file, api) {
6160
let trackedConvertedSource = j(file.source)
6261
.find(j.ClassProperty)
6362
.forEach(path => {
64-
if (computedProps.includes(path.node.key.name)) {
63+
if (!path.node.decorators && computedProps.includes(path.node.key.name)) {
6564
shouldImportBeAdded = true;
66-
var decorated = buildTrackedDecorator(
67-
path.node.key.name,
68-
path.node.value,
69-
j
70-
);
71-
path.replace(decorated);
65+
const trackedDecorator = buildTrackedDecorator(path.node.key.name, j);
66+
67+
// @TODO: Determine if @tracked can be prefixed alongside other decorators in a property,
68+
// if yes, then change this code to push the trackedDecorator along with the
69+
// others.
70+
path.node.decorators = trackedDecorator;
7271
}
7372
return path;
7473
})

transforms/tracked-properties/utils/helper.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ function _doesContainNonLocalArgs(argItem, computedMap, classProperties) {
5959

6060
while (stack.size() > 0) {
6161
currItem = stack.pop();
62-
// If currItem is not a class property, return true.
63-
if (!classProperties.includes(currItem)) {
62+
const dependentKeys = computedMap[currItem];
63+
64+
// If currItem is not a class property and
65+
// if it is not a computed property with dependent keys, return true.
66+
if (!classProperties.includes(currItem) && !dependentKeys) {
6467
return true;
6568
}
6669
// If currItem itself is a computed property, then it would have dependent keys.
6770
// Get the dependent keys and push them in the stack.
68-
const dependentKeys = computedMap[currItem];
6971
if (dependentKeys) {
7072
stack.push(...dependentKeys);
7173
}
@@ -78,15 +80,13 @@ function _doesContainNonLocalArgs(argItem, computedMap, classProperties) {
7880
* the key and values provided.
7981
* @param {*} macroName
8082
* @param {*} name
81-
* @param {*} value
8283
* @param {*} j
8384
*/
84-
function buildTrackedDecorator(name, value, j) {
85+
function buildTrackedDecorator(name, j) {
8586
var node = j('class Fake { @tracked' + ' ' + name + '; \n}')
8687
.find(j.ClassProperty)
8788
.get().node;
88-
node.value = value;
89-
return node;
89+
return node.decorators;
9090
}
9191

9292
/**

0 commit comments

Comments
 (0)