diff --git a/src/Plana.Composition.Extensions/ISymbolExtensions.cs b/src/Plana.Composition.Extensions/ISymbolExtensions.cs index 2f791e7..d067212 100644 --- a/src/Plana.Composition.Extensions/ISymbolExtensions.cs +++ b/src/Plana.Composition.Extensions/ISymbolExtensions.cs @@ -3,8 +3,6 @@ // Licensed under the MIT License. See LICENSE in the project root for license information. // ------------------------------------------------------------------------------------------ -using System.Collections.Immutable; - using Microsoft.CodeAnalysis; namespace Plana.Composition.Extensions; @@ -12,6 +10,7 @@ namespace Plana.Composition.Extensions; // ReSharper disable once InconsistentNaming public static class ISymbolExtensions { +#pragma warning disable CS8619 public static ISymbol? GetInterfaceSymbol(this ISymbol symbol) { if (symbol.Kind != SymbolKind.Method && symbol.Kind != SymbolKind.Property && symbol.Kind != SymbolKind.Event) @@ -32,7 +31,9 @@ public static class ISymbolExtensions return implementations.FirstOrDefault(w => w.Implementation?.Equals(symbol, SymbolEqualityComparer.Default) == true).Interface; } +#pragma warning restore CS8619 + /* // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // ref: https://sourceroslyn.io/#Microsoft.CodeAnalysis.Workspaces/J/s/src/Workspaces/SharedUtilitiesAndExtensions/Compiler/Core/Extensions/ISymbolExtensions.cs/ISymbolExtensions.cs,88c7a12382fb60b6 @@ -74,4 +75,5 @@ public static ImmutableArray ImplicitInterfaceImplementations(this ISym { return symbol.ExplicitOrImplicitInterfaceImplementations().Except(symbol.ExplicitInterfaceImplementations()).ToImmutableArray(); } + */ } \ No newline at end of file diff --git a/src/Plana.Composition.ShuffleDeclarations.Tests/ShuffleMemberDeclarationsTest.cs b/src/Plana.Composition.ShuffleDeclarations.Tests/ShuffleMemberDeclarationsTest.cs index e376e78..ffa78be 100644 --- a/src/Plana.Composition.ShuffleDeclarations.Tests/ShuffleMemberDeclarationsTest.cs +++ b/src/Plana.Composition.ShuffleDeclarations.Tests/ShuffleMemberDeclarationsTest.cs @@ -89,4 +89,38 @@ public PlanaRandom() } ".Trim()); } + + [Fact] + public async Task RemoveRegionAndEndregionPreprocessors() + { + var container = new PlanaContainer(); + await container.RunAsync("../../../../Plana.Composition.RenameSymbols/Plana.Composition.RenameSymbols.csproj"); + + var source = await container.GetSourceByPathAsync("CSharpSymbolsWalker.cs"); + + await source.HasDiffs(); + + Assert.False(await source.ContainsAsync("#region")); + Assert.False(await source.ContainsAsync("#endregion")); + } + + [Fact(Skip = "Not Implemented Yet")] + public Task KeepIfAndEndIfPreprocessors() + { + return Task.CompletedTask; + } + + [Fact] + public async Task RemovePragmaDisableAndRestorePreprocessors() + { + var container = new PlanaContainer(); + await container.RunAsync("../../../../Plana.Testing/Plana.Testing.csproj"); + + var source = await container.GetSourceByPathAsync("PlanaContainer{T}.cs"); + + await source.HasDiffs(); + + Assert.False(await source.ContainsAsync("#pragma warning disable")); + Assert.False(await source.ContainsAsync("#pragma warning restore")); + } } \ No newline at end of file diff --git a/src/Plana.Composition.ShuffleDeclarations/RemovePragmaRewriter.cs b/src/Plana.Composition.ShuffleDeclarations/RemovePragmaRewriter.cs new file mode 100644 index 0000000..9604a00 --- /dev/null +++ b/src/Plana.Composition.ShuffleDeclarations/RemovePragmaRewriter.cs @@ -0,0 +1,18 @@ +// ------------------------------------------------------------------------------------------ +// Copyright (c) Natsuneko. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// ------------------------------------------------------------------------------------------ + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Plana.Composition.ShuffleDeclarations; + +internal class RemovePragmaRewriter() : CSharpSyntaxRewriter(true) +{ + public override SyntaxNode? VisitPragmaWarningDirectiveTrivia(PragmaWarningDirectiveTriviaSyntax node) + { + return SyntaxFactory.SkippedTokensTrivia(); + } +} \ No newline at end of file diff --git a/src/Plana.Composition.ShuffleDeclarations/RemoveRegionAndEndRegionRewriter.cs b/src/Plana.Composition.ShuffleDeclarations/RemoveRegionAndEndRegionRewriter.cs new file mode 100644 index 0000000..e9ae45a --- /dev/null +++ b/src/Plana.Composition.ShuffleDeclarations/RemoveRegionAndEndRegionRewriter.cs @@ -0,0 +1,23 @@ +// ------------------------------------------------------------------------------------------ +// Copyright (c) Natsuneko. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. +// ------------------------------------------------------------------------------------------ + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +namespace Plana.Composition.ShuffleDeclarations; + +internal class RemoveRegionAndEndRegionRewriter() : CSharpSyntaxRewriter(true) +{ + public override SyntaxNode? VisitRegionDirectiveTrivia(RegionDirectiveTriviaSyntax node) + { + return SyntaxFactory.SkippedTokensTrivia(); + } + + public override SyntaxNode? VisitEndRegionDirectiveTrivia(EndRegionDirectiveTriviaSyntax node) + { + return SyntaxFactory.SkippedTokensTrivia(); + } +} \ No newline at end of file diff --git a/src/Plana.Composition.ShuffleDeclarations/ShuffleMemberDeclarations.cs b/src/Plana.Composition.ShuffleDeclarations/ShuffleMemberDeclarations.cs index 204cf1c..0574098 100644 --- a/src/Plana.Composition.ShuffleDeclarations/ShuffleMemberDeclarations.cs +++ b/src/Plana.Composition.ShuffleDeclarations/ShuffleMemberDeclarations.cs @@ -23,15 +23,24 @@ public void BindParameters(IPlanaPluginParameterBinder binder) // Nothing to do } + public async Task ObfuscateAsync(IPlanaPluginRunContext context) { + var transformers = new List + { + new RemoveRegionAndEndRegionRewriter(), + new RemovePragmaRewriter(), + new CSharpDeclarationRewriter(context.SecureRandom) + }; + foreach (var document in context.Solution.Projects.SelectMany(w => w.Documents)) { - var rewriter = new CSharpDeclarationRewriter(context.SecureRandom); - var oldNode = await document.SyntaxTree.GetRootAsync(context.CancellationToken); - var newNode = (CSharpSyntaxNode)rewriter.Visit(oldNode); + var node = await document.SyntaxTree.GetRootAsync(context.CancellationToken); + + foreach (var transformer in transformers) + node = (CSharpSyntaxNode)transformer.Visit(node); - await document.ApplyChangesAsync(newNode, context.CancellationToken); + await document.ApplyChangesAsync(node, context.CancellationToken); } } } \ No newline at end of file diff --git a/src/Plana.Testing/InlineSource.cs b/src/Plana.Testing/InlineSource.cs index 04c3ab6..3154d8f 100644 --- a/src/Plana.Testing/InlineSource.cs +++ b/src/Plana.Testing/InlineSource.cs @@ -47,6 +47,14 @@ public Task NoDiffs() return Task.CompletedTask; } + public Task ContainsAsync(string str) + { + if (document == null) + Assert.Fail("output and/or input is null"); + + return Task.FromResult(document.SyntaxTree.ToNormalizedFullString().Contains(str)); + } + public async Task GetSyntax() where T : CSharpSyntaxNode { return await GetSyntax(_ => true); diff --git a/src/Plana.Testing/PlanaContainer{T}.cs b/src/Plana.Testing/PlanaContainer{T}.cs index 34b021f..d9217be 100644 --- a/src/Plana.Testing/PlanaContainer{T}.cs +++ b/src/Plana.Testing/PlanaContainer{T}.cs @@ -51,11 +51,11 @@ public Task Instantiate() return Task.FromResult(instance); } +#pragma warning disable CS8774 [MemberNotNull(nameof(Workspace), nameof(Sources), nameof(_root))] public async Task RunAsync(string path = "../../../../Plana.sln", int seed = 150) { var logger = new Logger(); - var source = new CancellationTokenSource(); Workspace = path.EndsWith(".sln") ? await SolutionWorkspace.CreateWorkspaceAsync(new FileInfo(path), logger, CancellationToken.None) : await ProjectWorkspace.CreateWorkspaceAsync(new FileInfo(path), logger, CancellationToken.None); @@ -67,6 +67,7 @@ public async Task RunAsync(string path = "../../../../Plana.sln", int seed = 150 Sources = await obfuscator.RunAsync(RunKind.Obfuscate, random, random, CancellationToken.None); } +#pragma warning restore CS8774 public async Task GetSourceByPathAsync(string path) { diff --git a/src/Plana/Obfuscator.cs b/src/Plana/Obfuscator.cs index 9207f22..cc3e8b9 100644 --- a/src/Plana/Obfuscator.cs +++ b/src/Plana/Obfuscator.cs @@ -35,7 +35,7 @@ public async Task> RunAsync(RunKind kind, IPlanaR await instance.RunAsync(context); await workspace.CommitAsync(context.CancellationToken); } - catch (Exception ex) + catch { await workspace.RollbackAsync(ct); }