Skip to content

Commit b96aa7c

Browse files
committed
fix(typescript-plugin): improve session handling and type safety in protocol handlers
1 parent 882f55a commit b96aa7c

File tree

1 file changed

+53
-47
lines changed

1 file changed

+53
-47
lines changed

packages/typescript-plugin/index.ts

Lines changed: 53 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -72,31 +72,36 @@ export = createLanguageServicePlugin(
7272
const projectService = info.project.projectService;
7373
projectService.logger.info('Vue: called handler processing ' + info.project.projectKind);
7474

75-
const session = info.session;
76-
if (!session) {
75+
if (!info.session) {
7776
projectService.logger.info('Vue: there is no session in info.');
7877
return;
7978
}
79+
const session = info.session;
8080
if (!session.addProtocolHandler) {
8181
// addProtocolHandler was introduced in TS 4.4 or 4.5 in 2021, see https://github.com/microsoft/TypeScript/issues/43893
8282
projectService.logger.info('Vue: there is no addProtocolHandler method.');
8383
return;
8484
}
85-
if ((session as any).handlers.has('_vue:projectInfo')) {
85+
// @ts-expect-error
86+
const handlers = session.handlers as Map<
87+
string,
88+
(request: ts.server.protocol.Request) => ts.server.HandlerResponse
89+
>;
90+
if (handlers.has('_vue:projectInfo')) {
8691
return;
8792
}
8893

8994
session.addProtocolHandler('_vue:projectInfo', request => {
90-
return (session as any).handlers.get('projectInfo')?.(request);
95+
return handlers.get('projectInfo')!(request);
9196
});
9297
session.addProtocolHandler('_vue:documentHighlights-full', request => {
93-
return (session as any).handlers.get('documentHighlights-full')?.(request);
98+
return handlers.get('documentHighlights-full')!(request);
9499
});
95100
session.addProtocolHandler('_vue:encodedSemanticClassifications-full', request => {
96-
return (session as any).handlers.get('encodedSemanticClassifications-full')?.(request);
101+
return handlers.get('encodedSemanticClassifications-full')!(request);
97102
});
98103
session.addProtocolHandler('_vue:quickinfo', request => {
99-
return (session as any).handlers.get('quickinfo')?.(request);
104+
return handlers.get('quickinfo')!(request);
100105
});
101106
session.addProtocolHandler(
102107
'_vue:collectExtractProps',
@@ -158,51 +163,52 @@ export = createLanguageServicePlugin(
158163
});
159164

160165
projectService.logger.info('Vue specific commands are successfully added.');
161-
}
162-
163-
function createResponse(res: any): ts.server.HandlerResponse {
164-
return {
165-
response: res,
166-
responseRequired: true,
167-
};
168-
}
169166

170-
function getLanguageServiceAndVirtualCode(fileName: string) {
171-
const service = getLanguageService(fileName);
172-
const sourceScript = service?.language.scripts.get(fileName);
173-
if (!sourceScript) {
174-
throw new Error('No source script found for file: ' + fileName);
167+
function createResponse(res: any): ts.server.HandlerResponse {
168+
return {
169+
response: res,
170+
responseRequired: true,
171+
};
175172
}
176-
const virtualCode = sourceScript.generated?.root;
177-
if (!(virtualCode instanceof vue.VueVirtualCode)) {
178-
throw new Error('No virtual code found for file: ' + fileName);
173+
174+
function getLanguageServiceAndVirtualCode(fileName: string) {
175+
const service = getLanguageService(fileName);
176+
const sourceScript = service?.language.scripts.get(fileName);
177+
if (!sourceScript) {
178+
throw new Error('No source script found for file: ' + fileName);
179+
}
180+
const virtualCode = sourceScript.generated?.root;
181+
if (!(virtualCode instanceof vue.VueVirtualCode)) {
182+
throw new Error('No virtual code found for file: ' + fileName);
183+
}
184+
return {
185+
...service,
186+
sourceScript,
187+
virtualCode,
188+
};
179189
}
180-
return {
181-
...service,
182-
sourceScript,
183-
virtualCode,
184-
};
185-
}
186190

187-
function getLanguageService(fileName: string) {
188-
const { project } = (info.session as any).getFileAndProject({
189-
file: fileName,
190-
projectFileName: undefined,
191-
}) as {
192-
file: ts.server.NormalizedPath;
193-
project: ts.server.Project;
194-
};
195-
const service = project2Service.get(project);
196-
if (!service) {
197-
throw new Error('No vue service for project: ' + project.getProjectName());
191+
function getLanguageService(fileName: string) {
192+
// @ts-expect-error
193+
const { project } = session.getFileAndProject({
194+
file: fileName,
195+
projectFileName: undefined,
196+
}) as {
197+
file: ts.server.NormalizedPath;
198+
project: ts.server.Project;
199+
};
200+
const service = project2Service.get(project);
201+
if (!service) {
202+
throw new Error('No vue service for project: ' + project.getProjectName());
203+
}
204+
const [language, languageServiceHost, languageService] = service;
205+
return {
206+
typescript: ts,
207+
program: languageService.getProgram()!,
208+
languageServiceHost,
209+
language,
210+
};
198211
}
199-
const [language, languageServiceHost, languageService] = service;
200-
return {
201-
typescript: ts,
202-
program: languageService.getProgram()!,
203-
languageServiceHost,
204-
language,
205-
};
206212
}
207213
},
208214
);

0 commit comments

Comments
 (0)