Skip to content

Commit 5de1c92

Browse files
Add support for annotations for Columns and ColSpecs (#1190)
* Add support for stereotypes and tagged values to Columns/ColSpecs * fix: Fix setting stereotypesCoreInstance * feat: Add colSpec function that takes Column param * feat: Add new function signature to FunctionExpressionProcessor * feat: Add TestColSpecAnnotations * feat: Call new colSpec method if column has stereotypes/tagged values * feat: Add tests for col spec * feat: Add test to TestColSpecAnnotations * feat: Try not overloading the colSpec function * refactor: Make separate generateStereotypesBuilder and generateTaggedValuesBuilder functions * feat: Update TestColSpecAnnotations * fix: Fix processing tagged values in _Column * feat: Add tests to TestColSpecAnnotations * feat: Add overloaded getColumnInstance function that takes string type * feat: Remove extends AnnotatedElement from ColSpec class * fix: Remove unused import * feat: Feedback from comments * refactor: Update to getUserPathForPackageableElement * fix: Resolve import stubs in _RelationType * feat: Update getColumnInstance functions to handle resolved import stubs * fix: Fix paths in GenericTypeSerializationInCode * fix: Set assumeNoImportStubs flag to true * fix: Uncomment tests * fix: Update GenericType functions to pass stereotypes and tagged values * fix: Propagate stereotypes/tagged values wherever _Column.getColumnInstance is used * fix: Ensure correct passing of _stereotypes()/_stereotypesCoreInstance() * refactor: Re-add overloaded function calls * refactor: Add docs to getColumnInstance * fix: Add missing package * fix: Change to using _stereotypes() in GenericType * fix: Remove stereotypes/taggeed value passing in TDSExtension * refactor: Make separate function names for compiled vs. interpreted * Revert "refactor: Make separate function names for compiled vs. interpreted" This reverts commit 05b4cae. * refactor: Remove assumeNoImportStubs param * fix: Merge stereotypes/tagged values in merge function * fix: Ensure only distinct stereotypes/tagged values * fix: Use _stereotypes instead of _stereotypesCoreInstance in merge function
1 parent f3c8d7a commit 5de1c92

File tree

18 files changed

+534
-14
lines changed

18 files changed

+534
-14
lines changed

legend-pure-core/legend-pure-m3-core/src/main/antlr4/org/finos/legend/pure/m3/serialization/grammar/m3parser/antlr/core/M3CoreParser.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ atomicExpression:
315315

316316
columnBuilders: TILDE (oneColSpec | (BRACKET_OPEN (oneColSpec(COMMA oneColSpec)*)? BRACKET_CLOSE))
317317
;
318-
oneColSpec: columnName (COLON (type multiplicity? | anyLambda) extraFunction?)?
318+
oneColSpec: stereotypes? taggedValues? columnName (COLON (type multiplicity? | anyLambda) extraFunction?)?
319319
;
320320
extraFunction: (COLON anyLambda)
321321
;

legend-pure-core/legend-pure-m3-core/src/main/java/org/finos/legend/pure/m3/compiler/postprocessing/processor/valuespecification/FunctionExpressionProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ private static boolean manageMagicColumnFunctions(FunctionExpression functionExp
407407
}
408408
else
409409
{
410-
ctx.register((GenericType) processorSupport.function_getFunctionType(foundFunction).getValueForMetaPropertyToMany("parameters").get(1).getValueForMetaPropertyToOne("genericType"), (GenericType) processorSupport.type_wrapGenericType(_RelationType.build(found.collect(foundC -> _Column.getColumnInstance(foundC._name(), false, _Column.getColumnType(foundC), _Column.getColumnMultiplicity(foundC), functionExpression.getSourceInformation(), processorSupport)), functionExpression.getSourceInformation(), processorSupport)), ctx, observer);
410+
ctx.register((GenericType) processorSupport.function_getFunctionType(foundFunction).getValueForMetaPropertyToMany("parameters").get(1).getValueForMetaPropertyToOne("genericType"), (GenericType) processorSupport.type_wrapGenericType(_RelationType.build(found.collect(foundC -> _Column.getColumnInstance(foundC._name(), false, _Column.getColumnType(foundC), _Column.getColumnMultiplicity(foundC), foundC._stereotypesCoreInstance(), foundC._taggedValues(), functionExpression.getSourceInformation(), processorSupport)), functionExpression.getSourceInformation(), processorSupport)), ctx, observer);
411411
columnTypeInferenceSuccess = true;
412412
}
413413
}
@@ -481,7 +481,7 @@ private static boolean manageMagicColumnFunctions(FunctionExpression functionExp
481481
}
482482
else
483483
{
484-
ctx.register((GenericType) processorSupport.function_getFunctionType(foundFunction).getValueForMetaPropertyToMany("parameters").get(1).getValueForMetaPropertyToOne("genericType"), (GenericType) processorSupport.type_wrapGenericType(_RelationType.build(found.collect(foundC -> _Column.getColumnInstance(foundC._name(), false, _Column.getColumnType(foundC), _Column.getColumnMultiplicity(foundC), functionExpression.getSourceInformation(), processorSupport)), functionExpression.getSourceInformation(), processorSupport)), ctx, observer);
484+
ctx.register((GenericType) processorSupport.function_getFunctionType(foundFunction).getValueForMetaPropertyToMany("parameters").get(1).getValueForMetaPropertyToOne("genericType"), (GenericType) processorSupport.type_wrapGenericType(_RelationType.build(found.collect(foundC -> _Column.getColumnInstance(foundC._name(), false, _Column.getColumnType(foundC), _Column.getColumnMultiplicity(foundC), foundC._stereotypesCoreInstance(), foundC._taggedValues(), functionExpression.getSourceInformation(), processorSupport)), functionExpression.getSourceInformation(), processorSupport)), ctx, observer);
485485
columnTypeInferenceSuccess = true;
486486
}
487487
}

legend-pure-core/legend-pure-m3-core/src/main/java/org/finos/legend/pure/m3/navigation/generictype/GenericType.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ public static CoreInstance makeTypeArgumentAsConcreteAsPossible(CoreInstance typ
153153
c._nameWildCard(),
154154
(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) makeTypeArgumentAsConcreteAsPossible(_Column.getColumnType(c), filteredGenericTypeByTypeParameterNames, sourceMulBinding, processorSupport),
155155
_Column.getColumnMultiplicity(c),
156+
c._stereotypes(),
157+
c._taggedValues(),
156158
c.getSourceInformation(),
157159
processorSupport
158160
),
@@ -283,7 +285,7 @@ private static org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.ge
283285

284286
// Set RelationType on Generic
285287
return ((org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) processorSupport.newGenericType(null, operation, true))
286-
._rawType(_RelationType.build(newColumnSet.collect(c -> _Column.getColumnInstance(c._name(), c._nameWildCard(), _Column.getColumnType(c), _Column.getColumnMultiplicity(c), c.getSourceInformation(), processorSupport)), gLeft._rawType().getSourceInformation(), processorSupport));
288+
._rawType(_RelationType.build(newColumnSet.collect(c -> _Column.getColumnInstance(c._name(), c._nameWildCard(), _Column.getColumnType(c), _Column.getColumnMultiplicity(c), c._stereotypes(), c._taggedValues(), c.getSourceInformation(), processorSupport)), gLeft._rawType().getSourceInformation(), processorSupport));
287289
}
288290

289291
@Deprecated
@@ -1313,6 +1315,8 @@ else if (_RelationType.isRelationType(type, processorSupport))
13131315
c._nameWildCard(),
13141316
(org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.generics.GenericType) copyGenericType(_Column.getColumnType(c), replaceSourceInfo, newSourceInfo, processorSupport, inferred),
13151317
_Column.getColumnMultiplicity(c),
1318+
c._stereotypes(),
1319+
c._taggedValues(),
13161320
replaceSourceInfo ? newSourceInfo : src.getSourceInformation(),
13171321
processorSupport
13181322
),

legend-pure-core/legend-pure-m3-core/src/main/java/org/finos/legend/pure/m3/navigation/relation/_Column.java

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414

1515
package org.finos.legend.pure.m3.navigation.relation;
1616

17-
import java.util.Objects;
17+
import org.eclipse.collections.api.RichIterable;
1818
import org.eclipse.collections.api.factory.Lists;
19+
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.Stereotype;
20+
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.TaggedValue;
1921
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity;
2022
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.Column;
2123
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.type.Type;
@@ -34,6 +36,16 @@
3436
public class _Column
3537
{
3638
public static Column<?, ?> getColumnInstance(String name, boolean nameWildCard, String type, Multiplicity multiplicity, SourceInformation src, ProcessorSupport processorSupport)
39+
{
40+
return getColumnInstance(name, nameWildCard, type, multiplicity, null, null, src, processorSupport);
41+
}
42+
43+
public static Column<?, ?> getColumnInstance(String name, boolean nameWildCard, GenericType targetType, Multiplicity multiplicity, SourceInformation sourceInformation, ProcessorSupport processorSupport)
44+
{
45+
return getColumnInstance(name, nameWildCard, targetType, multiplicity, null, null, sourceInformation, processorSupport);
46+
}
47+
48+
public static Column<?, ?> getColumnInstance(String name, boolean nameWildCard, String type, Multiplicity multiplicity, RichIterable<? extends CoreInstance> stereotypes, RichIterable<? extends TaggedValue> taggedValues, SourceInformation src, ProcessorSupport processorSupport)
3749
{
3850
GenericType target = (GenericType) processorSupport.newAnonymousCoreInstance(src, M3Paths.GenericType);
3951
if (type == null)
@@ -49,10 +61,22 @@ public class _Column
4961
}
5062
target._rawType((Type)_type);
5163
}
52-
return _Column.getColumnInstance(name, nameWildCard, target, multiplicity, src, processorSupport);
64+
return _Column.getColumnInstance(name, nameWildCard, target, multiplicity, stereotypes, taggedValues, src, processorSupport);
5365
}
5466

55-
public static Column<?, ?> getColumnInstance(String name, boolean nameWildCard, GenericType targetType, org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity multiplicity, SourceInformation sourceInformation, ProcessorSupport processorSupport)
67+
/**
68+
* Create a Column instance with the given parameters. The targetType is expected to be a GenericType with the raw type of Column and one type argument for the column type. The multiplicity is expected to be the multiplicity argument for the column generic type.
69+
* @param name the column name, which may be a wildcard (e.g. "?") if nameWildCard is true. If the name is quoted, the quotes will be removed.
70+
* @param nameWildCard indicates whether the name is a wildcard. If true, the name will be treated as a wildcard and the column will match any name. If false, the name will be treated as a literal name.
71+
* @param targetType the generic type for the column.
72+
* @param multiplicity the multiplicity for the column.
73+
* @param stereotypes the stereotypes to apply to the column.
74+
* @param taggedValues the tagged values to apply to the column.
75+
* @param sourceInformation the source information for the column instance, used for error reporting and debugging.
76+
* @param processorSupport the processor support used for creating the column instance.
77+
* @return a Column instance with the specified properties and metadata.
78+
*/
79+
public static Column<?, ?> getColumnInstance(String name, boolean nameWildCard, GenericType targetType, Multiplicity multiplicity, RichIterable<? extends CoreInstance> stereotypes, RichIterable<? extends TaggedValue> taggedValues, SourceInformation sourceInformation, ProcessorSupport processorSupport)
5680
{
5781
Column<?, ?> columnInstance = (Column<?, ?>) processorSupport.newAnonymousCoreInstance(sourceInformation, M3Paths.Column);
5882
columnInstance._name(StringEscape.unescape(removeQuotes(name)));
@@ -63,6 +87,21 @@ public class _Column
6387
columnGenericType._typeArguments(Lists.mutable.with(null, targetType));
6488
columnGenericType._multiplicityArgumentsAdd(multiplicity);
6589
columnInstance.setKeyValues(M3PropertyPaths.classifierGenericType, Lists.mutable.with(columnGenericType));
90+
if (stereotypes != null && stereotypes.notEmpty())
91+
{
92+
if (stereotypes.allSatisfy(s -> s instanceof Stereotype))
93+
{
94+
columnInstance._stereotypes(ListHelper.wrapListIterable(stereotypes).selectInstancesOf(Stereotype.class));
95+
}
96+
else
97+
{
98+
columnInstance._stereotypesCoreInstance(stereotypes);
99+
}
100+
}
101+
if (taggedValues != null && taggedValues.notEmpty())
102+
{
103+
columnInstance._taggedValues(taggedValues);
104+
}
66105
return columnInstance;
67106
}
68107

legend-pure-core/legend-pure-m3-core/src/main/java/org/finos/legend/pure/m3/navigation/relation/_RelationType.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.eclipse.collections.api.set.MutableSet;
2525
import org.eclipse.collections.api.tuple.Pair;
2626
import org.eclipse.collections.impl.tuple.Tuples;
27+
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.Stereotype;
28+
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.extension.TaggedValue;
2729
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.Function;
2830
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.FunctionAccessor;
2931
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.Column;
@@ -225,7 +227,13 @@ public static GenericType merge(GenericType existingGenericType, GenericType gen
225227
Type rawTypeB = (Type) Instance.getValueForMetaPropertyToOneResolved(b, M3Properties.rawType, processorSupport);
226228
GenericType merged = rawTypeA == null ? b : rawTypeB == null ? a : (GenericType) org.finos.legend.pure.m3.navigation.generictype.GenericType.findBestCommonGenericType(Lists.mutable.with(a, b), isCovariant, false, genericTypeCopy.getSourceInformation(), processorSupport);
227229
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity mergedMul = rawTypeA == null ? _Column.getColumnMultiplicity(c.getTwo()) : rawTypeB == null ? _Column.getColumnMultiplicity(c.getOne()) : (org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity) Multiplicity.minSubsumingMultiplicity(_Column.getColumnMultiplicity(c.getOne()), _Column.getColumnMultiplicity(c.getTwo()), processorSupport);
228-
return _Column.getColumnInstance(cName, wildcard, merged, mergedMul, null, processorSupport);
230+
RichIterable<? extends Stereotype> stereotypesA = c.getOne()._stereotypes() == null ? Lists.mutable.empty() : c.getOne()._stereotypes();
231+
RichIterable<? extends Stereotype> stereotypesB = c.getTwo()._stereotypes() == null ? Lists.mutable.empty() : c.getTwo()._stereotypes();
232+
RichIterable<? extends Stereotype> mergedStereotypes = Lists.mutable.<Stereotype>withAll(stereotypesA).withAll(stereotypesB).distinct();
233+
RichIterable<? extends TaggedValue> taggedValuesA = c.getOne()._taggedValues() == null ? Lists.mutable.empty() : c.getOne()._taggedValues();
234+
RichIterable<? extends TaggedValue> taggedValuesB = c.getTwo()._taggedValues() == null ? Lists.mutable.empty() : c.getTwo()._taggedValues();
235+
RichIterable<? extends TaggedValue> mergedTaggedValues = Lists.mutable.<TaggedValue>withAll(taggedValuesA).withAll(taggedValuesB).distinctBy(TaggedValue::_tagCoreInstance);
236+
return _Column.getColumnInstance(cName, wildcard, merged, mergedMul, mergedStereotypes, mergedTaggedValues, null, processorSupport);
229237
}),
230238
existingGenericType.getValueForMetaPropertyToOne(M3Properties.rawType).getSourceInformation(),
231239
processorSupport
@@ -256,6 +264,8 @@ public static void resolveImportStubs(CoreInstance relationType, ProcessorSuppor
256264
{
257265
relationType.getValueForMetaPropertyToMany(M3Properties.columns).forEach(c ->
258266
{
267+
c.getValueForMetaPropertyToMany(M3Properties.stereotypes).forEach(s -> ImportStub.withImportStubByPass(s, processorSupport));
268+
c.getValueForMetaPropertyToMany(M3Properties.taggedValues).forEach(tv -> ImportStub.withImportStubByPass(tv.getValueForMetaPropertyToOne(M3Properties.tag), processorSupport));
259269
CoreInstance classifierGenericType = c.getValueForMetaPropertyToOne(M3Properties.classifierGenericType);
260270
classifierGenericType.getValueForMetaPropertyToMany(M3Properties.multiplicityArguments).forEach(arg -> ImportStub.withImportStubByPass(arg, processorSupport));
261271
// the first type argument of the column type is the relation type itself: we skip it to avoid infinite recursion

legend-pure-core/legend-pure-m3-core/src/main/java/org/finos/legend/pure/m3/serialization/grammar/m3parser/antlr/AntlrContextToM3CoreInstance.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.Multiplicity;
7878
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.MultiplicityInstance;
7979
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.multiplicity.MultiplicityValueInstance;
80+
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.Column;
8081
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.GenericTypeOperationInstance;
8182
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relation.RelationType;
8283
import org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.relationship.Association;
@@ -950,6 +951,11 @@ else if (ctx.columnBuilders() != null)
950951
columnNames.add(this.repository.newStringCoreInstance(colName));
951952
GenericType returnType = null;
952953
Multiplicity multiplicity = (Multiplicity) org.finos.legend.pure.m3.navigation.multiplicity.Multiplicity.newMultiplicity(0, 1, processorSupport);
954+
955+
// Extract stereotypes and tagged values
956+
RichIterable<? extends CoreInstance> stereotypes = (oneColSpec.stereotypes() == null) ? null : stereotypes(oneColSpec.stereotypes(), importId);
957+
RichIterable<? extends TaggedValue> taggedValues = (oneColSpec.taggedValues() == null) ? null : taggedValues(oneColSpec.taggedValues(), importId);
958+
953959
if (oneColSpec.anyLambda() != null)
954960
{
955961
lambdas.add(processLambda(oneColSpec.anyLambda(), Lists.mutable.empty(), Lists.mutable.empty(), lambdaContext, importId, space, addLines, false, Lists.mutable.empty()));
@@ -972,7 +978,7 @@ else if (oneColSpec.type() != null)
972978
returnType = (GenericType) processorSupport.newAnonymousCoreInstance(src, M3Paths.GenericType);
973979
returnType._rawType(null);
974980
}
975-
columnInstances.add(_Column.getColumnInstance(colName, false, returnType, multiplicity, src, processorSupport));
981+
columnInstances.add(_Column.getColumnInstance(colName, false, returnType, multiplicity, stereotypes, taggedValues, src, processorSupport));
976982
});
977983
RelationType<?> relationType = _RelationType.build(columnInstances, this.sourceInformation.getPureSourceInformation(ctx.getStart(), ctx.getStart(), ctx.getStop()), processorSupport);
978984
GenericType relationTypeGenericType = (GenericType) processorSupport.type_wrapGenericType(relationType);

0 commit comments

Comments
 (0)