@css-modules-kit/ts-plugin 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/language-plugin.d.ts.map +1 -1
- package/dist/language-plugin.js +9 -4
- package/dist/language-plugin.js.map +1 -1
- package/dist/language-service/feature/definition-and-bound-span.d.ts.map +1 -1
- package/dist/language-service/feature/definition-and-bound-span.js +37 -9
- package/dist/language-service/feature/definition-and-bound-span.js.map +1 -1
- package/dist/language-service/feature/find-references.d.ts +3 -0
- package/dist/language-service/feature/find-references.d.ts.map +1 -0
- package/dist/language-service/feature/find-references.js +45 -0
- package/dist/language-service/feature/find-references.js.map +1 -0
- package/dist/language-service/feature/semantic-diagnostic.d.ts.map +1 -1
- package/dist/language-service/feature/semantic-diagnostic.js +0 -1
- package/dist/language-service/feature/semantic-diagnostic.js.map +1 -1
- package/dist/language-service/proxy.d.ts.map +1 -1
- package/dist/language-service/proxy.js +2 -1
- package/dist/language-service/proxy.js.map +1 -1
- package/package.json +4 -4
- package/src/language-plugin.ts +9 -4
- package/src/language-service/feature/definition-and-bound-span.ts +41 -9
- package/src/language-service/feature/find-references.ts +46 -0
- package/src/language-service/feature/semantic-diagnostic.ts +0 -1
- package/src/language-service/proxy.ts +2 -1
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ TODO: Welcome to contribute
|
|
|
43
43
|
Install the ts-plugin via the Extension. Please follow the steps below:
|
|
44
44
|
|
|
45
45
|
1. Install ["CSS Modules Kit" extension](https://zed.dev/extensions/css-modules-kit).
|
|
46
|
-
2. Add the following to your
|
|
46
|
+
2. Add the following to your `~/.config/zed/settings.json` file:
|
|
47
47
|
```json
|
|
48
48
|
{
|
|
49
49
|
"languages": {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language-plugin.d.ts","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAItF,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,eAAO,MAAM,YAAY,eAAiC,CAAC;AAE3D,UAAU,oBAAqB,SAAQ,WAAW;IAChD,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,MAAM,CAAC;IAC3D,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,GAAG;QAC7C,IAAI,EAAE,oBAAoB,CAAC;KAC5B,CAAC;CACH;AAED,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,SAAS,GAChB,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,
|
|
1
|
+
{"version":3,"file":"language-plugin.d.ts","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAElF,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAItF,eAAO,MAAM,WAAW,QAAQ,CAAC;AAEjC,eAAO,MAAM,YAAY,eAAiC,CAAC;AAE3D,UAAU,oBAAqB,SAAQ,WAAW;IAChD,CAAC,YAAY,CAAC,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,eAAgB,SAAQ,YAAY,CAAC,MAAM,CAAC;IAC3D,SAAS,EAAE,YAAY,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,GAAG;QAC7C,IAAI,EAAE,oBAAoB,CAAC;KAC5B,CAAC;CACH;AAED,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,SAAS,GAChB,cAAc,CAAC,MAAM,EAAE,WAAW,CAAC,CAqErC;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,IAAI,eAAe,CAIrG"}
|
package/dist/language-plugin.js
CHANGED
|
@@ -34,7 +34,10 @@ export function createCSSLanguagePlugin(matchesPattern, config) {
|
|
|
34
34
|
keyframes: config.keyframes,
|
|
35
35
|
});
|
|
36
36
|
// eslint-disable-next-line prefer-const
|
|
37
|
-
let { text, mapping, linkedCodeMapping } = generateDts(cssModule, {
|
|
37
|
+
let { text, mapping, linkedCodeMapping, secondaryMapping } = generateDts(cssModule, {
|
|
38
|
+
...config,
|
|
39
|
+
forTsPlugin: true,
|
|
40
|
+
});
|
|
38
41
|
return {
|
|
39
42
|
id: 'main',
|
|
40
43
|
languageId: 'typescript',
|
|
@@ -43,9 +46,11 @@ export function createCSSLanguagePlugin(matchesPattern, config) {
|
|
|
43
46
|
getLength: () => text.length,
|
|
44
47
|
getChangeRange: () => undefined,
|
|
45
48
|
},
|
|
46
|
-
// `mappings` are required to support "Go to Definition" and
|
|
47
|
-
mappings: [
|
|
48
|
-
|
|
49
|
+
// `mappings` are required to support navigation features such as "Go to Definition" and "Find all References".
|
|
50
|
+
mappings: [mapping, secondaryMapping]
|
|
51
|
+
.filter((mapping) => mapping !== undefined)
|
|
52
|
+
.map((mapping) => ({ ...mapping, data: { navigation: true } })),
|
|
53
|
+
// `linkedCodeMappings` are required to support navigation features for the imported tokens.
|
|
49
54
|
linkedCodeMappings: [{ ...linkedCodeMapping, data: undefined }],
|
|
50
55
|
[CMK_DATA_KEY]: cssModule,
|
|
51
56
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"language-plugin.js","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGpE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,CAAC;AAEjC,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC;AAY3D,MAAM,UAAU,uBAAuB,CACrC,cAA8B,EAC9B,MAAiB;IAEjB,OAAO;QACL,aAAa,CAAC,QAAQ;YACpB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAAE,OAAO,SAAS,CAAC;YACjD,OAAO,WAAW,CAAC;QACrB,CAAC;QACD,iBAAiB,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ;YAC9C,IAAI,UAAU,KAAK,WAAW;gBAAE,OAAO,SAAS,CAAC;YACjD,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,2CAA2C;gBAC3C,qGAAqG;gBACrG,4DAA4D;gBAC5D,OAAO;oBACL,EAAE,EAAE,MAAM;oBACV,UAAU;oBACV,QAAQ;oBACR,QAAQ,EAAE,EAAE;iBACb,CAAC;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,CAAC;YACpC,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;YAClD,MAAM,SAAS,GAAG,cAAc,CAAC,aAAa,EAAE;gBAC9C,QAAQ,EAAE,QAAQ;gBAClB,wEAAwE;gBACxE,6EAA6E;gBAC7E,kEAAkE;gBAClE,kBAAkB,EAAE,KAAK;gBACzB,SAAS,EAAE,MAAM,CAAC,SAAS;aAC5B,CAAC,CAAC;YACH,wCAAwC;YACxC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,iBAAiB,EAAE,GAAG,WAAW,CAAC,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"language-plugin.js","sourceRoot":"","sources":["../src/language-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-and-bound-span.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/definition-and-bound-span.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,GAClC,EAAE,CAAC,eAAe,CAAC,2BAA2B,CAAC,
|
|
1
|
+
{"version":3,"file":"definition-and-bound-span.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/definition-and-bound-span.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,GAClC,EAAE,CAAC,eAAe,CAAC,2BAA2B,CAAC,CAwCjD"}
|
|
@@ -8,18 +8,46 @@ export function getDefinitionAndBoundSpan(language, languageService) {
|
|
|
8
8
|
return result;
|
|
9
9
|
for (const def of result.definitions) {
|
|
10
10
|
const script = language.scripts.get(def.fileName);
|
|
11
|
-
if (isCSSModuleScript(script))
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
11
|
+
if (!isCSSModuleScript(script))
|
|
12
|
+
continue;
|
|
13
|
+
const cssModule = script.generated.root[CMK_DATA_KEY];
|
|
14
|
+
// Search tokens and set `contextSpan`. `contextSpan` is used for Definition Preview in editors.
|
|
15
|
+
const defName = unquote(def.name);
|
|
16
|
+
const localToken = cssModule.localTokens.find((t) => t.name === defName && t.loc.start.offset === def.textSpan.start);
|
|
17
|
+
if (localToken?.declarationLoc) {
|
|
18
|
+
def.contextSpan = {
|
|
19
|
+
start: localToken.declarationLoc.start.offset,
|
|
20
|
+
length: localToken.declarationLoc.end.offset - localToken.declarationLoc.start.offset,
|
|
21
|
+
};
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
const importedValue = cssModule.tokenImporters
|
|
25
|
+
.flatMap((i) => (i.type === 'value' ? i.values : []))
|
|
26
|
+
.find((v) => {
|
|
27
|
+
const localName = v.localName ?? v.name;
|
|
28
|
+
const localLoc = v.localLoc ?? v.loc;
|
|
29
|
+
return localName === defName && localLoc.start.offset === def.textSpan.start;
|
|
30
|
+
});
|
|
31
|
+
if (importedValue) {
|
|
32
|
+
const loc = importedValue.localLoc ?? importedValue.loc;
|
|
33
|
+
def.contextSpan = {
|
|
34
|
+
start: loc.start.offset,
|
|
35
|
+
length: loc.end.offset - loc.start.offset,
|
|
36
|
+
};
|
|
20
37
|
}
|
|
21
38
|
}
|
|
22
39
|
return result;
|
|
23
40
|
};
|
|
24
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Removes surrounding single quotes from a string if present.
|
|
44
|
+
* When `namedExport` is false, `def.name` is `"'tokenName'"` (with quotes),
|
|
45
|
+
* but `token.name` is `"tokenName"` (without quotes).
|
|
46
|
+
*/
|
|
47
|
+
function unquote(name) {
|
|
48
|
+
if (name.length >= 2 && name.startsWith("'") && name.endsWith("'")) {
|
|
49
|
+
return name.slice(1, -1);
|
|
50
|
+
}
|
|
51
|
+
return name;
|
|
52
|
+
}
|
|
25
53
|
//# sourceMappingURL=definition-and-bound-span.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-and-bound-span.js","sourceRoot":"","sources":["../../../src/language-service/feature/definition-and-bound-span.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,UAAU,yBAAyB,CACvC,QAA0B,EAC1B,eAAmC;IAEnC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACjB,MAAM,MAAM,GAAG,eAAe,CAAC,yBAAyB,CAAC,GAAG,IAAI,CAAC,CAAC;QAClE,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,CAAC,MAAM,CAAC,WAAW;YAAE,OAAO,MAAM,CAAC;QACvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAClD,IAAI,iBAAiB,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"definition-and-bound-span.js","sourceRoot":"","sources":["../../../src/language-service/feature/definition-and-bound-span.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-references.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/find-references.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjC,wBAAgB,cAAc,CAAC,eAAe,EAAE,EAAE,CAAC,eAAe,GAAG,EAAE,CAAC,eAAe,CAAC,gBAAgB,CAAC,CAMxG"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export function findReferences(languageService) {
|
|
2
|
+
return (...args) => {
|
|
3
|
+
const symbols = languageService.findReferences(...args);
|
|
4
|
+
if (!symbols)
|
|
5
|
+
return symbols;
|
|
6
|
+
return mergeSameDefinitionSymbols(symbols);
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Merges ReferencedSymbols that have the same definition into one,
|
|
11
|
+
* combining their references.
|
|
12
|
+
*/
|
|
13
|
+
function mergeSameDefinitionSymbols(symbols) {
|
|
14
|
+
// Volar.js may return multiple ReferencedSymbols with the same definition
|
|
15
|
+
// when a VirtualCode contains multiple CodeMapping objects.
|
|
16
|
+
// Editors usually merge symbols with the same definition before displaying them,
|
|
17
|
+
// so this typically isn't an issue in practice.
|
|
18
|
+
// However, we merge them here to make comparisons in tests easier.
|
|
19
|
+
const map = new Map();
|
|
20
|
+
for (const symbol of symbols) {
|
|
21
|
+
const def = symbol.definition;
|
|
22
|
+
const key = `${def.fileName}:${def.textSpan.start}:${def.textSpan.length}`;
|
|
23
|
+
const existing = map.get(key);
|
|
24
|
+
if (existing) {
|
|
25
|
+
existing.references = uniqueReferences([...existing.references, ...symbol.references]);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
map.set(key, symbol);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return Array.from(map.values());
|
|
32
|
+
}
|
|
33
|
+
function uniqueReferences(references) {
|
|
34
|
+
const seen = new Set();
|
|
35
|
+
const result = [];
|
|
36
|
+
for (const ref of references) {
|
|
37
|
+
const key = `${ref.fileName}:${ref.textSpan.start}:${ref.textSpan.length}`;
|
|
38
|
+
if (!seen.has(key)) {
|
|
39
|
+
seen.add(key);
|
|
40
|
+
result.push(ref);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=find-references.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-references.js","sourceRoot":"","sources":["../../../src/language-service/feature/find-references.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,cAAc,CAAC,eAAmC;IAChE,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACjB,MAAM,OAAO,GAAG,eAAe,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,CAAC;QACxD,IAAI,CAAC,OAAO;YAAE,OAAO,OAAO,CAAC;QAC7B,OAAO,0BAA0B,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,0BAA0B,CAAC,OAA8B;IAChE,0EAA0E;IAC1E,4DAA4D;IAC5D,iFAAiF;IACjF,gDAAgD;IAChD,mEAAmE;IACnE,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+B,CAAC;IACnD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC;QAC9B,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3E,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,CAAC,UAAU,GAAG,gBAAgB,CAAC,CAAC,GAAG,QAAQ,CAAC,UAAU,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QACzF,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,gBAAgB,CAAC,UAAsC;IAC9D,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAA+B,EAAE,CAAC;IAC9C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-diagnostic.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/semantic-diagnostic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE3G,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"semantic-diagnostic.d.ts","sourceRoot":"","sources":["../../../src/language-service/feature/semantic-diagnostic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE3G,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAGjC,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,SAAS,GAAG,SAAS,EACrD,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,CAAC,wBAAwB,CAAC,CAyB9C"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { checkCSSModule, convertDiagnostic } from '@css-modules-kit/core';
|
|
2
2
|
import { CMK_DATA_KEY, isCSSModuleScript } from '../../language-plugin.js';
|
|
3
|
-
// eslint-disable-next-line max-params
|
|
4
3
|
export function getSemanticDiagnostics(language, languageService, exportBuilder, resolver, matchesPattern, getCSSModule, config) {
|
|
5
4
|
return (...args) => {
|
|
6
5
|
const [fileName] = args;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"semantic-diagnostic.js","sourceRoot":"","sources":["../../../src/language-service/feature/semantic-diagnostic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE3E,
|
|
1
|
+
{"version":3,"file":"semantic-diagnostic.js","sourceRoot":"","sources":["../../../src/language-service/feature/semantic-diagnostic.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1E,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAE3E,MAAM,UAAU,sBAAsB,CACpC,QAA0B,EAC1B,eAAmC,EACnC,aAA4B,EAC5B,QAAkB,EAClB,cAA8B,EAC9B,YAAqD,EACrD,MAAiB;IAEjB,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE;QACjB,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;QACxB,MAAM,KAAK,GAAG,eAAe,CAAC,sBAAsB,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,MAAM,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1C,MAAM,SAAS,GAAG,WAAW,CAAC,YAAY,CAAC,CAAC;YAE5C,qDAAqD;YACrD,aAAa,CAAC,UAAU,EAAE,CAAC;YAE3B,MAAM,WAAW,GAAG,cAAc,CAAC,SAAS,EAAE;gBAC5C,MAAM;gBACN,eAAe,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;gBAC9C,cAAc;gBACd,QAAQ;gBACR,YAAY;aACb,CAAC,CAAC;YACH,MAAM,UAAU,GAAG,eAAe,CAAC,UAAU,EAAG,CAAC,aAAa,CAAC,QAAQ,CAAE,CAAC;YAC1E,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;YACvG,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAuB,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAUjC,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAC1B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAuB,KAAK,cAAc,EAAE,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAChG,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,MAAM,YAAY,CAAC;AAUjC,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,EAC1B,eAAe,EAAE,EAAE,CAAC,eAAe,EACnC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,EAC1B,QAAQ,EAAE,QAAQ,EAClB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,SAAS,GAChB,EAAE,CAAC,eAAe,CAsCpB"}
|
|
@@ -3,10 +3,10 @@ import { CMK_DATA_KEY, isCSSModuleScript } from '../language-plugin.js';
|
|
|
3
3
|
import { getCodeFixesAtPosition } from './feature/code-fix.js';
|
|
4
4
|
import { getCompletionEntryDetails, getCompletionsAtPosition } from './feature/completion.js';
|
|
5
5
|
import { getDefinitionAndBoundSpan } from './feature/definition-and-bound-span.js';
|
|
6
|
+
import { findReferences } from './feature/find-references.js';
|
|
6
7
|
import { getApplicableRefactors, getEditsForRefactor } from './feature/refactor.js';
|
|
7
8
|
import { getSemanticDiagnostics } from './feature/semantic-diagnostic.js';
|
|
8
9
|
import { getSyntacticDiagnostics } from './feature/syntactic-diagnostic.js';
|
|
9
|
-
// eslint-disable-next-line max-params
|
|
10
10
|
export function proxyLanguageService(language, languageService, project, resolver, matchesPattern, config) {
|
|
11
11
|
const proxy = Object.create(null);
|
|
12
12
|
for (const k of Object.keys(languageService)) {
|
|
@@ -31,6 +31,7 @@ export function proxyLanguageService(language, languageService, project, resolve
|
|
|
31
31
|
proxy.getCompletionEntryDetails = getCompletionEntryDetails(languageService, resolver, config);
|
|
32
32
|
proxy.getCodeFixesAtPosition = getCodeFixesAtPosition(language, languageService, project, resolver, config);
|
|
33
33
|
proxy.getDefinitionAndBoundSpan = getDefinitionAndBoundSpan(language, languageService);
|
|
34
|
+
proxy.findReferences = findReferences(languageService);
|
|
34
35
|
return proxy;
|
|
35
36
|
}
|
|
36
37
|
//# sourceMappingURL=proxy.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAsC,MAAM,uBAAuB,CAAC;AAGhG,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAE5E,
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/language-service/proxy.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAsC,MAAM,uBAAuB,CAAC;AAGhG,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAE5E,MAAM,UAAU,oBAAoB,CAClC,QAA0B,EAC1B,eAAmC,EACnC,OAA0B,EAC1B,QAAkB,EAClB,cAA8B,EAC9B,MAAiB;IAEjB,MAAM,KAAK,GAAuB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAiC,EAAE,CAAC;QAC7E,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAE,CAAC;QAC9B,yEAAyE;QACzE,mEAAmE;QACnE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,IAAU,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,EAAE;QACpC,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1C,IAAI,iBAAiB,CAAC,MAAM,CAAC,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7C,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC;IACF,MAAM,aAAa,GAAG,mBAAmB,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,CAAC;IAEtF,KAAK,CAAC,uBAAuB,GAAG,uBAAuB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACnF,KAAK,CAAC,sBAAsB,GAAG,sBAAsB,CACnD,QAAQ,EACR,eAAe,EACf,aAAa,EACb,QAAQ,EACR,cAAc,EACd,YAAY,EACZ,MAAM,CACP,CAAC;IACF,KAAK,CAAC,sBAAsB,GAAG,sBAAsB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;IAChF,KAAK,CAAC,mBAAmB,GAAG,mBAAmB,CAAC,eAAe,CAAC,CAAC;IACjE,KAAK,CAAC,wBAAwB,GAAG,wBAAwB,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACnF,KAAK,CAAC,yBAAyB,GAAG,yBAAyB,CAAC,eAAe,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC/F,KAAK,CAAC,sBAAsB,GAAG,sBAAsB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC5G,KAAK,CAAC,yBAAyB,GAAG,yBAAyB,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IACvF,KAAK,CAAC,cAAc,GAAG,cAAc,CAAC,eAAe,CAAC,CAAC;IAEvD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@css-modules-kit/ts-plugin",
|
|
3
3
|
"description": "A TypeScript Language Service Plugin for CSS Modules",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"repository": {
|
|
@@ -47,9 +47,9 @@
|
|
|
47
47
|
"dist"
|
|
48
48
|
],
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@volar/language-core": "^2.4.
|
|
51
|
-
"@volar/typescript": "^2.4.
|
|
52
|
-
"@css-modules-kit/core": "^0.
|
|
50
|
+
"@volar/language-core": "^2.4.28",
|
|
51
|
+
"@volar/typescript": "^2.4.28",
|
|
52
|
+
"@css-modules-kit/core": "^0.9.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"typescript": ">=5.6.3"
|
package/src/language-plugin.ts
CHANGED
|
@@ -52,7 +52,10 @@ export function createCSSLanguagePlugin(
|
|
|
52
52
|
keyframes: config.keyframes,
|
|
53
53
|
});
|
|
54
54
|
// eslint-disable-next-line prefer-const
|
|
55
|
-
let { text, mapping, linkedCodeMapping } = generateDts(cssModule, {
|
|
55
|
+
let { text, mapping, linkedCodeMapping, secondaryMapping } = generateDts(cssModule, {
|
|
56
|
+
...config,
|
|
57
|
+
forTsPlugin: true,
|
|
58
|
+
});
|
|
56
59
|
return {
|
|
57
60
|
id: 'main',
|
|
58
61
|
languageId: 'typescript',
|
|
@@ -61,9 +64,11 @@ export function createCSSLanguagePlugin(
|
|
|
61
64
|
getLength: () => text.length,
|
|
62
65
|
getChangeRange: () => undefined,
|
|
63
66
|
},
|
|
64
|
-
// `mappings` are required to support "Go to Definition" and
|
|
65
|
-
mappings: [
|
|
66
|
-
|
|
67
|
+
// `mappings` are required to support navigation features such as "Go to Definition" and "Find all References".
|
|
68
|
+
mappings: [mapping, secondaryMapping]
|
|
69
|
+
.filter((mapping) => mapping !== undefined)
|
|
70
|
+
.map((mapping) => ({ ...mapping, data: { navigation: true } })),
|
|
71
|
+
// `linkedCodeMappings` are required to support navigation features for the imported tokens.
|
|
67
72
|
linkedCodeMappings: [{ ...linkedCodeMapping, data: undefined }],
|
|
68
73
|
[CMK_DATA_KEY]: cssModule,
|
|
69
74
|
};
|
|
@@ -12,17 +12,49 @@ export function getDefinitionAndBoundSpan(
|
|
|
12
12
|
if (!result.definitions) return result;
|
|
13
13
|
for (const def of result.definitions) {
|
|
14
14
|
const script = language.scripts.get(def.fileName);
|
|
15
|
-
if (isCSSModuleScript(script))
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
if (!isCSSModuleScript(script)) continue;
|
|
16
|
+
|
|
17
|
+
const cssModule = script.generated.root[CMK_DATA_KEY];
|
|
18
|
+
|
|
19
|
+
// Search tokens and set `contextSpan`. `contextSpan` is used for Definition Preview in editors.
|
|
20
|
+
const defName = unquote(def.name);
|
|
21
|
+
const localToken = cssModule.localTokens.find(
|
|
22
|
+
(t) => t.name === defName && t.loc.start.offset === def.textSpan.start,
|
|
23
|
+
);
|
|
24
|
+
if (localToken?.declarationLoc) {
|
|
25
|
+
def.contextSpan = {
|
|
26
|
+
start: localToken.declarationLoc.start.offset,
|
|
27
|
+
length: localToken.declarationLoc.end.offset - localToken.declarationLoc.start.offset,
|
|
28
|
+
};
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const importedValue = cssModule.tokenImporters
|
|
32
|
+
.flatMap((i) => (i.type === 'value' ? i.values : []))
|
|
33
|
+
.find((v) => {
|
|
34
|
+
const localName = v.localName ?? v.name;
|
|
35
|
+
const localLoc = v.localLoc ?? v.loc;
|
|
36
|
+
return localName === defName && localLoc.start.offset === def.textSpan.start;
|
|
37
|
+
});
|
|
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
|
+
};
|
|
24
44
|
}
|
|
25
45
|
}
|
|
26
46
|
return result;
|
|
27
47
|
};
|
|
28
48
|
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Removes surrounding single quotes from a string if present.
|
|
52
|
+
* When `namedExport` is false, `def.name` is `"'tokenName'"` (with quotes),
|
|
53
|
+
* but `token.name` is `"tokenName"` (without quotes).
|
|
54
|
+
*/
|
|
55
|
+
function unquote(name: string): string {
|
|
56
|
+
if (name.length >= 2 && name.startsWith("'") && name.endsWith("'")) {
|
|
57
|
+
return name.slice(1, -1);
|
|
58
|
+
}
|
|
59
|
+
return name;
|
|
60
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type ts from 'typescript';
|
|
2
|
+
|
|
3
|
+
export function findReferences(languageService: ts.LanguageService): ts.LanguageService['findReferences'] {
|
|
4
|
+
return (...args) => {
|
|
5
|
+
const symbols = languageService.findReferences(...args);
|
|
6
|
+
if (!symbols) return symbols;
|
|
7
|
+
return mergeSameDefinitionSymbols(symbols);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Merges ReferencedSymbols that have the same definition into one,
|
|
13
|
+
* combining their references.
|
|
14
|
+
*/
|
|
15
|
+
function mergeSameDefinitionSymbols(symbols: ts.ReferencedSymbol[]): ts.ReferencedSymbol[] {
|
|
16
|
+
// Volar.js may return multiple ReferencedSymbols with the same definition
|
|
17
|
+
// when a VirtualCode contains multiple CodeMapping objects.
|
|
18
|
+
// Editors usually merge symbols with the same definition before displaying them,
|
|
19
|
+
// so this typically isn't an issue in practice.
|
|
20
|
+
// However, we merge them here to make comparisons in tests easier.
|
|
21
|
+
const map = new Map<string, ts.ReferencedSymbol>();
|
|
22
|
+
for (const symbol of symbols) {
|
|
23
|
+
const def = symbol.definition;
|
|
24
|
+
const key = `${def.fileName}:${def.textSpan.start}:${def.textSpan.length}`;
|
|
25
|
+
const existing = map.get(key);
|
|
26
|
+
if (existing) {
|
|
27
|
+
existing.references = uniqueReferences([...existing.references, ...symbol.references]);
|
|
28
|
+
} else {
|
|
29
|
+
map.set(key, symbol);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return Array.from(map.values());
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function uniqueReferences(references: ts.ReferencedSymbolEntry[]): ts.ReferencedSymbolEntry[] {
|
|
36
|
+
const seen = new Set<string>();
|
|
37
|
+
const result: ts.ReferencedSymbolEntry[] = [];
|
|
38
|
+
for (const ref of references) {
|
|
39
|
+
const key = `${ref.fileName}:${ref.textSpan.start}:${ref.textSpan.length}`;
|
|
40
|
+
if (!seen.has(key)) {
|
|
41
|
+
seen.add(key);
|
|
42
|
+
result.push(ref);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|
|
@@ -4,7 +4,6 @@ import type { Language } from '@volar/language-core';
|
|
|
4
4
|
import type ts from 'typescript';
|
|
5
5
|
import { CMK_DATA_KEY, isCSSModuleScript } from '../../language-plugin.js';
|
|
6
6
|
|
|
7
|
-
// eslint-disable-next-line max-params
|
|
8
7
|
export function getSemanticDiagnostics(
|
|
9
8
|
language: Language<string>,
|
|
10
9
|
languageService: ts.LanguageService,
|
|
@@ -6,11 +6,11 @@ import { CMK_DATA_KEY, isCSSModuleScript } from '../language-plugin.js';
|
|
|
6
6
|
import { getCodeFixesAtPosition } from './feature/code-fix.js';
|
|
7
7
|
import { getCompletionEntryDetails, getCompletionsAtPosition } from './feature/completion.js';
|
|
8
8
|
import { getDefinitionAndBoundSpan } from './feature/definition-and-bound-span.js';
|
|
9
|
+
import { findReferences } from './feature/find-references.js';
|
|
9
10
|
import { getApplicableRefactors, getEditsForRefactor } from './feature/refactor.js';
|
|
10
11
|
import { getSemanticDiagnostics } from './feature/semantic-diagnostic.js';
|
|
11
12
|
import { getSyntacticDiagnostics } from './feature/syntactic-diagnostic.js';
|
|
12
13
|
|
|
13
|
-
// eslint-disable-next-line max-params
|
|
14
14
|
export function proxyLanguageService(
|
|
15
15
|
language: Language<string>,
|
|
16
16
|
languageService: ts.LanguageService,
|
|
@@ -53,6 +53,7 @@ export function proxyLanguageService(
|
|
|
53
53
|
proxy.getCompletionEntryDetails = getCompletionEntryDetails(languageService, resolver, config);
|
|
54
54
|
proxy.getCodeFixesAtPosition = getCodeFixesAtPosition(language, languageService, project, resolver, config);
|
|
55
55
|
proxy.getDefinitionAndBoundSpan = getDefinitionAndBoundSpan(language, languageService);
|
|
56
|
+
proxy.findReferences = findReferences(languageService);
|
|
56
57
|
|
|
57
58
|
return proxy;
|
|
58
59
|
}
|