@@ -144,6 +144,13 @@ export class ZModelLinker extends DefaultLinker {
144
144
}
145
145
146
146
private resolve ( node : AstNode , document : LangiumDocument , extraScopes : ScopeProvider [ ] = [ ] ) {
147
+ // if the field has enum declaration type, resolve the rest with that enum's fields on top of the scopes
148
+ if ( isDataModelField ( node ) && node . type . reference ?. ref && isEnum ( node . type . reference . ref ) ) {
149
+ const contextEnum = node . type . reference . ref as Enum ;
150
+ const enumScope : ScopeProvider = ( name ) => contextEnum ?. fields ?. find ( ( f ) => f . name === name ) ;
151
+ extraScopes = [ enumScope , ...extraScopes ] ;
152
+ }
153
+
147
154
switch ( node . $type ) {
148
155
case StringLiteral :
149
156
case NumberLiteral :
@@ -160,12 +167,7 @@ export class ZModelLinker extends DefaultLinker {
160
167
break ;
161
168
162
169
case ReferenceExpr :
163
- // If the reference comes from an alias, we resolve it against the first matching data model
164
- if ( getContainerOfType ( node , isAliasDecl ) ) {
165
- this . resolveAliasExpr ( node , document ) ;
166
- } else {
167
- this . resolveReference ( node as ReferenceExpr , document , extraScopes ) ;
168
- }
170
+ this . resolveReference ( node as ReferenceExpr , document , extraScopes ) ;
169
171
break ;
170
172
171
173
case MemberAccessExpr :
@@ -265,6 +267,10 @@ export class ZModelLinker extends DefaultLinker {
265
267
}
266
268
267
269
private resolveReference ( node : ReferenceExpr , document : LangiumDocument < AstNode > , extraScopes : ScopeProvider [ ] ) {
270
+ // If the reference comes from an alias, we resolve it against the first matching data model
271
+ if ( getContainerOfType ( node , isAliasDecl ) ) {
272
+ this . resolveAliasExpr ( node as ReferenceExpr , document ) ;
273
+ }
268
274
this . resolveDefault ( node , document , extraScopes ) ;
269
275
270
276
if ( node . target . ref ) {
@@ -468,11 +474,6 @@ export class ZModelLinker extends DefaultLinker {
468
474
// Find the first model that has the alias reference as a field
469
475
const matchingModel = models . find ( ( model ) => model . fields . some ( ( f ) => f . name === node . $cstNode ?. text ) ) ;
470
476
if ( ! matchingModel ) {
471
- this . createLinkingError ( {
472
- reference : ( node as ReferenceExpr ) . target ,
473
- container : node ,
474
- property : 'target' ,
475
- } ) ;
476
477
return ;
477
478
}
478
479
@@ -481,6 +482,11 @@ export class ZModelLinker extends DefaultLinker {
481
482
482
483
const visitExpr = ( node : Expression ) => {
483
484
if ( isReferenceExpr ( node ) ) {
485
+ // enums in alias expressions are already resolved
486
+ if ( isEnum ( node . target . ref ?. $container ) ) {
487
+ return ;
488
+ }
489
+
484
490
const resolved = this . resolveFromScopeProviders ( node , 'target' , document , [ scopeProvider ] ) ;
485
491
if ( resolved ) {
486
492
this . resolveToDeclaredType ( node , ( resolved as DataModelField ) . type ) ;
@@ -585,6 +591,10 @@ export class ZModelLinker extends DefaultLinker {
585
591
//#region Utils
586
592
587
593
private resolveToDeclaredType ( node : AstNode , type : FunctionParamType | DataModelFieldType | TypeDefFieldType ) {
594
+ // enums from alias expressions are already resolved and do not exist in the scope
595
+ if ( ! type ) {
596
+ return ;
597
+ }
588
598
let nullable = false ;
589
599
if ( isDataModelFieldType ( type ) || isTypeDefField ( type ) ) {
590
600
nullable = type . optional ;
0 commit comments