@@ -10,8 +10,8 @@ import {
1010 type LangiumDocument ,
1111 type LinkingError ,
1212 type Reference ,
13+ type ReferenceInfo ,
1314 interruptAndCheck ,
14- isReference ,
1515} from 'langium' ;
1616import { match } from 'ts-pattern' ;
1717import {
@@ -94,31 +94,29 @@ export class ZModelLinker extends DefaultLinker {
9494 document . state = DocumentState . Linked ;
9595 }
9696
97- private linkReference (
98- container : AstNode ,
99- property : string ,
100- document : LangiumDocument ,
101- extraScopes : ScopeProvider [ ] ,
102- ) {
103- if ( this . resolveFromScopeProviders ( container , property , document , extraScopes ) ) {
97+ private linkReference ( refInfo : ReferenceInfo , document : LangiumDocument , extraScopes : ScopeProvider [ ] ) {
98+ const defaultRef = refInfo . reference as DefaultReference ;
99+ if ( defaultRef . _ref ) {
100+ // already linked
104101 return ;
105102 }
106-
107- const reference : DefaultReference = ( container as any ) [ property ] ;
108- this . doLink ( { reference, container, property } , document ) ;
103+ if ( this . resolveFromScopeProviders ( refInfo . reference , document , extraScopes ) ) {
104+ // resolved from additional scope provider
105+ return ;
106+ }
107+ // default linking
108+ this . doLink ( refInfo , document ) ;
109109 }
110110
111111 //#endregion
112112
113113 //#region Expression type resolving
114114
115115 private resolveFromScopeProviders (
116- node : AstNode ,
117- property : string ,
116+ reference : DefaultReference ,
118117 document : LangiumDocument ,
119118 providers : ScopeProvider [ ] ,
120119 ) {
121- const reference : DefaultReference = ( node as any ) [ property ] ;
122120 for ( const provider of providers ) {
123121 const target = provider ( reference . $refText ) ;
124122 if ( target ) {
@@ -276,7 +274,7 @@ export class ZModelLinker extends DefaultLinker {
276274 }
277275
278276 private resolveInvocation ( node : InvocationExpr , document : LangiumDocument , extraScopes : ScopeProvider [ ] ) {
279- this . linkReference ( node , 'function' , document , extraScopes ) ;
277+ this . linkReference ( { reference : node . function , container : node , property : 'function' } , document , extraScopes ) ;
280278 node . args . forEach ( ( arg ) => this . resolve ( arg , document , extraScopes ) ) ;
281279 if ( node . function . ref ) {
282280 const funcDecl = node . function . ref as FunctionDecl ;
@@ -401,7 +399,7 @@ export class ZModelLinker extends DefaultLinker {
401399 if ( isArrayExpr ( node . value ) ) {
402400 node . value . items . forEach ( ( item ) => {
403401 if ( isReferenceExpr ( item ) ) {
404- const resolved = this . resolveFromScopeProviders ( item , ' target' , document , [ scopeProvider ] ) ;
402+ const resolved = this . resolveFromScopeProviders ( item . target , document , [ scopeProvider ] ) ;
405403 if ( resolved ) {
406404 this . resolveToDeclaredType ( item , ( resolved as DataField ) . type ) ;
407405 } else {
@@ -414,7 +412,7 @@ export class ZModelLinker extends DefaultLinker {
414412 this . resolveToBuiltinTypeOrDecl ( node . value , node . value . items [ 0 ] . $resolvedType . decl , true ) ;
415413 }
416414 } else if ( isReferenceExpr ( node . value ) ) {
417- const resolved = this . resolveFromScopeProviders ( node . value , ' target' , document , [ scopeProvider ] ) ;
415+ const resolved = this . resolveFromScopeProviders ( node . value . target , document , [ scopeProvider ] ) ;
418416 if ( resolved ) {
419417 this . resolveToDeclaredType ( node . value , ( resolved as DataField ) . type ) ;
420418 } else {
@@ -495,13 +493,9 @@ export class ZModelLinker extends DefaultLinker {
495493 }
496494
497495 private resolveDefault ( node : AstNode , document : LangiumDocument < AstNode > , extraScopes : ScopeProvider [ ] ) {
498- for ( const [ property , value ] of Object . entries ( node ) ) {
499- if ( ! property . startsWith ( '$' ) ) {
500- if ( isReference ( value ) ) {
501- this . linkReference ( node , property , document , extraScopes ) ;
502- }
503- }
504- }
496+ AstUtils . streamReferences ( node ) . forEach ( ( ref ) => {
497+ this . linkReference ( ref , document , extraScopes ) ;
498+ } ) ;
505499 for ( const child of AstUtils . streamContents ( node ) ) {
506500 this . resolve ( child , document , extraScopes ) ;
507501 }
0 commit comments