@@ -17,7 +17,13 @@ import {
1717 ModelImport ,
1818 ReferenceExpr ,
1919} from '@zenstackhq/language/ast' ;
20- import { getModelFieldsWithBases , getRecursiveBases , isDelegateModel , isFromStdlib } from '@zenstackhq/sdk' ;
20+ import {
21+ getInheritanceChain ,
22+ getModelFieldsWithBases ,
23+ getRecursiveBases ,
24+ isDelegateModel ,
25+ isFromStdlib ,
26+ } from '@zenstackhq/sdk' ;
2127import {
2228 AstNode ,
2329 copyAstNode ,
@@ -61,7 +67,7 @@ export function mergeBaseModels(model: Model, linker: Linker) {
6167 . concat ( dataModel . fields ) ;
6268
6369 dataModel . attributes = bases
64- . flatMap ( ( base ) => base . attributes . filter ( ( attr ) => filterBaseAttribute ( base , attr ) ) )
70+ . flatMap ( ( base ) => base . attributes . filter ( ( attr ) => filterBaseAttribute ( dataModel , base , attr ) ) )
6571 . map ( ( attr ) => cloneAst ( attr , dataModel , buildReference ) )
6672 . concat ( dataModel . attributes ) ;
6773 }
@@ -85,7 +91,7 @@ export function mergeBaseModels(model: Model, linker: Linker) {
8591 linkContentToContainer ( model ) ;
8692}
8793
88- function filterBaseAttribute ( base : DataModel , attr : DataModelAttribute ) {
94+ function filterBaseAttribute ( forModel : DataModel , base : DataModel , attr : DataModelAttribute ) {
8995 if ( attr . $inheritedFrom ) {
9096 // don't inherit from skip-level base
9197 return false ;
@@ -101,13 +107,26 @@ function filterBaseAttribute(base: DataModel, attr: DataModelAttribute) {
101107 return false ;
102108 }
103109
104- if ( isDelegateModel ( base ) && uninheritableFromDelegateAttributes . includes ( attr . decl . $refText ) ) {
110+ if (
111+ // checks if the inheritance is from a delegate model or through one, if so,
112+ // the attribute shouldn't be inherited as the delegate already inherits it
113+ isInheritedFromOrThroughDelegate ( forModel , base ) &&
114+ uninheritableFromDelegateAttributes . includes ( attr . decl . $refText )
115+ ) {
105116 return false ;
106117 }
107118
108119 return true ;
109120}
110121
122+ function isInheritedFromOrThroughDelegate ( model : DataModel , base : DataModel ) {
123+ if ( isDelegateModel ( base ) ) {
124+ return true ;
125+ }
126+ const chain = getInheritanceChain ( model , base ) ;
127+ return ! ! chain ?. some ( isDelegateModel ) ;
128+ }
129+
111130// deep clone an AST, relink references, and set its container
112131function cloneAst < T extends InheritableNode > (
113132 node : T ,
0 commit comments