@@ -2,7 +2,6 @@ import type { CMKConfig, Resolver } from '@css-modules-kit/core';
22import { isComponentFileName , isCSSModuleFile } from '@css-modules-kit/core' ;
33import type { Language } from '@volar/language-core' ;
44import ts from 'typescript' ;
5- import { isCSSModuleScript } from '../../language-plugin.js' ;
65import { convertDefaultImportsToNamespaceImports , createPreferencesForCompletion } from '../../util.js' ;
76
87// ref: https://github.com/microsoft/TypeScript/blob/220706eb0320ff46fad8bf80a5e99db624ee7dfb/src/compiler/diagnosticMessages.json
@@ -37,7 +36,7 @@ export function getCodeFixesAtPosition(
3736 if ( isComponentFileName ( fileName ) ) {
3837 // If a user is trying to use a non-existent token (e.g. `styles.nonExistToken`), provide a code fix to add the token.
3938 if ( errorCodes . some ( ( errorCode ) => PROPERTY_DOES_NOT_EXIST_ERROR_CODES . includes ( errorCode ) ) ) {
40- const tokenConsumer = getTokenConsumerAtPosition ( fileName , start , language , languageService , project ) ;
39+ const tokenConsumer = getTokenConsumerAtPosition ( fileName , start , languageService , project , config ) ;
4140 if ( tokenConsumer ) {
4241 prior . push ( {
4342 fixName : 'fixMissingCSSRule' ,
@@ -85,9 +84,9 @@ interface TokenConsumer {
8584function getTokenConsumerAtPosition (
8685 fileName : string ,
8786 position : number ,
88- language : Language < string > ,
8987 languageService : ts . LanguageService ,
9088 project : ts . server . Project ,
89+ config : CMKConfig ,
9190) : TokenConsumer | undefined {
9291 const sourceFile = project . getSourceFile ( project . projectService . toPath ( fileName ) ) ;
9392 if ( ! sourceFile ) return undefined ;
@@ -99,11 +98,19 @@ function getTokenConsumerAtPosition(
9998 // `expression` is the expression of the property access expression (e.g. `styles` in `styles.foo`).
10099 const expression = propertyAccessExpression . expression ;
101100
102- const definitions = languageService . getDefinitionAtPosition ( fileName , expression . getStart ( ) ) ;
103- if ( definitions && definitions [ 0 ] ) {
104- const script = language . scripts . get ( definitions [ 0 ] . fileName ) ;
105- if ( isCSSModuleScript ( script ) ) {
106- return { tokenName : propertyAccessExpression . name . text , from : definitions [ 0 ] . fileName } ;
101+ let [ definition ] = languageService . getDefinitionAtPosition ( fileName , expression . getStart ( ) ) ?? [ ] ;
102+ if ( ! definition ) return undefined ;
103+
104+ // `definition` is may be `styles` definition in CSS Modules file.
105+ if ( isCSSModuleFile ( definition . fileName ) ) {
106+ return { tokenName : propertyAccessExpression . name . text , from : definition . fileName } ;
107+ } else if ( config . namedExports ) {
108+ // If namespaced import is used, it may be a definition in a component file
109+ // (e.g. the `styles` of `import * as styles from './a.module.css'`).
110+ // In that case, we need to call `getDefinitionAtPosition` again to get the definition in CSS module file.
111+ [ definition ] = languageService . getDefinitionAtPosition ( definition . fileName , definition . textSpan . start ) ?? [ ] ;
112+ if ( definition && isCSSModuleFile ( definition . fileName ) ) {
113+ return { tokenName : propertyAccessExpression . name . text , from : definition . fileName } ;
107114 }
108115 }
109116 return undefined ;
0 commit comments