public void ExpressionRewriter_CanRewriteExpression_AdditionalArguments() { // Arrange var source = @" using System; using System.Linq.Expressions; public class Program { public static void CalledWithExpression(int x, Expression<Func<object, object>> expression, string name) { } public static void Main(string[] args) { CalledWithExpression(5, x => x, ""Billy""); } } "; var tree = CSharpSyntaxTree.ParseText(source); var compilation = Compile(tree); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); // Act var result = rewriter.Visit(tree.GetRoot()); // Assert var fields = FindFields(result); var field = Assert.Single(fields); Assert.Collection( field.Modifiers, m => Assert.Equal("private", m.ToString()), m => Assert.Equal("static", m.ToString()), m => Assert.Equal("readonly", m.ToString())); var declaration = field.Declaration; Assert.Equal( "global::System.Linq.Expressions.Expression<global::System.Func<object, object>>", declaration.Type.ToString()); var variable = Assert.Single(declaration.Variables); Assert.Equal("__h0", variable.Identifier.ToString()); Assert.Equal("x => x", variable.Initializer.Value.ToString()); var arguments = FindArguments(result); Assert.Equal(3, arguments.Arguments.Count); var argument = Assert.IsType <IdentifierNameSyntax>(arguments.Arguments[1].Expression); Assert.Equal("__h0", argument.Identifier.ToString()); }
public static CSharpCompilation Rewrite(CSharpCompilation compilation) { var rewrittenTrees = new List <SyntaxTree>(); foreach (var tree in compilation.SyntaxTrees) { var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); var rewrittenTree = tree.WithRootAndOptions(rewriter.Visit(tree.GetRoot()), tree.Options); rewrittenTrees.Add(rewrittenTree); } return(compilation.RemoveAllSyntaxTrees().AddSyntaxTrees(rewrittenTrees)); }
private CSharpCompilation CreateCompilation(string compilationContent, string assemblyName) { var sourceText = SourceText.From(compilationContent, Encoding.UTF8); var syntaxTree = _csharpCompiler.CreateSyntaxTree(sourceText).WithFilePath(assemblyName); var compilation = _csharpCompiler .CreateCompilation(assemblyName) .AddSyntaxTrees(syntaxTree); compilation = ExpressionRewriter.Rewrite(compilation); var compilationContext = new RoslynCompilationContext(compilation); _compilationCallback(compilationContext); compilation = compilationContext.Compilation; return(compilation); }
public void ExpressionRewriter_CanRewriteExpression_ComplexFormatting() { // Arrange var source = @" using System; using System.Linq.Expressions; public class Program { public static void CalledWithExpression(int z, Expression<Func<Person, int>> expression) { } public static void Main(string[] args) { CalledWithExpression( 17, x => x.Name. Length ); } } public class Person { public string Name { get; set; } } "; var tree = CSharpSyntaxTree.ParseText(source); var originalArguments = FindArguments(tree.GetRoot()); var originalSpan = originalArguments.GetLocation().GetMappedLineSpan(); var compilation = Compile(tree); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); // Act var result = rewriter.Visit(tree.GetRoot()); // Assert var arguments = FindArguments(result); Assert.Equal(originalSpan, arguments.GetLocation().GetMappedLineSpan()); }
public void ExpressionRewriter_DoesNotThrowsOnUnknownTypes() { // Arrange var source = @" using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Razor; public class ExamplePage : RazorPage { public IViewComponentHelper Component { get; set; } public override async Task ExecuteAsync() { Write( await Component.InvokeAsync( ""SomeComponent"", item => new HelperResult((__razor_template_writer) => WriteLiteralTo(__razor_template_writer, ""Hello World"")))); } } "; var tree = CSharpSyntaxTree.ParseText(source); // Allow errors here because of an anomaly where Roslyn (depending on code sample) will finish compilation // without diagnostic errors. This test case replicates that scenario by allowing a semantic model with // errors to be visited by the expression rewriter to validate unexpected exceptions aren't thrown. // Error created: "Cannot convert lambda expression to type 'object' because it is not a delegate type." var compilation = Compile(tree, allowErrors: true); var semanticModel = compilation.GetSemanticModel(tree, ignoreAccessibility: true); var rewriter = new ExpressionRewriter(semanticModel); var root = tree.GetRoot(); // Act var result = rewriter.Visit(root); // Assert Assert.True(root.IsEquivalentTo(result)); }