11import { createZModelLanguageServices } from '@zenstackhq/language' ;
2+ import type { Model } from '@zenstackhq/language/ast' ;
3+ import { getDocument , resolveImport } from '@zenstackhq/language/utils' ;
4+ import { URI , type LangiumDocument , type LangiumDocuments } from 'langium' ;
25import { startLanguageServer } from 'langium/lsp' ;
36import { NodeFileSystem } from 'langium/node' ;
47import { createConnection , ProposedFeatures } from 'vscode-languageserver/node.js' ;
@@ -15,5 +18,76 @@ const { shared } = createZModelLanguageServices(
1518 true ,
1619) ;
1720
21+ // Add custom LSP request handlers
22+ connection . onRequest ( 'zenstack/getAllImportedZModelURIs' , async ( params : { textDocument : { uri : string } } ) => {
23+ try {
24+ const uri = URI . parse ( params . textDocument . uri ) ;
25+ const document = await shared . workspace . LangiumDocuments . getOrCreateDocument ( uri ) ;
26+
27+ // Ensure the document is parsed and built
28+ if ( ! document . parseResult ) {
29+ await shared . workspace . DocumentBuilder . build ( [ document ] ) ;
30+ }
31+
32+ const langiumDocuments = shared . workspace . LangiumDocuments ;
33+
34+ // load all imports
35+ const importedURIs = eagerLoadAllImports ( document , langiumDocuments ) ;
36+
37+ const importedDocuments = await Promise . all (
38+ importedURIs . map ( ( uri ) => langiumDocuments . getOrCreateDocument ( uri ) ) ,
39+ ) ;
40+
41+ // build the document together with standard library, plugin modules, and imported documents
42+ await shared . workspace . DocumentBuilder . build ( [ document , ...importedDocuments ] , {
43+ validation : true ,
44+ } ) ;
45+
46+ let hasSyntaxErrors = false ;
47+ for ( const docUri of [ uri , ...importedURIs ] ) {
48+ const doc = await langiumDocuments . getOrCreateDocument ( docUri ) ;
49+ if (
50+ doc . parseResult . lexerErrors . length > 0 ||
51+ doc . parseResult . parserErrors . length > 0 ||
52+ doc . diagnostics ?. some ( ( e ) => e . severity === 1 )
53+ ) {
54+ hasSyntaxErrors = true ;
55+ break ;
56+ }
57+ }
58+
59+ return {
60+ hasSyntaxErrors,
61+ importedURIs,
62+ } ;
63+ } catch ( error ) {
64+ console . error ( 'Error getting imported ZModel file:' , error ) ;
65+ return {
66+ hasSyntaxErrors : true ,
67+ importedURIs : [ ] ,
68+ } ;
69+ }
70+ } ) ;
71+
72+ function eagerLoadAllImports ( document : LangiumDocument , documents : LangiumDocuments , uris : Set < string > = new Set ( ) ) {
73+ const uriString = document . uri . toString ( ) ;
74+ if ( ! uris . has ( uriString ) ) {
75+ uris . add ( uriString ) ;
76+ const model = document . parseResult . value as Model ;
77+
78+ for ( const imp of model . imports ) {
79+ const importedModel = resolveImport ( documents , imp ) ;
80+ if ( importedModel ) {
81+ const importedDoc = getDocument ( importedModel ) ;
82+ eagerLoadAllImports ( importedDoc , documents , uris ) ;
83+ }
84+ }
85+ }
86+
87+ return Array . from ( uris )
88+ . filter ( ( x ) => uriString != x )
89+ . map ( ( e ) => URI . parse ( e ) ) ;
90+ }
91+
1892// Start the language server with the shared services
1993startLanguageServer ( shared ) ;
0 commit comments