@@ -11,7 +11,12 @@ import {
1111} from 'vscode-languageserver/node' ;
1212
1313import { TextDocument } from 'vscode-languageserver-textdocument' ;
14- import { syntaxColouringLegend } from '@neo4j-cypher/language-support' ;
14+ import {
15+ DbSchema ,
16+ parserWrapper ,
17+ SymbolTable ,
18+ syntaxColouringLegend ,
19+ } from '@neo4j-cypher/language-support' ;
1520import { Neo4jSchemaPoller } from '@neo4j-cypher/query-tools' ;
1621import { doAutoCompletion } from './autocompletion' ;
1722import { formatDocument } from './formatting' ;
@@ -24,15 +29,82 @@ import {
2429 Neo4jParameters ,
2530 Neo4jSettings ,
2631} from './types' ;
32+ import workerpool from 'workerpool' ;
33+ import { join } from 'path' ;
34+ import { LintWorker } from '@neo4j-cypher/lint-worker' ;
35+
36+ class SymbolFetcher {
37+ private processing = false ;
38+ private nextJob : {
39+ query : string ;
40+ uri : string ;
41+ schema : DbSchema ;
42+ } ;
43+ private defaultWorkerPath = join ( __dirname , 'lintWorker.cjs' ) ;
44+ private symbolTablePool = workerpool . pool ( this . defaultWorkerPath , {
45+ maxWorkers : 1 ,
46+ workerTerminateTimeout : 0 ,
47+ } ) ;
48+
49+ public queueSymbolJob ( query : string , uri : string , schema : DbSchema ) {
50+ this . nextJob = { query, uri, schema } ;
51+ if ( ! this . processing ) {
52+ void this . processJobQueue ( ) ;
53+ }
54+ }
55+
56+ private async processJobQueue ( ) {
57+ this . processing = true ;
58+ const proxyWorker =
59+ ( await this . symbolTablePool . proxy ( ) ) as unknown as LintWorker ;
60+ while ( this . nextJob ) {
61+ try {
62+ const query = this . nextJob . query ;
63+ const dbSchema = this . nextJob . schema ;
64+ const docUri = this . nextJob . uri ;
65+ this . nextJob = undefined ;
66+
67+ const result = await proxyWorker . lintCypherQuery ( query , dbSchema ) ;
68+
69+ if (
70+ //if this.nextJob has new doc, our result is no longer valid
71+ result . symbolTables &&
72+ ! ( this . nextJob && this . nextJob . uri != docUri )
73+ ) {
74+ parserWrapper . setSymbolsInfo (
75+ {
76+ query,
77+ symbolTables : result . symbolTables ,
78+ } ,
79+ async ( symbolTables : SymbolTable [ ] ) =>
80+ await connection . sendNotification ( 'symbolTableDone' , {
81+ symbolTables,
82+ } ) ,
83+ ) ;
84+ }
85+ } catch ( e ) {
86+ //eslint-disable-next-line
87+ console . log ( 'Symbol table calculation failed' ) ;
88+ }
89+ }
90+ this . processing = false ;
91+ }
92+ }
2793
2894const connection = createConnection ( ProposedFeatures . all ) ;
2995let settings : Neo4jSettings | undefined = undefined ;
3096
3197// Create a simple text document manager.
3298const documents : TextDocuments < TextDocument > = new TextDocuments ( TextDocument ) ;
3399const neo4jSchemaPoller = new Neo4jSchemaPoller ( ) ;
100+ const symbolFetcher = new SymbolFetcher ( ) ;
34101
35102async function lintSingleDocument ( document : TextDocument ) : Promise < void > {
103+ symbolFetcher . queueSymbolJob (
104+ document . getText ( ) ,
105+ document . uri ,
106+ neo4jSchemaPoller ?. metadata ?. dbSchema ,
107+ ) ;
36108 if ( settings ?. features ?. linting ) {
37109 return lintDocument (
38110 document ,
@@ -42,6 +114,10 @@ async function lintSingleDocument(document: TextDocument): Promise<void> {
42114 diagnostics,
43115 } ) ;
44116 } ,
117+ async ( symbolTables : SymbolTable [ ] ) =>
118+ await connection . sendNotification ( 'symbolTableDone' , {
119+ symbolTables : symbolTables ,
120+ } ) ,
45121 neo4jSchemaPoller ,
46122 ) ;
47123 } else {
@@ -141,6 +217,25 @@ connection.onNotification(
141217 } ,
142218) ;
143219
220+ connection . onNotification (
221+ 'fetchSymbolTable' ,
222+ ( params : {
223+ query : string ;
224+ uri : string ;
225+ version : number ;
226+ schema : DbSchema ;
227+ } ) => {
228+ neo4jSchemaPoller . events . once (
229+ 'schemaFetched' ,
230+ void symbolFetcher . queueSymbolJob (
231+ params . query ,
232+ params . uri ,
233+ params . schema ,
234+ ) ,
235+ ) ;
236+ } ,
237+ ) ;
238+
144239connection . onNotification ( 'updateParameters' , ( parameters : Neo4jParameters ) => {
145240 neo4jSchemaPoller . setParameters ( parameters ) ;
146241 relintAllDocuments ( ) ;
0 commit comments