Skip to content

Commit

Permalink
fix generate setFeature for refined references and attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
georghinkel committed Sep 13, 2024
1 parent b03ede2 commit bb570e5
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Models/Models/Meta/Reference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1119,6 +1119,11 @@ protected override void SetFeature(string feature, object value)
this.UpperBound = ((int)(value));
return;
}
if ((feature == "TYPE"))
{
((ITypedElement)(this)).Type = ((IType)(value));
return;
}
base.SetFeature(feature, value);
}

Expand Down
80 changes: 76 additions & 4 deletions Transformations/Models.MetaTransformation/Meta/Class2Type.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1005,8 +1005,20 @@ protected virtual CodeMemberMethod CreateSetFeature(IClass input, CodeTypeDeclar
};
setFeature.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "feature"));
setFeature.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "value"));
AddReferencesOfClass(input, generatedType, (m, f, p, _) => AddSetFeature(m, f, p, context, true), setFeature, false, context);
AddAttributesOfClass(input, generatedType, (m, f, p, _) => AddSetFeature(m, f, p, context, false), setFeature, context);
var thisRef = new CodeThisReferenceExpression();
AddReferencesOfClass(input, generatedType, (m, f, p, _) => AddSetFeature(m, f, p, context, true, thisRef), setFeature, false, context);
AddAttributesOfClass(input, generatedType, (m, f, p, _) => AddSetFeature(m, f, p, context, false, thisRef), setFeature, context);
var type2Type = Rule<Type2Type>();
AddRefinedReferencesOfClass(input, generatedType, (m, f, p, _) =>
{
var type = context.Trace.ResolveIn(type2Type, f.Type);
return AddSetFeature(m, f, p, context, true, new CodeCastExpression(type.GetReferenceForType(), thisRef));
}, setFeature, false, context);
AddRefinedAttributesOfClass(input, generatedType, (m, f, p, _) =>
{
var type = context.Trace.ResolveIn(type2Type, f.Type);
return AddSetFeature(m, f, p, context, false, new CodeCastExpression(type.GetReferenceForType(), thisRef));
}, setFeature, context);
if (setFeature.Statements.Count == 0)
{
return null;
Expand Down Expand Up @@ -1074,11 +1086,11 @@ protected virtual CodeMemberMethod CreateCallOperation(IClass input, CodeTypeDec
return callOperation;
}

private static CodeMemberMethod AddSetFeature(CodeMemberMethod method, ITypedElement feature, CodeMemberProperty property, ITransformationContext context, bool isReference)
private static CodeMemberMethod AddSetFeature(CodeMemberMethod method, ITypedElement feature, CodeMemberProperty property, ITransformationContext context, bool isReference, CodeExpression thisReference)
{
if (feature.UpperBound == 1)
{
var propRef = new CodePropertyReferenceExpression(new CodeThisReferenceExpression(), property.Name);
var propRef = new CodePropertyReferenceExpression(thisReference, property.Name);
var ifStmt = new CodeConditionStatement(new CodeBinaryOperatorExpression(new CodeVariableReferenceExpression("feature"),
CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(feature.Name.ToUpperInvariant())));
CodeExpression value = new CodeArgumentReferenceExpression("value");
Expand Down Expand Up @@ -1302,6 +1314,38 @@ protected T AddReferencesOfClass<T>(IClass input, CodeTypeDeclaration typeDeclar
return initial;
}

/// <summary>
/// Iterates all references of the given class
/// </summary>
/// <typeparam name="T">The type of the result</typeparam>
/// <param name="input">The start class</param>
/// <param name="typeDeclaration">The type declaration in the context of which the references should be added</param>
/// <param name="action">the action that should be performed for each reference</param>
/// <param name="initial">an initial result object</param>
/// <param name="containmentsOnly">if true, only containment references are considered</param>
/// <param name="context">The context in which the references should be visited</param>
/// <returns>the result object after is has been applied for all references</returns>
protected T AddRefinedReferencesOfClass<T>(IClass input, CodeTypeDeclaration typeDeclaration, Func<T, IReference, CodeMemberProperty, ITransformationContext, T> action, T initial, bool containmentsOnly, ITransformationContext context)
{
var r2p = Rule<RefinedReferenceGenerator>();
foreach (var reference in input.Closure(c => c.BaseTypes)
.SelectMany(c => c.References)
.Select(r => r.Refines)
.Where(r => r != null)
.Distinct())
{
if (!containmentsOnly || reference.IsContainment)
{
var property = context.Trace.ResolveIn(r2p, input, reference);
if (typeDeclaration.Members.Contains(property))
{
initial = action(initial, reference, property, context);
}
}
}
return initial;
}

/// <summary>
/// Iterates all operations of the given class
/// </summary>
Expand Down Expand Up @@ -1356,6 +1400,34 @@ protected T AddAttributesOfClass<T>(IClass input, CodeTypeDeclaration typeDeclar
return initial;
}

/// <summary>
/// Iterates the attributes of the given class
/// </summary>
/// <typeparam name="T">The result type</typeparam>
/// <param name="input">The class whose attributes should be iterated</param>
/// <param name="typeDeclaration">The generated type declaration for the input</param>
/// <param name="action">The action that should be performed for each attribute</param>
/// <param name="initial">The initial result</param>
/// <param name="context">The context in which the attributes should be iterated</param>
/// <returns>The result after all attributes have been processed</returns>
protected T AddRefinedAttributesOfClass<T>(IClass input, CodeTypeDeclaration typeDeclaration, Func<T, IAttribute, CodeMemberProperty, ITransformationContext, T> action, T initial, ITransformationContext context)
{
var a2p = Rule<RefinedAttributeGenerator>();
foreach (var att in input.Closure(cl => cl.BaseTypes)
.SelectMany(c => c.Attributes)
.Select(a => a.Refines)
.Where(a => a != null)
.Distinct())
{
var property = context.Trace.ResolveIn(a2p, input, att);
if (typeDeclaration.Members.Contains(property))
{
initial = action(initial, att, property, context);
}
}
return initial;
}

private CodeMemberMethod AddToGetRelativeUriForChild(CodeMemberMethod method, IReference containment, CodeMemberProperty property, ITransformationContext context)
{
if (containment.UpperBound == 1)
Expand Down

0 comments on commit bb570e5

Please sign in to comment.