Skip to content

Commit 684410c

Browse files
lin-llLucy Lin
andauthored
Check template tags for service usages in no-unused-services (#1899)
* Check template tags for service usages in no-unused-services * Revert sourceCode change --------- Co-authored-by: Lucy Lin <[email protected]>
1 parent 5e7ddfc commit 684410c

File tree

4 files changed

+132
-7
lines changed

4 files changed

+132
-7
lines changed

lib/rules/no-unused-services.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ const {
99
MACROS_TO_TRACKED_ARGUMENT_COUNT,
1010
} = require('../utils/computed-property-macros');
1111
const Stack = require('../utils/stack');
12+
const { TEMPLATE_TAG_PLACEHOLDER } = require('ember-template-imports/src/util');
13+
const recast = require('ember-template-recast');
1214

1315
/** @type {import('eslint').Rule.RuleModule} */
1416
module.exports = {
@@ -24,7 +26,7 @@ module.exports = {
2426
hasSuggestions: true,
2527
schema: [],
2628
messages: {
27-
main: 'The service `{{name}}` is not referenced in this JS file and might be unused (note: it could still be used in a corresponding handlebars template file, mixin, or parent/child class).',
29+
main: 'The service `{{name}}` is not referenced in this file and might be unused (note: it could still be used in a corresponding handlebars template file, mixin, or parent/child class).',
2830
removeServiceInjection: 'Remove the service injection.',
2931
},
3032
},
@@ -170,7 +172,22 @@ module.exports = {
170172
return;
171173
}
172174

173-
if (
175+
if (node.callee.name === TEMPLATE_TAG_PLACEHOLDER) {
176+
// This is the <template></template> tag placeholder
177+
// We now have to parse the template elements here to see if the services are used
178+
const templateElements = node.arguments[0]?.quasis ?? [];
179+
for (const templateElem of templateElements) {
180+
const ast = recast.parse(templateElem.value.raw);
181+
recast.traverse(ast, {
182+
PathExpression(templateNode) {
183+
if (templateNode.head.type === 'ThisHead') {
184+
const tail = templateNode.tail[0];
185+
currentClass.uses.add(tail);
186+
}
187+
},
188+
});
189+
}
190+
} else if (
174191
emberUtils.isComputedProp(node, importedEmberName, importedComputedName, {
175192
includeMacro: true,
176193
})

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"css-tree": "^2.0.4",
7171
"ember-rfc176-data": "^0.3.15",
7272
"ember-template-imports": "^3.4.2",
73+
"ember-template-recast": "^6.1.4",
7374
"eslint-utils": "^3.0.0",
7475
"estraverse": "^5.2.0",
7576
"lodash.camelcase": "^4.1.1",

tests/lib/rules-preprocessor/gjs-gts-processor-test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ function initESLint(parser = '@babel/eslint-parser') {
4343
'no-unused-vars': 'error',
4444
'ember/no-get': 'off',
4545
'ember/no-array-prototype-extensions': 'error',
46+
'ember/no-unused-services': 'error',
4647
},
4748
},
4849
});
@@ -116,6 +117,23 @@ const valid = [
116117
}`,
117118
parser: '@typescript-eslint/parser',
118119
},
120+
{
121+
filename: 'my-component.gjs',
122+
code: `
123+
import Component from '@glimmer/component';
124+
import { inject as service } from '@ember/service';
125+
126+
export default class MyComponent extends Component {
127+
@service foo;
128+
129+
<template>
130+
{{this.foo}}
131+
<div></div>
132+
foobar
133+
</template>
134+
}
135+
`,
136+
},
119137
/**
120138
* TODO: SKIP this scenario. Tracked in https://github.com/ember-cli/eslint-plugin-ember/issues/1685
121139
{
@@ -285,6 +303,37 @@ const invalid = [
285303
},
286304
],
287305
},
306+
{
307+
filename: 'my-component.gjs',
308+
code: `
309+
import Component from '@glimmer/component';
310+
import { inject as service } from '@ember/service';
311+
312+
export default class MyComponent extends Component {
313+
@service foo;
314+
315+
@service bar;
316+
317+
<template>
318+
{{this.foo.bar}}
319+
{{this.bartender}}
320+
<div>this.bar</div>
321+
this.bar.foo
322+
something.bar
323+
</template>
324+
}
325+
`,
326+
errors: [
327+
{
328+
message:
329+
'The service `bar` is not referenced in this file and might be unused (note: it could still be used in a corresponding handlebars template file, mixin, or parent/child class).',
330+
line: 8,
331+
endLine: 8,
332+
endColumn: 22,
333+
column: 9,
334+
},
335+
],
336+
},
288337
];
289338

290339
describe('template-vars', () => {

yarn.lock

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -535,19 +535,37 @@
535535
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6"
536536
integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==
537537

538-
"@glimmer/[email protected]":
538+
"@glimmer/[email protected]", "@glimmer/env@^0.1.7":
539539
version "0.1.7"
540540
resolved "https://registry.yarnpkg.com/@glimmer/env/-/env-0.1.7.tgz#fd2d2b55a9029c6b37a6c935e8c8871ae70dfa07"
541541
integrity sha512-JKF/a9I9jw6fGoz8kA7LEQslrwJ5jms5CXhu/aqkBWk+PmZ6pTl8mlb/eJ/5ujBGTiQzBhy5AIWF712iA+4/mw==
542542

543+
"@glimmer/[email protected]":
544+
version "0.84.3"
545+
resolved "https://registry.yarnpkg.com/@glimmer/global-context/-/global-context-0.84.3.tgz#f8bf2cda9562716f2ddf3f96837e7559600635c4"
546+
integrity sha512-8Oy9Wg5IZxMEeAnVmzD2NkObf89BeHoFSzJgJROE/deutd3rxg83mvlOez4zBBGYwnTb+VGU2LYRpet92egJjA==
547+
dependencies:
548+
"@glimmer/env" "^0.1.7"
549+
543550
"@glimmer/[email protected]":
544551
version "0.84.3"
545552
resolved "https://registry.yarnpkg.com/@glimmer/interfaces/-/interfaces-0.84.3.tgz#629777a4abe373b0785656f6c8d08989f5784805"
546553
integrity sha512-dk32ykoNojt0mvEaIW6Vli5MGTbQo58uy3Epj7ahCgTHmWOKuw/0G83f2UmFprRwFx689YTXG38I/vbpltEjzg==
547554
dependencies:
548555
"@simple-dom/interface" "^1.4.0"
549556

550-
"@glimmer/syntax@^0.84.2":
557+
"@glimmer/reference@^0.84.3":
558+
version "0.84.3"
559+
resolved "https://registry.yarnpkg.com/@glimmer/reference/-/reference-0.84.3.tgz#6420ad9c102633ac83939fd1b2457269d21fb632"
560+
integrity sha512-lV+p/aWPVC8vUjmlvYVU7WQJsLh319SdXuAWoX/SE3pq340BJlAJiEcAc6q52y9JNhT57gMwtjMX96W5Xcx/qw==
561+
dependencies:
562+
"@glimmer/env" "^0.1.7"
563+
"@glimmer/global-context" "0.84.3"
564+
"@glimmer/interfaces" "0.84.3"
565+
"@glimmer/util" "0.84.3"
566+
"@glimmer/validator" "0.84.3"
567+
568+
"@glimmer/syntax@^0.84.2", "@glimmer/syntax@^0.84.3":
551569
version "0.84.3"
552570
resolved "https://registry.yarnpkg.com/@glimmer/syntax/-/syntax-0.84.3.tgz#4045a1708cef7fd810cff42fe6deeba40c7286d0"
553571
integrity sha512-ioVbTic6ZisLxqTgRBL2PCjYZTFIwobifCustrozRU2xGDiYvVIL0vt25h2c1ioDsX59UgVlDkIK4YTAQQSd2A==
@@ -566,6 +584,14 @@
566584
"@glimmer/interfaces" "0.84.3"
567585
"@simple-dom/interface" "^1.4.0"
568586

587+
"@glimmer/[email protected]", "@glimmer/validator@^0.84.3":
588+
version "0.84.3"
589+
resolved "https://registry.yarnpkg.com/@glimmer/validator/-/validator-0.84.3.tgz#cd83b7f9ab78953f23cc11a32d83d7f729c54df2"
590+
integrity sha512-RTBV4TokUB0vI31UC7ikpV7lOYpWUlyqaKV//pRC4pexYMlmqnVhkFrdiimB/R1XyNdUOQUmnIAcdic39NkbhQ==
591+
dependencies:
592+
"@glimmer/env" "^0.1.7"
593+
"@glimmer/global-context" "0.84.3"
594+
569595
"@handlebars/parser@~2.0.0":
570596
version "2.0.0"
571597
resolved "https://registry.yarnpkg.com/@handlebars/parser/-/parser-2.0.0.tgz#5e8b7298f31ff8f7b260e6b7363c7e9ceed7d9c5"
@@ -1605,7 +1631,7 @@ async-disk-cache@^1.2.1:
16051631
rsvp "^3.0.18"
16061632
username-sync "^1.0.2"
16071633

1608-
async-promise-queue@^1.0.3:
1634+
async-promise-queue@^1.0.3, async-promise-queue@^1.0.5:
16091635
version "1.0.5"
16101636
resolved "https://registry.yarnpkg.com/async-promise-queue/-/async-promise-queue-1.0.5.tgz#cb23bce9fce903a133946a700cc85f27f09ea49d"
16111637
integrity sha512-xi0aQ1rrjPWYmqbwr18rrSKbSaXIeIwSd1J4KAgVfkq8utNbdZoht7GfvfY6swFUAMJ9obkc4WPJmtGwl+B8dw==
@@ -2270,6 +2296,11 @@ color-name@~1.1.4:
22702296
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
22712297
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
22722298

2299+
colors@^1.4.0:
2300+
version "1.4.0"
2301+
resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78"
2302+
integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==
2303+
22732304
combined-stream@^1.0.8:
22742305
version "1.0.8"
22752306
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
@@ -2282,6 +2313,11 @@ commander@^10.0.0, commander@~10.0.1:
22822313
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
22832314
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
22842315

2316+
commander@^8.3.0:
2317+
version "8.3.0"
2318+
resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66"
2319+
integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==
2320+
22852321
22862322
version "0.0.1"
22872323
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
@@ -2667,6 +2703,23 @@ ember-template-imports@^3.4.2:
26672703
string.prototype.matchall "^4.0.6"
26682704
validate-peer-dependencies "^1.1.0"
26692705

2706+
ember-template-recast@^6.1.4:
2707+
version "6.1.4"
2708+
resolved "https://registry.yarnpkg.com/ember-template-recast/-/ember-template-recast-6.1.4.tgz#e964c184adfd876878009f8aa0b84c95633fce20"
2709+
integrity sha512-fCh+rOK6z+/tsdkTbOE+e7f84P6ObnIRQrCCrnu21E4X05hPeradikIkRMhJdxn4NWrxitfZskQDd37TR/lsNQ==
2710+
dependencies:
2711+
"@glimmer/reference" "^0.84.3"
2712+
"@glimmer/syntax" "^0.84.3"
2713+
"@glimmer/validator" "^0.84.3"
2714+
async-promise-queue "^1.0.5"
2715+
colors "^1.4.0"
2716+
commander "^8.3.0"
2717+
globby "^11.0.3"
2718+
ora "^5.4.0"
2719+
slash "^3.0.0"
2720+
tmp "^0.2.1"
2721+
workerpool "^6.4.0"
2722+
26702723
emittery@^0.13.1:
26712724
version "0.13.1"
26722725
resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad"
@@ -3553,7 +3606,7 @@ [email protected], globby@^13.1.2:
35533606
merge2 "^1.4.1"
35543607
slash "^4.0.0"
35553608

3556-
globby@^11.1.0:
3609+
globby@^11.0.3, globby@^11.1.0:
35573610
version "11.1.0"
35583611
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
35593612
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
@@ -5940,7 +5993,7 @@ [email protected]:
59405993
strip-ansi "^7.0.1"
59415994
wcwidth "^1.0.1"
59425995

5943-
ora@^5.4.1:
5996+
ora@^5.4.0, ora@^5.4.1:
59445997
version "5.4.1"
59455998
resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18"
59465999
integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==
@@ -7837,6 +7890,11 @@ word-wrap@^1.2.3, word-wrap@~1.2.3:
78377890
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
78387891
integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
78397892

7893+
workerpool@^6.4.0:
7894+
version "6.4.0"
7895+
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.4.0.tgz#f8d5cfb45fde32fa3b7af72ad617c3369567a462"
7896+
integrity sha512-i3KR1mQMNwY2wx20ozq2EjISGtQWDIfV56We+yGJ5yDs8jTwQiLLaqHlkBHITlCuJnYlVRmXegxFxZg7gqI++A==
7897+
78407898
wrap-ansi@^6.0.1, wrap-ansi@^6.2.0:
78417899
version "6.2.0"
78427900
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"

0 commit comments

Comments
 (0)