(
decl: DataModel | TypeDef,
includeDelegate = true,
documents?: LangiumDocuments,
seen = new Set<DataModel | TypeDef>(),
)
| 201 | * Gets all base models and mixins of a data model or type def, recursively. |
| 202 | */ |
| 203 | export function getRecursiveBases( |
| 204 | decl: DataModel | TypeDef, |
| 205 | includeDelegate = true, |
| 206 | documents?: LangiumDocuments, |
| 207 | seen = new Set<DataModel | TypeDef>(), |
| 208 | ): (TypeDef | DataModel)[] { |
| 209 | const result: (TypeDef | DataModel)[] = []; |
| 210 | if (seen.has(decl)) { |
| 211 | return result; |
| 212 | } |
| 213 | seen.add(decl); |
| 214 | const bases = [...decl.mixins, ...(isDataModel(decl) && decl.baseModel ? [decl.baseModel] : [])]; |
| 215 | bases.forEach((base) => { |
| 216 | let baseDecl: TypeDef | DataModel | undefined; |
| 217 | |
| 218 | if (base.ref && (isTypeDef(base.ref) || isDataModel(base.ref))) { |
| 219 | // base is already resolved |
| 220 | baseDecl = base.ref; |
| 221 | } else { |
| 222 | // otherwise, search by name, in all imported documents if provided |
| 223 | const declarations = documents |
| 224 | ? getAllDeclarationsIncludingImports(documents, decl.$container) |
| 225 | : decl.$container.declarations; |
| 226 | |
| 227 | baseDecl = declarations.find( |
| 228 | (d): d is TypeDef | DataModel => (isTypeDef(d) || isDataModel(d)) && d.name === base.$refText, |
| 229 | ); |
| 230 | } |
| 231 | |
| 232 | if (baseDecl) { |
| 233 | if (!includeDelegate && isDelegateModel(baseDecl)) { |
| 234 | return; |
| 235 | } |
| 236 | result.push(baseDecl); |
| 237 | result.push(...getRecursiveBases(baseDecl, includeDelegate, documents, seen)); |
| 238 | } |
| 239 | }); |
| 240 | return result; |
| 241 | } |
| 242 | |
| 243 | /** |
| 244 | * Gets `@@id` fields declared at the data model level (including search in base models) |
no test coverage detected