@neo4j-cypher/language-server 2.0.0-next.21 → 2.0.0-next.23
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/CHANGELOG.md +31 -0
- package/dist/cypher-language-server +223 -185
- package/dist/server.js +10 -5
- package/package.json +11 -7
- package/src/formatting.ts +1 -1
- package/src/linting.ts +56 -8
- package/src/server.ts +18 -11
- package/src/types.ts +6 -1
- package/src/lintWorker.ts +0 -31
package/dist/server.js
CHANGED
|
@@ -9,9 +9,6 @@ const formatting_1 = require("./formatting");
|
|
|
9
9
|
const linting_1 = require("./linting");
|
|
10
10
|
const signatureHelp_1 = require("./signatureHelp");
|
|
11
11
|
const syntaxColouring_1 = require("./syntaxColouring");
|
|
12
|
-
if (process.env.CYPHER_25 === 'true') {
|
|
13
|
-
language_support_1._internalFeatureFlags.cypher25 = true;
|
|
14
|
-
}
|
|
15
12
|
const connection = (0, node_1.createConnection)(node_1.ProposedFeatures.all);
|
|
16
13
|
let settings = undefined;
|
|
17
14
|
// Create a simple text document manager.
|
|
@@ -24,7 +21,7 @@ async function lintSingleDocument(document) {
|
|
|
24
21
|
uri: document.uri,
|
|
25
22
|
diagnostics,
|
|
26
23
|
});
|
|
27
|
-
}, neo4jSchemaPoller);
|
|
24
|
+
}, neo4jSchemaPoller, settings?.features?.useVersionedLinters);
|
|
28
25
|
}
|
|
29
26
|
else {
|
|
30
27
|
void connection.sendDiagnostics({
|
|
@@ -87,6 +84,14 @@ connection.languages.semanticTokens.on((0, syntaxColouring_1.applySyntaxColourin
|
|
|
87
84
|
connection.onSignatureHelp((0, signatureHelp_1.doSignatureHelp)(documents, neo4jSchemaPoller));
|
|
88
85
|
// Trigger the auto completion
|
|
89
86
|
connection.onCompletion((0, autocompletion_1.doAutoCompletion)(documents, neo4jSchemaPoller));
|
|
87
|
+
connection.onNotification('updateLintWorker', (linterSettings) => {
|
|
88
|
+
const lintWorkerPath = linterSettings.lintWorkerPath;
|
|
89
|
+
const linterVersion = linterSettings.linterVersion;
|
|
90
|
+
void (async () => {
|
|
91
|
+
await (0, linting_1.setLintWorker)(lintWorkerPath, linterVersion);
|
|
92
|
+
relintAllDocuments();
|
|
93
|
+
})();
|
|
94
|
+
});
|
|
90
95
|
connection.onNotification('connectionUpdated', (connectionSettings) => {
|
|
91
96
|
changeConnection(connectionSettings);
|
|
92
97
|
neo4jSchemaPoller.events.once('schemaFetched', relintAllDocuments);
|
|
@@ -105,7 +110,7 @@ connection.onNotification('connectionDisconnected', () => {
|
|
|
105
110
|
documents.listen(connection);
|
|
106
111
|
connection.listen();
|
|
107
112
|
connection.onExit(() => {
|
|
108
|
-
(0, linting_1.cleanupWorkers)();
|
|
113
|
+
void (0, linting_1.cleanupWorkers)();
|
|
109
114
|
});
|
|
110
115
|
const changeConnection = (connectionSettings) => {
|
|
111
116
|
disconnect();
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"cypher",
|
|
17
17
|
"language server"
|
|
18
18
|
],
|
|
19
|
-
"version": "2.0.0-next.
|
|
19
|
+
"version": "2.0.0-next.23",
|
|
20
20
|
"main": "./dist/server.js",
|
|
21
21
|
"types": "src/server.ts",
|
|
22
22
|
"repository": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"engineStrict": true,
|
|
30
30
|
"engines": {
|
|
31
|
-
"node": ">=
|
|
31
|
+
"node": ">=22.15.0"
|
|
32
32
|
},
|
|
33
33
|
"bin": {
|
|
34
34
|
"cypher-language-server": "./dist/cypher-language-server"
|
|
@@ -39,16 +39,20 @@
|
|
|
39
39
|
"vscode-languageserver": "^8.1.0",
|
|
40
40
|
"vscode-languageserver-textdocument": "^1.0.8",
|
|
41
41
|
"workerpool": "^9.0.4",
|
|
42
|
-
"
|
|
43
|
-
"@neo4j-cypher/
|
|
42
|
+
"axios": "^1.9.0",
|
|
43
|
+
"@neo4j-cypher/language-support": "2.0.0-next.22",
|
|
44
|
+
"@neo4j-cypher/lint-worker": "0.1.0-next.0",
|
|
45
|
+
"@neo4j-cypher/query-tools": "2.0.0-next.22"
|
|
44
46
|
},
|
|
45
47
|
"devDependencies": {
|
|
46
|
-
"@types/lodash.debounce": "^4.0.9"
|
|
48
|
+
"@types/lodash.debounce": "^4.0.9",
|
|
49
|
+
"copyfiles": "^2.4.1"
|
|
47
50
|
},
|
|
48
51
|
"scripts": {
|
|
49
|
-
"build": "tsc -b && pnpm bundle && pnpm make-executable && pnpm
|
|
52
|
+
"build": "tsc -b && pnpm bundle && pnpm make-executable && pnpm copy-lint-worker",
|
|
53
|
+
"copy-lint-worker": "copyfiles -u 4 ../lint-worker/dist/cjs/lintWorker.cjs dist/",
|
|
50
54
|
"bundle": "esbuild ./src/server.ts --bundle --format=cjs --platform=node --outfile=dist/cypher-language-server.js --minify --conditions=require",
|
|
51
|
-
"
|
|
55
|
+
"dev": "tsc --watch",
|
|
52
56
|
"make-executable": "cd dist && echo '#!/usr/bin/env node' > cypher-language-server && cat cypher-language-server.js >> cypher-language-server",
|
|
53
57
|
"clean": "rm -rf {dist,tsconfig.tsbuildinfo}"
|
|
54
58
|
}
|
package/src/formatting.ts
CHANGED
package/src/linting.ts
CHANGED
|
@@ -1,23 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
_internalFeatureFlags,
|
|
3
|
+
clampUnsafePositions,
|
|
4
|
+
parserWrapper,
|
|
5
|
+
} from '@neo4j-cypher/language-support';
|
|
2
6
|
import { Neo4jSchemaPoller } from '@neo4j-cypher/query-tools';
|
|
3
7
|
import debounce from 'lodash.debounce';
|
|
4
8
|
import { join } from 'path';
|
|
5
9
|
import { Diagnostic } from 'vscode-languageserver';
|
|
6
10
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
7
11
|
import workerpool from 'workerpool';
|
|
8
|
-
import {
|
|
12
|
+
import {
|
|
13
|
+
convertDbSchema,
|
|
14
|
+
LinterTask,
|
|
15
|
+
LintWorker,
|
|
16
|
+
} from '@neo4j-cypher/lint-worker';
|
|
9
17
|
|
|
10
|
-
const
|
|
18
|
+
const defaultWorkerPath = join(__dirname, 'lintWorker.cjs');
|
|
19
|
+
|
|
20
|
+
let pool = workerpool.pool(defaultWorkerPath, {
|
|
11
21
|
minWorkers: 2,
|
|
12
22
|
workerTerminateTimeout: 2000,
|
|
13
23
|
});
|
|
14
|
-
|
|
24
|
+
export let workerPath = defaultWorkerPath;
|
|
25
|
+
let linterVersion: string | undefined = undefined;
|
|
15
26
|
let lastSemanticJob: LinterTask | undefined;
|
|
16
27
|
|
|
28
|
+
/**Sets the lintworker to the one specified by the given path, reverting to default if the path is undefined */
|
|
29
|
+
export async function setLintWorker(
|
|
30
|
+
lintWorkerPath: string | undefined,
|
|
31
|
+
linter: string | undefined,
|
|
32
|
+
) {
|
|
33
|
+
lintWorkerPath = lintWorkerPath ? lintWorkerPath : defaultWorkerPath;
|
|
34
|
+
if (lintWorkerPath !== workerPath) {
|
|
35
|
+
await cleanupWorkers();
|
|
36
|
+
workerPath = lintWorkerPath;
|
|
37
|
+
linterVersion = linter;
|
|
38
|
+
pool = workerpool.pool(workerPath, {
|
|
39
|
+
minWorkers: 2,
|
|
40
|
+
workerTerminateTimeout: 2000,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
17
45
|
async function rawLintDocument(
|
|
18
46
|
document: TextDocument,
|
|
19
47
|
sendDiagnostics: (diagnostics: Diagnostic[]) => void,
|
|
20
48
|
neo4j: Neo4jSchemaPoller,
|
|
49
|
+
versionedLinters: boolean,
|
|
21
50
|
) {
|
|
22
51
|
const query = document.getText();
|
|
23
52
|
if (query.length === 0) {
|
|
@@ -32,14 +61,33 @@ async function rawLintDocument(
|
|
|
32
61
|
}
|
|
33
62
|
|
|
34
63
|
const proxyWorker = (await pool.proxy()) as unknown as LintWorker;
|
|
64
|
+
|
|
65
|
+
const fixedDbSchema = versionedLinters
|
|
66
|
+
? convertDbSchema(dbSchema, linterVersion)
|
|
67
|
+
: dbSchema;
|
|
35
68
|
lastSemanticJob = proxyWorker.lintCypherQuery(
|
|
36
69
|
query,
|
|
37
|
-
|
|
70
|
+
fixedDbSchema,
|
|
38
71
|
_internalFeatureFlags,
|
|
39
72
|
);
|
|
73
|
+
|
|
40
74
|
const result = await lastSemanticJob;
|
|
41
75
|
|
|
42
|
-
|
|
76
|
+
//marks the entire text if any position is negative
|
|
77
|
+
const positionSafeResult = clampUnsafePositions(
|
|
78
|
+
result.diagnostics,
|
|
79
|
+
document,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Pass the computed symbol tables to the parser
|
|
83
|
+
if (result.symbolTables) {
|
|
84
|
+
parserWrapper.setSymbolsInfo({
|
|
85
|
+
query,
|
|
86
|
+
symbolTables: result.symbolTables,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
sendDiagnostics(positionSafeResult);
|
|
43
91
|
} catch (err) {
|
|
44
92
|
if (!(err instanceof workerpool.Promise.CancellationError)) {
|
|
45
93
|
console.error(err);
|
|
@@ -56,6 +104,6 @@ export const lintDocument: typeof rawLintDocument = debounce(
|
|
|
56
104
|
},
|
|
57
105
|
);
|
|
58
106
|
|
|
59
|
-
export const cleanupWorkers = () => {
|
|
60
|
-
|
|
107
|
+
export const cleanupWorkers = async () => {
|
|
108
|
+
await pool.terminate();
|
|
61
109
|
};
|
package/src/server.ts
CHANGED
|
@@ -11,27 +11,20 @@ import {
|
|
|
11
11
|
} from 'vscode-languageserver/node';
|
|
12
12
|
|
|
13
13
|
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
_internalFeatureFlags,
|
|
17
|
-
syntaxColouringLegend,
|
|
18
|
-
} from '@neo4j-cypher/language-support';
|
|
14
|
+
import { syntaxColouringLegend } from '@neo4j-cypher/language-support';
|
|
19
15
|
import { Neo4jSchemaPoller } from '@neo4j-cypher/query-tools';
|
|
20
16
|
import { doAutoCompletion } from './autocompletion';
|
|
21
17
|
import { formatDocument } from './formatting';
|
|
22
|
-
import { cleanupWorkers, lintDocument } from './linting';
|
|
18
|
+
import { cleanupWorkers, lintDocument, setLintWorker } from './linting';
|
|
23
19
|
import { doSignatureHelp } from './signatureHelp';
|
|
24
20
|
import { applySyntaxColouringForDocument } from './syntaxColouring';
|
|
25
21
|
import {
|
|
22
|
+
LintWorkerSettings,
|
|
26
23
|
Neo4jConnectionSettings,
|
|
27
24
|
Neo4jParameters,
|
|
28
25
|
Neo4jSettings,
|
|
29
26
|
} from './types';
|
|
30
27
|
|
|
31
|
-
if (process.env.CYPHER_25 === 'true') {
|
|
32
|
-
_internalFeatureFlags.cypher25 = true;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
28
|
const connection = createConnection(ProposedFeatures.all);
|
|
36
29
|
let settings: Neo4jSettings | undefined = undefined;
|
|
37
30
|
|
|
@@ -50,6 +43,7 @@ async function lintSingleDocument(document: TextDocument): Promise<void> {
|
|
|
50
43
|
});
|
|
51
44
|
},
|
|
52
45
|
neo4jSchemaPoller,
|
|
46
|
+
settings?.features?.useVersionedLinters,
|
|
53
47
|
);
|
|
54
48
|
} else {
|
|
55
49
|
void connection.sendDiagnostics({
|
|
@@ -127,6 +121,19 @@ connection.onSignatureHelp(doSignatureHelp(documents, neo4jSchemaPoller));
|
|
|
127
121
|
// Trigger the auto completion
|
|
128
122
|
connection.onCompletion(doAutoCompletion(documents, neo4jSchemaPoller));
|
|
129
123
|
|
|
124
|
+
connection.onNotification(
|
|
125
|
+
'updateLintWorker',
|
|
126
|
+
(linterSettings: LintWorkerSettings) => {
|
|
127
|
+
const lintWorkerPath = linterSettings.lintWorkerPath;
|
|
128
|
+
const linterVersion = linterSettings.linterVersion;
|
|
129
|
+
|
|
130
|
+
void (async () => {
|
|
131
|
+
await setLintWorker(lintWorkerPath, linterVersion);
|
|
132
|
+
relintAllDocuments();
|
|
133
|
+
})();
|
|
134
|
+
},
|
|
135
|
+
);
|
|
136
|
+
|
|
130
137
|
connection.onNotification(
|
|
131
138
|
'connectionUpdated',
|
|
132
139
|
(connectionSettings: Neo4jConnectionSettings) => {
|
|
@@ -154,7 +161,7 @@ documents.listen(connection);
|
|
|
154
161
|
connection.listen();
|
|
155
162
|
|
|
156
163
|
connection.onExit(() => {
|
|
157
|
-
cleanupWorkers();
|
|
164
|
+
void cleanupWorkers();
|
|
158
165
|
});
|
|
159
166
|
|
|
160
167
|
const changeConnection = (connectionSettings: Neo4jConnectionSettings) => {
|
package/src/types.ts
CHANGED
|
@@ -7,11 +7,16 @@ export type Neo4jConnectionSettings = {
|
|
|
7
7
|
database?: string;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
|
+
export type LintWorkerSettings = {
|
|
11
|
+
lintWorkerPath: string;
|
|
12
|
+
linterVersion: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
10
15
|
export type Neo4jSettings = {
|
|
11
16
|
trace: {
|
|
12
17
|
server: 'off' | 'messages' | 'verbose';
|
|
13
18
|
};
|
|
14
|
-
features: { linting: boolean };
|
|
19
|
+
features: { linting: boolean; useVersionedLinters?: boolean };
|
|
15
20
|
};
|
|
16
21
|
|
|
17
22
|
export type Neo4jParameters = Record<string, unknown>;
|
package/src/lintWorker.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DbSchema,
|
|
3
|
-
lintCypherQuery as _lintCypherQuery,
|
|
4
|
-
_internalFeatureFlags,
|
|
5
|
-
} from '@neo4j-cypher/language-support';
|
|
6
|
-
import workerpool from 'workerpool';
|
|
7
|
-
|
|
8
|
-
function lintCypherQuery(
|
|
9
|
-
query: string,
|
|
10
|
-
dbSchema: DbSchema,
|
|
11
|
-
featureFlags: { consoleCommands?: boolean; cypher25?: boolean } = {},
|
|
12
|
-
) {
|
|
13
|
-
// We allow to override the consoleCommands feature flag
|
|
14
|
-
if (featureFlags.consoleCommands !== undefined) {
|
|
15
|
-
_internalFeatureFlags.consoleCommands = featureFlags.consoleCommands;
|
|
16
|
-
}
|
|
17
|
-
if (featureFlags.cypher25 !== undefined) {
|
|
18
|
-
_internalFeatureFlags.cypher25 = featureFlags.cypher25;
|
|
19
|
-
}
|
|
20
|
-
return _lintCypherQuery(query, dbSchema);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
workerpool.worker({ lintCypherQuery });
|
|
24
|
-
|
|
25
|
-
type LinterArgs = Parameters<typeof lintCypherQuery>;
|
|
26
|
-
|
|
27
|
-
export type LinterTask = workerpool.Promise<ReturnType<typeof lintCypherQuery>>;
|
|
28
|
-
|
|
29
|
-
export type LintWorker = {
|
|
30
|
-
lintCypherQuery: (...args: LinterArgs) => LinterTask;
|
|
31
|
-
};
|