Skip to content

Commit

Permalink
adequately resolve source/target set impl with unknown mapping include
Browse files Browse the repository at this point in the history
  • Loading branch information
akphi committed May 28, 2023
1 parent 846b9ac commit 2083aee
Show file tree
Hide file tree
Showing 11 changed files with 136 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
type AggregationAwareSetImplementation,
type PropertyMapping,
type InstanceSetImplementation,
type TEMPORARY__UnresolvedSetImplementation,
type INTERNAL__UnresolvedSetImplementation,
type Mapping,
getAllClassMappings,
PurePropertyMapping,
Expand Down Expand Up @@ -652,8 +652,8 @@ export class MappingElementDecorator implements SetImplementationVisitor<void> {
}
}

visit_TEMPORARY__UnresolvedSetImplementation(
setImplementation: TEMPORARY__UnresolvedSetImplementation,
visit_INTERNAL__UnresolvedSetImplementation(
setImplementation: INTERNAL__UnresolvedSetImplementation,
): void {
return;
}
Expand Down Expand Up @@ -799,8 +799,8 @@ export class MappingElementDecorationCleaner
}
}

visit_TEMPORARY__UnresolvedSetImplementation(
setImplementation: TEMPORARY__UnresolvedSetImplementation,
visit_INTERNAL__UnresolvedSetImplementation(
setImplementation: INTERNAL__UnresolvedSetImplementation,
): void {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,6 @@
&__workspace {
flex-direction: column;
}

&__project-name__input {
flex: 1 0 auto;
background: var(--color-dark-grey-280);
color: var(--color-light-grey-200);
border-radius: 0 0.2rem 0.2rem 0;
height: 3rem;
padding: 1rem;
}

&__workspace-name__input {
flex: 1 0 auto;
background: var(--color-dark-grey-280);
color: var(--color-light-grey-200);
border-radius: 0 0.2rem 0.2rem 0;
height: 3rem;
padding: 1rem;
margin-top: 1rem;
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ import type {
import type { SetImplementationContainer } from '../../../graph/metamodel/pure/packageableElements/mapping/SetImplementationContainer.js';
import type { SetImplementationReference } from '../../../graph/metamodel/pure/packageableElements/mapping/SetImplementationReference.js';
import type { SubstituteStore } from '../../../graph/metamodel/pure/packageableElements/mapping/SubstituteStore.js';
import type { TEMPORARY__UnresolvedSetImplementation } from '../../../graph/metamodel/pure/packageableElements/mapping/TEMPORARY__UnresolvedSetImplementation.js';
import type { INTERNAL__UnresolvedSetImplementation } from '../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnresolvedSetImplementation.js';
import type { XStorePropertyMapping } from '../../../graph/metamodel/pure/packageableElements/mapping/xStore/XStorePropertyMapping.js';
import type { PackageableRuntime } from '../../../graph/metamodel/pure/packageableElements/runtime/PackageableRuntime.js';
import {
Expand Down Expand Up @@ -714,8 +714,8 @@ class SetImplementationObserver implements SetImplementationVisitor<void> {
// TODO
}

visit_TEMPORARY__UnresolvedSetImplementation(
setImplementation: TEMPORARY__UnresolvedSetImplementation,
visit_INTERNAL__UnresolvedSetImplementation(
setImplementation: INTERNAL__UnresolvedSetImplementation,
): void {
return;
}
Expand Down Expand Up @@ -920,6 +920,7 @@ export const observe_Mapping = skipObservedWithContext(
_elementHashCode: override,
});

// TODO: create extension mechanism to observe mapping includes when we build editor for this
metamodel.includes.forEach(observe_MappingInclude);
metamodel.classMappings.forEach((classMapping) =>
observe_SetImplementation(classMapping, context),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ import type { SubstituteStore } from '../../../../../../../graph/metamodel/pure/
import { V1_BindingTransformer } from '../../../model/packageableElements/externalFormat/store/V1_DSL_ExternalFormat_BindingTransformer.js';
import { V1_MergeOperationClassMapping } from '../../../model/packageableElements/mapping/V1_MergeOperationClassMapping.js';
import { MergeOperationSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/MergeOperationSetImplementation.js';
import type { TEMPORARY__UnresolvedSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/TEMPORARY__UnresolvedSetImplementation.js';
import type { INTERNAL__UnresolvedSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnresolvedSetImplementation.js';
import { isStubbed_EnumValueMapping } from '../../../../../../../graph/helpers/creator/DSL_Mapping_ModelCreatorHelper.js';
import { isStubbed_RawLambda } from '../../../../../../../graph/helpers/creator/RawValueSpecificationCreatorHelper.js';
import { isStubbed_RawRelationalOperationElement } from '../../../../../../../graph/helpers/creator/STO_Relational_ModelCreatorHelper.js';
Expand Down Expand Up @@ -1353,8 +1353,8 @@ export class V1_SetImplementationTransformer
*
* @discrepancy graph-building
*/
visit_TEMPORARY__UnresolvedSetImplementation(
setImplementation: TEMPORARY__UnresolvedSetImplementation,
visit_INTERNAL__UnresolvedSetImplementation(
setImplementation: INTERNAL__UnresolvedSetImplementation,
): V1_ClassMapping | undefined {
throw new IllegalStateError(
`Can't transform unresolved set implementation. This type of set implementation should only show up in references.`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ import { V1_transformRelationalOperationElement } from '../from/V1_DatabaseTrans
import { V1_GraphTransformerContextBuilder } from '../from/V1_GraphTransformerContext.js';
import {
getAllEnumerationMappings,
getAllIncludedMappings,
getClassMappingById,
getClassMappingsByClass,
} from '../../../../../../../graph/helpers/DSL_Mapping_Helper.js';
Expand All @@ -90,7 +91,7 @@ import type { AbstractProperty } from '../../../../../../../graph/metamodel/pure
import { BindingTransformer } from '../../../../../../../graph/metamodel/pure/packageableElements/externalFormat/store/DSL_ExternalFormat_BindingTransformer.js';
import type { Mapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/Mapping.js';
import { V1_resolveBinding } from './V1_DSL_ExternalFormat_GraphBuilderHelper.js';
import { TEMPORARY__UnresolvedSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/TEMPORARY__UnresolvedSetImplementation.js';
import { INTERNAL__UnresolvedSetImplementation } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnresolvedSetImplementation.js';
import {
getAssociatedPropertyClass,
getOwnProperty,
Expand All @@ -103,44 +104,52 @@ import type { V1_FlatDataAssociationPropertyMapping } from '../../../model/packa
import { FlatDataAssociationPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/store/flatData/mapping/FlatDataAssociationPropertyMapping.js';
import type { V1_INTERNAL__UnknownPropertyMapping } from '../../../model/packageableElements/mapping/V1_INTERNAL__UnknownPropertyMapping.js';
import { INTERNAL__UnknownPropertyMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__UnknownPropertyMapping.js';
import { INTERNAL__PseudoMapping } from '../../../../../../../graph/metamodel/pure/packageableElements/mapping/INTERNAL__PseudoMapping.js';

const TEMPORARY__getClassMappingByIdOrReturnUnresolved = (
const TEMPORARY__resolveSetImplementationByID = (
mapping: Mapping,
id: string,
context: V1_GraphBuilderContext,
): SetImplementation => {
const classMapping = returnUndefOnError(() =>
getClassMappingById(mapping, id),
);
const isMappingWithUnknownMappingIncludes = getAllIncludedMappings(
mapping,
).includes(INTERNAL__PseudoMapping.INSTANCE);

if (!classMapping) {
const message = `Can't find class mapping with ID '${id}' in mapping '${mapping.path}'`;
/**
* In strict-mode, graph builder will consider this as an error
* If the mapping has unknown mapping includes, this kind of problems
* might be due to the fact that the class mapping is not reachable due to the system
* not knowing how to analyze the unknown mapping include, as such, we will not throw
* errors, otherwise, we should in strict-mode
*
* See https://github.com/finos/legend-studio/issues/880
* See https://github.com/finos/legend-studio/issues/941
*
* @discrepancy graph-building
*/
if (context.options?.strict) {
if (context.options?.strict && !isMappingWithUnknownMappingIncludes) {
throw new GraphBuilderError(message);
}
context.logService.warn(LogEvent.create(message));
return new TEMPORARY__UnresolvedSetImplementation(id, mapping);
return new INTERNAL__UnresolvedSetImplementation(id, mapping);
}

return classMapping;
};

const resolvePropertyMappingSource = (
const resolvePropertyMappingSourceImplementation = (
immediateParent: PropertyMappingsImplementation,
value: V1_PropertyMapping,
topParent: InstanceSetImplementation | undefined,
context: V1_GraphBuilderContext,
): SetImplementation | undefined => {
if (immediateParent instanceof AssociationImplementation) {
if (value.source) {
return TEMPORARY__getClassMappingByIdOrReturnUnresolved(
return TEMPORARY__resolveSetImplementationByID(
immediateParent._PARENT,
value.source,
context,
Expand Down Expand Up @@ -278,12 +287,11 @@ export class V1_PropertyMappingBuilder
const topParent = guaranteeNonNullable(this.topParent);
if (propertyType instanceof Class) {
if (protocol.target) {
targetSetImplementation =
TEMPORARY__getClassMappingByIdOrReturnUnresolved(
topParent._PARENT,
protocol.target,
this.context,
);
targetSetImplementation = TEMPORARY__resolveSetImplementationByID(
topParent._PARENT,
protocol.target,
this.context,
);
} else {
// NOTE: if no there is one non-root class mapping, auto-nominate that as the target set implementation
targetSetImplementation = getClassMappingsByClass(
Expand All @@ -293,7 +301,7 @@ export class V1_PropertyMappingBuilder
}
}
const sourceSetImplementation = protocol.source
? TEMPORARY__getClassMappingByIdOrReturnUnresolved(
? TEMPORARY__resolveSetImplementationByID(
topParent._PARENT,
protocol.source,
this.context,
Expand Down Expand Up @@ -385,7 +393,7 @@ export class V1_PropertyMappingBuilder
const propertyType = property.genericType.value.rawType;
if (propertyType instanceof Class && protocol.target) {
targetSetImplementation = this.topParent
? TEMPORARY__getClassMappingByIdOrReturnUnresolved(
? TEMPORARY__resolveSetImplementationByID(
this.topParent._PARENT,
protocol.target,
this.context,
Expand Down Expand Up @@ -615,7 +623,7 @@ export class V1_PropertyMappingBuilder
}
if (protocol.target) {
targetSetImplementation = parentMapping
? TEMPORARY__getClassMappingByIdOrReturnUnresolved(
? TEMPORARY__resolveSetImplementationByID(
parentMapping,
protocol.target,
this.context,
Expand All @@ -631,7 +639,7 @@ export class V1_PropertyMappingBuilder
}
}
const sourceSetImplementation = guaranteeNonNullable(
resolvePropertyMappingSource(
resolvePropertyMappingSourceImplementation(
this.immediateParent,
protocol,
this.topParent,
Expand Down Expand Up @@ -757,12 +765,11 @@ export class V1_PropertyMappingBuilder
const parentMapping = this.immediateParent._PARENT;

if (protocol.target) {
targetSetImplementation =
TEMPORARY__getClassMappingByIdOrReturnUnresolved(
parentMapping,
protocol.target,
this.context,
);
targetSetImplementation = TEMPORARY__resolveSetImplementationByID(
parentMapping,
protocol.target,
this.context,
);
} else {
targetSetImplementation = getClassMappingsByClass(
parentMapping,
Expand All @@ -771,7 +778,7 @@ export class V1_PropertyMappingBuilder
}
}
const sourceSetImplementation = guaranteeNonNullable(
resolvePropertyMappingSource(
resolvePropertyMappingSourceImplementation(
this.immediateParent,
protocol,
this.topParent,
Expand Down Expand Up @@ -869,12 +876,11 @@ export class V1_PropertyMappingBuilder
InferableMappingElementIdExplicitValue.create(id, ''),
undefined,
);
inline.inlineSetImplementation =
TEMPORARY__getClassMappingByIdOrReturnUnresolved(
topParent._PARENT,
protocol.setImplementationId,
this.context,
);
inline.inlineSetImplementation = TEMPORARY__resolveSetImplementationByID(
topParent._PARENT,
protocol.setImplementationId,
this.context,
);
return inline;
}

Expand Down Expand Up @@ -1043,12 +1049,30 @@ export class V1_PropertyMappingBuilder
const _association = xStoreParent.association.value;
const property = getOwnProperty(_association, protocol.property.property);
const sourceSetImplementation = guaranteeNonNullable(
this.allClassMappings.find((c) => c.id.value === protocol.source),
`Can't find XStore property mapping source implementation with ID '${protocol.source}'`,
);
const targetSetImplementation = this.allClassMappings.find(
(c) => c.id.value === protocol.target,
resolvePropertyMappingSourceImplementation(
this.immediateParent,
protocol,
this.topParent,
this.context,
),
);
let targetSetImplementation: SetImplementation | undefined;
const propertyType = property.genericType.value.rawType;
if (propertyType instanceof Class) {
const parentMapping = this.immediateParent._PARENT;
if (protocol.target) {
targetSetImplementation = TEMPORARY__resolveSetImplementationByID(
parentMapping,
protocol.target,
this.context,
);
} else {
targetSetImplementation = getClassMappingsByClass(
parentMapping,
guaranteeType(propertyType, Class),
)[0];
}
}
const xStorePropertyMapping = new XStorePropertyMapping(
xStoreParent,
PropertyImplicitReference.create(
Expand Down Expand Up @@ -1106,12 +1130,32 @@ export class V1_PropertyMappingBuilder
propertyMapping?.property ??
this.context.resolveProperty(protocol.property);

const sourceSetImplementation = this.allClassMappings.find(
(c) => c.id.value === protocol.source,
);
const targetSetImplementation = this.allClassMappings.find(
(c) => c.id.value === protocol.target,
const sourceSetImplementation = guaranteeNonNullable(
resolvePropertyMappingSourceImplementation(
this.immediateParent,
protocol,
this.topParent,
this.context,
),
);
let targetSetImplementation: SetImplementation | undefined;
const propertyType = property.value.genericType.value.rawType;
if (propertyType instanceof Class) {
const parentMapping = this.immediateParent._PARENT;

if (protocol.target) {
targetSetImplementation = TEMPORARY__resolveSetImplementationByID(
parentMapping,
protocol.target,
this.context,
);
} else {
targetSetImplementation = getClassMappingsByClass(
parentMapping,
guaranteeType(propertyType, Class),
)[0];
}
}

const aggregationAwarePropertyMapping = new AggregationAwarePropertyMapping(
this.topParent ?? this.immediateParent,
Expand Down
Loading

0 comments on commit 2083aee

Please sign in to comment.