Skip to content

Commit

Permalink
Code split
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Feb 20, 2024
1 parent 1f565bd commit e37f35a
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
*--------------------------------------------------------------------------------------------*/

import { createServer, createConnection, createSimpleProjectProvider } from '@volar/language-server/node';
import { create as createCssServicePlugin } from 'volar-service-css';
import { create as createHtmlServicePlugin } from 'volar-service-html';
import { htmlLanguagePlugin } from '../modes/languagePlugin';
import { getLanguageServices } from '../modes/servicePlugins';

const connection = createConnection();
const server = createServer(connection);
Expand All @@ -17,10 +16,7 @@ connection.onInitialize(params => {
return [htmlLanguagePlugin];
},
getServicePlugins() {
return [
createCssServicePlugin(),
createHtmlServicePlugin(),
];
return getLanguageServices(server.modules.typescript!);
},
});
});
Expand Down
68 changes: 68 additions & 0 deletions extensions/html-language-features/server/src/modes/project.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { ServerProject } from '@volar/language-server';
import { ServerContext, ServerOptions } from '@volar/language-server/lib/server';
import { LanguageService, ServiceEnvironment, ServicePlugin, createLanguageService } from '@volar/language-service';
import type { SnapshotDocument } from '@volar/snapshot-document';
import { createLanguage, createSys } from '@volar/typescript';
import { createProjectHost } from './projectHost';

export async function createProject(
context: ServerContext,
serviceEnv: ServiceEnvironment,
getLanguagePlugins: ServerOptions['getLanguagePlugins'],
servicePlugins: ServicePlugin[],
getCurrentTextDocument: () => SnapshotDocument,
): Promise<ServerProject> {

let languageService: LanguageService | undefined;

const ts = context.ts!;
const sys = createSys(ts, serviceEnv, '');
const host = createProjectHost(
serviceEnv.typescript!,
fileName => sys.readFile(fileName),
getCurrentTextDocument,
() => getCurrentTextDocument().getSnapshot(),
context.tsLocalized,
)
const languagePlugins = await getLanguagePlugins(serviceEnv, {
typescript: {
configFileName: undefined,
host,
sys,
},
});

return {
serviceEnv,
getLanguageService,
getLanguageServiceDontCreate: () => languageService,
dispose,
};

function getLanguageService() {
if (!languageService) {
const language = createLanguage(
ts,
sys,
languagePlugins,
undefined,
host,
{
fileNameToFileId: serviceEnv.typescript!.fileNameToUri,
fileIdToFileName: serviceEnv.typescript!.uriToFileName,
},
);
languageService = createLanguageService(
language,
servicePlugins,
serviceEnv,
);
}
return languageService;
}

function dispose() {
sys.dispose();
languageService?.dispose();
}
}
48 changes: 48 additions & 0 deletions extensions/html-language-features/server/src/modes/projectHost.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ServiceEnvironment, TypeScriptProjectHost, resolveCommonLanguageId, TextDocument } from '@volar/language-service';
import type * as ts from 'typescript';
import { JQUERY_PATH } from './javascriptLibs';

export function createProjectHost(
{ uriToFileName, fileNameToUri }: NonNullable<ServiceEnvironment['typescript']>,
readFile: (fileName: string) => string | undefined,
getCurrentTextDocument: () => TextDocument,
getCurrentDocumentSnapshot: () => ts.IScriptSnapshot,
tsLocalized?: ts.MapLike<string>,
) {
const libSnapshots = new Map<string, ts.IScriptSnapshot | undefined>();
const compilerOptions: ts.CompilerOptions = { allowNonTsExtensions: true, allowJs: true, lib: ['lib.es2020.full.d.ts'], target: 99 satisfies ts.ScriptTarget.Latest, moduleResolution: 1 satisfies ts.ModuleResolutionKind.Classic, experimentalDecorators: false };
const host: TypeScriptProjectHost = {
getCompilationSettings: () => compilerOptions,
getScriptFileNames: () => [uriToFileName(getCurrentTextDocument().uri), JQUERY_PATH],
getCurrentDirectory: () => '',
getProjectVersion: () => getCurrentTextDocument().uri + ',' + getCurrentTextDocument().version.toString(),
getScriptSnapshot: fileName => {
if (fileNameToUri(fileName) === getCurrentTextDocument().uri) {
return getCurrentDocumentSnapshot();
}
else {
let snapshot = libSnapshots.get(fileName);
if (!snapshot) {
const text = readFile(fileName);
if (text !== undefined) {
snapshot = {
getText: (start, end) => text.substring(start, end),
getLength: () => text.length,
getChangeRange: () => undefined,
};
}
libSnapshots.set(fileName, snapshot);
}
return snapshot;
}
},
getLocalizedDiagnosticMessages: tsLocalized ? () => tsLocalized : undefined,
getLanguageId: uri => {
if (uri === getCurrentTextDocument().uri) {
return getCurrentTextDocument().languageId;
}
return resolveCommonLanguageId(uri)
},
};
return host;
}
100 changes: 9 additions & 91 deletions extensions/html-language-features/server/src/modes/projectProvider.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { ServerProject, ServerProjectProviderFactory } from '@volar/language-server';
import { ServerContext, ServerOptions } from '@volar/language-server/lib/server';
import { createServiceEnvironment, getWorkspaceFolder } from '@volar/language-server/node';
import { LanguageService, ServiceEnvironment, ServicePlugin, TypeScriptProjectHost, createLanguageService, resolveCommonLanguageId } from '@volar/language-service';
import { createLanguage, createSys } from '@volar/typescript';
import type * as ts from 'typescript';
import type { SnapshotDocument } from '@volar/snapshot-document';
import { URI } from 'vscode-uri';
import type { SnapshotDocument } from '@volar/snapshot-document'
import { JQUERY_PATH } from './javascriptLibs';
import { createProject } from './project';

export const serverProjectProviderFactory: ServerProjectProviderFactory = (context, serverOptions, servicePlugins) => {

Expand Down Expand Up @@ -38,93 +34,15 @@ export const serverProjectProviderFactory: ServerProjectProviderFactory = (conte
if (!inferredProject) {
inferredProject = (async () => {
const serviceEnv = createServiceEnvironment(context, workspaceFolder);
return createProject(context, serviceEnv, serverOptions.getLanguagePlugins, servicePlugins);
})();
}
return await inferredProject;
}

async function createProject(
context: ServerContext,
serviceEnv: ServiceEnvironment,
getLanguagePlugins: ServerOptions['getLanguagePlugins'],
servicePlugins: ServicePlugin[],
): Promise<ServerProject> {

let languageService: LanguageService | undefined;

const libSnapshots = new Map<string, ts.IScriptSnapshot | undefined>();
const { fileNameToUri } = context.runtimeEnv;
const ts = context.ts!;
const compilerOptions: ts.CompilerOptions = { allowNonTsExtensions: true, allowJs: true, lib: ['lib.es2020.full.d.ts'], target: ts.ScriptTarget.Latest, moduleResolution: ts.ModuleResolutionKind.Classic, experimentalDecorators: false };
const sys = createSys(ts, serviceEnv, '');
const host: TypeScriptProjectHost = {
getCompilationSettings: () => compilerOptions,
getScriptFileNames: () => [uriToFileName(currentTextDocument!.uri), JQUERY_PATH],
getCurrentDirectory: () => '',
getProjectVersion: () => currentTextDocument!.uri + ',' + currentTextDocument!.version.toString() + ',' + sys.version,
getScriptSnapshot: fileName => {
if (fileNameToUri(fileName) === currentTextDocument!.uri) {
const document = context.documents.get(fileNameToUri(fileName));
if (document) {
return document.getSnapshot();
}
}
else {
let snapshot = libSnapshots.get(fileName);
if (!snapshot) {
const text = sys.readFile?.(fileName);
if (text !== undefined) {
snapshot = ts.ScriptSnapshot.fromString(text);
}
libSnapshots.set(fileName, snapshot);
}
return snapshot;
}
return undefined;
},
getLocalizedDiagnosticMessages: context.tsLocalized ? () => context.tsLocalized : undefined,
getLanguageId: uri => context.documents.get(uri)?.languageId ?? resolveCommonLanguageId(uri),
};
const languagePlugins = await getLanguagePlugins(serviceEnv, {
typescript: {
configFileName: undefined,
host,
sys,
},
});

return {
serviceEnv,
getLanguageService,
getLanguageServiceDontCreate: () => languageService,
dispose,
};

function getLanguageService() {
if (!languageService) {
const language = createLanguage(
ts,
sys,
languagePlugins,
undefined,
host,
{
fileNameToFileId: serviceEnv.typescript!.fileNameToUri,
fileIdToFileName: serviceEnv.typescript!.uriToFileName,
},
);
languageService = createLanguageService(
language,
servicePlugins,
return createProject(
context,
serviceEnv,
serverOptions.getLanguagePlugins,
servicePlugins,
() => currentTextDocument!,
);
}
return languageService;
}
function dispose() {
sys.dispose();
languageService?.dispose();
})();
}
return await inferredProject;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import type { ServicePlugin } from '@volar/language-service';
import { create as createCssServicePlugin } from 'volar-service-css';
import { create as createHtmlServicePlugin } from 'volar-service-html';
import { create as createTypeScriptServicePlugin } from 'volar-service-typescript';

export function getLanguageServices(ts: typeof import('typescript')) {
const html1ServicePlugins: ServicePlugin[] = [
createCssServicePlugin(),
createHtmlServicePlugin(),
createTypeScriptServicePlugin(ts),
{
create() {
return {
resolveEmbeddedCodeFormattingOptions(code, options) {
if (code.id.startsWith('css_')) {
options.initialIndentLevel++;
}
return options;
},
};
},
},
];
return html1ServicePlugins;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
*--------------------------------------------------------------------------------------------*/

import { createServer, createConnection } from '@volar/language-server/node';
import { create as createCssServicePlugin } from 'volar-service-css';
import { create as createHtmlServicePlugin } from 'volar-service-html';
import { create as createTypeScriptServicePlugin } from 'volar-service-typescript';
import { htmlLanguagePlugin } from '../modes/languagePlugin';
import { serverProjectProviderFactory } from '../modes/projectProvider';
import { getLanguageServices } from '../modes/servicePlugins';

const connection = createConnection();
const server = createServer(connection);
Expand All @@ -19,23 +17,7 @@ connection.onInitialize(params => {
return [htmlLanguagePlugin];
},
getServicePlugins() {
return [
createCssServicePlugin(),
createHtmlServicePlugin(),
createTypeScriptServicePlugin(server.modules.typescript!),
{
create() {
return {
resolveEmbeddedCodeFormattingOptions(code, options) {
if (code.id.startsWith('css_')) {
options.initialIndentLevel++;
}
return options;
},
};
},
},
];
return getLanguageServices(server.modules.typescript!);
},
});
});
Expand Down

0 comments on commit e37f35a

Please sign in to comment.