Skip to content

Commit 88fb242

Browse files
authored
Merge pull request #58 from dont-code/prj-enh
Support for out of order types
2 parents d265b76 + c7def41 commit 88fb242

3 files changed

Lines changed: 109 additions & 10 deletions

File tree

libs/xt-components/projects/xt-components/src/lib/angular/xt-resolver.service.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,56 @@ describe('XtResolverService', () => {
5353
expect(result).toEqual(['subType2', 'subType21']);
5454
});
5555

56+
it ('should support type registration', () => {
57+
service.registerTypes({
58+
"Author": {
59+
firstName:"string",
60+
lastName:"string"
61+
},
62+
"Book": {
63+
children: {
64+
"title": "string",
65+
"publishedYear":"number",
66+
"author": {
67+
toType:"Author",
68+
referenceType:"MANY-TO-ONE",
69+
field:"lastName"
70+
}
71+
}
72+
}
73+
});
74+
expect(service.typeResolver.findType("Author")).toBeTruthy();
75+
expect(service.typeResolver.findType("Book")).toBeTruthy();
76+
});
77+
78+
it ('should support out of order type registration', () => {
79+
service.registerTypes({
80+
"NewBook": {
81+
children: {
82+
"title": "string",
83+
"publishedYear":"number",
84+
"author": {
85+
toType:"NewAuthor",
86+
referenceType:"MANY-TO-ONE",
87+
field:"lastName"
88+
},
89+
type: "NewBookType"
90+
}
91+
},
92+
"NewAuthor": {
93+
firstName:"string",
94+
lastName:"string"
95+
},
96+
"NewBookType": {
97+
typeName:"string"
98+
}
99+
});
100+
service.resolvePendingReferences();
101+
expect(service.typeResolver.findType("NewAuthor")).toBeTruthy();
102+
expect(service.typeResolver.findType("NewBook")).toBeTruthy();
103+
expect(service.typeResolver.findType("NewBookType")).toBeTruthy();
104+
});
105+
56106
it('should properly set typeHandlers', () => {
57107
service.registerPlugin({
58108
name: 'resolverTest',

libs/xt-type/src/resolver/xt-type-resolver.spec.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, expect, it } from 'vitest';
22
import { xtTypeManager } from '../globals';
3+
import { XtBaseTypeHierarchy } from './xt-type-resolver.ts';
34

45
describe('Xt Type Resolver', () => {
56
it ('should correctly calculates properties per types', () => {
@@ -34,7 +35,7 @@ describe('Xt Type Resolver', () => {
3435
name: 'string',
3536
author: {
3637
type: 'authorType',
37-
referenceType:'ONE'
38+
referenceType:'MANY-TO-ONE'
3839
}
3940
}
4041
});
@@ -43,5 +44,22 @@ describe('Xt Type Resolver', () => {
4344
expect(authorRef).toBeTruthy();
4445
expect(authorRef?.type).toEqual('authorType');
4546
});
47+
48+
it ('should correctly managed unordered types', () => {
49+
const resolver = xtTypeManager();
50+
resolver.addRootType('newBookType', {
51+
name: 'string',
52+
author:'newAuthorType'
53+
});
54+
resolver.addRootType('newAuthorType', {
55+
firstName: 'string',
56+
lastName: 'string'
57+
});
58+
59+
resolver.resolveAllTypeReferences();
60+
const newBookType=resolver.findType('newBookType') as XtBaseTypeHierarchy;
61+
expect((newBookType.children!['author'] as XtBaseTypeHierarchy).children).toBeDefined();
62+
63+
});
4664
})
4765

libs/xt-type/src/resolver/xt-type-resolver.ts

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,10 @@ export class XtTypeHierarchyResolver implements XtUpdatableTypeResolver {
269269
if (!this.isPrimitiveType(typeHierarchy)) {
270270
// Find the reference to an non primitive type
271271
ret = this.types.get(typeHierarchy) as XtBaseTypeHierarchy??null;
272-
if( ret==null) throw new Error('Type '+typeHierarchy+' not found in the type hierarchy.');
272+
if( ret==null) {
273+
// Either it's an unknown type, or the type is defined at a later stage. Let's keep a placeholder
274+
ret = new UNRESOLVED_TYPE (typeHierarchy);
275+
}
273276
} else {
274277
// Just create the hierarchy to the primitive type
275278
ret= new XtBaseTypeHierarchy(typeHierarchy, handler);
@@ -325,14 +328,25 @@ export class XtTypeHierarchyResolver implements XtUpdatableTypeResolver {
325328

326329
resolveAllTypeReferences ():void {
327330
for (const type of this.types.values()) {
328-
const refs = type.listReferences();
329-
for (const ref of Object.keys(refs)) {
330-
if( refs[ref].type==XtBaseTypeReference.UNRESOLVED_TYPE) {
331-
const refType = this.findType(refs[ref].toType, refs[ref].field);
332-
if( refType!=null) {
333-
refs[ref].type=refType.type;
334-
}else {
335-
throw new Error('Unable to resolve reference '+ref+' of type '+type.type);
331+
if (type.children!=null) {
332+
for (const ref of Object.keys(type.children)) {
333+
const subType=type.children[ref];
334+
if (isTypeReference(subType)) {
335+
if( subType.type==XtBaseTypeReference.UNRESOLVED_TYPE) {
336+
const refType = this.findType(subType.toType, subType.field);
337+
if( refType!=null) {
338+
subType.type=refType.type;
339+
}else {
340+
throw new Error('Unable to resolve reference '+ref+' of type '+type.type);
341+
}
342+
}
343+
} else if (isUnresolvedType(subType)) {
344+
const realType=this.findType(subType.unknownType);
345+
if( realType!=null) {
346+
type.children[ref]=realType;
347+
} else {
348+
throw new Error('Unable to resolve type '+ref+' of type '+type.type+'. '+subType.unknownType+' is not defined.');
349+
}
336350
}
337351
}
338352
}
@@ -367,6 +381,7 @@ export class XtBaseTypeHierarchy implements XtTypeHierarchy {
367381
displayTemplate?:string;
368382
numericField?:string;
369383

384+
370385
constructor (type:string, handler?:XtTypeHandler<any> ) {
371386
this.type=type;
372387
this.handler=handler;
@@ -412,6 +427,22 @@ export class XtBaseTypeHierarchy implements XtTypeHierarchy {
412427
}
413428
}
414429

430+
export class UNRESOLVED_TYPE extends XtBaseTypeHierarchy {
431+
unknownType:string|null=null;
432+
433+
constructor(unknownType:string) {
434+
super(unknownType);
435+
this.unknownType=unknownType;
436+
}
437+
}
438+
439+
export function isUnresolvedType (type: XtTypeHierarchy): type is UNRESOLVED_TYPE {
440+
if ((type as any).unknownType!==undefined) return true;
441+
else
442+
return false;
443+
}
444+
445+
415446
/**
416447
* Internally manages a link between two types
417448
*/

0 commit comments

Comments
 (0)