Пример #1
0
        public void FilterActiveViewport_Should_Return_Viewport_In_ActiveBufferId()
        {
            var text = @"
using System;
namespace RoslynRecorder
{
    class Program
    {
        static void Main(string[] args)
        {
{|regionStart:#region test|}
            int a = 0;
            Console.WriteLine(""Entry Point"");
{|regionEnd:#endregion|}
        }
#region notthis
    }
#endregion
}".EnforceLF();

            MarkupTestFile.GetNamedSpans(text, out var code, out var spans);
            var workspace      = new Workspace(files: new[] { new File("testFile.cs", code) });
            var viewports      = workspace.ExtractViewPorts();
            var activeViewport = InstrumentationLineMapper.FilterActiveViewport(viewports, BufferId.Parse("testFile.cs@test")).First();

            activeViewport.Region.Start.Should().Be(spans["regionStart"].First().End);
            activeViewport.Region.End.Should().Be(spans["regionEnd"].First().Start);
        }
Пример #2
0
        public async Task MapLineLocationsRelativeToViewport_Does_Nothing_Without_Viewport()
        {
            var(augmentation, locations, document, _, _) = await Setup(@"Console.WriteLine(""hello world"");");

            var(newAugmentation, newLocations) = await InstrumentationLineMapper.MapLineLocationsRelativeToViewportAsync(augmentation, locations, document);

            augmentation.Should().BeEquivalentTo(newAugmentation);
            locations.Should().BeEquivalentTo(newLocations);
        }
Пример #3
0
        public void FilterActiveViewport_Should_Return_Empty_Array_If_No_Regions()
        {
            var text           = Sources.simple.EnforceLF();
            var workspace      = new Workspace(files: new[] { new File("testFile.cs", text) });
            var viewports      = workspace.ExtractViewPorts();
            var activeViewport = InstrumentationLineMapper.FilterActiveViewport(viewports, BufferId.Parse("testFile.cs@test"));

            activeViewport.Should().BeEmpty();
        }
Пример #4
0
        public async Task MapLineLocationsRelativeToViewport_Maps_Augmentation_FilePosition_Correctly()
        {
            var(augmentation, locations, document, viewport, spans) = await Setup(
                @"
{|a:int a = 0;|}
{|b:Console.WriteLine(""Entry Point"");|}
"
                );

            var(newAugmentation, newLocations) = await InstrumentationLineMapper.MapLineLocationsRelativeToViewportAsync(augmentation, locations, document, viewport);

            var linePositions         = newAugmentation.Data.Values.Select(state => state.CurrentFilePosition.Line);
            var expectedLinePositions = spans.Values.Select(span => span.First().Start.Line);

            linePositions.Should().Equal(expectedLinePositions);
        }
Пример #5
0
        public async Task MapLineLocationsRelativeToViewport_Maps_Variable_Location_Correctly()
        {
            var(augmentation, locations, document, viewport, spans) = await Setup(
                @"
{|a:int a = 0;|}
{|b:Console.WriteLine(""Entry Point"");|}
");

            var(newAugmentation, newLocations) = await InstrumentationLineMapper.MapLineLocationsRelativeToViewportAsync(augmentation, locations, document, viewport);

            var variableLocationLines = newLocations.Data.Values
                                        .SelectMany(locs => locs)
                                        .Select(loc => loc.StartLine);
            var expectedLocations = spans["a"].First().Start.Line;

            variableLocationLines.Should().Equal(new[] { expectedLocations });
        }
Пример #6
0
        public async Task MapLineLocationsRelativeToViewport_Maps_Multiple_Variables_On_Single_Line_Correctly()
        {
            var(augmentation, locations, document, viewport, spans) = await Setup(
                @"
{|variables:var (a, b) = (1, 2);|}
");

            var(newAugmentation, newLocations) = await InstrumentationLineMapper.MapLineLocationsRelativeToViewportAsync(augmentation, locations, document, viewport);

            var variableLocationLines = newLocations.Data.Values
                                        .SelectMany(locs => locs)
                                        .Select(loc => loc.StartLine)
                                        .Distinct();
            var expectedLocations = spans["variables"].First().Start.Line;

            variableLocationLines.Should().Equal(new[] { expectedLocations });
        }
Пример #7
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);
        }