From 2b4b8b8408dd95fd868cd350ca5e7c5d305902c3 Mon Sep 17 00:00:00 2001 From: Michael Becker Date: Sat, 25 Oct 2025 14:14:44 -0400 Subject: [PATCH] improvements to dynamic code generation and interface modeling --- .../Expressions/CreateInstance.cs | 9 +- .../CodeGeneration/Expressions/MethodCall.cs | 3 +- .../Expressions/MethodParameter.cs | 10 +- .../Expressions/ObjectReference.cs | 19 +++- .../Mocha.Modeling/CodeGeneration/Field.cs | 34 +++++++ .../Generators/CSharpCodeGenerator.cs | 99 ++++++++++++++----- .../Generators/DotNetCodeGenerator.cs | 18 ++-- .../lib/Mocha.Modeling/OmsObjectFactory.cs | 90 +++++++++++++++-- .../OmsPropertyImplementation.cs | 26 +++++ .../OmsNonsingularRelationshipProperty.cs | 65 +++++++++++- ....cs => OmsSingularRelationshipProperty.cs} | 6 +- 11 files changed, 324 insertions(+), 55 deletions(-) create mode 100644 mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Field.cs create mode 100644 mocha-dotnet/src/lib/Mocha.Modeling/OmsPropertyImplementation.cs rename mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/{OmsRelationshipProperty.cs => OmsSingularRelationshipProperty.cs} (87%) diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/CreateInstance.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/CreateInstance.cs index 5afebd7..230bf23 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/CreateInstance.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/CreateInstance.cs @@ -22,9 +22,12 @@ public class CreateInstance : IMethodMember public ObjectReference ObjectReference { get; set; } public List ParameterValues { get; } = new List(); - public CreateInstance(IEnumerable objectNames, IEnumerable parameterValues) + public CreateInstance(ObjectReference createWhat, IEnumerable? parameterValues = null) { - ObjectReference = new ObjectReference(objectNames); - ParameterValues.AddRange(parameterValues); + ObjectReference = createWhat; + if (parameterValues != null) + { + ParameterValues.AddRange(parameterValues); + } } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodCall.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodCall.cs index e2d1afc..329df95 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodCall.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodCall.cs @@ -32,8 +32,7 @@ public class MethodCall : IMethodMember { foreach (object parmValue in parmValues) { - MethodParameter parm = new MethodParameter(); - parm.Value = parmValue; + MethodParameter parm = new MethodParameter(parmValue); Parameters.Add(parm); } } diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodParameter.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodParameter.cs index f8a88ba..0497c23 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodParameter.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/MethodParameter.cs @@ -19,13 +19,17 @@ namespace Mocha.Modeling.CodeGeneration; public class MethodParameter { - public MethodParameter(string? name = null, ObjectReference? dataType = null) + public MethodParameter(object value) + { + Value = value; + } + public MethodParameter(string name, ObjectReference dataType) { Name = name; DataType = dataType; } - public ObjectReference? DataType { get; set; } = null; - public string? Name { get; set; } = null; + public ObjectReference DataType { get; set; } = null; + public string Name { get; set; } = null; public object? Value { get; set; } = null; } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/ObjectReference.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/ObjectReference.cs index 8ec526d..aa281a8 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/ObjectReference.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Expressions/ObjectReference.cs @@ -15,14 +15,31 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . +using System.Text; + namespace Mocha.Modeling.CodeGeneration; public class ObjectReference { public IEnumerable ObjectNames { get; set; } = null; + public IEnumerable? GenericArguments { get; set; } = null; - public ObjectReference(IEnumerable objectNames) + public ObjectReference(IEnumerable objectNames, IEnumerable? genericArguments = null) { ObjectNames = objectNames; + GenericArguments = genericArguments; + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(String.Join('.', ObjectNames)); + if (GenericArguments != null && GenericArguments.Count() > 0) + { + sb.Append('<'); + sb.Append(String.Join(',', GenericArguments)); + sb.Append('>'); + } + return sb.ToString(); } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Field.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Field.cs new file mode 100644 index 0000000..77d127d --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Field.cs @@ -0,0 +1,34 @@ +// Copyright (C) 2025 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +namespace Mocha.Modeling.CodeGeneration; + +public class Field : IClassMember +{ + public Field(string name, ObjectReference returnType, object? value = null) + { + Name = name; + ReturnType = returnType; + Value = value; + } + + public AccessModifier AccessModifier { get; set; } = AccessModifier.None; + public string Name { get; set; } = ""; + public ObjectReference ReturnType { get; set; } + public object? Value { get; set; } + public bool ReadOnly { get; set; } = false; +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/CSharpCodeGenerator.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/CSharpCodeGenerator.cs index e849ea3..e2a23ae 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/CSharpCodeGenerator.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/CSharpCodeGenerator.cs @@ -47,7 +47,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator if (item is Namespace ns) { sb.Append("namespace "); - sb.Append(BuildObjectReference(ns.Names)); + sb.Append(BuildObjectReference(new ObjectReference(ns.Names))); sb.Append(" { "); foreach (ICodeItem subItem in ns.Items) { @@ -63,7 +63,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator if (c.InheritsClass != null) { sb.Append(" : "); - sb.Append(BuildObjectReference(c.InheritsClass.ObjectNames)); + sb.Append(BuildObjectReference(c.InheritsClass)); } sb.Append(" { "); foreach (IClassMember subItem in c.Items) @@ -115,10 +115,35 @@ public class CSharpCodeGenerator : DotNetCodeGenerator if (p.Value != null || (p.UseAutoProperty && p.ReadOnly)) { sb.Append("= "); - sb.Append(ExpressionOrLiteral(p.Value)); + if (p.Value != null) + { + sb.Append(ExpressionOrLiteral(p.Value)); + } + else if (p.UseAutoProperty && p.GetMethod != null && p.GetMethod.Items.Count == 1 && p.GetMethod.Items[0] is Return r) + { + sb.Append(ExpressionOrLiteral(r.Value)); + } sb.Append(";"); } } + else if (item is Field f) + { + sb.Append(GenerateCode(f.AccessModifier)); + sb.Append(' '); + if (f.ReadOnly) + { + sb.Append("readonly "); + } + sb.Append(GenerateCode(f.ReturnType)); + sb.Append(' '); + sb.Append(f.Name); + if (f.Value != null) + { + sb.Append(" = "); + sb.Append(ExpressionOrLiteral(f.Value)); + } + sb.Append(";"); + } else if (item is Method m) { sb.Append(GenerateCode(m.AccessModifier)); @@ -144,7 +169,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator for (int i = 0; i < m.Parameters.Count; i++) { MethodParameter parm = m.Parameters[i]; - sb.Append(BuildObjectReference(parm.DataType.ObjectNames)); + sb.Append(BuildObjectReference(parm.DataType)); sb.Append(' '); sb.Append(parm.Name); if (i < m.Parameters.Count - 1) @@ -165,7 +190,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator else if (item is CreateInstance ci) { sb.Append("new "); - sb.Append(BuildObjectReference(ci.ObjectReference.ObjectNames)); + sb.Append(BuildObjectReference(ci.ObjectReference)); sb.Append("("); sb.Append(BuildParameterList(ci.ParameterValues)); sb.Append(")"); @@ -177,7 +202,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator } else if (item is MethodCall mc) { - sb.Append(BuildObjectReference(mc.ObjectName.ObjectNames)); + sb.Append(BuildObjectReference(mc.ObjectName)); sb.Append('.'); sb.Append(mc.MethodName); if (mc.GenericParameters != null) @@ -192,16 +217,9 @@ public class CSharpCodeGenerator : DotNetCodeGenerator } else if (item is PropertyAssignment pa) { - sb.Append(BuildObjectReference(pa.ObjectReference.ObjectNames)); + sb.Append(BuildObjectReference(pa.ObjectReference)); sb.Append(" = "); - if (pa.Value != null) - { - sb.Append(pa.Value); - } - else - { - sb.Append("null"); - } + sb.Append(ExpressionOrLiteral(pa.Value)); } return sb.ToString(); } @@ -242,7 +260,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator } else if (value is ObjectReference orr) { - return BuildObjectReference(orr.ObjectNames); + return BuildObjectReference(orr); } return value.ToString() ?? ""; } @@ -251,20 +269,49 @@ public class CSharpCodeGenerator : DotNetCodeGenerator protected ObjectReference ParseObjectReference(string value) { - string[] parts = value.Split(new char[] { '.' }); - return new ObjectReference(parts); + string[]? genericArgs = null; + string typePart = value; + List genericArgList = new List(); + if (value.Contains('<') && value.Contains('>')) + { + string genericPart = value.Substring(value.IndexOf('<') + 1, value.IndexOf('>') - value.IndexOf('<') - 1); + genericArgs = genericPart.Split(new char[] { ',' }); + foreach (string genericArg in genericArgs) + { + genericArgList.Add(ParseObjectReference(genericArg)); + } + typePart = value.Substring(0, value.IndexOf('<')); + } + string[] parts = typePart.Split(new char[] { '.' }); + return new ObjectReference(parts, genericArgList); } - protected Property GenerateProperty(PropertyInfo pi) + protected Property GenerateProperty(CodeGeneration.Class parentClass, PropertyInfo pi) { Property pp = new Property(pi.Name, ParseObjectReference(SafeTypeName(pi.PropertyType))); pp.AccessModifier = AccessModifier.Public; if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>))) { - pp.GetMethod = new Method(new IMethodMember[] + Type[] genericArgs = pi.PropertyType.GetGenericArguments(); + if (genericArgs.Length == 1 && genericArgs[0].GetInterfaces().Contains(typeof(IOmsClass))) { - new Return(null) - }); + Field backingField = new Field("__backing_" + pi.Name, ParseObjectReference(SafeTypeName(pi.PropertyType))); + parentClass.Items.Add(backingField); + + pp.GetMethod = new Method(new IMethodMember[] + { + new Return(new ObjectReference(new string[] { "__backing_" + pi.Name })) + }); + pp.UseAutoProperty = false; + pp.ReadOnly = true; + } + else + { + pp.GetMethod = new Method(new IMethodMember[] + { + new Return(null) + }); + } if (pi.GetSetMethod() != null) { @@ -281,7 +328,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] { new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), - new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) + new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) }) { GenericParameters = [ new ObjectReference(["string"]) ]}) }); // GetAttributeValue(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) @@ -298,7 +345,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] { new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), - new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) + new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) }) { GenericParameters = [ new ObjectReference(["int"]) ]}) }); // GetAttributeValue(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) @@ -315,7 +362,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] { new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), - new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) + new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) }) { GenericParameters = [ new ObjectReference(["decimal"]) ]}) }); // GetAttributeValue(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) @@ -332,7 +379,7 @@ public class CSharpCodeGenerator : DotNetCodeGenerator new Return(new MethodCall(new string[] { "this", "Oms" }, "GetAttributeValue", new object[] { new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new ObjectReference(new string[] { "this", "GlobalIdentifier" })}), - new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new string[] { "System", "Guid" }, new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) + new MethodCall(new string[] { "this", "Oms" }, "GetInstance", new object[] { new CreateInstance(new ObjectReference(new string[] { "System", "Guid" }), new object[] { "{9153A637-992E-4712-ADF2-B03F0D9EDEA6}" })}) }) { GenericParameters = [ new ObjectReference(["System.DateTime"]) ]}) }); // GetAttributeValue(InstanceKey source, InstanceHandle attribute, T defaultValue = default(T), DateTime? effectiveDate = null) diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/DotNetCodeGenerator.cs b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/DotNetCodeGenerator.cs index 0281b3f..9eeb16d 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/DotNetCodeGenerator.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/CodeGeneration/Generators/DotNetCodeGenerator.cs @@ -28,7 +28,7 @@ public abstract class DotNetCodeGenerator : CodeGenerator { public string GenerateCode(ObjectReference objectReference) { - return BuildObjectReference(objectReference.ObjectNames); + return BuildObjectReference(objectReference); } protected string? SafeTypeName(Type type) { @@ -92,22 +92,20 @@ public abstract class DotNetCodeGenerator : CodeGenerator protected abstract string ExpressionOrLiteral(object? value); - protected virtual string BuildObjectReference(IEnumerable objectNames) + protected virtual string BuildObjectReference(ObjectReference objectReference) { StringBuilder sb = new StringBuilder(); - int i = 0; - foreach (string objectName in objectNames) + sb.Append(String.Join('.', objectReference.ObjectNames)); + if (objectReference.GenericArguments != null && objectReference.GenericArguments.Count() > 0) { - sb.Append(objectName); - if (i < objectNames.Count() - 1) - { - sb.Append('.'); - } - i++; + sb.Append('<'); + sb.Append(String.Join(',', objectReference.GenericArguments)); + sb.Append('>'); } return sb.ToString(); } + protected Assembly CompileScript(SyntaxTree syntaxTree, IEnumerable? additionalDLLs = null) { // thanks https://stackoverflow.com/questions/66672329 diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/OmsObjectFactory.cs b/mocha-dotnet/src/lib/Mocha.Modeling/OmsObjectFactory.cs index 62a0aac..fad51c5 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/OmsObjectFactory.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/OmsObjectFactory.cs @@ -41,6 +41,17 @@ public class OmsObjectFactory : CSharpCodeGenerator where TOmsClass : { CreateType(oms, t2); } + foreach (Type t2 in t.GetNestedTypes()) + { + PropertyInfo[] pis = t2.GetProperties(BindingFlags.Public | BindingFlags.Instance); + foreach (PropertyInfo pi in pis) + { + if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>)) || pi.PropertyType.GetInterfaces().Contains(typeof(IOmsClass))) + { + CreateRelationship(oms, t2, pi); + } + } + } Type?[] tis; try @@ -60,6 +71,58 @@ public class OmsObjectFactory : CSharpCodeGenerator where TOmsClass : } throw new TypeInitializationException(typeof(TOmsClass).Name, null); } + + private void CreateRelationship(Oms oms, Type parentClassType, PropertyInfo pi) + { + OmsRelationshipTypeAttribute? attrRelationshipType = pi.GetCustomAttribute(); + OmsGlobalIdentifierAttribute? attrGlobalIdentifier = pi.GetCustomAttribute(); + + if (attrGlobalIdentifier != null) + { + if (!oms.TryGetInstance(attrGlobalIdentifier.GlobalIdentifier, out InstanceHandle ih)) + { + InstanceHandle ihRelationship = oms.CreateInstanceOf(oms.GetInstance(KnownInstanceGuids.Classes.Relationship), attrGlobalIdentifier.GlobalIdentifier); + + InstanceHandle ihSourceClass = InstanceHandle.Empty; + InstanceHandle ihDestinationClass = InstanceHandle.Empty; + + OmsGlobalIdentifierAttribute? attrParentClassGlobalIdentifier = parentClassType.GetCustomAttribute(); + if (attrParentClassGlobalIdentifier != null) + { + ihSourceClass = oms.GetInstance(attrParentClassGlobalIdentifier.GlobalIdentifier); + } + + bool singular = false; + if (pi.PropertyType.IsSubclassOfGeneric(typeof(IList<>))) + { + OmsGlobalIdentifierAttribute? attrTargetClassGlobalIdentifier = pi.PropertyType.GetGenericArguments()[0].GetCustomAttribute(); + if (attrTargetClassGlobalIdentifier != null) + { + ihDestinationClass = oms.GetInstance(attrTargetClassGlobalIdentifier.GlobalIdentifier); + } + singular = false; + } + else if (pi.PropertyType.GetInterfaces().Contains(typeof(IOmsClass))) + { + OmsGlobalIdentifierAttribute? attrTargetClassGlobalIdentifier = pi.PropertyType.GetCustomAttribute(); + if (attrTargetClassGlobalIdentifier != null) + { + ihDestinationClass = oms.GetInstance(attrTargetClassGlobalIdentifier.GlobalIdentifier); + } + singular = true; + } + + oms.AssignRelationship(ihRelationship, oms.GetInstance(KnownRelationshipGuids.Relationship__has_source__Class), ihSourceClass); + oms.AssignRelationship(ihRelationship, oms.GetInstance(KnownRelationshipGuids.Relationship__has_destination__Class), ihDestinationClass); + if (attrRelationshipType != null) + { + oms.SetAttributeValue(ihRelationship, oms.GetInstance(KnownAttributeGuids.Text.RelationshipType), attrRelationshipType.Value); + } + oms.SetAttributeValue(ihRelationship, oms.GetInstance(KnownAttributeGuids.Boolean.Singular), singular); + } + } + } + public TOmsClass CreateInstance(Oms oms, Guid globalIdentifier) { string script = BuildScript(globalIdentifier); @@ -132,14 +195,29 @@ public class OmsObjectFactory : CSharpCodeGenerator where TOmsClass : foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { - cl.Items.Add(GenerateProperty(pi)); + cl.Items.Add(GenerateProperty(cl, pi)); } cl.Items.Add(new Property("Oms", new ObjectReference(new string[] { "Mocha", "Core", "Oms" }), null) { AccessModifier = CodeGeneration.AccessModifier.Public, UseAutoProperty = true, ReadOnly = false }); - cl.Items.Add(new CodeGeneration.Method("Initialize", new MethodParameter[] { new MethodParameter("oms", new ObjectReference(["Mocha", "Core", "Oms"]))}, new IMethodMember[] + + List list = new List(); + list.Add(new PropertyAssignment(new ObjectReference(["this", "Oms"]), "oms")); + foreach (IClassMember item in cl.Items) { - new PropertyAssignment(new ObjectReference(["this", "Oms"]), "oms") - }) { AccessModifier = CodeGeneration.AccessModifier.Public}); + if (item is Field f) + { + if (f.Name.StartsWith("__backing_")) + { + ObjectReference returnType = f.ReturnType; + if (f.ReturnType.ToString().StartsWith("System.Collections.Generic.IList<")) + { + returnType = new ObjectReference(["Mocha", "Core", "Modeling", "PropertyImplementations", "OmsNonsingularRelationshipProperty"], f.ReturnType.GenericArguments); + } + list.Add(new PropertyAssignment(new ObjectReference(["this", f.Name]), new CreateInstance(returnType, new object[] { new ObjectReference(["this", "Oms"]) }))); + } + } + } + cl.Items.Add(new CodeGeneration.Method("Initialize", new MethodParameter[] { new MethodParameter("oms", new ObjectReference(["Mocha", "Core", "Oms"])) }, list) { AccessModifier = CodeGeneration.AccessModifier.Public }); return cl; } @@ -155,12 +233,12 @@ public class OmsObjectFactory : CSharpCodeGenerator where TOmsClass : globalIdentifier = OmsDatabase.GetGlobalIdentifierForClass(t); } - cl.Items.Add(new Property("GlobalIdentifier", new ObjectReference(new string[] { "System", "Guid" }), new CreateInstance(["System", "Guid"], [globalIdentifier.ToString()])) { AccessModifier = CodeGeneration.AccessModifier.Public }); + cl.Items.Add(new Property("GlobalIdentifier", new ObjectReference(new string[] { "System", "Guid" }), new CreateInstance(new ObjectReference(["System", "Guid"]), [globalIdentifier.ToString()])) { AccessModifier = CodeGeneration.AccessModifier.Public }); cl.Items.Add(new Property("Oms", new ObjectReference(new string[] { "Mocha", "Core", "Oms" }), null) { AccessModifier = CodeGeneration.AccessModifier.Public, UseAutoProperty = true, ReadOnly = false }); foreach (PropertyInfo pi in t.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { - cl.Items.Add(GenerateProperty(pi)); + cl.Items.Add(GenerateProperty(cl, pi)); } return cl; } diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/OmsPropertyImplementation.cs b/mocha-dotnet/src/lib/Mocha.Modeling/OmsPropertyImplementation.cs new file mode 100644 index 0000000..96f9726 --- /dev/null +++ b/mocha-dotnet/src/lib/Mocha.Modeling/OmsPropertyImplementation.cs @@ -0,0 +1,26 @@ +// Copyright (C) 2025 Michael Becker +// +// This file is part of Mocha.NET. +// +// Mocha.NET is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Mocha.NET is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Mocha.NET. If not, see . + +namespace Mocha.Core.Modeling; + +public abstract class OmsPropertyImplementation +{ + internal OmsPropertyImplementation(Oms oms) + { + + } +} \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsNonsingularRelationshipProperty.cs b/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsNonsingularRelationshipProperty.cs index 2c6b4a3..1b627ac 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsNonsingularRelationshipProperty.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsNonsingularRelationshipProperty.cs @@ -15,8 +15,71 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . +using System.Collections; +using Mocha.Modeling; + namespace Mocha.Core.Modeling.PropertyImplementations; -public class OmsNonsingularRelationshipProperty : OmsRelationshipProperty +public class OmsNonsingularRelationshipProperty : OmsPropertyImplementation, IList where T : IOmsClass { + internal OmsNonsingularRelationshipProperty(Oms oms) : base(oms) + { + + } + + public T this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public int Count => throw new NotImplementedException(); + + public bool IsReadOnly => throw new NotImplementedException(); + + public void Add(T item) + { + throw new NotImplementedException(); + } + + public void Clear() + { + throw new NotImplementedException(); + } + + public bool Contains(T item) + { + throw new NotImplementedException(); + } + + public void CopyTo(T[] array, int arrayIndex) + { + throw new NotImplementedException(); + } + + public IEnumerator GetEnumerator() + { + throw new NotImplementedException(); + } + + public int IndexOf(T item) + { + throw new NotImplementedException(); + } + + public void Insert(int index, T item) + { + throw new NotImplementedException(); + } + + public bool Remove(T item) + { + throw new NotImplementedException(); + } + + public void RemoveAt(int index) + { + throw new NotImplementedException(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } } \ No newline at end of file diff --git a/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsRelationshipProperty.cs b/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsSingularRelationshipProperty.cs similarity index 87% rename from mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsRelationshipProperty.cs rename to mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsSingularRelationshipProperty.cs index 3717e0f..260868b 100644 --- a/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsRelationshipProperty.cs +++ b/mocha-dotnet/src/lib/Mocha.Modeling/PropertyImplementations/OmsSingularRelationshipProperty.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2024 Michael Becker +// Copyright (C) 2025 Michael Becker // // This file is part of Mocha.NET. // @@ -15,9 +15,9 @@ // You should have received a copy of the GNU General Public License // along with Mocha.NET. If not, see . + namespace Mocha.Core.Modeling.PropertyImplementations; -public abstract class OmsRelationshipProperty +public class OmsSingularRelationshipProperty { - } \ No newline at end of file