Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions packages/schema/src/language-server/zmodel-linker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -519,12 +519,17 @@ export class ZModelLinker extends DefaultLinker {

private resolveDataModel(node: DataModel, document: LangiumDocument<AstNode>, extraScopes: ScopeProvider[]) {
if (node.superTypes.length > 0) {
const providers = node.superTypes.map(
(superType) => (name: string) => superType.ref?.fields.find((f) => f.name === name)
);
extraScopes = [...providers, ...extraScopes];
const superTypeProviders: ScopeProvider[] = [];
// build scope providers for super types recursively with breadth-first search
const queue = node.superTypes.map((t) => t.ref!);
while (queue.length > 0) {
const superType = queue.shift()!;
const provider = (name: string) => superType.fields.find((f) => f.name === name);
superTypeProviders.push(provider);
queue.push(...superType.superTypes.map((t) => t.ref!));
}
extraScopes = [...superTypeProviders, ...extraScopes];
}

return this.resolveDefault(node, document, extraScopes);
}

Expand Down
23 changes: 23 additions & 0 deletions tests/integration/tests/regression/issue-971.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { loadSchema } from '@zenstackhq/testtools';

describe('Regression: issue 971', () => {
it('regression', async () => {
await loadSchema(
`
abstract model Level1 {
id String @id @default(cuid())
URL String?
@@validate(URL != null, "URL must be provided") // works
}
abstract model Level2 extends Level1 {
@@validate(URL != null, "URL must be provided") // works
}
abstract model Level3 extends Level2 {
@@validate(URL != null, "URL must be provided") // doesn't work
}
model Foo extends Level3 {
}
`
);
});
});