-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Added `MtconnectTranspiler.Sinks.CSharp.Example` project to be used as a starting point for others to create their own transpiler.
- Loading branch information
Showing
11 changed files
with
349 additions
and
2 deletions.
There are no files selected for viewing
Binary file not shown.
13 changes: 13 additions & 0 deletions
13
MtconnectTranspiler.Sinks.CSharp.Example/Models/ExampleClass.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
using MtconnectTranspiler.Model; | ||
using MtconnectTranspiler.Sinks.CSharp.Attributes; | ||
using MtconnectTranspiler.Sinks.CSharp.Models; | ||
using MtconnectTranspiler.Xmi.UML; | ||
|
||
namespace MtconnectTranspiler.Sinks.CSharp.Example.Models | ||
{ | ||
[ScribanTemplate("MtconnectCore.Class.scriban")] | ||
public class ExampleClass : Class | ||
{ | ||
public ExampleClass(MTConnectModel model, UmlClass source) : base(model, source) { } | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
MtconnectTranspiler.Sinks.CSharp.Example/Models/ExampleEnum.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
using MtconnectTranspiler.Model; | ||
using MtconnectTranspiler.Sinks.CSharp.Attributes; | ||
using MtconnectTranspiler.Xmi; | ||
using MtconnectTranspiler.Xmi.UML; | ||
|
||
namespace MtconnectTranspiler.Sinks.CSharp.Example.Models | ||
{ | ||
[ScribanTemplate("Example.Enum.scriban")] | ||
public class ExampleEnum : CSharp.Models.Enum | ||
{ | ||
// NOTE: Only used for CATEGORY types that have subTypes. | ||
public Dictionary<string, string> SubTypes { get; set; } = new Dictionary<string, string>(); | ||
|
||
// NOTE: Only used for CATEGORY types that have value enums. | ||
public Dictionary<string, string> ValueTypes { get; set; } = new Dictionary<string, string>(); | ||
|
||
public ExampleEnum(MTConnectModel model, XmiElement source, string name) : base(model, source, name) { } | ||
|
||
public ExampleEnum(MTConnectModel model, UmlEnumeration source) : base(model, source) { } | ||
|
||
public ExampleEnum(MTConnectModel model, UmlPackage source) : base(model, source) { } | ||
|
||
public ExampleEnum(MTConnectModel model, MTConnectDeviceInformationModel source) : base(model, source) { } | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
MtconnectTranspiler.Sinks.CSharp.Example/MtconnectTranspiler.Sinks.CSharp.Example.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<StartupObject>Program</StartupObject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Consoul" Version="1.6.2" /> | ||
<PackageReference Include="MtconnectTranspiler" Version="0.0.3" /> | ||
<PackageReference Include="MtconnectTranspiler.Sinks.CSharp" Version="0.0.12-beta" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Content Include="Templates\Example.Class.scriban"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</Content> | ||
<Content Include="Templates\Example.Enum.scriban"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</Content> | ||
<Content Include="Templates\UmlCommentsSummaryContent.scriban" /> | ||
<Content Update="Templates\UmlCommentsSummaryContent.scriban"> | ||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> | ||
</Content> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
using ConsoulLibrary; | ||
using Microsoft.Extensions.Logging; | ||
using MtconnectTranspiler; | ||
using MtconnectTranspiler.Sinks.CSharp.Example; | ||
|
||
internal class Program | ||
{ | ||
private static void Main(string[] args) | ||
{ | ||
if (args.Length == 0) throw new ArgumentNullException(nameof(args), "Missing projectPath argument"); | ||
|
||
string projectPath = args[0]; | ||
if (!Directory.Exists(projectPath)) | ||
{ | ||
Consoul.Write("Creating project path: " + projectPath); | ||
Directory.CreateDirectory(projectPath); | ||
} | ||
|
||
var logFactory = LoggerFactory.Create((o) => o.AddConsoulLogger()); | ||
var dispatchLogger = logFactory.CreateLogger<TranspilerDispatcher>(); | ||
var transpilerLogger = logFactory.CreateLogger<Transpiler>(); | ||
|
||
|
||
// NOTE: The GitHubRelease can be a reference to a specific tag referring to the version in which to download. | ||
TranspilerDispatcherOptions dispatchOptions = null; | ||
if (args.Length > 1) | ||
{ | ||
if (!File.Exists(args[1])) throw new FileNotFoundException(args[1]); | ||
|
||
dispatchOptions = new FromFileOptions() { Filepath = args[1] }; | ||
Consoul.Write("Dispatching from file: " + args[1]); | ||
} | ||
else | ||
{ | ||
dispatchOptions = new FromGitHubOptions() { GitHubRelease = "latest" }; | ||
Consoul.Write("Dispatching from GitHub's latest release"); | ||
} | ||
|
||
using (var tokenSource = new CancellationTokenSource()) | ||
using (var dispatcher = new TranspilerDispatcher(dispatchOptions, dispatchLogger)) | ||
{ | ||
dispatcher.AddSink(new Transpiler(projectPath, transpilerLogger)); | ||
|
||
Consoul.Write("Beginning deserialization and dispatching"); | ||
var task = Task.Run(() => dispatcher.TranspileAsync(tokenSource.Token)); | ||
|
||
#if DEBUG | ||
task = task.ContinueWith((t) => tokenSource.Cancel()); | ||
Consoul.Wait(cancellationToken: tokenSource.Token); | ||
#else | ||
task.Wait(); | ||
#endif | ||
|
||
if (task.IsCompletedSuccessfully) | ||
{ | ||
Consoul.Write("Done!", ConsoleColor.Green); | ||
|
||
Environment.Exit(0); | ||
} | ||
else | ||
{ | ||
Consoul.Write("Cancelled", ConsoleColor.Red); | ||
Environment.Exit(1); | ||
} | ||
|
||
} | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
MtconnectTranspiler.Sinks.CSharp.Example/Templates/Example.Class.scriban
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using System; | ||
|
||
namespace {{ to_pascal_code source.namespace }} { | ||
/// <summary> | ||
/// View in the MTConnect Model browser <seealso href="https://model.mtconnect.org/#Structure__{{ source.id }}">model.mtconnect.org</seealso> | ||
{{ source?.summary }} | ||
/// </summary> | ||
[GeneratedCode("MtconnectTranspiler.Sinks.CSharp.Example", "{{ version }}")] | ||
public {{ source.modifier }} class {{ source.name }} { | ||
{{~ for item in source.items ~}} | ||
/// <summary> | ||
{{ item?.summary }} | ||
/// </summary> | ||
/// <remarks>Original Name: {{ item.name }}</remarks> | ||
{{ item.access_modifier }} {{ item.type }} {{ item.name }} { get; set; } | ||
{{~ end ~}} | ||
|
||
# region Rules | ||
{{~ for constraint in source.constraints ~}} | ||
/// <summary> | ||
/// {{ constraint.name }} | ||
/// </summary> | ||
/// <remarks>Specification Language: <c>{{ constraint?.specification?.language ?? "Unspecified" }}</c></remarks> | ||
/* | ||
{{ constraint?.raw_script ?? "No Content" }} | ||
*/ | ||
{{~ end ~}} | ||
# endregion | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
MtconnectTranspiler.Sinks.CSharp.Example/Templates/Example.Enum.scriban
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using System.CodeDom.Compiler; | ||
|
||
namespace {{ to_pascal_code source.namespace }} | ||
{ | ||
/// <summary> | ||
/// View in the MTConnect Model browser <seealso href="https://model.mtconnect.org/#Enumeration__{{ source.sysml_id }}">model.mtconnect.org</seealso> | ||
{{ include 'UmlCommentsSummaryContent.scriban' source?.summary ~}} | ||
/// </summary> | ||
{{~ if source?.deprecated_version != "" ~}} | ||
[Obsolete("Deprecated according to https://model.mtconnect.org/")] | ||
{{~ end ~}} | ||
[GeneratedCode("MtconnectTranspiler.Sinks.CSharp.Example", "{{ version }}")] | ||
public enum {{ to_pascal_case source.name }} | ||
{ | ||
{{~ for item in source.items ~}} | ||
/// <summary> | ||
{{ include 'UmlCommentsSummaryContent.scriban' item?.summary ~}} | ||
/// </summary> | ||
{{~ if item?.deprecated_version != "" ~}} | ||
[Obsolete("Deprecated according to https://model.mtconnect.org/")] | ||
{{~ end ~}} | ||
{{~ if category_contains_type source item ~}} | ||
/// <remarks><b>Observational Sub-Type</b>: {{ source?.sub_types[item.name] }}</remarks> | ||
{{ end ~}} | ||
{{~ if category_contains_value source item ~}} | ||
/// <remarks><b>Observational Value</b>: {{ source?.value_types[item.name] }}</remarks> | ||
{{ end ~}} | ||
{{ item.name }}, | ||
{{~ end ~}} | ||
} | ||
} |
3 changes: 3 additions & 0 deletions
3
MtconnectTranspiler.Sinks.CSharp.Example/Templates/UmlCommentsSummaryContent.scriban
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{{~ if $1 ~}} | ||
{{ $1 }} | ||
{{~ end ~}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
using Microsoft.Extensions.Logging; | ||
using MtconnectTranspiler.Model; | ||
using MtconnectTranspiler.Sinks.CSharp; | ||
using MtconnectTranspiler.Sinks.CSharp.Models; | ||
using MtconnectTranspiler.Sinks.CSharp.Example.Models; | ||
using MtconnectTranspiler.Xmi.UML; | ||
using Scriban.Runtime; | ||
|
||
namespace MtconnectTranspiler.Sinks.CSharp.Example | ||
{ | ||
public class CategoryFunctions : ScriptObject | ||
{ | ||
public static bool CategoryContainsType(ExampleEnum @enum, EnumItem item) => @enum.SubTypes.ContainsKey(item.Name); | ||
public static bool CategoryContainsValue(ExampleEnum @enum, EnumItem item) => @enum.ValueTypes.ContainsKey(item.Name); | ||
public static bool EnumHasValues(ExampleEnum @enum) => @enum.ValueTypes.Any(); | ||
} | ||
internal class Transpiler : CsharpTranspiler | ||
{ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/// <param name="projectPath"></param> | ||
public Transpiler(string projectPath, ILogger<Transpiler> logger = default) : base(projectPath, logger) { } | ||
|
||
public override void Transpile(MTConnectModel model, CancellationToken cancellationToken = default(CancellationToken)) | ||
{ | ||
_logger?.LogInformation("Received MTConnectModel, beginning transpilation"); | ||
|
||
Model.SetValue("model", model, true); | ||
|
||
base.TemplateContext.PushGlobal(new CategoryFunctions()); | ||
|
||
const string DataItemNamespace = "Example.Enums.DataItemTypes"; | ||
const string DataItemValueNamespace = "Example.Enums.DataItemValues"; | ||
|
||
// Process DataItem Types/Sub-Types | ||
var dataItemTypeEnums = new List<ExampleEnum>(); | ||
var valueEnums = new List<ExampleEnum>(); | ||
string[] categories = new string[] { "Sample", "Event", "Condition" }; | ||
|
||
foreach (var category in categories) | ||
{ | ||
// Get the UmlPackage for the category (ie. Samples, Events, Conditions). | ||
var typesPackage = model | ||
?.ObservationInformationModel | ||
?.ObservationTypes | ||
?.Elements | ||
?.Where(o => o.Name == $"{category} Types") | ||
?.FirstOrDefault() as UmlPackage; | ||
// Get all DataItem Type and SubType references | ||
var allTypes = typesPackage | ||
?.Elements | ||
?.Where(o => o is UmlClass) | ||
?.Select(o => o as UmlClass); | ||
// Filter to get just the Type references | ||
var types = allTypes | ||
?.Where(o => !o.Name.Contains(".")); | ||
// Filter and group each SubType by the relevant Type reference | ||
var subTypes = allTypes | ||
?.Where(o => o.Name.Contains(".")) | ||
?.GroupBy(o => o.Name.Substring(0, o.Name.IndexOf(".")), o => o) | ||
?.Where(o => o.Any()) | ||
?.ToDictionary(o => o.Key, o => o?.ToList()); | ||
|
||
var categoryEnum = new ExampleEnum(model, typesPackage, $"{category}Types") { Namespace = DataItemNamespace }; | ||
|
||
foreach (var type in types) | ||
{ | ||
// Add type to CATEGORY enum | ||
categoryEnum.AddItem(model, type); | ||
|
||
// Find value | ||
var typeResult = type?.Properties?.FirstOrDefault(o => o.Name == "result"); | ||
if (typeResult != null) | ||
{ | ||
var typeValuesSysEnum = model | ||
?.Profile | ||
?.ProfileDataTypes | ||
?.Elements | ||
?.FirstOrDefault(o => o is UmlEnumeration && o.Id == typeResult.PropertyType); | ||
if (typeValuesSysEnum != null) | ||
{ | ||
var typeValuesEnum = new ExampleEnum(model, typeValuesSysEnum as UmlEnumeration) { Namespace = DataItemValueNamespace, Name = $"{type.Name}Values" }; | ||
foreach (var value in typeValuesEnum.Items) | ||
{ | ||
value.Name = value.SysML_Name; | ||
} | ||
if (!categoryEnum.ValueTypes.ContainsKey(type.Name)) categoryEnum.ValueTypes.Add(ScribanHelperMethods.ToUpperSnakeCode(type.Name), $"{type.Name}Values"); | ||
valueEnums.Add(typeValuesEnum); | ||
} | ||
} | ||
|
||
// Add subType as enum | ||
if (subTypes.ContainsKey(type.Name)) | ||
{ | ||
// Register type as having a subType in the CATEGORY enum | ||
if (!categoryEnum.SubTypes.ContainsKey(type.Name)) categoryEnum.SubTypes.Add(ScribanHelperMethods.ToUpperSnakeCode(type.Name), $"{type.Name}SubTypes"); | ||
|
||
var subTypeEnum = new ExampleEnum(model, type, $"{type.Name}SubTypes") { Namespace = DataItemNamespace }; | ||
|
||
var typeSubTypes = subTypes[type.Name]; | ||
subTypeEnum.AddItems(model, typeSubTypes); | ||
|
||
// Cleanup Enum names | ||
foreach (var item in subTypeEnum.Items) | ||
{ | ||
if (!item.Name.Contains(".")) continue; | ||
item.Name = ScribanHelperMethods.ToUpperSnakeCode(item.Name.Substring(item.Name.IndexOf(".") + 1)); | ||
} | ||
|
||
// Register the DataItem SubType Enum | ||
dataItemTypeEnums.Add(subTypeEnum); | ||
} | ||
} | ||
|
||
// Cleanup Enum names | ||
foreach (var item in categoryEnum.Items) | ||
{ | ||
item.Name = ScribanHelperMethods.ToUpperSnakeCode(item.Name); | ||
} | ||
|
||
// Register the DataItem Category Enum (ie. Samples, Events, Conditions) | ||
dataItemTypeEnums.Add(categoryEnum); | ||
} | ||
|
||
_logger?.LogInformation($"Processing {dataItemTypeEnums.Count} DataItem types/subTypes"); | ||
|
||
// Process the template into enum files | ||
processTemplate(dataItemTypeEnums, Path.Combine(ProjectPath, "Enums", "Devices", "DataItemTypes"), true); | ||
processTemplate(valueEnums, Path.Combine(ProjectPath, "Enums", "Streams"), true); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters