|
1 | | -import { BlockFactory, CssBlockError, Options, resolveConfiguration } from "@css-blocks/core/dist/src"; |
2 | | -import { BlockParser } from "@css-blocks/core/dist/src/BlockParser/BlockParser"; |
| 1 | +import { search as searchForConfig } from "@css-blocks/config"; |
| 2 | +import { BlockFactory, Configuration, CssBlockError, resolveConfiguration } from "@css-blocks/core"; |
3 | 3 | import { CompletionItem, Definition, DidChangeConfigurationNotification, DocumentLink, DocumentLinkParams, IConnection, InitializeParams, InitializeResult, TextDocumentChangeEvent, TextDocumentPositionParams, TextDocuments } from "vscode-languageserver"; |
| 4 | +import { URI } from "vscode-uri"; |
4 | 5 |
|
5 | 6 | import { emberCompletionProvider } from "./completionProviders/emberCompletionProvider"; |
6 | 7 | import { createBlockFactory } from "./createBlockFactory"; |
7 | | -import { createBlockParser } from "./createBlockParser"; |
8 | 8 | import { emberDefinitionProvider } from "./definitionProviders/emberDefinitionProvider"; |
9 | 9 | import { blockLinksProvider } from "./documentLinksProviders/blockLinkProvider"; |
10 | 10 | import { documentContentChange } from "./eventHandlers/documentContentChange"; |
| 11 | +import { LSImporter } from "./Importer"; |
11 | 12 | import { PathTransformer } from "./pathTransformers/PathTransformer"; |
12 | 13 | import { SERVER_CAPABILITIES } from "./serverCapabilities"; |
13 | 14 | import { isBlockFile } from "./util/blockUtils"; |
14 | 15 | import { convertErrorsToDiagnostics } from "./util/diagnosticsUtils"; |
15 | 16 | import { isTemplateFile, validateTemplates } from "./util/hbsUtils"; |
16 | 17 |
|
17 | 18 | export class Server { |
| 19 | + _blockFactory: BlockFactory | undefined; |
| 20 | + _config: Readonly<Configuration> | undefined; |
18 | 21 | connection: IConnection; |
19 | 22 | documents: TextDocuments; |
20 | | - blockFactory: BlockFactory; |
21 | | - blockParser: BlockParser; |
22 | 23 | pathTransformer: PathTransformer; |
23 | 24 | hasConfigurationCapability = false; |
24 | 25 | hasWorkspaceFolderCapability = false; |
25 | 26 |
|
26 | | - constructor(connection: IConnection, documents: TextDocuments, pathTransformer: PathTransformer, cssBlocksOptions?: Options) { |
| 27 | + constructor(connection: IConnection, documents: TextDocuments, pathTransformer: PathTransformer) { |
27 | 28 | this.connection = connection; |
28 | 29 | this.documents = documents; |
29 | 30 | this.pathTransformer = pathTransformer; |
30 | 31 |
|
31 | | - // NOTE: creating these instances directly in the constructor because we |
32 | | - // don't currently have a need to expose them for mocking in testing. |
33 | | - const config = resolveConfiguration(cssBlocksOptions); |
34 | | - let blockFactory = createBlockFactory(config); |
35 | | - this.blockFactory = blockFactory; |
36 | | - this.blockParser = createBlockParser(config, blockFactory); |
37 | | - |
38 | 32 | this.registerDocumentEvents(); |
39 | 33 | this.registerConnectionEvents(); |
40 | 34 | } |
41 | 35 |
|
| 36 | + get config(): Readonly<Configuration> { |
| 37 | + if (!this._config) { |
| 38 | + this._config = resolveConfiguration({}); |
| 39 | + return this._config; |
| 40 | + } |
| 41 | + return this._config; |
| 42 | + } |
| 43 | + |
| 44 | + get blockFactory(): BlockFactory { |
| 45 | + if (!this._blockFactory) { |
| 46 | + this._blockFactory = createBlockFactory(this.config); |
| 47 | + } |
| 48 | + return this._blockFactory; |
| 49 | + } |
| 50 | + |
42 | 51 | listen() { |
43 | 52 | this.documents.listen(this.connection); |
44 | 53 | this.connection.listen(); |
@@ -91,8 +100,35 @@ export class Server { |
91 | 100 | }); |
92 | 101 | } |
93 | 102 |
|
94 | | - private onConnectionInitialize(params: InitializeParams): InitializeResult { |
| 103 | + private async onConnectionInitialize(params: InitializeParams): Promise<InitializeResult> { |
95 | 104 | let capabilities = params.capabilities; |
| 105 | + let options: Partial<Configuration>; |
| 106 | + |
| 107 | + // TODO #1: We need to spin up a server per workspace folder. |
| 108 | + // TODO #1: Then the rootUri should come in as part of the constructor params. |
| 109 | + // TODO #1: But the rest of the config lookup logic should remain basically the same. |
| 110 | + // TODO #2: There should be a configuration option to set the rootDir for CSS Blocks |
| 111 | + // TODO #2: as well as a configuration option to set the configuration file explicitly |
| 112 | + // TODO #2: instead of only doing a search for the configuration file. |
| 113 | + let result: Partial<Configuration> | null = null; |
| 114 | + let rootDir: string | null = null; |
| 115 | + if (params.workspaceFolders) { |
| 116 | + for (let wsFolder of params.workspaceFolders) { |
| 117 | + let folderPath = URI.parse(wsFolder.uri).fsPath; |
| 118 | + result = await searchForConfig(folderPath); |
| 119 | + if (result) { |
| 120 | + rootDir = folderPath; |
| 121 | + break; |
| 122 | + } |
| 123 | + } |
| 124 | + } else if (params.rootPath) { |
| 125 | + rootDir = params.rootPath; |
| 126 | + result = await searchForConfig(params.rootPath); |
| 127 | + } |
| 128 | + options = result || (rootDir ? {rootDir} : {}); |
| 129 | + options.importer = new LSImporter(this.documents, options.importer); |
| 130 | + this._config = resolveConfiguration(options); |
| 131 | + this._blockFactory = createBlockFactory(this._config); |
96 | 132 |
|
97 | 133 | // Does the client support the `workspace/configuration` request? |
98 | 134 | // If not, we will fall back using global settings |
|
0 commit comments