@@ -5,6 +5,7 @@ import { createFileRegistry, resolveCommonLanguageId } from '@vue/language-core'
5
5
import { projects } from './lib/utils' ;
6
6
import * as vue from '@vue/language-core' ;
7
7
import { startNamedPipeServer } from './lib/server' ;
8
+ import { _getComponentNames } from './lib/requests/componentInfos' ;
8
9
9
10
const windowsPathReg = / \\ / g;
10
11
const externalFiles = new WeakMap < ts . server . Project , string [ ] > ( ) ;
@@ -62,6 +63,7 @@ function createLanguageServicePlugin(): ts.server.PluginModuleFactory {
62
63
startNamedPipeServer ( ) ;
63
64
64
65
const getCompletionsAtPosition = info . languageService . getCompletionsAtPosition ;
66
+ const getEncodedSemanticClassifications = info . languageService . getEncodedSemanticClassifications ;
65
67
66
68
info . languageService . getCompletionsAtPosition = ( fileName , position , options ) => {
67
69
const result = getCompletionsAtPosition ( fileName , position , options ) ;
@@ -70,6 +72,62 @@ function createLanguageServicePlugin(): ts.server.PluginModuleFactory {
70
72
}
71
73
return result ;
72
74
} ;
75
+ info . languageService . getEncodedSemanticClassifications = ( fileName , span , format ) => {
76
+ const result = getEncodedSemanticClassifications ( fileName , span , format ) ;
77
+ const file = files . get ( fileName ) ;
78
+ if (
79
+ file ?. generated ?. code instanceof vue . VueGeneratedCode
80
+ && file . generated . code . sfc . template
81
+ ) {
82
+ const validComponentNames = _getComponentNames ( ts , info . languageService , file . generated . code , vueOptions ) ;
83
+ const components = new Set ( [
84
+ ...validComponentNames ,
85
+ ...validComponentNames . map ( vue . hyphenateTag ) ,
86
+ ] ) ;
87
+ const { template } = file . generated . code . sfc ;
88
+ const spanTemplateRange = [
89
+ span . start - template . startTagEnd ,
90
+ span . start + span . length - template . startTagEnd ,
91
+ ] as const ;
92
+ template . ast ?. children . forEach ( function visit ( node ) {
93
+ if ( node . loc . end . offset <= spanTemplateRange [ 0 ] || node . loc . start . offset >= spanTemplateRange [ 1 ] ) {
94
+ return ;
95
+ }
96
+ if ( node . type === 1 satisfies vue . CompilerDOM . NodeTypes . ELEMENT ) {
97
+ if ( components . has ( node . tag ) ) {
98
+ result . spans . push (
99
+ node . loc . start . offset + node . loc . source . indexOf ( node . tag ) + template . startTagEnd ,
100
+ node . tag . length ,
101
+ 256 , // class
102
+ ) ;
103
+ if ( template . lang === 'html' && ! node . isSelfClosing ) {
104
+ result . spans . push (
105
+ node . loc . start . offset + node . loc . source . lastIndexOf ( node . tag ) + template . startTagEnd ,
106
+ node . tag . length ,
107
+ 256 , // class
108
+ ) ;
109
+ }
110
+ }
111
+ for ( const child of node . children ) {
112
+ visit ( child ) ;
113
+ }
114
+ }
115
+ else if ( node . type === 9 satisfies vue . CompilerDOM . NodeTypes . IF ) {
116
+ for ( const branch of node . branches ) {
117
+ for ( const child of branch . children ) {
118
+ visit ( child ) ;
119
+ }
120
+ }
121
+ }
122
+ else if ( node . type === 11 satisfies vue . CompilerDOM . NodeTypes . FOR ) {
123
+ for ( const child of node . children ) {
124
+ visit ( child ) ;
125
+ }
126
+ }
127
+ } ) ;
128
+ }
129
+ return result ;
130
+ } ;
73
131
}
74
132
75
133
return info . languageService ;
0 commit comments