Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to merge format #7595

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/ecschema-editing/src/Differencing/SchemaConflicts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export enum ConflictCode {
ConflictingEnumerationType = "C-700",
ConflictingEnumeratorValue = "C-701",

ConflictingFormatUnit = "C-800",
ConflictingFormatUnitPhenomenon = "C-801",

ConflictingPersistenceUnit = "C-1010",
MixinAppliedMustDeriveFromConstraint = "C-1100",

Expand Down Expand Up @@ -109,6 +112,8 @@ export type AnySchemaDifferenceConflict =
SchemaDifferenceConflict<ConflictCode.ConflictingPropertyName, SchemaOtherTypes.Property> |
SchemaDifferenceConflict<ConflictCode.ConflictingPropertyKindOfQuantity, SchemaOtherTypes.Property> |
SchemaDifferenceConflict<ConflictCode.ConflictingPropertyKindOfQuantityUnit, SchemaOtherTypes.Property> |
SchemaDifferenceConflict<ConflictCode.ConflictingFormatUnit, SchemaOtherTypes.FormatUnit> |
SchemaDifferenceConflict<ConflictCode.ConflictingFormatUnitPhenomenon, SchemaOtherTypes.FormatUnit> |
SchemaDifferenceConflict<ConflictCode.AbstractConstraintMustNarrowBaseConstraints, SchemaOtherTypes.RelationshipConstraint> |
SchemaDifferenceConflict<ConflictCode.DerivedConstraintsMustNarrowBaseConstraints, SchemaOtherTypes.RelationshipConstraint> |
SchemaDifferenceConflict<ConflictCode.ConstraintClassesDeriveFromAbstractConstraint, SchemaOtherTypes.RelationshipConstraint>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import type { AnyDiagnostic } from "../Validation/Diagnostic";
import { SchemaCompareCodes } from "../Validation/SchemaCompareDiagnostics";
import {
AnyEnumerator, AnyPropertyProps, AnySchemaItem, CustomAttribute, ECClass,
Enumeration, Format, KindOfQuantity, Mixin, OverrideFormat, Property, PropertyProps,
RelationshipConstraint, RelationshipConstraintProps, Schema, SchemaItem,
Enumeration, Format, InvertedUnit, KindOfQuantity, Mixin, OverrideFormat, Property, PropertyProps,
RelationshipConstraint, RelationshipConstraintProps, Schema, SchemaItem, Unit,
} from "@itwin/ecschema-metadata";
import {
type AnyClassItemDifference,
Expand All @@ -22,6 +22,7 @@ import {
type DifferenceType,
type EntityClassMixinDifference,
type EnumeratorDifference,
type FormatUnitDifference,
type KindOfQuantityPresentationFormatDifference,
type RelationshipConstraintClassDifference,
type RelationshipConstraintDifference,
Expand All @@ -39,7 +40,10 @@ import {
export class SchemaDiagnosticVisitor {

public readonly schemaDifferences: Array<SchemaDifference | SchemaReferenceDifference>;
public readonly schemaItemDifferences: Array<AnySchemaItemDifference | EntityClassMixinDifference | KindOfQuantityPresentationFormatDifference>;
public readonly schemaItemDifferences: Array<AnySchemaItemDifference
| EntityClassMixinDifference
| KindOfQuantityPresentationFormatDifference
| FormatUnitDifference>;
public readonly schemaItemPathDifferences: Array<AnySchemaItemPathDifference>;
public readonly customAttributeDifferences: Array<CustomAttributeDifference>;

Expand Down Expand Up @@ -107,10 +111,10 @@ export class SchemaDiagnosticVisitor {
case SchemaCompareCodes.PresentationUnitMissing:
return this.visitMissingPresentationUnit(diagnostic);

// Currently not handled...
case SchemaCompareCodes.FormatUnitMissing:
return this.visitMissingFormatUnit(diagnostic);
case SchemaCompareCodes.UnitLabelOverrideDelta:
break;
return this.visitChangedFormatUnitLabel(diagnostic);
}
return;
}
Expand Down Expand Up @@ -462,7 +466,61 @@ export class SchemaDiagnosticVisitor {
}
addEntry.difference.push(presentationFormat.fullName);
}
}

private visitMissingFormatUnit(diagnostic: AnyDiagnostic) {
const format = diagnostic.ecDefinition as Format;

for (let index = this.schemaItemPathDifferences.length-1; index>=0; index--) {
const entry = this.schemaItemPathDifferences[index];
if (entry.changeType === "modify" && entry.schemaType === SchemaOtherTypes.FormatUnitLabel && entry.itemName === format.name) {
this.schemaItemPathDifferences.splice(index, 1);
}
}

let modifyEntry = this.schemaItemDifferences.find((entry): entry is FormatUnitDifference => {
return entry.changeType === "modify" && entry.schemaType === SchemaOtherTypes.FormatUnit
&& entry.itemName === format.name;
});

if (modifyEntry === undefined && format.units) {
modifyEntry = {
changeType: "modify",
schemaType: SchemaOtherTypes.FormatUnit,
itemName: format.name,
difference: [],
};

for (const [unit, label] of format.units) {
modifyEntry.difference.push({
name: unit.fullName,
label,
});
};

this.schemaItemDifferences.push(modifyEntry);
}
}

private visitChangedFormatUnitLabel(diagnostic: AnyDiagnostic) {
const format = diagnostic.ecDefinition as Format;

if (this.schemaItemDifferences.find((entry): entry is FormatUnitDifference => { return entry.changeType === "modify"
&& entry.schemaType === SchemaOtherTypes.FormatUnit && entry.itemName === format.name})) {
return;
}

const [unit, label] = diagnostic.messageArgs as [Unit | InvertedUnit, string | undefined];
this.schemaItemPathDifferences.push({
changeType: "modify",
schemaType: SchemaOtherTypes.FormatUnitLabel,
itemName: format.name,
path: unit.fullName,
difference: {
label,
},
});
};
};

function isPropertyTypeName(property: Property, propertyName: string) {
return (propertyName === "type") ||
Expand Down
39 changes: 35 additions & 4 deletions core/ecschema-editing/src/Differencing/SchemaDifference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import { AnySchemaEdits, SchemaEditType } from "../Merging/Edits/SchemaEdits";
import { SchemaDiagnosticVisitor } from "./SchemaDiagnosticVisitor";
import { SchemaChanges } from "../Validation/SchemaChanges";
import { SchemaComparer } from "../Validation/SchemaComparer";
import {
AnyEnumerator, AnyProperty, AnyPropertyProps, ConstantProps, CustomAttribute,
import { AnyEnumerator, AnyProperty, AnyPropertyProps, ConstantProps, CustomAttribute,
CustomAttributeClassProps, ECClass, EntityClassProps, EnumerationProps, InvertedUnitProps, KindOfQuantityProps,
MixinProps, PhenomenonProps, PropertyCategoryProps, RelationshipClassProps, RelationshipConstraintProps,
type Schema, SchemaItem, SchemaItemFormatProps, SchemaItemKey, SchemaItemProps, SchemaItemType, SchemaItemUnitProps, SchemaReferenceProps, StructClassProps, UnitSystemProps,
Expand Down Expand Up @@ -55,6 +54,8 @@ export enum SchemaOtherTypes {
RelationshipConstraintClass = "RelationshipConstraintClass",
EntityClassMixin = "EntityClassMixin",
KindOfQuantityPresentationFormat = "KindOfQuantityPresentationFormat",
FormatUnit = "FormatUnit",
FormatUnitLabel = "FormatUnitLabel",
}

/**
Expand Down Expand Up @@ -91,7 +92,8 @@ export type AnySchemaDifference =
AnySchemaItemPathDifference |
EntityClassMixinDifference |
CustomAttributeDifference |
KindOfQuantityPresentationFormatDifference;
KindOfQuantityPresentationFormatDifference |
FormatUnitDifference;

/**
* Differencing entry for changes on a Schema.
Expand Down Expand Up @@ -152,7 +154,8 @@ export type AnySchemaItemPathDifference =
RelationshipConstraintClassDifference |
CustomAttributePropertyDifference |
EnumeratorDifference |
ClassPropertyDifference;
ClassPropertyDifference |
FormatUnitLabelDifference;

/**
* Internal base class for all Schema Item differencing entries.
Expand Down Expand Up @@ -404,6 +407,34 @@ export interface KindOfQuantityPresentationFormatDifference {
readonly difference: string[];
}

/**
* Differencing entry for changed Units on Formats.
* @alpha
*/
export interface FormatUnitDifference {
readonly changeType: "modify";
readonly schemaType: SchemaOtherTypes.FormatUnit;
readonly itemName: string;
readonly difference: {
name: string;
label?: string;
}[];
}

/**
* Differencing entry for changed labels on Format Units.
* @alpha
*/
export interface FormatUnitLabelDifference {
readonly changeType: "modify";
readonly schemaType: SchemaOtherTypes.FormatUnitLabel;
readonly itemName: string;
readonly path: string;
readonly difference: {
label?: string;
};
}

/**
* Creates a [[SchemaDifferenceResult]] for two given schemas.
* @param targetSchema The schema the differences gets merged into.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
* @module Differencing
*/

import { classModifierToString, ECClass, ECClassModifier, EntityClass, Enumeration, KindOfQuantity, LazyLoadedSchemaItem, Mixin, parseClassModifier, primitiveTypeToString, Property, propertyTypeToString, Schema, SchemaItem, SchemaItemKey, SchemaMatchType } from "@itwin/ecschema-metadata";
import { AnyClassItemDifference, AnySchemaDifference, AnySchemaItemDifference, ClassPropertyDifference, ConstantDifference, CustomAttributeClassDifference, CustomAttributeDifference, EntityClassDifference, EntityClassMixinDifference, EnumerationDifference, EnumeratorDifference, FormatDifference, InvertedUnitDifference, KindOfQuantityDifference, KindOfQuantityPresentationFormatDifference, MixinClassDifference, PhenomenonDifference, PropertyCategoryDifference, RelationshipClassDifference, RelationshipConstraintClassDifference, RelationshipConstraintDifference, SchemaDifference, SchemaReferenceDifference, StructClassDifference, UnitDifference, UnitSystemDifference } from "./SchemaDifference";
import { classModifierToString, ECClass, ECClassModifier, EntityClass, Enumeration, Format, InvertedUnit, KindOfQuantity, LazyLoadedSchemaItem, Mixin, parseClassModifier, primitiveTypeToString, Property, propertyTypeToString, Schema, SchemaItem, SchemaItemKey, SchemaItemType, SchemaMatchType, Unit } from "@itwin/ecschema-metadata";
import { AnyClassItemDifference, AnySchemaDifference, AnySchemaItemDifference, ClassPropertyDifference, ConstantDifference, CustomAttributeClassDifference, CustomAttributeDifference, EntityClassDifference, EntityClassMixinDifference, EnumerationDifference, EnumeratorDifference, FormatDifference, FormatUnitDifference, FormatUnitLabelDifference, InvertedUnitDifference, KindOfQuantityDifference, KindOfQuantityPresentationFormatDifference, MixinClassDifference, PhenomenonDifference, PropertyCategoryDifference, RelationshipClassDifference, RelationshipConstraintClassDifference, RelationshipConstraintDifference, SchemaDifference, SchemaReferenceDifference, StructClassDifference, UnitDifference, UnitSystemDifference } from "./SchemaDifference";
import { AnySchemaDifferenceConflict, ConflictCode } from "./SchemaConflicts";
import { SchemaDifferenceVisitor, SchemaDifferenceWalker } from "./SchemaDifferenceVisitor";
import { NameMapping, PropertyKey } from "../Merging/Edits/NameMapping";
Expand Down Expand Up @@ -477,6 +477,51 @@ class SchemaDifferenceValidationVisitor implements SchemaDifferenceVisitor {
public async visitKindOfQuantityPresentationFormatDifference(_entry: KindOfQuantityPresentationFormatDifference) {
}

/**
* Visitor implementation for handling FormatUnitDifference.
* @internal
*/
public async visitFormatUnitDifference(entry: FormatUnitDifference) {
const targetFormat = await this.getTargetSchemaItem(entry.itemName) as Format;

if (targetFormat.units === undefined) {
return this.addConflict({
code: ConflictCode.ConflictingFormatUnit,
difference: entry,
source: entry.difference[0].name,
target: null,
description: "The unit cannot be assiged if the format did not have a unit before.",
});
};

const targetUnit = targetFormat.units[0][0];
const targetPhenomenon = targetUnit.schemaItemType === SchemaItemType.InvertedUnit
? (await targetUnit.invertsUnit)?.phenomenon
: targetUnit.phenomenon;

const sourceUnit = await this._sourceSchema.lookupItem(entry.difference[0].name) as Unit | InvertedUnit;
const sourcePhenomenon = sourceUnit.schemaItemType === SchemaItemType.InvertedUnit
? (await sourceUnit.invertsUnit)?.phenomenon
: sourceUnit.phenomenon;

if (resolveLazyItemName(targetPhenomenon) !== resolveLazyItemName(sourcePhenomenon)) {
return this.addConflict({
code: ConflictCode.ConflictingFormatUnitPhenomenon,
difference: entry,
source: entry.difference[0].name,
target: targetUnit.fullName,
description: "Format units has a different phenomenon.",
});
};
};

/**
* Visitor implementation for handling FormatUnitLabelDifference.
* @internal
*/
public async visitFormatUnitLabelDifference(_entry: FormatUnitLabelDifference) {
}

/**
* Recursive synchronous function to figure whether a given class derived from
* a class with the given baseClass name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ export class SchemaDifferenceWalker {
return this._visitor.visitEnumeratorDifference(difference, index, array);
case SchemaItemType.Format:
return this._visitor.visitFormatDifference(difference, index, array);
case SchemaOtherTypes.FormatUnit:
return this._visitor.visitFormatUnitDifference(difference, index, array);
case SchemaOtherTypes.FormatUnitLabel:
return this._visitor.visitFormatUnitLabelDifference(difference, index, array);
case SchemaItemType.InvertedUnit:
return this._visitor.visitInvertedUnitDifference(difference, index, array);
case SchemaItemType.KindOfQuantity:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { Format, InvertedUnit, Unit } from "@itwin/ecschema-metadata";
import { FormatType, ShowSignOption } from "@itwin/core-quantity";
import { FormatTraits, FormatType, ScientificType, ShowSignOption } from "@itwin/core-quantity";

/**
* @internal
Expand All @@ -19,5 +19,12 @@ export abstract class MutableFormat extends Format {
public abstract override setThousandSeparator(separator: string): void;
public abstract override setUomSeparator(separator: string): void;
public abstract override setStationSeparator(separator: string): void;
public abstract override setMinWidth(minWidth: number): void;
public abstract override setStationOffsetSize(stationOffsetSize: number): void;
public abstract override setScientificType(scientificType: ScientificType): void;
public abstract override setSpacer(spacer: string): void;
public abstract override setIncludeZero(includeZero: boolean): void;
public abstract override setFormatTraits(formatTraits: FormatTraits): void;
public abstract override setUnits(units: Array<[Unit | InvertedUnit, string | undefined]>): void;
public abstract override setDisplayLabel(displayLabel: string): void;
}
Loading
Loading