Esempio n. 1
0
    void OnClosed(object sender, EventArgs e)
    {
        if (ReplayHost == null)
        {
            return;
        }
        ReplayHost.AdornmentChanged -= ReplayHostAdornmentChanged;
        ReplayHost.Erred            -= ReplayHostErred;

        ReplayHost toDispose = null;

        lock (ReplayHosts)
        {
            var t = ReplayHosts[Project.OutputFilePath];
            t = Tuple.Create(t.Item1, t.Item2 - 1);
            if (t.Item2 == 0)
            {
                ReplayHosts.Remove(Project.OutputFilePath); toDispose = t.Item1;
            }
            else
            {
                ReplayHosts[Project.OutputFilePath] = t;
            }
        }
        toDispose?.Dispose();

        ReplayHost = null;
    }
Esempio n. 2
0
    static async Task TestClientAsync()
    {
        //var workspace = Microsoft.CodeAnalysis.MSBuild.MSBuildWorkspace.Create();
        //var solution = await workspace.OpenSolutionAsync(@"C:\Users\lwischik\Documents\Visual Studio 2015\Projects\ConsoleApplicationCS\ConsoleApplicationCS.sln");
        //var project = solution.Projects.Single();

        var workspace = new Microsoft.DotNet.ProjectModel.Workspaces.ProjectJsonWorkspace(SampleProjectsDirectory + "/ConsoleApp1");
        var solution  = workspace.CurrentSolution;
        var project   = solution.Projects.Single();
        var txt       = "int x = 15;\r\nint y = x+2;\r\nSystem.Console.WriteLine(y);\r\n";

        project = project.AddDocument("a.csx", txt, null, "c:\\a.csx").WithSourceCodeKind(SourceCodeKind.Script).Project;

        project = await ReplayHost.InstrumentProjectAsync(project, ImmutableArray <Diagnostic> .Empty, CancellationToken.None);

        var document = project.Documents.FirstOrDefault(d => Path.GetFileName(d.FilePath) == "a.csx");

        if (document != null)
        {
            Console.WriteLine($"{document.FilePath}\r\n{await document.GetTextAsync()}");
        }
        var result = await ReplayHost.BuildAsync(project, CancellationToken.None);

        foreach (var d in result.Diagnostics)
        {
            if (d.Severity != DiagnosticSeverity.Error && d.Severity != DiagnosticSeverity.Warning)
            {
                continue;
            }
            var path = d.Location.IsInSource ? Path.GetFileName(d.Location.SourceTree.FilePath) : "";
            var line = d.Location.IsInSource ? d.Location.GetMappedLineSpan().StartLinePosition.Line.ToString() : "";
            Console.WriteLine($"{path}({line}):{d.GetMessage()}");
        }
        if (!result.Success)
        {
            return;
        }
        var process = await ReplayHost.LaunchProcessAsync(result.ReplayOutputFilePath, CancellationToken.None);

        var cts  = new CancellationTokenSource();
        var task = Runner(process, cts.Token);
        var cmd  = $"WATCH\t{document.FilePath}\t1\t40\t0";

        Console.WriteLine(cmd);
        await process.PostLineAsync(cmd, CancellationToken.None);

        while (true)
        {
            cmd = await Task.Run(Console.In.ReadLineAsync);

            if (cmd == null)
            {
                break;
            }
            await process.PostLineAsync(cmd, CancellationToken.None);
        }
        cts.Cancel();
        await task.IgnoreCancellation();
    }
Esempio n. 3
0
    static async Task TestScriptInstrumentingAsync()
    {
        var workspace   = new AdhocWorkspace();
        var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "TestProject", "TestProject", LanguageNames.CSharp);
        var project     = workspace.AddProject(projectInfo);
        var src         = SourceText.From(File.ReadAllText(@"C:\Users\ljw10\Documents\Visual Studio 2015\Projects\ScriptApplicationCS\CodeFile1.csx"));
        var document    = workspace.AddDocument(project.Id, "CodeFile1.csx", src).WithSourceCodeKind(SourceCodeKind.Script);

        document = await ReplayHost.InstrumentDocumentAsync(document, null, null, CancellationToken.None);

        Console.WriteLine($"{document.FilePath}\r\n{await document.GetTextAsync()}");
    }
Esempio n. 4
0
    bool Initialize()
    {
        if (DocumentId == null)
        {
            var dte            = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(EnvDTE.DTE)) as EnvDTE.DTE;
            var activeDocument = dte?.ActiveDocument; // sometimes we're constructed/invoked before ActiveDocument has been set
            if (activeDocument != null)
            {
                DocumentId = Workspace.CurrentSolution.GetDocumentIdsWithFilePath(activeDocument.FullName).FirstOrDefault();
            }
            if (DocumentId == null)
            {
                return(false);
            }
        }

        var document = Workspace.CurrentSolution.GetDocument(DocumentId);
        var project  = document?.Project;

        if (project == null)
        {
            return(false);
        }

        if (ReplayHost == null)
        {
            lock (ReplayHosts)
            {
                Tuple <ReplayHost, int> t;
                if (ReplayHosts.TryGetValue(project.OutputFilePath, out t))
                {
                    t = Tuple.Create(t.Item1, t.Item2 + 1);
                }
                else
                {
                    t = Tuple.Create(new ReplayHost(false), 1);
                }
                ReplayHosts[project.OutputFilePath] = t;
                ReplayHost = t.Item1;
            }
            ReplayHost.AdornmentChanged += ReplayHostAdornmentChanged;
            ReplayHost.Erred            += ReplayHostErred;
            var dummy = ReplayHost.ChangeDocumentAsync(Project, null, -1, -1, -1);
        }

        return(true);
    }
Esempio n. 5
0
    static async Task TestCodeInstrumentingAsync()
    {
        var workspace   = new AdhocWorkspace();
        var projectInfo = ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), "TestProject", "TestProject", LanguageNames.CSharp);
        var project     = workspace.AddProject(projectInfo);
        var txt         = @"
using System;

class Program
{
    static void Main()
    {
        Console.WriteLine(""hello"");
        int x = 2;
        Console.WriteLine(x);
    }
}
";
        var document    = workspace.AddDocument(project.Id, "program.cs", SourceText.From(txt));

        document = await ReplayHost.InstrumentDocumentAsync(document, null, null, CancellationToken.None);

        Console.WriteLine($"{document.FilePath}\r\n{await document.GetTextAsync()}");
    }
Esempio n. 6
0
    static async Task TestHostAsync(string projectName)
    {
        Project project;

        if (projectName == "ConsoleApp1")
        {
            var workspace = new Microsoft.DotNet.ProjectModel.Workspaces.ProjectJsonWorkspace(SampleProjectsDirectory + "/ConsoleApp1");
            var solution  = workspace.CurrentSolution;
            project = solution.Projects.Single();
            var txt      = "int x = 15;\r\nint y = x+2;\r\nSystem.Console.WriteLine(y);\r\n";
            var document = project.AddDocument("a.csx", txt, null, "c:\\a.csx").WithSourceCodeKind(SourceCodeKind.Script);
            project = document.Project;
        }
        else if (projectName == "Methods")
        {
            project = await ScriptWorkspace.FromDirectoryScanAsync(SampleProjectsDirectory + "/Methods");
        }
        else
        {
            throw new ArgumentException("Projects 'ConsoleApp1' and 'Methods' both work", nameof(projectName));
        }


        var host = new ReplayHost(false);

        host.DiagnosticChanged += (isAdd, tag, diagnostic, deferrable, cancel) =>
        {
            if (isAdd)
            {
                Console.WriteLine($"+D{tag}: {diagnostic.GetMessage()}");
            }
            else
            {
                Console.WriteLine($"-D{tag}");
            }
        };
        host.AdornmentChanged += (isAdd, tag, file, line, content, deferrable, cancel) =>
        {
            if (isAdd)
            {
                Console.WriteLine($"+A{tag}: {Path.GetFileName(file)}({line}) {content}");
            }
            else
            {
                Console.WriteLine($"-A{tag}");
            }
        };
        host.Erred += (error, deferrable, cancel) =>
        {
            Console.WriteLine(error);
        };

        Console.WriteLine("PROJECT");
        await host.ChangeDocumentAsync(project, null, 0, 0, 0);

        Console.WriteLine("VIEW");
        await host.WatchAsync();

        if (projectName == "ConsoleApp1")
        {
            Console.WriteLine("CHANGE");
            var txt      = "int x = 15;\r\nint y = x+2;d\r\nSystem.Console.WriteLine(y);\r\n";
            var document = project.Documents.First(d => d.Name == "a.csx");
            document = document.WithText(SourceText.From(txt));
            project  = document.Project;
            await host.ChangeDocumentAsync(project, "a.csx", 1, 1, 1);
        }
        else if (projectName == "Methods")
        {
            Console.WriteLine("CHANGE MARKDOWN");
            var document = project.Documents.First(d => d.Name == "methods.md");
            var src      = document.GetTextAsync().Result;
            var txt      = src.ToString();
            int i        = src.Lines.FindIndex(line => txt.Substring(line.Span.Start, line.Span.Length) == "Introductory prose");
            txt      = txt.Replace("Introductory prose", "Some\nintroduction.");
            document = document.WithText(SourceText.From(txt));
            project  = document.Project;
            //
            document = project.Documents.First(d => d.Name == "methods.md.csx");
            txt      = ScriptWorkspace.Md2Csx("methods.md", txt);
            document = document.WithText(SourceText.From(txt));
            project  = document.Project;
            await host.ChangeDocumentAsync(project, "methods.md", i, 1, 2);

            Console.WriteLine("VIEW");
            await host.WatchAsync();

            Console.WriteLine("CHANGE CODE");
            document = project.Documents.First(d => d.Name == "methods.md");
            src      = document.GetTextAsync().Result;
            txt      = src.ToString();
            i        = src.Lines.FindIndex(line => txt.Substring(line.Span.Start, line.Span.Length) == "var txt = GetText();");
            txt      = txt.Replace("var txt = GetText();", "var txt = GetText();\n");
            document = document.WithText(SourceText.From(txt));
            project  = document.Project;
            //
            document = project.Documents.First(d => d.Name == "methods.md.csx");
            src      = document.GetTextAsync().Result;
            txt      = src.ToString();
            txt      = txt.Replace("var txt = GetText();", "var txt = GetText();\n");
            document = document.WithText(SourceText.From(txt));
            project  = document.Project;
            //
            await host.ChangeDocumentAsync(project, "methods.md", i, 1, 2);
        }


        Console.WriteLine("DONE");
    }
Esempio n. 7
0
    public static async Task DoSocketAsync(HttpContext http, WebSocket socket)
    {
        Exception _ex = null;

        try
        {
            if (!http.Request.Path.HasValue)
            {
                await socket.SendStringAsync("ERROR\tNo project specified"); return;
            }

            var dir = Directory.GetCurrentDirectory();
            for (; dir != null; dir = Path.GetDirectoryName(dir))
            {
                if (Directory.Exists(dir + "/SampleProjects"))
                {
                    break;
                }
            }
            dir = Path.GetFullPath(dir + "/SampleProjects" + http.Request.Path.Value);
            if (!Directory.Exists(dir))
            {
                await socket.SendStringAsync($"ERROR\tProject doesn't exist '{dir}'"); return;
            }

            // Load the project, and establish the "OK" handshake to show we've done it
            var project = await ScriptWorkspace.FromDirectoryScanAsync(dir);

            await socket.SendStringAsync("OK");

            var cmd = await socket.RecvStringAsync();

            if (cmd != "OK")
            {
                await socket.SendStringAsync($"ERROR\tExpected 'OK' not '{cmd}'"); return;
            }

            // Set up monitoring for diagnostics
            var host = new ReplayHost(true);
            ReplayHost.AdornmentChangedHandler lambdaAdornmentChanged = async(isAdd, tag, file, line, content, deferrable, cancel) =>
            {
                // ADORNMENT remove 7
                // ADORNMENT ADD 7 231 Hello world
                var deferral = deferrable.GetDeferral();
                var msg      = isAdd ? $"ADORNMENT\tadd\t{tag}\t{file}\t{line+1}\t{content}" : $"ADORNMENT\tremove\t{tag}\t{file}";
                if (socket.State != WebSocketState.Closed)
                {
                    await socket.SendStringAsync(msg);
                }
                deferral.Complete();
            };
            ReplayHost.DiagnosticChangedHandler lambdaDiagnosticChanged = async(isAdd, tag, diagnostic, deferrable, cancel) =>
            {
                // DIAGNOSTIC remove 7 file.cs
                // DIAGNOSTIC add 7 file.cs Hidden startLine startCol length msg
                var    deferral = deferrable.GetDeferral();
                string msg;
                if (isAdd)
                {
                    var file = ""; int startLine = -1, startCol = -1, length = 0;
                    if (diagnostic.Location.IsInSource)
                    {
                        var loc = diagnostic.Location.GetMappedLineSpan();
                        file      = loc.HasMappedPath ? loc.Path : diagnostic.Location.SourceTree.FilePath;
                        startLine = loc.StartLinePosition.Line + 1;
                        startCol  = loc.StartLinePosition.Character + 1;
                        length    = diagnostic.Location.SourceSpan.Length;
                    }
                    msg = $"DIAGNOSTIC\tadd\t{tag}\t{file}\t{diagnostic.Severity}\t{startLine}\t{startCol}\t{length}\t{diagnostic.Id}: {diagnostic.GetMessage()}";
                }
                else
                {
                    msg = $"DIAGNOSTIC\tremove\t{tag}";
                }
                if (socket.State != WebSocketState.Closed)
                {
                    await socket.SendStringAsync(msg);
                }
                deferral.Complete();
            };
            ReplayHost.ReplayHostError lambdaErred = async(error, deferrable, cancel) =>
            {
                var deferral = deferrable.GetDeferral();
                if (socket.State != WebSocketState.Closed)
                {
                    await socket.SendStringAsync($"ERROR\tCLIENT: {error}");
                }
                deferral.Complete();
            };

            host.AdornmentChanged  += lambdaAdornmentChanged;
            host.DiagnosticChanged += lambdaDiagnosticChanged;
            host.Erred             += lambdaErred;

            var dummy = host.ChangeDocumentAsync(project, null, -1, -1, -1);

            // Run the conversation!
            while (true)
            {
                cmd = await socket.RecvStringAsync();

                if (cmd == null)
                {
                    host.AdornmentChanged -= lambdaAdornmentChanged; host.DiagnosticChanged -= lambdaDiagnosticChanged; host.Erred -= lambdaErred; return;
                }
                var cmds = cmd.Split(new[] { '\t' });

                if (cmds[0] == "GET")
                {
                    if (cmds.Length != 2)
                    {
                        await socket.SendStringAsync($"ERROR\tExpected 'GET fn', not '{cmd}'"); return;
                    }
                    var document = project.Documents.SingleOrDefault(d => d.Name == cmds[1]);
                    if (document == null)
                    {
                        await socket.SendStringAsync($"ERROR\tFile doesn't exist '{cmds[1]}'"); return;
                    }
                    var s = (await document.GetTextAsync()).ToString().Replace("\\", "\\\\").Replace("\r", "\\r").Replace("\n", "\\n");
                    await socket.SendStringAsync($"GOT\t{cmds[1]}\t{s}");
                }

                else if (cmds[0] == "CHANGE")
                {
                    string file, newContent; int startLine, startCol, oldLineCount, newLineCount, oldLength; Document document;
                    if (cmds.Length != 8 ||
                        (file = cmds[1]) == null ||
                        (document = project.Documents.SingleOrDefault(d => d.Name == file)) == null ||
                        !int.TryParse(cmds[2], out startLine) ||
                        !int.TryParse(cmds[3], out startCol) ||
                        !int.TryParse(cmds[4], out oldLineCount) ||
                        !int.TryParse(cmds[5], out newLineCount) ||
                        !int.TryParse(cmds[6], out oldLength) ||
                        (newContent = cmds[7].Replace("\\n", "\n").Replace("\\r", "\r").Replace("\\\\", "\\")) == null)
                    {
                        await socket.SendStringAsync($"ERROR\tExpected 'CHANGE file startLine startCol oldLineCount newLineCount oldLength newContent', not '{cmd}'");

                        continue;
                    }
                    //
                    var txt = await document.GetTextAsync();

                    var startPosition = txt.Lines[startLine - 1].Start + startCol - 1;
                    var change        = new TextChange(new TextSpan(startPosition, oldLength), newContent);
                    txt      = txt.WithChanges(change);
                    document = document.WithText(txt);
                    project  = document.Project;
                    if (file.EndsWith(".md"))
                    {
                        var csx         = ScriptWorkspace.Md2Csx(file, txt.ToString());
                        var csxDocument = project.Documents.Single(d => d.Name == file + ".csx");
                        csxDocument = csxDocument.WithText(SourceText.From(csx));
                        project     = csxDocument.Project;
                    }
                    //
                    dummy = host.ChangeDocumentAsync(project, document.FilePath, startLine - 1, oldLineCount, newLineCount);
                }

                else if (cmds[0] == "WATCH")
                {
                    string file; int line = -1, count = -1; Document document = null;
                    if ((cmds.Length != 4 && cmds.Length != 2) ||
                        (file = cmds[1]) == null ||
                        (file != "*" && (document = project.Documents.Single(d => d.Name == file)) == null) ||
                        (cmds.Length == 4 && !int.TryParse(cmds[2], out line)) ||
                        (cmds.Length == 4 && !int.TryParse(cmds[3], out count)))
                    {
                        await socket.SendStringAsync($"ERROR\tExpected 'WATCH file line count', got '{cmd}'");

                        continue;
                    }
                    //
                    dummy = host.WatchAsync(file == "*" ? file : document.FilePath, line, count);
                }

                else
                {
                    await socket.SendStringAsync($"ERROR\tServer doesn't recognize command '{cmd}'");
                }
            }
        }
        catch (Exception ex)
        {
            _ex = ex;
        }
        if (_ex != null)
        {
            await socket.SendStringAsync($"ERROR\t{_ex.Message} - {_ex.StackTrace.Replace("\r\n"," || ").Replace("\r"," || ").Replace("\n"," || ")}");
        }
    }