Beispiel #1
0
                             )> Setup(string viewportCodeMarkup)
        {
            MarkupTestFile.GetNamedSpans(viewportCodeMarkup, out var viewportCode, out var textSpans);
            var code = $@"
using System;
using System.Linq;
namespace RoslynRecorder
{{
    class Program
    {{
        static void Main(string[] args)
        {{
        int thisShouldBeIgnored = 1;
#region test
        {viewportCode}
#endregion
        }}
    }}
}}
";
            var linePositionSpans = textSpans.ToDictionary(
                kv => kv.Key,
                kv => kv.Value.Select(span => span.ToLinePositionSpan(SourceText.From(viewportCode))
                                      )
                );

            var withLF    = code.EnforceLF();
            var document  = Sources.GetDocument(withLF);
            var workspace = new Workspace(files: new[] { new File("test.cs", withLF) });
            var visitor   = new InstrumentationSyntaxVisitor(document, await document.GetSemanticModelAsync());
            var viewport  = workspace.ExtractViewPorts().DefaultIfEmpty(null).First();

            return(visitor.Augmentations, visitor.VariableLocations, document, viewport, linePositionSpans);
        }
Beispiel #2
0
        private async Task <string> RewriteCodeWithInstrumentation(string text)
        {
            var document  = Sources.GetDocument(text, true);
            var visitor   = new InstrumentationSyntaxVisitor(document, await document.GetSemanticModelAsync());
            var rewritten = new InstrumentationSyntaxRewriter(
                visitor.Augmentations.Data.Keys,
                visitor.VariableLocations,
                visitor.Augmentations
                );

            return(rewritten.ApplyToTree(document.GetSyntaxTreeAsync().Result).GetText().ToString().EnforceLF());
        }
        public async Task Static_Fields_Are_Captured_In_Static_Methods()
        {
            //arrange
            var document = Sources.GetDocument(Sources.withStaticAndNonStaticField, true);
            InstrumentationSyntaxVisitor visitor = new InstrumentationSyntaxVisitor(document, await document.GetSemanticModelAsync());

            //act
            var augmentations = visitor.Augmentations.Data.Values.ToList();

            //assert
            Assert.Single(augmentations[0].Fields);
            Assert.Contains(augmentations[0].Fields, f => f.Name == "a");
        }
Beispiel #4
0
        private async Task FindAndValidateVariablesAsync(string markup)
        {
            MarkupTestFile.GetNamedSpans(
                markup,
                out var text,
                out IDictionary <string, ImmutableArray <TextSpan> > spans);

            var document = Sources.GetDocument(text);
            var fileLineLocationSpans = ConvertSpans(spans, await document.GetTextAsync());

            var visitor   = new InstrumentationSyntaxVisitor(document, await document.GetSemanticModelAsync());
            var locations = visitor.VariableLocations.Data.ToDictionary(
                key => key.Key.Name,
                values => values.Value.Select(location => location.ToLinePositionSpan()));

            foreach (var kv in locations)
            {
                var expected = new HashSet <LinePositionSpan>(fileLineLocationSpans[kv.Key]);
                var actual   = new HashSet <LinePositionSpan>(kv.Value);
                Assert.Equal(expected, actual);
            }
        }
Beispiel #5
0
        private static async Task <Compilation> AugmentCompilationAsync(
            IEnumerable <Viewport> viewports,
            Compilation compilation,
            Document document,
            BufferId activeBufferId,
            Package build)
        {
            var regions = InstrumentationLineMapper.FilterActiveViewport(viewports, activeBufferId)
                          .Where(v => v.Destination?.Name != null)
                          .GroupBy(v => v.Destination.Name,
                                   v => v.Region,
                                   (name, region) => new InstrumentationMap(name, region))
                          .ToArray();

            var solution       = document.Project.Solution;
            var newCompilation = compilation;

            foreach (var tree in newCompilation.SyntaxTrees)
            {
                var replacementRegions = regions.FirstOrDefault(r => tree.FilePath.EndsWith(r.FileToInstrument))?.InstrumentationRegions;

                var subdocument = solution.GetDocument(tree);
                var visitor     = new InstrumentationSyntaxVisitor(subdocument, await subdocument.GetSemanticModelAsync(), replacementRegions);
                var linesWithInstrumentation = visitor.Augmentations.Data.Keys;

                var activeViewport = viewports.DefaultIfEmpty(null).First();

                var(augmentationMap, variableLocationMap) =
                    await InstrumentationLineMapper.MapLineLocationsRelativeToViewportAsync(
                        visitor.Augmentations,
                        visitor.VariableLocations,
                        document,
                        activeViewport);

                var rewrite = new InstrumentationSyntaxRewriter(
                    linesWithInstrumentation,
                    variableLocationMap,
                    augmentationMap);
                var newRoot = rewrite.Visit(tree.GetRoot());
                var newTree = tree.WithRootAndOptions(newRoot, tree.Options);

                newCompilation = newCompilation.ReplaceSyntaxTree(tree, newTree);
            }

            var instrumentationSyntaxTree = build.GetInstrumentationEmitterSyntaxTree();

            newCompilation = newCompilation.AddSyntaxTrees(instrumentationSyntaxTree);

            var augmentedDiagnostics = newCompilation.GetDiagnostics();

            if (augmentedDiagnostics.ContainsError())
            {
                throw new InvalidOperationException(
                          $@"Augmented source failed to compile

Diagnostics
-----------
{string.Join(NewLine, augmentedDiagnostics)}

Source
------
{newCompilation.SyntaxTrees.Select(s => $"// {s.FilePath ?? "(anonymous)"}{NewLine}//---------------------------------{NewLine}{NewLine}{s}").Join(NewLine + NewLine)}");
            }

            return(newCompilation);
        }