@atlaspack/lsp 2.14.2-typescript-8a6ec6c8b.0 → 2.14.2-typescript-d6e6d169c.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/LspServer.js +28 -23
- package/lib/LspServer.js.map +1 -1
- package/package.json +3 -3
- package/src/LspServer.ts +31 -22
package/lib/LspServer.js
CHANGED
|
@@ -5,9 +5,9 @@ var $cBkJy$vscodelanguageservernode = require("vscode-languageserver/node");
|
|
|
5
5
|
var $cBkJy$vscodejsonrpcnode = require("vscode-jsonrpc/node");
|
|
6
6
|
var $cBkJy$assert = require("assert");
|
|
7
7
|
var $cBkJy$url = require("url");
|
|
8
|
-
var $cBkJy$commonpathprefix = require("common-path-prefix");
|
|
9
8
|
var $cBkJy$parcelwatcher = require("@parcel/watcher");
|
|
10
9
|
var $cBkJy$atlaspacklspprotocol = require("@atlaspack/lsp-protocol");
|
|
10
|
+
var $cBkJy$commonpathprefix = require("common-path-prefix");
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
@@ -60,21 +60,22 @@ $7ef283f05e7b48bf$var$connection.onInitialize((params)=>{
|
|
|
60
60
|
$7ef283f05e7b48bf$var$connection.onInitialized(()=>{
|
|
61
61
|
if ($7ef283f05e7b48bf$var$hasConfigurationCapability) // Register for all configuration changes.
|
|
62
62
|
$7ef283f05e7b48bf$var$connection.client.register((0, $cBkJy$vscodelanguageservernode.DidChangeConfigurationNotification).type, undefined);
|
|
63
|
-
if ($7ef283f05e7b48bf$var$hasWorkspaceFolderCapability)
|
|
63
|
+
if ($7ef283f05e7b48bf$var$hasWorkspaceFolderCapability) // eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
64
|
+
$7ef283f05e7b48bf$var$connection.workspace.onDidChangeWorkspaceFolders((_event)=>{
|
|
64
65
|
$7ef283f05e7b48bf$var$connection.console.log('Workspace folder change event received.');
|
|
65
66
|
});
|
|
66
67
|
});
|
|
67
68
|
// Proxy
|
|
68
69
|
$7ef283f05e7b48bf$var$connection.onRequest((0, $cBkJy$atlaspacklspprotocol.RequestImporters), async (params)=>{
|
|
69
|
-
|
|
70
|
+
const client = $7ef283f05e7b48bf$var$findClient(params);
|
|
70
71
|
if (client) {
|
|
71
|
-
|
|
72
|
+
const result = await client.connection.sendRequest((0, $cBkJy$atlaspacklspprotocol.RequestImporters), params);
|
|
72
73
|
return result;
|
|
73
74
|
}
|
|
74
75
|
return null;
|
|
75
76
|
});
|
|
76
77
|
$7ef283f05e7b48bf$var$connection.onRequest((0, $cBkJy$vscodelanguageservernode.DocumentDiagnosticRequest).type, async (params)=>{
|
|
77
|
-
|
|
78
|
+
const client = $7ef283f05e7b48bf$var$findClient(params.textDocument.uri);
|
|
78
79
|
let result;
|
|
79
80
|
if (client) {
|
|
80
81
|
// console.log(
|
|
@@ -99,6 +100,7 @@ $7ef283f05e7b48bf$var$connection.listen();
|
|
|
99
100
|
class $7ef283f05e7b48bf$var$ProgressReporter {
|
|
100
101
|
begin() {
|
|
101
102
|
this.progressReporterPromise = (async ()=>{
|
|
103
|
+
// eslint-disable-next-line prefer-const
|
|
102
104
|
let reporter = await $7ef283f05e7b48bf$var$connection.window.createWorkDoneProgress();
|
|
103
105
|
reporter.begin('Atlaspack');
|
|
104
106
|
return reporter;
|
|
@@ -118,7 +120,7 @@ class $7ef283f05e7b48bf$var$ProgressReporter {
|
|
|
118
120
|
this.lastMessage = message;
|
|
119
121
|
this.begin();
|
|
120
122
|
} else {
|
|
121
|
-
|
|
123
|
+
const r = await this.progressReporterPromise;
|
|
122
124
|
r.report(message);
|
|
123
125
|
}
|
|
124
126
|
}
|
|
@@ -126,21 +128,22 @@ class $7ef283f05e7b48bf$var$ProgressReporter {
|
|
|
126
128
|
function $7ef283f05e7b48bf$var$sendDiagnosticsRefresh() {
|
|
127
129
|
if ($7ef283f05e7b48bf$var$hasDiagnosticsRefreshSupport) $7ef283f05e7b48bf$var$connection.sendRequest((0, $cBkJy$vscodelanguageservernode.DiagnosticRefreshRequest).type);
|
|
128
130
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
const $7ef283f05e7b48bf$var$progressReporter = new $7ef283f05e7b48bf$var$ProgressReporter();
|
|
132
|
+
const $7ef283f05e7b48bf$var$clients = new Map();
|
|
131
133
|
function $7ef283f05e7b48bf$var$findClient(document) {
|
|
132
|
-
|
|
134
|
+
const filepath = $cBkJy$url.fileURLToPath(document);
|
|
133
135
|
let longestPrefix = 0;
|
|
134
136
|
let bestClient;
|
|
135
|
-
for (
|
|
136
|
-
|
|
137
|
+
for (const [, client] of $7ef283f05e7b48bf$var$clients){
|
|
138
|
+
const prefix = $cBkJy$commonpathprefix([
|
|
137
139
|
client.projectRoot,
|
|
138
140
|
filepath
|
|
139
141
|
]).length;
|
|
140
142
|
if (longestPrefix < prefix) {
|
|
141
143
|
longestPrefix = prefix;
|
|
142
144
|
bestClient = client;
|
|
143
|
-
} else if (longestPrefix === prefix)
|
|
145
|
+
} else if (longestPrefix === prefix) // eslint-disable-next-line no-console
|
|
146
|
+
console.warn('Ambiguous client for ' + filepath);
|
|
144
147
|
}
|
|
145
148
|
return bestClient;
|
|
146
149
|
}
|
|
@@ -149,12 +152,12 @@ function $7ef283f05e7b48bf$var$loadMetafile(filepath) {
|
|
|
149
152
|
return JSON.parse(file);
|
|
150
153
|
}
|
|
151
154
|
function $7ef283f05e7b48bf$var$createClient(metafilepath, metafile) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
+
const socketfilepath = metafilepath.slice(0, -5);
|
|
156
|
+
const [reader, writer] = (0, $cBkJy$vscodejsonrpcnode.createServerPipeTransport)(socketfilepath);
|
|
157
|
+
const client = (0, $cBkJy$vscodejsonrpcnode.createMessageConnection)(reader, writer);
|
|
155
158
|
client.listen();
|
|
156
|
-
|
|
157
|
-
|
|
159
|
+
const uris = new Set();
|
|
160
|
+
const result = {
|
|
158
161
|
connection: client,
|
|
159
162
|
uris: uris,
|
|
160
163
|
projectRoot: metafile.projectRoot,
|
|
@@ -164,7 +167,7 @@ function $7ef283f05e7b48bf$var$createClient(metafilepath, metafile) {
|
|
|
164
167
|
// console.log('got NotificationBuildStatus', state, message);
|
|
165
168
|
if (state === 'start') {
|
|
166
169
|
$7ef283f05e7b48bf$var$progressReporter.begin();
|
|
167
|
-
for (
|
|
170
|
+
for (const uri of uris)$7ef283f05e7b48bf$var$connection.sendDiagnostics({
|
|
168
171
|
uri: uri,
|
|
169
172
|
diagnostics: []
|
|
170
173
|
});
|
|
@@ -178,7 +181,7 @@ function $7ef283f05e7b48bf$var$createClient(metafilepath, metafile) {
|
|
|
178
181
|
});
|
|
179
182
|
client.onNotification((0, $cBkJy$atlaspacklspprotocol.NotificationWorkspaceDiagnostics), (diagnostics)=>{
|
|
180
183
|
// console.log('got NotificationWorkspaceDiagnostics', diagnostics);
|
|
181
|
-
for (
|
|
184
|
+
for (const d of diagnostics){
|
|
182
185
|
uris.add(d.uri);
|
|
183
186
|
$7ef283f05e7b48bf$var$connection.sendDiagnostics(d);
|
|
184
187
|
}
|
|
@@ -204,24 +207,26 @@ $cBkJy$fs.mkdirSync($7ef283f05e7b48bf$var$BASEDIR, {
|
|
|
204
207
|
$cBkJy$fs.writeFileSync($cBkJy$path.join($7ef283f05e7b48bf$var$BASEDIR, $7ef283f05e7b48bf$var$LSP_SENTINEL_FILENAME), '');
|
|
205
208
|
// Search for currently running Atlaspack processes in the parcel-lsp dir.
|
|
206
209
|
// Create an IPC client connection for each running process.
|
|
207
|
-
for (
|
|
210
|
+
for (const filename of $cBkJy$fs.readdirSync($7ef283f05e7b48bf$var$BASEDIR)){
|
|
208
211
|
if (!filename.endsWith('.json')) continue;
|
|
209
|
-
|
|
212
|
+
const filepath = $cBkJy$path.join($7ef283f05e7b48bf$var$BASEDIR, filename);
|
|
210
213
|
const contents = $7ef283f05e7b48bf$var$loadMetafile(filepath);
|
|
211
214
|
const { projectRoot: projectRoot } = contents;
|
|
212
215
|
if ($7ef283f05e7b48bf$var$WORKSPACE_ROOT === projectRoot) $7ef283f05e7b48bf$var$createClient(filepath, contents);
|
|
213
216
|
}
|
|
214
217
|
// Watch for new Atlaspack processes in the parcel-lsp dir, and disconnect the
|
|
215
218
|
// client for each corresponding connection when a Atlaspack process ends
|
|
219
|
+
// eslint-disable-next-line require-await
|
|
216
220
|
$cBkJy$parcelwatcher.subscribe($7ef283f05e7b48bf$var$BASEDIR, async (err, events)=>{
|
|
217
221
|
if (err) throw err;
|
|
218
|
-
for (
|
|
222
|
+
for (const event of events){
|
|
219
223
|
if (event.type === 'create' && event.path.endsWith('.json')) {
|
|
220
224
|
const contents = $7ef283f05e7b48bf$var$loadMetafile(event.path);
|
|
221
225
|
const { projectRoot: projectRoot } = contents;
|
|
222
226
|
if ($7ef283f05e7b48bf$var$WORKSPACE_ROOT === projectRoot) $7ef283f05e7b48bf$var$createClient(event.path, contents);
|
|
223
227
|
} else if (event.type === 'delete' && event.path.endsWith('.json')) {
|
|
224
|
-
|
|
228
|
+
const existing = $7ef283f05e7b48bf$var$clients.get(event.path);
|
|
229
|
+
// eslint-disable-next-line no-console
|
|
225
230
|
console.log('existing', event.path, existing);
|
|
226
231
|
if (existing) {
|
|
227
232
|
$7ef283f05e7b48bf$var$clients.delete(event.path);
|
package/lib/LspServer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/utils/atlaspack-lsp/src/LspServer.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport {\n createConnection,\n DiagnosticRefreshRequest,\n DidChangeConfigurationNotification,\n DocumentDiagnosticParams,\n DocumentDiagnosticReport,\n DocumentDiagnosticReportKind,\n DocumentDiagnosticRequest,\n DocumentUri,\n InitializeParams,\n InitializeResult,\n ProposedFeatures,\n TextDocumentSyncKind,\n WorkDoneProgressServerReporter,\n} from 'vscode-languageserver/node';\n\nimport {\n createServerPipeTransport,\n createMessageConnection,\n MessageConnection,\n} from 'vscode-jsonrpc/node';\nimport * as invariant from 'assert';\nimport * as url from 'url';\nimport commonPathPrefix = require('common-path-prefix');\n\n// import {TextDocument} from 'vscode-languageserver-textdocument';\nimport * as watcher from '@parcel/watcher';\nimport {\n NotificationBuild,\n NotificationBuildStatus,\n NotificationWorkspaceDiagnostics,\n RequestDocumentDiagnostics,\n RequestImporters,\n} from '@atlaspack/lsp-protocol';\n\ntype Metafile = {\n projectRoot: string;\n pid: typeof process['pid'];\n argv: typeof process['argv'];\n};\n\nconst connection = createConnection(ProposedFeatures.all);\nconst WORKSPACE_ROOT = process.cwd();\nconst LSP_SENTINEL_FILENAME = 'lsp-server';\n// Create a simple text document manager.\n// const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);\n\nlet hasConfigurationCapability = false;\nlet hasWorkspaceFolderCapability = false;\n// let hasDiagnosticRelatedInformationCapability = false;\nlet hasDiagnosticsRefreshSupport = false;\n\nconnection.onInitialize((params: InitializeParams) => {\n const capabilities = params.capabilities;\n\n // Does the client support the `workspace/configuration` request?\n // If not, we fall back using global settings.\n hasConfigurationCapability = !!(\n capabilities.workspace && !!capabilities.workspace.configuration\n );\n hasWorkspaceFolderCapability = !!(\n capabilities.workspace && !!capabilities.workspace.workspaceFolders\n );\n // hasDiagnosticRelatedInformationCapability = !!(\n // capabilities.textDocument &&\n // capabilities.textDocument.publishDiagnostics &&\n // capabilities.textDocument.publishDiagnostics.relatedInformation\n // );\n hasDiagnosticsRefreshSupport = Boolean(\n capabilities.workspace?.diagnostics?.refreshSupport,\n );\n\n const result: InitializeResult = {\n capabilities: {\n textDocumentSync: TextDocumentSyncKind.Incremental,\n // Tell the client that this server supports code completion.\n diagnosticProvider: {\n workspaceDiagnostics: false,\n interFileDependencies: true,\n },\n },\n };\n\n if (hasWorkspaceFolderCapability) {\n result.capabilities.workspace = {\n workspaceFolders: {\n supported: true,\n },\n };\n }\n return result;\n});\n\nconnection.onInitialized(() => {\n if (hasConfigurationCapability) {\n // Register for all configuration changes.\n connection.client.register(\n DidChangeConfigurationNotification.type,\n undefined,\n );\n }\n if (hasWorkspaceFolderCapability) {\n connection.workspace.onDidChangeWorkspaceFolders((_event) => {\n connection.console.log('Workspace folder change event received.');\n });\n }\n});\n\n// Proxy\nconnection.onRequest(RequestImporters, async (params) => {\n let client = findClient(params);\n if (client) {\n let result = await client.connection.sendRequest(RequestImporters, params);\n return result;\n }\n return null;\n});\n\nconnection.onRequest(\n DocumentDiagnosticRequest.type,\n async (\n params: DocumentDiagnosticParams,\n ): Promise<DocumentDiagnosticReport> => {\n let client = findClient(params.textDocument.uri);\n let result;\n if (client) {\n // console.log(\n // 'DocumentDiagnosticRequest',\n // params.textDocument.uri,\n // params.previousResultId === client.lastBuild,\n // );\n\n if (params.previousResultId === client.lastBuild) {\n return {\n kind: DocumentDiagnosticReportKind.Unchanged,\n resultId: client.lastBuild,\n };\n }\n\n result = await client.connection.sendRequest(\n RequestDocumentDiagnostics,\n params.textDocument.uri,\n );\n\n if (result) {\n client.uris.add(params.textDocument.uri);\n }\n }\n\n return {\n kind: DocumentDiagnosticReportKind.Full,\n resultId: client?.lastBuild,\n items: result ?? [],\n };\n },\n);\n\nconnection.listen();\n\nclass ProgressReporter {\n progressReporterPromise?: Promise<WorkDoneProgressServerReporter> | null;\n lastMessage?: string;\n begin() {\n this.progressReporterPromise = (async () => {\n let reporter = await connection.window.createWorkDoneProgress();\n reporter.begin('Atlaspack');\n return reporter;\n })();\n this.progressReporterPromise.then((reporter) => {\n if (this.lastMessage != null) {\n reporter.report(this.lastMessage);\n }\n });\n }\n async done() {\n if (this.progressReporterPromise == null) {\n this.begin();\n }\n invariant(this.progressReporterPromise != null);\n (await this.progressReporterPromise).done();\n this.progressReporterPromise = null;\n }\n async report(message: string) {\n if (this.progressReporterPromise == null) {\n this.lastMessage = message;\n this.begin();\n } else {\n let r = await this.progressReporterPromise;\n r.report(message);\n }\n }\n}\n\nfunction sendDiagnosticsRefresh() {\n if (hasDiagnosticsRefreshSupport) {\n connection.sendRequest(DiagnosticRefreshRequest.type);\n }\n}\n\ntype Client = {\n connection: MessageConnection;\n projectRoot: string;\n uris: Set<DocumentUri>;\n lastBuild: string;\n};\n\nlet progressReporter = new ProgressReporter();\nlet clients: Map<string, Client> = new Map();\n\nfunction findClient(document: DocumentUri): Client | undefined {\n let filepath = url.fileURLToPath(document);\n\n let longestPrefix = 0;\n let bestClient;\n for (let [, client] of clients) {\n let prefix = commonPathPrefix([client.projectRoot, filepath]).length;\n if (longestPrefix < prefix) {\n longestPrefix = prefix;\n bestClient = client;\n } else if (longestPrefix === prefix) {\n console.warn('Ambiguous client for ' + filepath);\n }\n }\n return bestClient;\n}\n\nfunction loadMetafile(filepath: string) {\n const file = fs.readFileSync(filepath, 'utf-8');\n return JSON.parse(file);\n}\n\nfunction createClient(metafilepath: string, metafile: Metafile) {\n let socketfilepath = metafilepath.slice(0, -5);\n let [reader, writer] = createServerPipeTransport(socketfilepath);\n let client = createMessageConnection(reader, writer);\n client.listen();\n\n let uris = new Set<DocumentUri>();\n\n let result = {\n connection: client,\n uris,\n projectRoot: metafile.projectRoot,\n lastBuild: '0',\n };\n\n client.onNotification(NotificationBuildStatus, (state, message) => {\n // console.log('got NotificationBuildStatus', state, message);\n if (state === 'start') {\n progressReporter.begin();\n for (let uri of uris) {\n connection.sendDiagnostics({uri, diagnostics: []});\n }\n } else if (state === 'progress' && message != null) {\n progressReporter.report(message);\n } else if (state === 'end') {\n result.lastBuild = String(Date.now());\n sendDiagnosticsRefresh();\n progressReporter.done();\n connection.sendNotification(NotificationBuild);\n }\n });\n\n client.onNotification(NotificationWorkspaceDiagnostics, (diagnostics) => {\n // console.log('got NotificationWorkspaceDiagnostics', diagnostics);\n for (let d of diagnostics) {\n uris.add(d.uri);\n connection.sendDiagnostics(d);\n }\n });\n\n client.onClose(() => {\n clients.delete(JSON.stringify(metafile));\n sendDiagnosticsRefresh();\n return Promise.all(\n [...uris].map((uri) =>\n connection.sendDiagnostics({uri, diagnostics: []}),\n ),\n );\n });\n\n sendDiagnosticsRefresh();\n clients.set(JSON.stringify(metafile), result);\n}\n\n// Take realpath because to have consistent cache keys on macOS (/var -> /private/var)\nconst BASEDIR = path.join(fs.realpathSync(os.tmpdir()), 'parcel-lsp');\nfs.mkdirSync(BASEDIR, {recursive: true});\n\nfs.writeFileSync(path.join(BASEDIR, LSP_SENTINEL_FILENAME), '');\n\n// Search for currently running Atlaspack processes in the parcel-lsp dir.\n// Create an IPC client connection for each running process.\nfor (let filename of fs.readdirSync(BASEDIR)) {\n if (!filename.endsWith('.json')) continue;\n let filepath = path.join(BASEDIR, filename);\n const contents = loadMetafile(filepath);\n const {projectRoot} = contents;\n\n if (WORKSPACE_ROOT === projectRoot) {\n createClient(filepath, contents);\n }\n}\n\n// Watch for new Atlaspack processes in the parcel-lsp dir, and disconnect the\n// client for each corresponding connection when a Atlaspack process ends\nwatcher.subscribe(BASEDIR, async (err, events) => {\n if (err) {\n throw err;\n }\n\n for (let event of events) {\n if (event.type === 'create' && event.path.endsWith('.json')) {\n const contents = loadMetafile(event.path);\n const {projectRoot} = contents;\n\n if (WORKSPACE_ROOT === projectRoot) {\n createClient(event.path, contents);\n }\n } else if (event.type === 'delete' && event.path.endsWith('.json')) {\n let existing = clients.get(event.path);\n console.log('existing', event.path, existing);\n if (existing) {\n clients.delete(event.path);\n existing.connection.end();\n }\n }\n }\n});\n"],"names":["path","fs","os","createConnection","DiagnosticRefreshRequest","DidChangeConfigurationNotification","DocumentDiagnosticParams","DocumentDiagnosticReport","DocumentDiagnosticReportKind","DocumentDiagnosticRequest","DocumentUri","InitializeParams","InitializeResult","ProposedFeatures","TextDocumentSyncKind","WorkDoneProgressServerReporter","createServerPipeTransport","createMessageConnection","MessageConnection","invariant","url","commonPathPrefix","watcher","NotificationBuild","NotificationBuildStatus","NotificationWorkspaceDiagnostics","RequestDocumentDiagnostics","RequestImporters","Metafile","projectRoot","pid","process","argv","connection","all","WORKSPACE_ROOT","cwd","LSP_SENTINEL_FILENAME","hasConfigurationCapability","hasWorkspaceFolderCapability","hasDiagnosticsRefreshSupport","onInitialize","params","capabilities","workspace","configuration","workspaceFolders","Boolean","diagnostics","refreshSupport","result","textDocumentSync","Incremental","diagnosticProvider","workspaceDiagnostics","interFileDependencies","supported","onInitialized","client","register","type","undefined","onDidChangeWorkspaceFolders","_event","console","log","onRequest","findClient","sendRequest","Promise","textDocument","uri","previousResultId","lastBuild","kind","Unchanged","resultId","uris","add","Full","items","listen","ProgressReporter","begin","progressReporterPromise","reporter","window","createWorkDoneProgress","then","lastMessage","report","done","message","r","sendDiagnosticsRefresh","Client","Set","progressReporter","clients","Map","document","filepath","fileURLToPath","longestPrefix","bestClient","prefix","length","warn","loadMetafile","file","readFileSync","JSON","parse","createClient","metafilepath","metafile","socketfilepath","slice","reader","writer","onNotification","state","sendDiagnostics","String","Date","now","sendNotification","d","onClose","delete","stringify","map","set","BASEDIR","join","realpathSync","tmpdir","mkdirSync","recursive","writeFileSync","filename","readdirSync","endsWith","contents","subscribe","err","events","event","existing","get","end"],"version":3,"file":"LspServer.js.map","sourceRoot":"../../../../"}
|
|
1
|
+
{"mappings":";;;;;;;;;;;;;;;;;;;;;AA6CA,MAAMkC,mCAAa/B,CAAAA,GAAAA,gDAAAA,EAAiBU,CAAAA,GAAAA,gDAAAA,EAAiBsB,GAAG;AACxD,MAAMC,uCAAiBJ,QAAQK,GAAG;AAClC,MAAMC,8CAAwB;AAC9B,yCAAA;AACA,kFAAA;AAEA,IAAIC,mDAA6B;AACjC,IAAIC,qDAA+B;AACnC,yDAAA;AACA,IAAIC,qDAA+B;AAEnCP,iCAAWQ,YAAY,CAAC,CAACC;IACvB,MAAMC,eAAeD,OAAOC,YAAY;IAExC,iEAAA;IACA,8CAAA;IACAL,mDAA6B,CAAC,CAC5BK,CAAAA,aAAaC,SAAS,IAAI,CAAC,CAACD,aAAaC,SAAS,CAACC,aAAa,AAAbA;IAErDN,qDAA+B,CAAC,CAC9BI,CAAAA,aAAaC,SAAS,IAAI,CAAC,CAACD,aAAaC,SAAS,CAACE,gBAAgB,AAAhBA;IAErD,kDAAA;IACA,iCAAA;IACA,oDAAA;IACA,oEAAA;IACA,KAAA;IACAN,qDAA+BO,QAC7BJ,aAAaC,SAAS,EAAEI,aAAaC;IAGvC,MAAMC,SAA2B;QAC/BP,cAAc;YACZQ,kBAAkBtC,CAAAA,GAAAA,oDAAAA,EAAqBuC,WAAW;YAClD,6DAAA;YACAC,oBAAoB;gBAClBC,sBAAsB;gBACtBC,uBAAuB;YACzB;QACF;IACF;IAEA,IAAIhB,oDACFW,OAAOP,YAAY,CAACC,SAAS,GAAG;QAC9BE,kBAAkB;YAChBU,WAAW;QACb;IACF;IAEF,OAAON;AACT;AAEAjB,iCAAWwB,aAAa,CAAC;IACvB,IAAInB,kDACF,0CAAA;IACAL,iCAAWyB,MAAM,CAACC,QAAQ,CACxBvD,CAAAA,GAAAA,kEAAAA,EAAmCwD,IAAI,EACvCC;IAGJ,IAAItB,oDACF,6DAAA;IACAN,iCAAWW,SAAS,CAACkB,2BAA2B,CAAEC,CAAAA;QAChD9B,iCAAW+B,OAAO,CAACC,GAAG,CAAC;IACzB;AAEJ;AAEA,QAAA;AACAhC,iCAAWiC,SAAS,CAACzC,CAAAA,GAAAA,4CAAAA,GAAkB,OAAOiB;IAC5C,MAAMgB,SAASS,iCAAWzB;IAC1B,IAAIgB,QAAQ;QACV,MAAMR,SAAS,MAAMQ,OAAOzB,UAAU,CAACmC,WAAW,CAChD3C,CAAAA,GAAAA,4CAAAA,GACAiB;QAEF,OAAOQ;IACT;IACA,OAAO;AACT;AAEAjB,iCAAWiC,SAAS,CAClB1D,CAAAA,GAAAA,yDAAAA,EAA0BoD,IAAI,EAC9B,OACElB;IAEA,MAAMgB,SAASS,iCAAWzB,OAAO4B,YAAY,CAACC,GAAG;IACjD,IAAIrB;IACJ,IAAIQ,QAAQ;QACV,eAAA;QACA,iCAAA;QACA,6BAAA;QACA,kDAAA;QACA,KAAA;QAEA,IAAIhB,OAAO8B,gBAAgB,KAAKd,OAAOe,SAAS,EAC9C,OAAO;YACLC,MAAMnE,CAAAA,GAAAA,4DAAAA,EAA6BoE,SAAS;YAC5CC,UAAUlB,OAAOe,SAAjBG;QACF;QAGF1B,SAAS,MAAMQ,OAAOzB,UAAU,CAACmC,WAAW,CAC1C5C,CAAAA,GAAAA,sDAAAA,GACAkB,OAAO4B,YAAY,CAACC,GACtB;QAEA,IAAIrB,QACFQ,OAAOmB,IAAI,CAACC,GAAG,CAACpC,OAAO4B,YAAY,CAACC,GAAG;IAE3C;IAEA,OAAO;QACLG,MAAMnE,CAAAA,GAAAA,4DAAAA,EAA6BwE,IAAI;QACvCH,UAAUlB,QAAQe;QAClBO,OAAO9B,UAAU,EAAjB8B;IACF;AACF;AAGF/C,iCAAWgD,MAAM;AAEjB,MAAMC;IAGJC,QAAQ;QACN,IAAI,CAACC,uBAAuB,GAAG,AAAC,CAAA;YAC9B,wCAAA;YACA,IAAIC,WAAW,MAAMpD,iCAAWqD,MAAM,CAACC,sBAAsB;YAC7DF,SAASF,KAAK,CAAC;YACf,OAAOE;QACT,CAAA;QACA,IAAI,CAACD,uBAAuB,CAACI,IAAI,CAAEH,CAAAA;YACjC,IAAI,IAAI,CAACI,WAAW,IAAI,MACtBJ,SAASK,MAAM,CAAC,IAAI,CAACD,WAAW;QAEpC;IACF;IACA,MAAME,OAAO;QACX,IAAI,IAAI,CAACP,uBAAuB,IAAI,MAClC,IAAI,CAACD,KAAK;QAEZjE,cAAU,IAAI,CAACkE,uBAAuB,IAAI;QACzC,CAAA,MAAM,IAAI,CAACA,uBAAuB,AAAvBA,EAAyBO,IAAI;QACzC,IAAI,CAACP,uBAAuB,GAAG;IACjC;IACA,MAAMM,OAAOE,OAAe,EAAE;QAC5B,IAAI,IAAI,CAACR,uBAAuB,IAAI,MAAM;YACxC,IAAI,CAACK,WAAW,GAAGG;YACnB,IAAI,CAACT,KAAK;QACZ,OAAO;YACL,MAAMU,IAAI,MAAM,IAAI,CAACT,uBAAuB;YAC5CS,EAAEH,MAAM,CAACE;QACX;IACF;AACF;AAEA,SAASE;IACP,IAAItD,oDACFP,iCAAWmC,WAAW,CAACjE,CAAAA,GAAAA,wDAAAA,EAAyByD,IAAI;AAExD;AASA,MAAMqC,yCAAmB,IAAIf;AAC7B,MAAMgB,gCAA+B,IAAIC;AAEzC,SAAShC,iCAAWiC,QAAqB;IACvC,MAAMC,WAAWlF,yBAAkBiF;IAEnC,IAAIG,gBAAgB;IACpB,IAAIC;IACJ,KAAK,MAAM,GAAG9C,OAAO,IAAIwC,8BAAS;QAChC,MAAMO,SAAS/E,wBAAiB;YAACgC,OAAO7B,WAAW;YAAEwE;SAAS,EAAEK,MAAM;QACtE,IAAIH,gBAAgBE,QAAQ;YAC1BF,gBAAgBE;YAChBD,aAAa9C;QACf,OAAO,IAAI6C,kBAAkBE,QAC3B,sCAAA;QACAzC,QAAQ2C,IAAI,CAAC,0BAA0BN;IAE3C;IACA,OAAOG;AACT;AAEA,SAASI,mCAAaP,QAAgB;IACpC,MAAMQ,OAAO7G,uBAAgBqG,UAAU;IACvC,OAAOU,KAAKC,KAAK,CAACH;AACpB;AAEA,SAASI,mCAAaC,YAAoB,EAAEC,QAAkB;IAC5D,MAAMC,iBAAiBF,aAAaG,KAAK,CAAC,GAAG;IAC7C,MAAM,CAACC,QAAQC,OAAO,GAAGxG,CAAAA,GAAAA,kDAAAA,EAA0BqG;IACnD,MAAM1D,SAAS1C,CAAAA,GAAAA,gDAAAA,EAAwBsG,QAAQC;IAC/C7D,OAAOuB,MAAM;IAEb,MAAMJ,OAAO,IAAImB;IAEjB,MAAM9C,SAAS;QACbjB,YAAYyB;cACZmB;QACAhD,aAAasF,SAAStF,WAAW;QACjC4C,WAAW;IACb;IAEAf,OAAO8D,cAAc,CAAClG,CAAAA,GAAAA,mDAAAA,GAAyB,CAACmG,OAAO7B;QACrD,8DAAA;QACA,IAAI6B,UAAU,SAAS;YACrBxB,uCAAiBd,KAAK;YACtB,KAAK,MAAMZ,OAAOM,KAChB5C,iCAAWyF,eAAe,CAAC;qBAACnD;gBAAKvB,aAAa,EAAbA;YAAe;QAEpD,OAAO,IAAIyE,UAAU,cAAc7B,WAAW,MAC5CK,uCAAiBP,MAAM,CAACE;aACnB,IAAI6B,UAAU,OAAO;YAC1BvE,OAAOuB,SAAS,GAAGkD,OAAOC,KAAKC,GAAG;YAClC/B;YACAG,uCAAiBN,IAAI;YACrB1D,iCAAW6F,gBAAgB,CAACzG,CAAAA,GAAAA,6CAAAA;QAC9B;IACF;IAEAqC,OAAO8D,cAAc,CAACjG,CAAAA,GAAAA,4DAAAA,GAAmCyB,CAAAA;QACvD,oEAAA;QACA,KAAK,MAAM+E,KAAK/E,YAAa;YAC3B6B,KAAKC,GAAG,CAACiD,EAAExD,GAAG;YACdtC,iCAAWyF,eAAe,CAACK;QAC7B;IACF;IAEArE,OAAOsE,OAAO,CAAC;QACb9B,8BAAQ+B,MAAM,CAAClB,KAAKmB,SAAS,CAACf;QAC9BrB;QACA,OAAOzB,QAAQnC,GAAG,CAChB;eAAI2C;SAAK,CAACsD,GAAG,CAAE5D,CAAAA,MACbtC,iCAAWyF,eAAe,CAAC;qBAACnD;gBAAKvB,aAAa,EAAbA;YAAe;IAGtD;IAEA8C;IACAI,8BAAQkC,GAAG,CAACrB,KAAKmB,SAAS,CAACf,WAAWjE;AACxC;AAEA,sFAAA;AACA,MAAMmF,gCAAUtI,iBAAUC,uBAAgBC,qBAAc;AACxDD,oBAAaqI,+BAAS;IAACK,WAAW;AAAI;AAEtC1I,wBAAiBD,iBAAUsI,+BAAShG,8CAAwB;AAE5D,0EAAA;AACA,4DAAA;AACA,KAAK,MAAMuG,YAAY5I,sBAAeqI,+BAAU;IAC9C,IAAI,CAACO,SAASE,QAAQ,CAAC,UAAU;IACjC,MAAMzC,WAAWtG,iBAAUsI,+BAASO;IACpC,MAAMG,WAAWnC,mCAAaP;IAC9B,MAAM,eAACxE,WAAAA,EAAY,GAAGkH;IAEtB,IAAI5G,yCAAmBN,aACrBoF,mCAAaZ,UAAU0C;AAE3B;AAEA,8EAAA;AACA,yEAAA;AACA,yCAAA;AACA3H,+BAAkBiH,+BAAS,OAAOY,KAAKC;IACrC,IAAID,KACF,MAAMA;IAGR,KAAK,MAAME,SAASD,OAAQ;QAC1B,IAAIC,MAAMvF,IAAI,KAAK,YAAYuF,MAAMpJ,IAAI,CAAC+I,QAAQ,CAAC,UAAU;YAC3D,MAAMC,WAAWnC,mCAAauC,MAAMpJ,IAAI;YACxC,MAAM,eAAC8B,WAAAA,EAAY,GAAGkH;YAEtB,IAAI5G,yCAAmBN,aACrBoF,mCAAakC,MAAMpJ,IAAI,EAAEgJ;QAE7B,OAAO,IAAII,MAAMvF,IAAI,KAAK,YAAYuF,MAAMpJ,IAAI,CAAC+I,QAAQ,CAAC,UAAU;YAClE,MAAMM,WAAWlD,8BAAQmD,GAAG,CAACF,MAAMpJ,IAAI;YACvC,sCAAA;YACAiE,QAAQC,GAAG,CAAC,YAAYkF,MAAMpJ,IAAI,EAAEqJ;YACpC,IAAIA,UAAU;gBACZlD,8BAAQ+B,MAAM,CAACkB,MAAMpJ,IAAI;gBACzBqJ,SAASnH,UAAU,CAACqH,GAAG;YACzB;QACF;IACF;AACF","sources":["packages/utils/atlaspack-lsp/src/LspServer.ts"],"sourcesContent":["import * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport {\n createConnection,\n DiagnosticRefreshRequest,\n DidChangeConfigurationNotification,\n DocumentDiagnosticParams,\n DocumentDiagnosticReport,\n DocumentDiagnosticReportKind,\n DocumentDiagnosticRequest,\n DocumentUri,\n InitializeParams,\n InitializeResult,\n ProposedFeatures,\n TextDocumentSyncKind,\n WorkDoneProgressServerReporter,\n} from 'vscode-languageserver/node';\n\nimport {\n createServerPipeTransport,\n createMessageConnection,\n MessageConnection,\n} from 'vscode-jsonrpc/node';\nimport * as invariant from 'assert';\nimport * as url from 'url';\n// import {TextDocument} from 'vscode-languageserver-textdocument';\nimport * as watcher from '@parcel/watcher';\nimport {\n NotificationBuild,\n NotificationBuildStatus,\n NotificationWorkspaceDiagnostics,\n RequestDocumentDiagnostics,\n RequestImporters,\n} from '@atlaspack/lsp-protocol';\n\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nconst commonPathPrefix = require('common-path-prefix');\n\ntype Metafile = {\n projectRoot: string;\n pid: typeof process['pid'];\n argv: typeof process['argv'];\n};\n\nconst connection = createConnection(ProposedFeatures.all);\nconst WORKSPACE_ROOT = process.cwd();\nconst LSP_SENTINEL_FILENAME = 'lsp-server';\n// Create a simple text document manager.\n// const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);\n\nlet hasConfigurationCapability = false;\nlet hasWorkspaceFolderCapability = false;\n// let hasDiagnosticRelatedInformationCapability = false;\nlet hasDiagnosticsRefreshSupport = false;\n\nconnection.onInitialize((params: InitializeParams) => {\n const capabilities = params.capabilities;\n\n // Does the client support the `workspace/configuration` request?\n // If not, we fall back using global settings.\n hasConfigurationCapability = !!(\n capabilities.workspace && !!capabilities.workspace.configuration\n );\n hasWorkspaceFolderCapability = !!(\n capabilities.workspace && !!capabilities.workspace.workspaceFolders\n );\n // hasDiagnosticRelatedInformationCapability = !!(\n // capabilities.textDocument &&\n // capabilities.textDocument.publishDiagnostics &&\n // capabilities.textDocument.publishDiagnostics.relatedInformation\n // );\n hasDiagnosticsRefreshSupport = Boolean(\n capabilities.workspace?.diagnostics?.refreshSupport,\n );\n\n const result: InitializeResult = {\n capabilities: {\n textDocumentSync: TextDocumentSyncKind.Incremental,\n // Tell the client that this server supports code completion.\n diagnosticProvider: {\n workspaceDiagnostics: false,\n interFileDependencies: true,\n },\n },\n };\n\n if (hasWorkspaceFolderCapability) {\n result.capabilities.workspace = {\n workspaceFolders: {\n supported: true,\n },\n };\n }\n return result;\n});\n\nconnection.onInitialized(() => {\n if (hasConfigurationCapability) {\n // Register for all configuration changes.\n connection.client.register(\n DidChangeConfigurationNotification.type,\n undefined,\n );\n }\n if (hasWorkspaceFolderCapability) {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n connection.workspace.onDidChangeWorkspaceFolders((_event) => {\n connection.console.log('Workspace folder change event received.');\n });\n }\n});\n\n// Proxy\nconnection.onRequest(RequestImporters, async (params) => {\n const client = findClient(params);\n if (client) {\n const result = await client.connection.sendRequest(\n RequestImporters,\n params,\n );\n return result;\n }\n return null;\n});\n\nconnection.onRequest(\n DocumentDiagnosticRequest.type,\n async (\n params: DocumentDiagnosticParams,\n ): Promise<DocumentDiagnosticReport> => {\n const client = findClient(params.textDocument.uri);\n let result;\n if (client) {\n // console.log(\n // 'DocumentDiagnosticRequest',\n // params.textDocument.uri,\n // params.previousResultId === client.lastBuild,\n // );\n\n if (params.previousResultId === client.lastBuild) {\n return {\n kind: DocumentDiagnosticReportKind.Unchanged,\n resultId: client.lastBuild,\n };\n }\n\n result = await client.connection.sendRequest(\n RequestDocumentDiagnostics,\n params.textDocument.uri,\n );\n\n if (result) {\n client.uris.add(params.textDocument.uri);\n }\n }\n\n return {\n kind: DocumentDiagnosticReportKind.Full,\n resultId: client?.lastBuild,\n items: result ?? [],\n };\n },\n);\n\nconnection.listen();\n\nclass ProgressReporter {\n progressReporterPromise?: Promise<WorkDoneProgressServerReporter> | null;\n lastMessage?: string;\n begin() {\n this.progressReporterPromise = (async () => {\n // eslint-disable-next-line prefer-const\n let reporter = await connection.window.createWorkDoneProgress();\n reporter.begin('Atlaspack');\n return reporter;\n })();\n this.progressReporterPromise.then((reporter) => {\n if (this.lastMessage != null) {\n reporter.report(this.lastMessage);\n }\n });\n }\n async done() {\n if (this.progressReporterPromise == null) {\n this.begin();\n }\n invariant(this.progressReporterPromise != null);\n (await this.progressReporterPromise).done();\n this.progressReporterPromise = null;\n }\n async report(message: string) {\n if (this.progressReporterPromise == null) {\n this.lastMessage = message;\n this.begin();\n } else {\n const r = await this.progressReporterPromise;\n r.report(message);\n }\n }\n}\n\nfunction sendDiagnosticsRefresh() {\n if (hasDiagnosticsRefreshSupport) {\n connection.sendRequest(DiagnosticRefreshRequest.type);\n }\n}\n\ntype Client = {\n connection: MessageConnection;\n projectRoot: string;\n uris: Set<DocumentUri>;\n lastBuild: string;\n};\n\nconst progressReporter = new ProgressReporter();\nconst clients: Map<string, Client> = new Map();\n\nfunction findClient(document: DocumentUri): Client | undefined {\n const filepath = url.fileURLToPath(document);\n\n let longestPrefix = 0;\n let bestClient;\n for (const [, client] of clients) {\n const prefix = commonPathPrefix([client.projectRoot, filepath]).length;\n if (longestPrefix < prefix) {\n longestPrefix = prefix;\n bestClient = client;\n } else if (longestPrefix === prefix) {\n // eslint-disable-next-line no-console\n console.warn('Ambiguous client for ' + filepath);\n }\n }\n return bestClient;\n}\n\nfunction loadMetafile(filepath: string) {\n const file = fs.readFileSync(filepath, 'utf-8');\n return JSON.parse(file);\n}\n\nfunction createClient(metafilepath: string, metafile: Metafile) {\n const socketfilepath = metafilepath.slice(0, -5);\n const [reader, writer] = createServerPipeTransport(socketfilepath);\n const client = createMessageConnection(reader, writer);\n client.listen();\n\n const uris = new Set<DocumentUri>();\n\n const result = {\n connection: client,\n uris,\n projectRoot: metafile.projectRoot,\n lastBuild: '0',\n };\n\n client.onNotification(NotificationBuildStatus, (state, message) => {\n // console.log('got NotificationBuildStatus', state, message);\n if (state === 'start') {\n progressReporter.begin();\n for (const uri of uris) {\n connection.sendDiagnostics({uri, diagnostics: []});\n }\n } else if (state === 'progress' && message != null) {\n progressReporter.report(message);\n } else if (state === 'end') {\n result.lastBuild = String(Date.now());\n sendDiagnosticsRefresh();\n progressReporter.done();\n connection.sendNotification(NotificationBuild);\n }\n });\n\n client.onNotification(NotificationWorkspaceDiagnostics, (diagnostics) => {\n // console.log('got NotificationWorkspaceDiagnostics', diagnostics);\n for (const d of diagnostics) {\n uris.add(d.uri);\n connection.sendDiagnostics(d);\n }\n });\n\n client.onClose(() => {\n clients.delete(JSON.stringify(metafile));\n sendDiagnosticsRefresh();\n return Promise.all(\n [...uris].map((uri) =>\n connection.sendDiagnostics({uri, diagnostics: []}),\n ),\n );\n });\n\n sendDiagnosticsRefresh();\n clients.set(JSON.stringify(metafile), result);\n}\n\n// Take realpath because to have consistent cache keys on macOS (/var -> /private/var)\nconst BASEDIR = path.join(fs.realpathSync(os.tmpdir()), 'parcel-lsp');\nfs.mkdirSync(BASEDIR, {recursive: true});\n\nfs.writeFileSync(path.join(BASEDIR, LSP_SENTINEL_FILENAME), '');\n\n// Search for currently running Atlaspack processes in the parcel-lsp dir.\n// Create an IPC client connection for each running process.\nfor (const filename of fs.readdirSync(BASEDIR)) {\n if (!filename.endsWith('.json')) continue;\n const filepath = path.join(BASEDIR, filename);\n const contents = loadMetafile(filepath);\n const {projectRoot} = contents;\n\n if (WORKSPACE_ROOT === projectRoot) {\n createClient(filepath, contents);\n }\n}\n\n// Watch for new Atlaspack processes in the parcel-lsp dir, and disconnect the\n// client for each corresponding connection when a Atlaspack process ends\n// eslint-disable-next-line require-await\nwatcher.subscribe(BASEDIR, async (err, events) => {\n if (err) {\n throw err;\n }\n\n for (const event of events) {\n if (event.type === 'create' && event.path.endsWith('.json')) {\n const contents = loadMetafile(event.path);\n const {projectRoot} = contents;\n\n if (WORKSPACE_ROOT === projectRoot) {\n createClient(event.path, contents);\n }\n } else if (event.type === 'delete' && event.path.endsWith('.json')) {\n const existing = clients.get(event.path);\n // eslint-disable-next-line no-console\n console.log('existing', event.path, existing);\n if (existing) {\n clients.delete(event.path);\n existing.connection.end();\n }\n }\n }\n});\n"],"names":["path","fs","os","createConnection","DiagnosticRefreshRequest","DidChangeConfigurationNotification","DocumentDiagnosticParams","DocumentDiagnosticReport","DocumentDiagnosticReportKind","DocumentDiagnosticRequest","DocumentUri","InitializeParams","InitializeResult","ProposedFeatures","TextDocumentSyncKind","WorkDoneProgressServerReporter","createServerPipeTransport","createMessageConnection","MessageConnection","invariant","url","watcher","NotificationBuild","NotificationBuildStatus","NotificationWorkspaceDiagnostics","RequestDocumentDiagnostics","RequestImporters","commonPathPrefix","require","Metafile","projectRoot","pid","process","argv","connection","all","WORKSPACE_ROOT","cwd","LSP_SENTINEL_FILENAME","hasConfigurationCapability","hasWorkspaceFolderCapability","hasDiagnosticsRefreshSupport","onInitialize","params","capabilities","workspace","configuration","workspaceFolders","Boolean","diagnostics","refreshSupport","result","textDocumentSync","Incremental","diagnosticProvider","workspaceDiagnostics","interFileDependencies","supported","onInitialized","client","register","type","undefined","onDidChangeWorkspaceFolders","_event","console","log","onRequest","findClient","sendRequest","Promise","textDocument","uri","previousResultId","lastBuild","kind","Unchanged","resultId","uris","add","Full","items","listen","ProgressReporter","begin","progressReporterPromise","reporter","window","createWorkDoneProgress","then","lastMessage","report","done","message","r","sendDiagnosticsRefresh","Client","Set","progressReporter","clients","Map","document","filepath","fileURLToPath","longestPrefix","bestClient","prefix","length","warn","loadMetafile","file","readFileSync","JSON","parse","createClient","metafilepath","metafile","socketfilepath","slice","reader","writer","onNotification","state","sendDiagnostics","String","Date","now","sendNotification","d","onClose","delete","stringify","map","set","BASEDIR","join","realpathSync","tmpdir","mkdirSync","recursive","writeFileSync","filename","readdirSync","endsWith","contents","subscribe","err","events","event","existing","get","end"],"version":3,"file":"LspServer.js.map","sourceRoot":"../../../../"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/lsp",
|
|
3
|
-
"version": "2.14.2-typescript-
|
|
3
|
+
"version": "2.14.2-typescript-d6e6d169c.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"node": ">= 16.0.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@atlaspack/lsp-protocol": "2.14.2-typescript-
|
|
23
|
+
"@atlaspack/lsp-protocol": "2.14.2-typescript-d6e6d169c.0",
|
|
24
24
|
"@parcel/watcher": "^2.0.7",
|
|
25
25
|
"common-path-prefix": "^3.0.0",
|
|
26
26
|
"nullthrows": "^1.1.1",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"types": false
|
|
41
41
|
},
|
|
42
42
|
"type": "commonjs",
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "d6e6d169cb16a0bbc98d7743646a7097b82c7fe2"
|
|
44
44
|
}
|
package/src/LspServer.ts
CHANGED
|
@@ -24,8 +24,6 @@ import {
|
|
|
24
24
|
} from 'vscode-jsonrpc/node';
|
|
25
25
|
import * as invariant from 'assert';
|
|
26
26
|
import * as url from 'url';
|
|
27
|
-
import commonPathPrefix = require('common-path-prefix');
|
|
28
|
-
|
|
29
27
|
// import {TextDocument} from 'vscode-languageserver-textdocument';
|
|
30
28
|
import * as watcher from '@parcel/watcher';
|
|
31
29
|
import {
|
|
@@ -36,6 +34,9 @@ import {
|
|
|
36
34
|
RequestImporters,
|
|
37
35
|
} from '@atlaspack/lsp-protocol';
|
|
38
36
|
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
38
|
+
const commonPathPrefix = require('common-path-prefix');
|
|
39
|
+
|
|
39
40
|
type Metafile = {
|
|
40
41
|
projectRoot: string;
|
|
41
42
|
pid: typeof process['pid'];
|
|
@@ -103,6 +104,7 @@ connection.onInitialized(() => {
|
|
|
103
104
|
);
|
|
104
105
|
}
|
|
105
106
|
if (hasWorkspaceFolderCapability) {
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
106
108
|
connection.workspace.onDidChangeWorkspaceFolders((_event) => {
|
|
107
109
|
connection.console.log('Workspace folder change event received.');
|
|
108
110
|
});
|
|
@@ -111,9 +113,12 @@ connection.onInitialized(() => {
|
|
|
111
113
|
|
|
112
114
|
// Proxy
|
|
113
115
|
connection.onRequest(RequestImporters, async (params) => {
|
|
114
|
-
|
|
116
|
+
const client = findClient(params);
|
|
115
117
|
if (client) {
|
|
116
|
-
|
|
118
|
+
const result = await client.connection.sendRequest(
|
|
119
|
+
RequestImporters,
|
|
120
|
+
params,
|
|
121
|
+
);
|
|
117
122
|
return result;
|
|
118
123
|
}
|
|
119
124
|
return null;
|
|
@@ -124,7 +129,7 @@ connection.onRequest(
|
|
|
124
129
|
async (
|
|
125
130
|
params: DocumentDiagnosticParams,
|
|
126
131
|
): Promise<DocumentDiagnosticReport> => {
|
|
127
|
-
|
|
132
|
+
const client = findClient(params.textDocument.uri);
|
|
128
133
|
let result;
|
|
129
134
|
if (client) {
|
|
130
135
|
// console.log(
|
|
@@ -165,6 +170,7 @@ class ProgressReporter {
|
|
|
165
170
|
lastMessage?: string;
|
|
166
171
|
begin() {
|
|
167
172
|
this.progressReporterPromise = (async () => {
|
|
173
|
+
// eslint-disable-next-line prefer-const
|
|
168
174
|
let reporter = await connection.window.createWorkDoneProgress();
|
|
169
175
|
reporter.begin('Atlaspack');
|
|
170
176
|
return reporter;
|
|
@@ -188,7 +194,7 @@ class ProgressReporter {
|
|
|
188
194
|
this.lastMessage = message;
|
|
189
195
|
this.begin();
|
|
190
196
|
} else {
|
|
191
|
-
|
|
197
|
+
const r = await this.progressReporterPromise;
|
|
192
198
|
r.report(message);
|
|
193
199
|
}
|
|
194
200
|
}
|
|
@@ -207,20 +213,21 @@ type Client = {
|
|
|
207
213
|
lastBuild: string;
|
|
208
214
|
};
|
|
209
215
|
|
|
210
|
-
|
|
211
|
-
|
|
216
|
+
const progressReporter = new ProgressReporter();
|
|
217
|
+
const clients: Map<string, Client> = new Map();
|
|
212
218
|
|
|
213
219
|
function findClient(document: DocumentUri): Client | undefined {
|
|
214
|
-
|
|
220
|
+
const filepath = url.fileURLToPath(document);
|
|
215
221
|
|
|
216
222
|
let longestPrefix = 0;
|
|
217
223
|
let bestClient;
|
|
218
|
-
for (
|
|
219
|
-
|
|
224
|
+
for (const [, client] of clients) {
|
|
225
|
+
const prefix = commonPathPrefix([client.projectRoot, filepath]).length;
|
|
220
226
|
if (longestPrefix < prefix) {
|
|
221
227
|
longestPrefix = prefix;
|
|
222
228
|
bestClient = client;
|
|
223
229
|
} else if (longestPrefix === prefix) {
|
|
230
|
+
// eslint-disable-next-line no-console
|
|
224
231
|
console.warn('Ambiguous client for ' + filepath);
|
|
225
232
|
}
|
|
226
233
|
}
|
|
@@ -233,14 +240,14 @@ function loadMetafile(filepath: string) {
|
|
|
233
240
|
}
|
|
234
241
|
|
|
235
242
|
function createClient(metafilepath: string, metafile: Metafile) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
243
|
+
const socketfilepath = metafilepath.slice(0, -5);
|
|
244
|
+
const [reader, writer] = createServerPipeTransport(socketfilepath);
|
|
245
|
+
const client = createMessageConnection(reader, writer);
|
|
239
246
|
client.listen();
|
|
240
247
|
|
|
241
|
-
|
|
248
|
+
const uris = new Set<DocumentUri>();
|
|
242
249
|
|
|
243
|
-
|
|
250
|
+
const result = {
|
|
244
251
|
connection: client,
|
|
245
252
|
uris,
|
|
246
253
|
projectRoot: metafile.projectRoot,
|
|
@@ -251,7 +258,7 @@ function createClient(metafilepath: string, metafile: Metafile) {
|
|
|
251
258
|
// console.log('got NotificationBuildStatus', state, message);
|
|
252
259
|
if (state === 'start') {
|
|
253
260
|
progressReporter.begin();
|
|
254
|
-
for (
|
|
261
|
+
for (const uri of uris) {
|
|
255
262
|
connection.sendDiagnostics({uri, diagnostics: []});
|
|
256
263
|
}
|
|
257
264
|
} else if (state === 'progress' && message != null) {
|
|
@@ -266,7 +273,7 @@ function createClient(metafilepath: string, metafile: Metafile) {
|
|
|
266
273
|
|
|
267
274
|
client.onNotification(NotificationWorkspaceDiagnostics, (diagnostics) => {
|
|
268
275
|
// console.log('got NotificationWorkspaceDiagnostics', diagnostics);
|
|
269
|
-
for (
|
|
276
|
+
for (const d of diagnostics) {
|
|
270
277
|
uris.add(d.uri);
|
|
271
278
|
connection.sendDiagnostics(d);
|
|
272
279
|
}
|
|
@@ -294,9 +301,9 @@ fs.writeFileSync(path.join(BASEDIR, LSP_SENTINEL_FILENAME), '');
|
|
|
294
301
|
|
|
295
302
|
// Search for currently running Atlaspack processes in the parcel-lsp dir.
|
|
296
303
|
// Create an IPC client connection for each running process.
|
|
297
|
-
for (
|
|
304
|
+
for (const filename of fs.readdirSync(BASEDIR)) {
|
|
298
305
|
if (!filename.endsWith('.json')) continue;
|
|
299
|
-
|
|
306
|
+
const filepath = path.join(BASEDIR, filename);
|
|
300
307
|
const contents = loadMetafile(filepath);
|
|
301
308
|
const {projectRoot} = contents;
|
|
302
309
|
|
|
@@ -307,12 +314,13 @@ for (let filename of fs.readdirSync(BASEDIR)) {
|
|
|
307
314
|
|
|
308
315
|
// Watch for new Atlaspack processes in the parcel-lsp dir, and disconnect the
|
|
309
316
|
// client for each corresponding connection when a Atlaspack process ends
|
|
317
|
+
// eslint-disable-next-line require-await
|
|
310
318
|
watcher.subscribe(BASEDIR, async (err, events) => {
|
|
311
319
|
if (err) {
|
|
312
320
|
throw err;
|
|
313
321
|
}
|
|
314
322
|
|
|
315
|
-
for (
|
|
323
|
+
for (const event of events) {
|
|
316
324
|
if (event.type === 'create' && event.path.endsWith('.json')) {
|
|
317
325
|
const contents = loadMetafile(event.path);
|
|
318
326
|
const {projectRoot} = contents;
|
|
@@ -321,7 +329,8 @@ watcher.subscribe(BASEDIR, async (err, events) => {
|
|
|
321
329
|
createClient(event.path, contents);
|
|
322
330
|
}
|
|
323
331
|
} else if (event.type === 'delete' && event.path.endsWith('.json')) {
|
|
324
|
-
|
|
332
|
+
const existing = clients.get(event.path);
|
|
333
|
+
// eslint-disable-next-line no-console
|
|
325
334
|
console.log('existing', event.path, existing);
|
|
326
335
|
if (existing) {
|
|
327
336
|
clients.delete(event.path);
|