Skip to content

Commit 17fd61e

Browse files
mizdraclaude
andcommitted
fix(ts-plugin): exclude re-exported @value tokens from Go to Definition results
Re-exported tokens from `@value ... from '...'` were being returned as definition candidates, even though the actual definition lives in the imported file. Filter them out so Go to Definition only returns the original definition. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e1f2983 commit 17fd61e

3 files changed

Lines changed: 17 additions & 51 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@css-modules-kit/ts-plugin': patch
3+
---
4+
5+
fix(ts-plugin): exclude re-exported `@value ... from '...'` tokens from Go to Definition results

packages/ts-plugin/e2e-test/feature/go-to-definition.test.ts

Lines changed: 4 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -226,96 +226,60 @@ describe.each([
226226
file: iff.paths['index.ts'],
227227
line: 7,
228228
offset: 8,
229-
// NOTE: Ideally, only the definition from c.module.css should be returned.
230-
// However, for simplicity of implementation, when `namedExports: false`, the definition from a.module.css is also returned.
231229
expected: [
232-
!namedExports && {
233-
file: formatPath(iff.paths['a.module.css']),
234-
start: { line: 2, offset: 8 },
235-
end: { line: 2, offset: 11 },
236-
contextStart: { line: 2, offset: 8 },
237-
contextEnd: { line: 2, offset: 11 },
238-
},
239230
{
240231
file: formatPath(iff.paths['c.module.css']),
241232
start: { line: 1, offset: 8 },
242233
end: { line: 1, offset: 11 },
243234
contextStart: { line: 1, offset: 1 },
244235
contextEnd: { line: 1, offset: 16 },
245236
},
246-
].filter((c) => c !== false),
237+
],
247238
},
248239
{
249240
name: 'c_1 in a.module.ts',
250241
file: iff.paths['a.module.css'],
251242
line: 2,
252243
offset: 8,
253-
// NOTE: Ideally, only the definition from c.module.css should be returned.
254-
// However, for simplicity of implementation, when `namedExports: false`, the definition from a.module.css is also returned.
255244
expected: [
256-
!namedExports && {
257-
file: formatPath(iff.paths['a.module.css']),
258-
start: { line: 2, offset: 8 },
259-
end: { line: 2, offset: 11 },
260-
contextStart: { line: 2, offset: 8 },
261-
contextEnd: { line: 2, offset: 11 },
262-
},
263245
{
264246
file: formatPath(iff.paths['c.module.css']),
265247
start: { line: 1, offset: 8 },
266248
end: { line: 1, offset: 11 },
267249
contextStart: { line: 1, offset: 1 },
268250
contextEnd: { line: 1, offset: 16 },
269251
},
270-
].filter((c) => c !== false),
252+
],
271253
},
272254
{
273255
name: 'c_alias in index.ts',
274256
file: iff.paths['index.ts'],
275257
line: 8,
276258
offset: 8,
277-
// NOTE: Ideally, only the definition from c.module.css should be returned.
278-
// However, for simplicity of implementation, when `namedExports: false`, the definition from a.module.css is also returned.
279259
expected: [
280-
!namedExports && {
281-
file: formatPath(iff.paths['a.module.css']),
282-
start: { line: 2, offset: 20 },
283-
end: { line: 2, offset: 27 },
284-
contextStart: { line: 2, offset: 20 },
285-
contextEnd: { line: 2, offset: 27 },
286-
},
287260
{
288261
file: formatPath(iff.paths['c.module.css']),
289262
start: { line: 2, offset: 8 },
290263
end: { line: 2, offset: 11 },
291264
contextStart: { line: 2, offset: 1 },
292265
contextEnd: { line: 2, offset: 16 },
293266
},
294-
].filter((c) => c !== false),
267+
],
295268
},
296269
{
297270
name: 'c_alias in a.module.css',
298271
file: iff.paths['a.module.css'],
299272
line: 2,
300273
offset: 20,
301-
// NOTE: Ideally, only the definition from c.module.css should be returned.
302-
// However, for simplicity of implementation, when `namedExports: false`, the definition from a.module.css is also returned.
303274
expected: [
304-
!namedExports && {
305-
file: formatPath(iff.paths['a.module.css']),
306-
start: { line: 2, offset: 20 },
307-
end: { line: 2, offset: 27 },
308-
contextStart: { line: 2, offset: 20 },
309-
contextEnd: { line: 2, offset: 27 },
310-
},
311275
{
312276
file: formatPath(iff.paths['c.module.css']),
313277
start: { line: 2, offset: 8 },
314278
end: { line: 2, offset: 11 },
315279
contextStart: { line: 2, offset: 1 },
316280
contextEnd: { line: 2, offset: 16 },
317281
},
318-
].filter((c) => c !== false),
282+
],
319283
},
320284
{
321285
name: 'c_2 in a.module.css',

packages/ts-plugin/src/language-service/feature/definition-and-bound-span.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ export function getDefinitionAndBoundSpan(
1010
const result = languageService.getDefinitionAndBoundSpan(...args);
1111
if (!result) return;
1212
if (!result.definitions) return result;
13-
for (const def of result.definitions) {
13+
result.definitions = result.definitions.filter((def) => {
1414
const script = language.scripts.get(def.fileName);
15-
if (!isCSSModuleScript(script)) continue;
15+
if (!isCSSModuleScript(script)) return true;
1616

1717
const cssModule = script.generated.root[CMK_DATA_KEY];
1818

@@ -26,23 +26,20 @@ export function getDefinitionAndBoundSpan(
2626
start: localToken.declarationLoc.start.offset,
2727
length: localToken.declarationLoc.end.offset - localToken.declarationLoc.start.offset,
2828
};
29-
continue;
29+
return true;
3030
}
31+
// Exclude re-exported tokens from `@value ... from '...'`; the real definition lives in the target file.
3132
const importedValue = cssModule.tokenImporters
3233
.flatMap((i) => (i.type === 'value' ? i.values : []))
3334
.find((v) => {
3435
const localName = v.localName ?? v.name;
3536
const localLoc = v.localLoc ?? v.loc;
3637
return localName === defName && localLoc.start.offset === def.textSpan.start;
3738
});
38-
if (importedValue) {
39-
const loc = importedValue.localLoc ?? importedValue.loc;
40-
def.contextSpan = {
41-
start: loc.start.offset,
42-
length: loc.end.offset - loc.start.offset,
43-
};
44-
}
45-
}
39+
if (importedValue) return false;
40+
41+
return true;
42+
});
4643
return result;
4744
};
4845
}

0 commit comments

Comments
 (0)