11import type { AstNode , AstNodeDescription , ReferenceInfo , Scope } from 'langium'
22import type { ZenScriptAstType } from '../generated/ast'
33import type { ZenScriptServices } from '../module'
4+ import type { ZenScriptClassIndex } from '../workspace/class-index'
45import type { PackageManager } from '../workspace/package-manager'
56import type { DynamicProvider } from './dynamic-provider'
67import type { MemberProvider } from './member-provider'
78import { substringBeforeLast } from '@intellizen/shared'
8- import { AstUtils , DefaultScopeProvider , EMPTY_SCOPE , stream } from 'langium'
9+ import { AstUtils , DefaultScopeProvider , EMPTY_SCOPE , MapScope , stream , StreamScope } from 'langium'
910import { ClassDeclaration , ImportDeclaration , isClassDeclaration , TypeParameter } from '../generated/ast'
1011import { getPathAsString } from '../utils/ast'
12+ import { getPrecomputedDescription } from '../utils/document'
1113import { generateStream } from '../utils/stream'
12- import { createSyntheticAstNodeDescription } from './synthetic'
1314
1415type SourceMap = ZenScriptAstType
1516type RuleMap = { [ K in keyof SourceMap ] ?: ( source : ReferenceInfo & { container : SourceMap [ K ] } ) => Scope }
@@ -18,12 +19,14 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
1819 private readonly packageManager : PackageManager
1920 private readonly memberProvider : MemberProvider
2021 private readonly dynamicProvider : DynamicProvider
22+ private readonly classIndex : ZenScriptClassIndex
2123
2224 constructor ( services : ZenScriptServices ) {
2325 super ( services )
2426 this . packageManager = services . workspace . PackageManager
2527 this . memberProvider = services . references . MemberProvider
2628 this . dynamicProvider = services . references . DynamicProvider
29+ this . classIndex = services . workspace . ClassIndex
2730 }
2831
2932 override getScope ( context : ReferenceInfo ) : Scope {
@@ -41,7 +44,7 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
4144 . map ( container => precomputed ?. get ( container ) )
4245 . nonNullable ( )
4346 . map ( descriptions => stream ( descriptions ) . map ( processor ) . nonNullable ( ) )
44- . reduce ( ( outer , descriptions ) => this . createScope ( descriptions , outer ) , outside as Scope )
47+ . reduce ( ( outer , descriptions ) => new StreamScope ( descriptions , outer ) , outside as Scope )
4548 }
4649
4750 private dynamicScope ( astNode : AstNode , outside ?: Scope ) {
@@ -50,22 +53,45 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
5053
5154 private globalScope ( outside ?: Scope ) {
5255 return this . createScope ( this . indexManager . allElements ( ) , outside )
56+ // return new MapScope(this.indexManager.allElements(), outside)
5357 }
5458
5559 private packageScope ( outside ?: Scope ) {
5660 const packages = stream ( this . packageManager . root . children . values ( ) )
5761 . filter ( it => it . isInternalNode ( ) )
58- . map ( it => createSyntheticAstNodeDescription ( 'SyntheticHierarchyNode' , it . name , it ) )
59- return this . createScope ( packages , outside )
62+ . map ( it => this . packageManager . syntheticDescriptionOf ( it ) )
63+ return new StreamScope ( packages , outside )
6064 }
6165
6266 private classScope ( outside ?: Scope ) {
6367 const classes = stream ( this . packageManager . root . children . values ( ) )
6468 . filter ( it => it . isDataNode ( ) )
6569 . flatMap ( it => it . data )
6670 . filter ( isClassDeclaration )
67- . map ( it => this . descriptions . createDescription ( it , it . name ) )
68- return this . createScope ( classes , outside )
71+ . map ( ( it ) => {
72+ const document = AstUtils . getDocument ( it )
73+ return getPrecomputedDescription ( document , it )
74+ } )
75+ return new StreamScope ( classes , outside )
76+ }
77+
78+ private getImportDescription ( importDecl : ImportDeclaration ) : AstNodeDescription | undefined {
79+ const refNode = importDecl . path . at ( - 1 )
80+ if ( ! refNode ) {
81+ return
82+ }
83+
84+ // access the ref to ensure the lookup of the import
85+ const ref = refNode ?. ref
86+ if ( ! ref ) {
87+ return
88+ }
89+
90+ if ( ! importDecl . alias ) {
91+ return refNode ?. $nodeDescription
92+ }
93+
94+ return this . descriptions . createDescription ( ref , this . nameProvider . getName ( importDecl ) , AstUtils . getDocument ( ref ) )
6995 }
7096
7197 private readonly rules : RuleMap = {
@@ -80,10 +106,13 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
80106 const elements : AstNodeDescription [ ] = [ ]
81107 for ( const sibling of siblings ) {
82108 if ( sibling . isDataNode ( ) ) {
83- sibling . data . forEach ( it => elements . push ( this . descriptions . createDescription ( it , sibling . name ) ) )
109+ sibling . data . forEach ( ( it ) => {
110+ const document = AstUtils . getDocument ( it )
111+ elements . push ( getPrecomputedDescription ( document , it ) )
112+ } )
84113 }
85114 else {
86- elements . push ( createSyntheticAstNodeDescription ( 'SyntheticHierarchyNode' , sibling . name , sibling ) )
115+ elements . push ( this . packageManager . syntheticDescriptionOf ( sibling ) )
87116 }
88117 }
89118 return this . createScope ( elements )
@@ -101,8 +130,7 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
101130 return
102131 case ImportDeclaration : {
103132 const importDecl = desc . node as ImportDeclaration
104- const ref = importDecl . path . at ( - 1 ) ?. ref ?? importDecl
105- return this . descriptions . createDescription ( ref , this . nameProvider . getName ( importDecl ) )
133+ return this . getImportDescription ( importDecl ) ?? desc
106134 }
107135 default :
108136 return desc
@@ -114,7 +142,7 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
114142 MemberAccess : ( source ) => {
115143 const outer = this . dynamicScope ( source . container )
116144 const members = this . memberProvider . getMembers ( source . container . receiver )
117- return this . createScope ( members , outer )
145+ return new StreamScope ( members , outer )
118146 } ,
119147
120148 NamedTypeReference : ( source ) => {
@@ -127,8 +155,7 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
127155 return desc
128156 case ImportDeclaration : {
129157 const importDecl = desc . node as ImportDeclaration
130- const ref = importDecl . path . at ( - 1 ) ?. ref ?? importDecl
131- return this . descriptions . createDescription ( ref , this . nameProvider . getName ( importDecl ) )
158+ return this . getImportDescription ( importDecl ) ?? desc
132159 }
133160 }
134161 }
@@ -137,7 +164,7 @@ export class ZenScriptScopeProvider extends DefaultScopeProvider {
137164 else {
138165 const prev = source . container . path [ source . index - 1 ] . ref
139166 const members = this . memberProvider . getMembers ( prev )
140- return this . createScope ( members )
167+ return new StreamScope ( members )
141168 }
142169 } ,
143170 }
0 commit comments