From e485524d807c9e2397fb2d7e5c2a6037e5b2da3b Mon Sep 17 00:00:00 2001 From: JG Date: Sun, 31 Dec 2023 18:42:14 +0000 Subject: [PATCH] fix: Show the correct incomplete error for multiple level inheritance case --- .../validator/datamodel-validator.ts | 23 ++++++------------ .../validation/datamodel-validation.test.ts | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/packages/schema/src/language-server/validator/datamodel-validator.ts b/packages/schema/src/language-server/validator/datamodel-validator.ts index 8d7bb7740..ce1886f5e 100644 --- a/packages/schema/src/language-server/validator/datamodel-validator.ts +++ b/packages/schema/src/language-server/validator/datamodel-validator.ts @@ -235,22 +235,13 @@ export default class DataModelValidator implements AstValidator { const node = field.$isInherited ? field.$container : field; const info: DiagnosticInfo = { node, code: IssueCodes.MissingOppositeRelation }; - let relationFieldDocUri: string; - let relationDataModelName: string; - - if (field.$isInherited) { - info.property = 'name'; - const container = field.$container as DataModel; - const abstractContainer = container.superTypes.find((x) => - x.ref?.fields.find((f) => f.name === field.name) - )?.ref as DataModel; - - relationFieldDocUri = getDocument(abstractContainer).textDocument.uri; - relationDataModelName = abstractContainer.name; - } else { - relationFieldDocUri = getDocument(field).textDocument.uri; - relationDataModelName = field.$container.name; - } + info.property = 'name'; + // use cstNode because the field might be inherited from parent model + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const container = field.$cstNode!.element.$container as DataModel; + + const relationFieldDocUri = getDocument(container).textDocument.uri; + const relationDataModelName = container.name; const data: MissingOppositeRelationData = { relationFieldName: field.name, diff --git a/packages/schema/tests/schema/validation/datamodel-validation.test.ts b/packages/schema/tests/schema/validation/datamodel-validation.test.ts index a2d68f2c0..e1f06d268 100644 --- a/packages/schema/tests/schema/validation/datamodel-validation.test.ts +++ b/packages/schema/tests/schema/validation/datamodel-validation.test.ts @@ -633,5 +633,29 @@ describe('Data Model Validation Tests', () => { expect(errors.length).toBe(1); expect(errors[0]).toEqual(`Model A cannot be extended because it's not abstract`); + + // relation incomplete from multiple level inheritance + expect( + await loadModelWithError(` + ${prelude} + model User { + id Int @id @default(autoincrement()) + } + + abstract model Base { + id Int @id @default(autoincrement()) + user User @relation(fields: [userId], references: [id]) + userId Int + } + + abstract model Base1 extends Base { + isPublic Boolean @default(false) + } + + model A extends Base1 { + a String + } + `) + ).toContain(`The relation field "user" on model "A" is missing an opposite relation field on model "User"`); }); });