From f859223a611d9e05ce635a61dfb7b407d43a128f Mon Sep 17 00:00:00 2001 From: Peter Kurhajec <61538034+PTKu@users.noreply.github.com> Date: Mon, 8 Dec 2025 14:35:22 +0100 Subject: [PATCH] Enhance metadata generation and update project settings Refactored `GenerateMetadata` to accept `sources` for filtering types based on their location in project source files. Added support for generating metadata for methods in classes and method prototypes in interfaces using new helper methods `CreateMetaMethod` and `CreateMetaMethodPrototype`. Commented out diagnostic logging for compilation errors, providing a future debugging mechanism. Updated `launchSettings.json` by adding the `rangarok` profile, removing `tiax-rooted`, and making minor formatting changes. Improved code readability with formatting adjustments and broader type filtering in `GenerateMetadata`. Commented out `TargetProject.ProvisionProjectStructure` and updated method calls to reflect new parameters. --- .../src/AXSharp.Compiler/AXSharpProject.cs | 105 +++++++++++++++++- .../src/ixc/Properties/launchSettings.json | 8 +- 2 files changed, 105 insertions(+), 8 deletions(-) diff --git a/src/AXSharp.compiler/src/AXSharp.Compiler/AXSharpProject.cs b/src/AXSharp.compiler/src/AXSharp.Compiler/AXSharpProject.cs index 834b574f..bac20568 100644 --- a/src/AXSharp.compiler/src/AXSharp.Compiler/AXSharpProject.cs +++ b/src/AXSharp.compiler/src/AXSharp.Compiler/AXSharpProject.cs @@ -112,7 +112,15 @@ public void Generate() var compilationResult = Compilation.Create(toCompile, new List(), Compilation.Settings.Default).Result; - + + //compilationResult.Compilation.GetDiagnostics() + // .Where(d => d.Severity == AX.Text.Diagnostics.DiagnosticSeverity.Error) + // .ToList() + // .ForEach(d => + // { + // Log.Logger.Error(d.ToString()); + // }); + this.CleanOutput(this.OutputFolder); foreach (var origin in projectSources) @@ -194,7 +202,7 @@ public void Generate() } //TargetProject.ProvisionProjectStructure(); - GenerateMetadata(compilationResult.Compilation); + GenerateMetadata(compilationResult.Compilation, projectSources); TargetProject.GenerateResources(); TargetProject.GenerateCompanionData(); Log.Logger.Information($"Compilation of project '{AxProject.SrcFolder}' done."); @@ -368,9 +376,18 @@ private string GetApaxFolderFromProjectReference(IReference projectReference) return string.Empty; } - private void GenerateMetadata(Compilation compilation) + private void GenerateMetadata(Compilation compilation, IEnumerable<(ISyntaxTree parseTree, SourceFileText source)> sources) { - var meta = compilation.GetSemanticTree().Types.Where(p => p.AccessModifier == AccessModifier.Public) + var projectSourceFiles = sources.Select(s => s.source.Filename).ToHashSet(); + + var meta = compilation.GetSemanticTree().Types + .Where(p => true)//p.AccessModifier == AccessModifier.Public | p.AccessModifier == AccessModifier.Internal) + .Where(p => { + var typeLocation = p.Location; + if (typeLocation == null) return false; + var lineSpan = typeLocation.GetLineSpan(); + return projectSourceFiles.Contains(lineSpan.Filename); + }) .Select(p => CreateMetaType(p)); using (var swr = new StreamWriter(Path.Combine(EnsureFolder(TargetProject.GetMetaDataFolder), "meta.json"))) @@ -417,13 +434,29 @@ private static string CreateMetaType(ITypeDeclaration type) sb.Append($"TYPE {type.Name} : STRUCT ; END_STRUCT\n"); break; case DeclarationKind.Class: - sb.Append($"CLASS {type.Name} \nEND_CLASS\n"); + sb.Append($"CLASS {type.Name}\n"); + if (type is IClassDeclaration classDecl) + { + foreach (var method in classDecl.Methods) + { + sb.Append(CreateMetaMethod(method)); + } + } + sb.Append("END_CLASS\n"); break; case DeclarationKind.Enumeration: sb.Append($"TYPE {type.Name} : (item0); \nEND_TYPE\n"); break; case DeclarationKind.Interface: - sb.Append($"INTERFACE {type.Name} \nEND_INTERFACE\n"); + sb.Append($"INTERFACE {type.Name}\n"); + if (type is IInterfaceDeclaration interfaceDecl) + { + foreach (var method in interfaceDecl.Methods) + { + sb.Append(CreateMetaMethodPrototype(method)); + } + } + sb.Append("END_INTERFACE\n"); break; case DeclarationKind.NamedValueType: sb.Append($"TYPE {type.Name} : INT (item0 := 0); \nEND_TYPE\n"); @@ -434,4 +467,64 @@ private static string CreateMetaType(ITypeDeclaration type) return sb.ToString(); } + + private static string CreateMetaMethod(IMethodDeclaration method) + { + var sb = new StringBuilder(); + + // Get return type + var returnVariable = method.Variables.FirstOrDefault(v => v.Section == Section.Return); + var returnType = returnVariable != null ? $" : {returnVariable.Type.Name}" : string.Empty; + + // Build method signature with access modifier + var accessModifier = method.AccessModifier.ToString().ToUpperInvariant(); + + sb.Append($"METHOD {accessModifier} {method.Name}{returnType}\n"); + + // Add VAR_INPUT section if there are input parameters + var inputVars = method.Variables.Where(v => v.Section == Section.Input).ToList(); + if (inputVars.Any()) + { + sb.Append("VAR_INPUT\n"); + foreach (var inputVar in inputVars) + { + sb.Append($"{inputVar.Name} : {inputVar.Type.Name};\n"); + } + sb.Append("END_VAR\n"); + } + + // Add at least one statement (semicolon) to method body + sb.Append(";\n"); + + sb.Append("END_METHOD\n"); + + return sb.ToString(); + } + + private static string CreateMetaMethodPrototype(IMethodPrototypeDeclaration method) + { + var sb = new StringBuilder(); + + // Get return type + var returnVariable = method.Variables.FirstOrDefault(v => v.Section == Section.Return); + var returnType = returnVariable != null ? $" : {returnVariable.Type.Name}" : string.Empty; + + sb.Append($"METHOD {method.Name}{returnType}\n"); + + // Add VAR_INPUT section if there are input parameters + var inputVars = method.Variables.Where(v => v.Section == Section.Input).ToList(); + if (inputVars.Any()) + { + sb.Append("VAR_INPUT\n"); + foreach (var inputVar in inputVars) + { + sb.Append($"{inputVar.Name} : {inputVar.Type.Name};\n"); + } + sb.Append("END_VAR\n"); + } + + sb.Append("END_METHOD\n"); + + return sb.ToString(); + } } \ No newline at end of file diff --git a/src/AXSharp.compiler/src/ixc/Properties/launchSettings.json b/src/AXSharp.compiler/src/ixc/Properties/launchSettings.json index 03c4a8d4..a807cdf2 100644 --- a/src/AXSharp.compiler/src/ixc/Properties/launchSettings.json +++ b/src/AXSharp.compiler/src/ixc/Properties/launchSettings.json @@ -7,7 +7,7 @@ "ixc-tom": { "commandName": "Project", "workingDirectory": "D:\\github\\Inxton\\axopen\\src\\components.elements\\app" - }, + }, "integration_plc": { "commandName": "Project", "workingDirectory": "c:\\W\\Develop\\gh\\inxton\\axopen\\src\\integrations\\ctrl\\" @@ -51,11 +51,15 @@ "commandLineArgs": "--source-project-folder C:\\W\\Develop\\gh\\inxton\\ax\\TiaAxTools\\Sandbox\\src\\Connectors\\plc1\\ax --output-project-folder C:\\W\\Develop\\gh\\inxton\\ax\\TiaAxTools\\Sandbox\\src\\Connectors\\plc1\\ix --project-file plc1.csproj --target-platform-moniker tia", "workingDirectory": "C:\\W\\Develop\\gh\\inxton\\ax\\TiaAxTools\\Sandbox\\" }, - "tiax-rooted": { "commandName": "Project", "commandLineArgs": "-v Verbose", "workingDirectory": "C:\\W\\Develop\\gh\\inxton\\ax\\TiaAxTools\\Sandbox\\src\\Connectors\\plc1\\ax" + }, + "rangarok": { + "commandName": "Project", + "commandLineArgs": "--verbosity Information", + "workingDirectory": "c:\\W\\Develop\\gh\\inxton\\simatic-ax\\RANGAROK\\ST20\\ax\\" } } } \ No newline at end of file