|
1 | 1 | import { get } from '../utils/get';
|
2 |
| -import { getCaller } from '../utils/caller'; |
3 |
| - |
4 |
| - |
5 |
| -function isCPDesc(node, method) { |
6 |
| - if (node.type !== "FunctionExpression") { |
7 |
| - return false; |
8 |
| - } |
9 |
| - |
10 |
| - if (get(node, "parent.key.name") !== method) { |
11 |
| - return false; |
12 |
| - } |
13 |
| - |
14 |
| - let grandParent = get(node, "parent.parent"); |
15 |
| - if (!grandParent) { |
16 |
| - return false; |
17 |
| - } |
18 |
| - if (grandParent.type !== "ObjectExpression") { |
19 |
| - return false; |
20 |
| - } |
21 |
| - var greatGrandParent = pParent.parent; // more parents! |
22 |
| - if (greatGrandParent.type !== "CallExpression") { |
23 |
| - return false; |
24 |
| - } |
25 |
| - var callee = greatGrandParent.callee; |
26 |
| - if (greatGrandParent.type === "Identifier" && callee.name === "computed") { |
27 |
| - return true; |
28 |
| - } |
29 |
| - if (callee.type === "MemberExpression") { |
30 |
| - var caller = getCaller(callee); |
31 |
| - return caller === "Ember.computed" || caller === "Em.computed"; |
32 |
| - } |
33 |
| - return false; // don't know how you could get here |
34 |
| -} |
35 |
| - |
36 |
| -function _isCpGetter2(node) { |
37 |
| - if (node.type !== "FunctionExpression") { |
38 |
| - return false; |
39 |
| - } |
40 |
| - var parent = node.parent; |
41 |
| - if (parent.type !== "CallExpression") { |
42 |
| - return false; |
43 |
| - } |
44 |
| - var callee = parent.callee; |
45 |
| - if (callee.type === "Identifier" && callee.name === "computed") { |
46 |
| - return true; |
47 |
| - } |
48 |
| - if (callee.type === "MemberExpression") { |
49 |
| - var caller = n.getCaller(callee); |
50 |
| - return caller === "Ember.computed" || caller === "Em.computed"; |
51 |
| - } |
52 |
| - return false; |
53 |
| -} |
54 |
| - |
55 |
| -function isCpGetter(node) { |
56 |
| - return isCPDesc(node, 'get') || isCPAccessor(node) |
57 |
| -} |
| 2 | +import { getCaller, cleanCaller } from '../utils/caller'; |
| 3 | +import { isCPGetter } from '../utils/computer-property'; |
58 | 4 |
|
| 5 | +const SENDERS = ['send', 'sendAction', 'sendEvent', 'Em.sendEvent', 'Ember.sendEvent']; |
59 | 6 |
|
60 | 7 | export default function noActionCp(context) {
|
61 |
| - |
| 8 | + let inCPGettter = false; |
| 9 | + |
| 10 | + return { |
| 11 | + FunctionExpression(node) { |
| 12 | + if (isCPGetter(node)) { |
| 13 | + inCPGettter = true; |
| 14 | + } |
| 15 | + }, |
| 16 | + 'FunctionExpression:exit'(node) { |
| 17 | + if (isCPGetter(node)) { |
| 18 | + inCPGettter = false; |
| 19 | + } |
| 20 | + }, |
| 21 | + CallExpression(node) { |
| 22 | + if (inCPGettter) { |
| 23 | + let caller = cleanCaller(getCaller(node)); |
| 24 | + |
| 25 | + if (SENDERS.indexOf(caller) !== -1) { |
| 26 | + context.report(node, 'Do not send events or actions in Computed Properties. This will cause data flow issues in the application, where the accessing of a property causes some side-effect. You should only send actions on behalf of user initiated events. Please see the following guide for more infromation: http://github.com/chadhietala/ember-best-practices/files/guides/no-action-cp.md'); |
| 27 | + } |
| 28 | + } |
| 29 | + } |
| 30 | + }; |
62 | 31 | }
|
0 commit comments