Skip to content

Commit 4bcf1eb

Browse files
mergify[bot]soham-bentleynaveedkhan8067hl662
authored
Fixed the issue of getAllBaseClasses() function not returning all the base classes (backport #8912) [release/5.5.x] (#8918)
Co-authored-by: Soham Bhattacharjee <177123878+soham-bentley@users.noreply.github.com> Co-authored-by: naveedkhan8067 <38525837+naveedkhan8067@users.noreply.github.com> Co-authored-by: Nam Le <50554904+hl662@users.noreply.github.com>
1 parent 4859452 commit 4bcf1eb

File tree

3 files changed

+1623
-5
lines changed

3 files changed

+1623
-5
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@itwin/ecschema-metadata",
5+
"comment": "Fixed the issue of getAllBaseClasses() method of ECClass not returning all the base classes",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@itwin/ecschema-metadata"
10+
}

core/ecschema-metadata/src/Metadata/Class.ts

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* @module Metadata
77
*/
88

9-
import { assert } from "@itwin/core-bentley";
9+
import { assert, Logger } from "@itwin/core-bentley";
1010
import { DelayedPromiseWithProps } from "../DelayedPromise";
1111
import { ClassProps } from "../Deserialization/JsonProps";
1212
import { XmlSerializationUtils } from "../Deserialization/XmlSerializationUtils";
@@ -23,6 +23,8 @@ import { Schema } from "./Schema";
2323
import { SchemaItem } from "./SchemaItem";
2424
import { ECSpecVersion, SchemaReadHelper } from "../Deserialization/Helper";
2525

26+
const loggingCategory = "ECClass";
27+
2628
/**
2729
* A common abstract class for all of the ECClass types.
2830
* @public @preview
@@ -86,7 +88,13 @@ export abstract class ECClass extends SchemaItem implements CustomAttributeConta
8688
public async getDerivedClasses(): Promise<ECClass[] | undefined> {
8789
const derivedClasses: ECClass[] = [];
8890
for(const derivedClassKey of this.schema.context.classHierarchy.getDerivedClassKeys(this.key)) {
89-
const derivedClass = await this.schema.context.getSchemaItem(derivedClassKey, ECClass);
91+
let derivedClass = await this.schema.getItem(derivedClassKey.name, ECClass); // if the derived class is in the same schema this will get it without going to the context
92+
if (derivedClass) {
93+
derivedClasses.push(derivedClass);
94+
continue;
95+
}
96+
Logger.logInfo(loggingCategory, `Derived class ${derivedClassKey.name} not found in schema ${this.schema.name}, looking in schema context.`);
97+
derivedClass = await this.schema.context.getSchemaItem(derivedClassKey, ECClass);
9098
if (derivedClass)
9199
derivedClasses.push(derivedClass);
92100
}
@@ -586,20 +594,60 @@ export abstract class ECClass extends SchemaItem implements CustomAttributeConta
586594
*/
587595
public async *getAllBaseClasses(): AsyncIterable<ECClass> {
588596
for (const baseClassKey of this.schema.context.classHierarchy.getBaseClassKeys(this.key)) {
589-
const baseClass = await this.schema.lookupItem(baseClassKey, ECClass);
597+
const baseClass = await this.getClassFromReferencesRecursively(baseClassKey); // Search in schema ref tree all the way to the top
590598
if (baseClass)
591599
yield baseClass;
592600
}
593601
}
594602

603+
/**
604+
* gets a class from this schema or its references recursively using the item key
605+
* @param itemKey
606+
* @returns ECClass if it could be found, undefined otherwise
607+
* @internal
608+
*/
609+
private async getClassFromReferencesRecursively(itemKey: SchemaItemKey): Promise<ECClass | undefined> {
610+
const schemaList: Schema[] = [this.schema];
611+
while(schemaList.length > 0) {
612+
const currentSchema = schemaList.shift();
613+
if(currentSchema!.schemaKey.compareByName(itemKey.schemaKey)) {
614+
const baseClass = await currentSchema!.getItem(itemKey.name, ECClass);
615+
schemaList.splice(0); // clear the list
616+
return baseClass;
617+
}
618+
schemaList.push(...currentSchema!.references);
619+
}
620+
return undefined;
621+
}
622+
595623
public *getAllBaseClassesSync(): Iterable<AnyClass> {
596-
for(const baseClassKey of this.schema.context.classHierarchy.getBaseClassKeys(this.key)) {
597-
const baseClass = this.schema.lookupItemSync(baseClassKey, ECClass);
624+
for (const baseClassKey of this.schema.context.classHierarchy.getBaseClassKeys(this.key)) {
625+
const baseClass = this.getClassFromReferencesRecursivelySync(baseClassKey); // Search in schema ref tree all the way to the top
598626
if (baseClass)
599627
yield baseClass;
600628
}
601629
}
602630

631+
/**
632+
* gets a class from this schema or its references recursively using the item key synchronously
633+
* @param itemKey
634+
* @returns ECClass if it could be found, undefined otherwise
635+
* @internal
636+
*/
637+
private getClassFromReferencesRecursivelySync(itemKey: SchemaItemKey): ECClass | undefined {
638+
const schemaList: Schema[] = [this.schema];
639+
while(schemaList.length > 0) {
640+
const currentSchema = schemaList.shift();
641+
if(currentSchema!.schemaKey.compareByName(itemKey.schemaKey)) {
642+
const baseClass = currentSchema!.getItemSync(itemKey.name, ECClass);
643+
schemaList.splice(0); // clear the list
644+
return baseClass;
645+
}
646+
schemaList.push(...currentSchema!.references);
647+
}
648+
return undefined;
649+
}
650+
603651
/**
604652
*
605653
* @param cache

0 commit comments

Comments
 (0)