From f4c3e80254c806ef4e98102d9a5a31568f75a199 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 22 Dec 2025 10:31:29 -0600 Subject: [PATCH 1/6] When compiling include the required PreProcessorDirectives --- src/PluginMerge/Compile/CompileHandler.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/PluginMerge/Compile/CompileHandler.cs b/src/PluginMerge/Compile/CompileHandler.cs index 82f0083..b302bc4 100644 --- a/src/PluginMerge/Compile/CompileHandler.cs +++ b/src/PluginMerge/Compile/CompileHandler.cs @@ -32,7 +32,8 @@ public async Task Run() } string code = await File.ReadAllTextAsync(_fileName).ConfigureAwait(false); - SyntaxTree tree = CSharpSyntaxTree.ParseText(code, new CSharpParseOptions(_config.PlatformSettings.Lang)); + CSharpParseOptions parse = new(_config.PlatformSettings.Lang, preprocessorSymbols: _config.PreprocessorDirectives.EnabledDirectives.Select(d => d.Directive)); + SyntaxTree tree = CSharpSyntaxTree.ParseText(code, parse); FileScanner scanner = new(_compile.AssemblyPaths, "*.dll", _compile.IgnorePaths, _compile.IgnoreFiles); @@ -44,8 +45,9 @@ public async Task Run() } await using MemoryStream stream = new(); - - CSharpCompilation compilation = CSharpCompilation.Create("output.dll", new List {tree}, references, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); + + CSharpCompilationOptions options = new(OutputKind.DynamicallyLinkedLibrary); + CSharpCompilation compilation = CSharpCompilation.Create("output.dll", new List {tree}, references, options); EmitResult results = compilation.Emit(stream); foreach (Diagnostic diagnostic in results.Diagnostics.Where(r => r.Severity >= _compile.CompileLogLevel).OrderBy(r => (int)r.Severity)) { From 41c4f3876730f8db736e453bc39052711d493d48 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 22 Dec 2025 10:35:05 -0600 Subject: [PATCH 2/6] Better handling for Using statements. Now supports static usings. Fixes #8 and #25. --- src/PluginMerge/Creator/FileCreator.cs | 22 +++++++++++++++------- src/PluginMerge/Merge/FileHandler.cs | 16 ++-------------- src/PluginMerge/Writer/CodeWriter.cs | 4 ++-- 3 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/PluginMerge/Creator/FileCreator.cs b/src/PluginMerge/Creator/FileCreator.cs index f048739..a55134e 100644 --- a/src/PluginMerge/Creator/FileCreator.cs +++ b/src/PluginMerge/Creator/FileCreator.cs @@ -185,14 +185,22 @@ private void WriteUsings() .Select(f => f.TypeNamespace)) .ToList(); - _writer.WriteUsings(_files - .SelectMany(f => f.UsingStatements) - .Distinct() - .Where(u => !_settings.Merge.IgnoreNameSpaces.Any(u.StartsWith) && !extensionNameSpaces.Contains(u))); + var uniqueUsings = _files + .SelectMany(f => f.UsingStatements.Select(u => new + { + File = f, + Using = u, + UsingText = u.ToString(), + UsingName = u.Name.ToString() + })) + .DistinctBy(u => u.UsingText) + .Where(u => !_settings.Merge.IgnoreNameSpaces.Any(u.UsingName.StartsWith) && !extensionNameSpaces.Contains(u.UsingText)) + .OrderBy(u => u.UsingText) + .ToArray(); - _writer.WriteUsings(_files - .SelectMany(f => f.UsingAliases) - .Distinct()); + _writer.WriteUsings(uniqueUsings.Where(u => u.Using.Alias == null && u.Using.StaticKeyword == default).Select(u => u.UsingText)); + _writer.WriteUsings(uniqueUsings.Where(u => u.Using.StaticKeyword != default).Select(u => u.UsingText)); + _writer.WriteUsings(uniqueUsings.Where(u => u.Using.Alias is not null).Select(u => u.UsingText)); if (_extensionTypes.Count != 0) { diff --git a/src/PluginMerge/Merge/FileHandler.cs b/src/PluginMerge/Merge/FileHandler.cs index bdd33fd..41648ba 100644 --- a/src/PluginMerge/Merge/FileHandler.cs +++ b/src/PluginMerge/Merge/FileHandler.cs @@ -28,12 +28,7 @@ public class FileHandler /// /// Using statements in the code file /// - public List UsingStatements { get; } = new(); - - /// - /// Using statements in the code file - /// - public List UsingAliases { get; } = new(); + public List UsingStatements { get; } = new(); /// /// Using statements in the code file @@ -168,14 +163,7 @@ private Task ProcessUsings(PlatformSettings settings, CompilationUnitSyntax root string name = @using.Name.ToString(); if (!name.Equals(settings.Namespace)) { - if (@using.Alias is null) - { - UsingStatements.Add(name); - } - else - { - UsingAliases.Add($"{@using.Alias.ToString()} {name}"); - } + UsingStatements.Add(@using); } } diff --git a/src/PluginMerge/Writer/CodeWriter.cs b/src/PluginMerge/Writer/CodeWriter.cs index c571f85..ae45bde 100644 --- a/src/PluginMerge/Writer/CodeWriter.cs +++ b/src/PluginMerge/Writer/CodeWriter.cs @@ -89,10 +89,10 @@ public void WriteDefines(IEnumerable defines) public void WriteUsings(IEnumerable usings) { bool didWrite = false; - foreach (string @using in usings.OrderBy(u => u)) + foreach (string @using in usings) { didWrite = true; - WriteUsing(@using); + _writer.AppendLine(@using); } if (didWrite) From 5e6a5050cc5e989f6dad91f01a5876eee21b7856 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 22 Dec 2025 10:35:28 -0600 Subject: [PATCH 3/6] Cleanup --- src/PluginMerge/Merge/FileHandler.cs | 7 ++----- src/PluginMerge/Scanner/FileScanner.cs | 8 +------- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/PluginMerge/Merge/FileHandler.cs b/src/PluginMerge/Merge/FileHandler.cs index 41648ba..9b38791 100644 --- a/src/PluginMerge/Merge/FileHandler.cs +++ b/src/PluginMerge/Merge/FileHandler.cs @@ -113,12 +113,9 @@ private Task ProcessComments(CompilationUnitSyntax root) Settings |= FileSettings.Exclude; return Task.CompletedTask; } - else if (comment.Contains(Constants.Definitions.OrderFile)) + else if (comment.Contains(Constants.Definitions.OrderFile) && int.TryParse(comment.Replace(Constants.Definitions.OrderFile, string.Empty), out int order)) { - if (int.TryParse(comment.Replace(Constants.Definitions.OrderFile, string.Empty), out int order)) - { - Order = order; - } + Order = order; } ProcessFrameworkComments(comment); diff --git a/src/PluginMerge/Scanner/FileScanner.cs b/src/PluginMerge/Scanner/FileScanner.cs index 4178ad4..451a320 100644 --- a/src/PluginMerge/Scanner/FileScanner.cs +++ b/src/PluginMerge/Scanner/FileScanner.cs @@ -24,13 +24,7 @@ public FileScanner(List inputPaths, string filter = "*", IEnumerable ScanFiles() { - foreach (string path in _inputPaths.Select(p => p.ToFullPath())) - { - foreach (ScannedFile file in ScanPath(path)) - { - yield return file; - } - } + return _inputPaths.Select(p => p.ToFullPath()).SelectMany(ScanPath); } private IEnumerable ScanPath(string dir) From fdaf1f1a88f95dc89a9eaef505de5e0fbf7e7db8 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 22 Dec 2025 10:36:15 -0600 Subject: [PATCH 4/6] Bumped dotnet min version to 8.0 Bumped nuget packages --- src/PluginMerge/PluginMerge.csproj | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/PluginMerge/PluginMerge.csproj b/src/PluginMerge/PluginMerge.csproj index 83246fe..d93b6c2 100644 --- a/src/PluginMerge/PluginMerge.csproj +++ b/src/PluginMerge/PluginMerge.csproj @@ -27,7 +27,7 @@ latest true true - net6.0 + net8.0 disable LatestMajor @@ -42,12 +42,12 @@ - - - - - - + + + + + + From 022a0e55fd8f20c82ba9bdd8a95263753f1c337a Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 22 Dec 2025 11:01:22 -0600 Subject: [PATCH 5/6] Added Oxide //Requires: to config Added parsing of Oxide //Requires: and //References in files. Fixes #24 --- src/PluginMerge/Configuration/MergeConfig.cs | 5 +++++ src/PluginMerge/Constants.cs | 6 ++++++ src/PluginMerge/Creator/FileCreator.cs | 15 ++++++++++++--- src/PluginMerge/Merge/FileHandler.cs | 20 +++++++++++++++++++- src/PluginMerge/Writer/CodeWriter.cs | 16 +++++++++++++++- 5 files changed, 57 insertions(+), 5 deletions(-) diff --git a/src/PluginMerge/Configuration/MergeConfig.cs b/src/PluginMerge/Configuration/MergeConfig.cs index 5d264d8..da5716a 100644 --- a/src/PluginMerge/Configuration/MergeConfig.cs +++ b/src/PluginMerge/Configuration/MergeConfig.cs @@ -30,6 +30,10 @@ public class MergeConfig [JsonPropertyName("Reference Definitions")] public List References { get; set; } + [YamlMember(Alias = "Requires Definitions", Description = "Oxide //Requires: definitions")] + [JsonPropertyName("Requires Definitions")] + public List Requires { get; set; } + [JsonPropertyName("Define Definitions")] [YamlMember(Alias = "Define Definitions", Description = "#define definitions")] public List Defines { get; set; } @@ -64,6 +68,7 @@ public void Initialize() OutputPaths ??= new List {"./build"}; Defines ??= new List { "DEBUG" }; References ??= new List(); + Requires ??= new List(); IgnorePaths ??= new List{"./IgnoreThisPath"}; IgnoreFiles ??= new List{"./IgnoreThisFile.cs"}; IgnoreNameSpaces ??= new List {"IgnoreThisNameSpace"}; diff --git a/src/PluginMerge/Constants.cs b/src/PluginMerge/Constants.cs index 427c293..10bb5a1 100644 --- a/src/PluginMerge/Constants.cs +++ b/src/PluginMerge/Constants.cs @@ -33,6 +33,12 @@ public static class Definitions public const string OrderFile = "//Define:FileOrder="; } + public static class OxideDefinitions + { + public const string Reference = "//Reference: "; + public const string Requires = "//Requires: "; + } + /// /// Regexs for the application /// diff --git a/src/PluginMerge/Creator/FileCreator.cs b/src/PluginMerge/Creator/FileCreator.cs index a55134e..3a6fc1b 100644 --- a/src/PluginMerge/Creator/FileCreator.cs +++ b/src/PluginMerge/Creator/FileCreator.cs @@ -70,7 +70,8 @@ public bool Create() FilterFiles(_plugin.PluginData); _writer = new CodeWriter(_plugin.PluginData, _settings.Merge); - + + WriteRequires(); WriteReferences(); WriteRequiredPreprocessorDirectives(); WriteDefines(); @@ -156,11 +157,19 @@ private void WriteErrorPreprocessorMessages() } /// - /// writes usings to the code writer + /// writes oxide //References: to the code writer /// private void WriteReferences() { - _writer.WriteReferences(_settings.Merge.References); + _writer.WriteReferences(_files.SelectMany(f => f.References).Concat(_settings.Merge.References).Distinct()); + } + + /// + /// writes oxide //Requires: to the code writer + /// + private void WriteRequires() + { + _writer.WriteRequires(_files.SelectMany(f => f.Requires).Concat(_settings.Merge.Requires).Distinct()); } /// diff --git a/src/PluginMerge/Merge/FileHandler.cs b/src/PluginMerge/Merge/FileHandler.cs index 9b38791..74ec5d9 100644 --- a/src/PluginMerge/Merge/FileHandler.cs +++ b/src/PluginMerge/Merge/FileHandler.cs @@ -30,6 +30,16 @@ public class FileHandler /// public List UsingStatements { get; } = new(); + /// + /// //References: comments + /// + public List References { get; } = new(); + + /// + /// //Requires: comments + /// + public List Requires { get; } = new(); + /// /// Using statements in the code file /// @@ -98,7 +108,7 @@ private Task ProcessComments(CompilationUnitSyntax root) { if (trivia.IsKind(SyntaxKind.SingleLineCommentTrivia)) { - if (trivia.Token.Parent is not (NamespaceDeclarationSyntax or ClassDeclarationSyntax or AttributeListSyntax)) + if (trivia.Token.Parent is not (BaseNamespaceDeclarationSyntax or ClassDeclarationSyntax or AttributeListSyntax or UsingDirectiveSyntax)) { continue; } @@ -117,6 +127,14 @@ private Task ProcessComments(CompilationUnitSyntax root) { Order = order; } + else if (comment.StartsWith(Constants.OxideDefinitions.Reference, StringComparison.OrdinalIgnoreCase)) + { + References.Add(comment[Constants.OxideDefinitions.Reference.Length..]); + } + else if (comment.StartsWith(Constants.OxideDefinitions.Requires, StringComparison.OrdinalIgnoreCase)) + { + Requires.Add(comment[Constants.OxideDefinitions.Requires.Length..]); + } ProcessFrameworkComments(comment); } diff --git a/src/PluginMerge/Writer/CodeWriter.cs b/src/PluginMerge/Writer/CodeWriter.cs index ae45bde..3320c3e 100644 --- a/src/PluginMerge/Writer/CodeWriter.cs +++ b/src/PluginMerge/Writer/CodeWriter.cs @@ -62,7 +62,21 @@ public void WriteReferences(IEnumerable references) { foreach (string define in references.OrderBy(u => u)) { - _writer.Append("//Reference: "); + _writer.Append(Constants.OxideDefinitions.Reference); + _writer.Append(define); + _writer.AppendLine(); + } + } + + /// + /// Writes requires to the code + /// + /// + public void WriteRequires(IEnumerable requires) + { + foreach (string define in requires.OrderBy(u => u)) + { + _writer.Append(Constants.OxideDefinitions.Requires); _writer.Append(define); _writer.AppendLine(); } From f28293fa186eb3251204cfd71b366dcffdf4cb58 Mon Sep 17 00:00:00 2001 From: Josh Dassinger Date: Mon, 22 Dec 2025 11:04:35 -0600 Subject: [PATCH 6/6] Bump CLI dotnet version to 8.0.x --- .github/workflows/ci.yml | 2 +- .github/workflows/pre-release.yml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1c79521..1b37fdd 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: '6.0.x' + dotnet-version: '8.0.x' - name: Build run: dotnet build --configuration Release working-directory: src \ No newline at end of file diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index 705451a..2148aa6 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -16,7 +16,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: '6.0.x' + dotnet-version: '8.0.x' - name: Build run: dotnet build --configuration Release /p:Version=${VERSION} working-directory: src diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3da9afa..6620086 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,7 @@ jobs: - name: Setup dotnet uses: actions/setup-dotnet@v1 with: - dotnet-version: '6.0.x' + dotnet-version: '8.0.x' - name: Build run: dotnet build --configuration Release /p:Version=${VERSION} working-directory: src