66 * @module Metadata
77 */
88
9- import { assert } from "@itwin/core-bentley" ;
9+ import { assert , Logger } from "@itwin/core-bentley" ;
1010import { DelayedPromiseWithProps } from "../DelayedPromise" ;
1111import { ClassProps } from "../Deserialization/JsonProps" ;
1212import { XmlSerializationUtils } from "../Deserialization/XmlSerializationUtils" ;
@@ -23,6 +23,8 @@ import { Schema } from "./Schema";
2323import { SchemaItem } from "./SchemaItem" ;
2424import { 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