Skip to content

Commit

Permalink
Merge pull request #22 from mika-f/fix/shuffle-declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
mika-f committed Feb 28, 2024
2 parents d4549d1 + f42d173 commit eb1de4a
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/Plana.Composition.Extensions/ISymbolExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@
// 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;

// 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)
Expand All @@ -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
Expand Down Expand Up @@ -74,4 +75,5 @@ public static ImmutableArray<ISymbol> ImplicitInterfaceImplementations(this ISym
{
return symbol.ExplicitOrImplicitInterfaceImplementations().Except(symbol.ExplicitInterfaceImplementations()).ToImmutableArray();
}
*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,38 @@ public PlanaRandom()
}
".Trim());
}

[Fact]
public async Task RemoveRegionAndEndregionPreprocessors()
{
var container = new PlanaContainer<ShuffleMemberDeclarations>();
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<ShuffleMemberDeclarations>();
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"));
}
}
18 changes: 18 additions & 0 deletions src/Plana.Composition.ShuffleDeclarations/RemovePragmaRewriter.cs
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
@@ -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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,24 @@ public void BindParameters(IPlanaPluginParameterBinder binder)
// Nothing to do
}


public async Task ObfuscateAsync(IPlanaPluginRunContext context)
{
var transformers = new List<CSharpSyntaxRewriter>
{
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);
}
}
}
8 changes: 8 additions & 0 deletions src/Plana.Testing/InlineSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ public Task NoDiffs()
return Task.CompletedTask;
}

public Task<bool> 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<T> GetSyntax<T>() where T : CSharpSyntaxNode
{
return await GetSyntax<T>(_ => true);
Expand Down
3 changes: 2 additions & 1 deletion src/Plana.Testing/PlanaContainer{T}.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ public Task<T> 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);

Expand All @@ -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<InlineSource> GetSourceByPathAsync(string path)

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (ubuntu-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.

Check warning on line 72 in src/Plana.Testing/PlanaContainer{T}.cs

View workflow job for this annotation

GitHub Actions / build (windows-latest)

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
Expand Down
2 changes: 1 addition & 1 deletion src/Plana/Obfuscator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task<IReadOnlyCollection<IDocument>> RunAsync(RunKind kind, IPlanaR
await instance.RunAsync(context);
await workspace.CommitAsync(context.CancellationToken);
}
catch (Exception ex)
catch
{
await workspace.RollbackAsync(ct);
}
Expand Down

0 comments on commit eb1de4a

Please sign in to comment.