Skip to content

Commit

Permalink
Remove EC rule 102 Abstract class must have abstract base class (back…
Browse files Browse the repository at this point in the history
…port #5353) [release/3.7.x] (#5483)

Co-authored-by: christophermlawson <32881725+christophermlawson@users.noreply.github.com>
  • Loading branch information
mergify[bot] and christophermlawson authored May 4, 2023
1 parent 441244f commit 7b3d0f6
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@itwin/ecschema-editing",
"comment": "Removed obsolete EC rule 102 - Abstract class must have abstract base class.",
"type": "none"
}
],
"packageName": "@itwin/ecschema-editing"
}
20 changes: 2 additions & 18 deletions core/ecschema-editing/src/Validation/ECRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const DiagnosticCodes = {
// Class Rule Codes (100-199)
BaseClassIsSealed: getCode(100),
BaseClassOfDifferentType: getCode(101),
// EC-102 has been deprecated. Leaving the code here to prevent re-use.
AbstractClassWithNonAbstractBase: getCode(102),

// CA Container Rule Codes (500-599)
Expand Down Expand Up @@ -111,7 +112,7 @@ export const Diagnostics = {
BaseClassIsOfDifferentType: createClassDiagnosticClass<[string, string, string]>(DiagnosticCodes.BaseClassOfDifferentType,
"Class '{0}' cannot derive from base class '{1}' of type '{2}'."),

/** EC-102: Required message parameters: childClass.FullName, baseClass.FullName */
/** **DEPRECATED** EC-102: Required message parameters: childClass.FullName, baseClass.FullName */
AbstractClassWithNonAbstractBase: createClassDiagnosticClass<[string, string]>(DiagnosticCodes.AbstractClassWithNonAbstractBase,
"Abstract Class '{0}' cannot derive from base class '{1}' because it is not an abstract class."),

Expand Down Expand Up @@ -197,7 +198,6 @@ export const ECRuleSet: IRuleSet = {
classRules: [
baseClassIsSealed,
baseClassIsOfDifferentType,
abstractClassWithNonAbstractBase,
],
propertyRules: [
incompatibleValueTypePropertyOverride,
Expand Down Expand Up @@ -298,22 +298,6 @@ export async function* baseClassIsOfDifferentType(ecClass: AnyClass): AsyncItera
yield new Diagnostics.BaseClassIsOfDifferentType(ecClass, [ecClass.fullName, baseClass.fullName, itemType]);
}

/**
* EC Rule: Abstract class cannot derive from a non-abstract base class.
* @internal
*/
export async function* abstractClassWithNonAbstractBase(ecClass: AnyClass): AsyncIterable<ClassDiagnostic<any[]>> {
if (ecClass.modifier !== ECClassModifier.Abstract || !ecClass.baseClass)
return;

const baseClass = await ecClass.baseClass;
// return if rule passed
if (baseClass.modifier === ECClassModifier.Abstract)
return;

yield new Diagnostics.AbstractClassWithNonAbstractBase(ecClass, [ecClass.fullName, baseClass.fullName]);
}

/**
* EC Rule: When overriding a class primitive property, the child and base property must be of the same type (string, number, etc...).
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,73 +98,4 @@ describe("ClassRule tests", () => {
expect(false, "Rule should have passed").to.be.true;
}
});

it("AbstractClassWithNonAbstractBase, base class is sealed, rule violated.", async () => {
const baseClass = new EntityClass(schema, "TestBase", ECClassModifier.Sealed);
const entityClass = new EntityClass(schema, "TestClass", ECClassModifier.Abstract);
entityClass.baseClass = new DelayedPromiseWithProps(baseClass.key, async () => baseClass);

const result = Rules.abstractClassWithNonAbstractBase(entityClass);
expect(result).not.undefined;
let resultHasEntries = false;
for await (const diagnostic of result) {
resultHasEntries = true;
expect(diagnostic.ecDefinition).to.equal(entityClass);
expect(diagnostic.messageArgs).to.eql([entityClass.fullName, baseClass.fullName]);
expect(diagnostic.category).to.equal(DiagnosticCategory.Error);
expect(diagnostic.code).to.equal(Rules.DiagnosticCodes.AbstractClassWithNonAbstractBase);
expect(diagnostic.diagnosticType).to.equal(DiagnosticType.SchemaItem);
}
expect(resultHasEntries, "expected rule to return an AsyncIterable with entries.").to.be.true;
});

it("AbstractClassWithNonAbstractBase, base class modifier is `none`, rule violated.", async () => {
const baseClass = new EntityClass(schema, "TestBase", ECClassModifier.None);
const entityClass = new EntityClass(schema, "TestClass", ECClassModifier.Abstract);
entityClass.baseClass = new DelayedPromiseWithProps(baseClass.key, async () => baseClass);

const result = Rules.abstractClassWithNonAbstractBase(entityClass);
expect(result).not.undefined;
let resultHasEntries = false;
for await (const diagnostic of result) {
resultHasEntries = true;
expect(diagnostic.ecDefinition).to.equal(entityClass);
expect(diagnostic.messageArgs).to.eql([entityClass.fullName, baseClass.fullName]);
expect(diagnostic.category).to.equal(DiagnosticCategory.Error);
expect(diagnostic.code).to.equal(Rules.DiagnosticCodes.AbstractClassWithNonAbstractBase);
expect(diagnostic.diagnosticType).to.equal(DiagnosticType.SchemaItem);
}
expect(resultHasEntries, "expected rule to return an AsyncIterable with entries.").to.be.true;
});

it("AbstractClassWithNonAbstractBase, no base class, rule passes.", async () => {
const entityClass = new EntityClass(schema, "TestClass", ECClassModifier.Abstract);

const result = Rules.abstractClassWithNonAbstractBase(entityClass);
for await (const _diagnostic of result) {
expect(false, "Rule should have passed").to.be.true;
}
});

it("AbstractClassWithNonAbstractBase, base class is abstract, rule passes.", async () => {
const baseClass = new EntityClass(schema, "TestBase", ECClassModifier.Abstract);
const entityClass = new EntityClass(schema, "TestClass", ECClassModifier.Abstract);
entityClass.baseClass = new DelayedPromiseWithProps(baseClass.key, async () => baseClass);

const result = Rules.abstractClassWithNonAbstractBase(entityClass);
for await (const _diagnostic of result) {
expect(false, "Rule should have passed").to.be.true;
}
});

it("AbstractClassWithNonAbstractBase, class is not abstract, rule passes.", async () => {
const baseClass = new EntityClass(schema, "TestBase", ECClassModifier.Sealed);
const entityClass = new EntityClass(schema, "TestClass", ECClassModifier.None);
entityClass.baseClass = new DelayedPromiseWithProps(baseClass.key, async () => baseClass);

const result = Rules.abstractClassWithNonAbstractBase(entityClass);
for await (const _diagnostic of result) {
expect(false, "Rule should have passed").to.be.true;
}
});
});

0 comments on commit 7b3d0f6

Please sign in to comment.