Skip to content

Conversation

@tcobbs-bentley
Copy link
Member

@tcobbs-bentley tcobbs-bentley commented Aug 8, 2025

Clean up the lint warnings in all the core/ec* directories.

  1. Where possible, clean up code to not require non-null assertions (!).
  2. Use the new expectDefined and expectNotNull functions when there isn't an obviously correct way to get rid of the !. As time passes, code using expectDefined and expectNotNull will be updated to stop using it.
  3. Fix code that triggers the @typescript-eslint/restrict-template-expressions warning.

@tcobbs-bentley tcobbs-bentley changed the title DRAFT: Clean up lint warnings in core/ec* Clean up lint warnings in core/ec* Aug 13, 2025
@tcobbs-bentley tcobbs-bentley marked this pull request as ready for review August 13, 2025 16:49
Comment on lines 124 to 127
await this.validate(relClass!);
await this.validate(expectDefined(relClass));
} catch(e: any) {
await (relClass! as ECClass as MutableClass).setBaseClass(baseClass);
await (expectDefined(relClass) as ECClass as MutableClass).setBaseClass(baseClass);
Copy link
Member

@ColinKerr ColinKerr Aug 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@christophermlawson what is the expected behavior when the item key doesn't resolve to a relationship class?

This should be fixed properly rather than with this hack and the behavior should be documented and tested

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ColinKerr This would be unexpected, so I think an exception would be appropriate here.

const enumeration = await context.targetSchema.lookupItem(itemKey) as MutableEnumeration;
if(change.difference.type !== undefined) {
throw new Error(`The Enumeration ${itemKey.name} has an incompatible type. It must be "${primitiveTypeToString(enumeration.type!)}", not "${change.difference.type}".`);
throw new Error(`The Enumeration ${itemKey.name} has an incompatible type. It must be "${enumeration.type ? primitiveTypeToString(enumeration.type) : "<unknown>"}", not "${change.difference.type}".`);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the underlying Enumeration._type property possibly undefined? Any valid enumeration MUST have a type set so we should not force callers to test if the type is null.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ColinKerr The constructor also has this as optional. It's internal so we can change this. Should we require the parameter or have a default (int or string)?

return;

return new Diagnostics.IncompatibleValueTypePropertyOverride(property, [property.class.fullName, property.name, baseClass.fullName, primitiveTypeToString(baseType), primitiveTypeToString(primitiveType!)]);
return new Diagnostics.IncompatibleValueTypePropertyOverride(property, [property.class.fullName, property.name, baseClass.fullName, primitiveTypeToString(baseType), primitiveTypeToString(expectDefined(primitiveType))]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code should be rewritten so the call back isn't reaching out of its scope to get primitiveType. It would be clearer if primitiveType was passed in as the overrideType of something like that indicating that this the type of the property that is trying to override a property from the base class. It would also avoid the need for expectDefined here.

Copy link
Member Author

@tcobbs-bentley tcobbs-bentley Aug 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I discovered that the requirement for ! or expectDefined was caused by what I feel is a compiler bug. (The compiler for some reason thinks that primitiveType might be undefined in callback, even though it's a const that has already been verified to be defined.) Introducing another const removed the need for either ! or expectDefined, so I made that change. Note that this doesn't address your actual comment here, but it does provide what I feel is a better fix to get rid of the !, and your comment no longer seems to be in the scope of this PR.

const maxCandidate = candidates.sort(this.compareSchemaKeyByVersion)[candidates.length - 1];
const alias = this.getSchemaAlias(maxCandidate.schemaText!);
// Note: if maxCandidate.schemaText is undefined, the "" passed to getSchemaAlias will throw an ECSchemaError.
const alias = this.getSchemaAlias(maxCandidate.schemaText ?? "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is problematic. findEligibleSchemaKeys always fills out the schemaText. Some code uses the schemaText and other code loads it all over again. It looks like we may load the text from disk more than once and in some cases we may hold onto the text long after we need it (when we construct the schema with a SchemaFileKey)

This should be rationalized and fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ColinKerr I'm assuming you are referring to the other locaters (json and xml)? Looks like we may read it twice. The StubSchemaXmlFileLocater looks ok to me.

private loadSchemaReferenceSync(ref: SchemaReferenceProps): void {
const schemaKey = new SchemaKey(ref.name, ECVersion.fromString(ref.version));
const refSchema = this._context.getSchemaSync(schemaKey, SchemaMatchType.LatestWriteCompatible);
if (undefined === this._schema) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be cleaner to rewrite this method to take the schema in as a parameter. As called _schema will always be defined but changing the signature makes the method's contract clear.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made that simple change. While doing so I noticed that it is being cast to MutableSchema without a guard. Should a new guard be added that verifies that it is an instance of MutableSchema and throw an exception if not?

@mergify
Copy link
Contributor

mergify bot commented Aug 20, 2025

This pull request is now in conflicts. Could you fix it @tcobbs-bentley? 🙏
To fixup this pull request, you can check out it locally. See documentation: https://help.github.com/articles/checking-out-pull-requests-locally/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants