Пример #1
0
        public void WriteResult(IFastJsonWriter writer, object result, IWorkSession session)
        {
            if (result == null)
            {
                writer.WriteValue((string)null);
                return;
            }

            var targetName = session.GetTargetName();

            if (targetName == TargetNames.Ast)
            {
                var astTarget = _astTargets.GetValueOrDefault(session.LanguageName);
                astTarget.SerializeAst(result, writer, session);
                return;
            }

            if (targetName == TargetNames.Run)
            {
                _executor.Serialize((ExecutionResult)result, writer);
                return;
            }

            var decompiler = _decompilers[targetName];

            using (var stream = (Stream)result)
                using (var stringWriter = writer.OpenString()) {
                    decompiler.Decompile(stream, stringWriter);
                }
        }
Пример #2
0
        public async Task <object> ProcessAsync(IWorkSession session, IList <Diagnostic> diagnostics, CancellationToken cancellationToken)
        {
            var targetName = session.GetTargetName();

            if (targetName == TargetNames.Ast)
            {
                var astTarget = _astTargets.GetValueOrDefault(session.LanguageName);
                return(await astTarget.GetAstAsync(session, cancellationToken).ConfigureAwait(false));
            }

            if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                return(null);
            }

            if (targetName == TargetNames.Verify)
            {
                return("✔️ Compilation completed.");
            }

            if (targetName != TargetNames.Run && !_decompilers.ContainsKey(targetName))
            {
                throw new NotSupportedException($"Target '{targetName}' is not (yet?) supported by this branch.");
            }

            MemoryStream assemblyStream = null;
            MemoryStream symbolStream   = null;

            try {
                assemblyStream = _memoryStreamManager.GetStream();
                if (targetName == TargetNames.Run)
                {
                    symbolStream = _memoryStreamManager.GetStream();
                }

                if (!await _compiler.TryCompileToStreamAsync(assemblyStream, symbolStream, session, diagnostics, cancellationToken).ConfigureAwait(false))
                {
                    assemblyStream.Dispose();
                    symbolStream?.Dispose();
                    return(null);
                }
                assemblyStream.Seek(0, SeekOrigin.Begin);
                symbolStream?.Seek(0, SeekOrigin.Begin);
                if (targetName == TargetNames.Run)
                {
                    return(_executor.Execute(assemblyStream, symbolStream, session));
                }

                // it's fine not to Dispose() here -- MirrorSharp will dispose it after calling WriteResult()
                return(assemblyStream);
            }
            catch {
                assemblyStream?.Dispose();
                symbolStream?.Dispose();
                throw;
            }
        }
Пример #3
0
        private string GetAndEnsureTargetName(IWorkSession session)
        {
            var targetName = session.GetTargetName();

            if (targetName == null)
            {
                throw new InvalidOperationException("Target is not set on the session (timing issue?). Please try reloading.");
            }
            return(targetName);
        }
        public void UpdateOutputKind(IWorkSession session, IList <Diagnostic>?diagnostics = null)
        {
            if (session.LanguageName != LanguageNames.CSharp)
            {
                return;
            }

            if (GlobalStatement == null)
            {
                return; // this branch does not support global statements
            }
            if (session.GetTargetName() == TargetNames.Run)
            {
                return; // must always use executable mode for Run
            }
            if (!session.Roslyn.Project.Documents.Single().TryGetSyntaxRoot(out var syntaxRoot))
            {
                if (diagnostics != null) // we must update now, otherwise diagnostics will be incorrect
                {
                    throw new InvalidOperationException("Syntax root was not cached.");
                }
                return; // will update later
            }

            // We can't always mark it as executable as it would require Main() to be present,
            // so we toggle conditionally.
            var shouldBeExecutable = syntaxRoot.ChildNodes().Any(n => n.IsKind(GlobalStatement.Value));
            var isExecutable       = session.Roslyn.Project.CompilationOptions?.OutputKind == ConsoleApplication;

            if (isExecutable == shouldBeExecutable)
            {
                return;
            }

            diagnostics?.RemoveWhere(
                d => shouldBeExecutable
                   ? (d.Id == DiagnosticIds.TopLevelNotInExecutable || d.Id == DiagnosticIds.TopLevelNotInExecutableOld)
                   : (d.Id == DiagnosticIds.NoStaticMain)
                );

            var project = session.Roslyn.Project;

            session.Roslyn.Project = project.WithCompilationOptions(
                project.CompilationOptions !.WithOutputKind(shouldBeExecutable ? ConsoleApplication : DynamicallyLinkedLibrary)
                );
        }
Пример #5
0
        public void WriteResult(IFastJsonWriter writer, object result, IWorkSession session)
        {
            if (result == null)
            {
                writer.WriteValue((string?)null);
                return;
            }

            if (result is string s)
            {
                writer.WriteValue(s);
                return;
            }

            var targetName = session.GetTargetName();

            if (targetName == TargetNames.Ast)
            {
                var astTarget = _astTargets[session.LanguageName];
                astTarget.SerializeAst(result, writer, session);
                return;
            }

            if (targetName == TargetNames.Explain)
            {
                _explainer.Serialize((ExplanationResult)result, writer);
                return;
            }

            if (targetName == TargetNames.Run)
            {
                _executor.Serialize((ExecutionResult)result, writer);
                return;
            }

            var decompiler = _decompilers[targetName];

            using (var streams = (CompilationStreamPair)result)
                using (var stringWriter = writer.OpenString()) {
                    decompiler.Decompile(streams, stringWriter);
                }
        }
Пример #6
0
        public async Task <object?> ProcessAsync(IWorkSession session, IList <Diagnostic> diagnostics, CancellationToken cancellationToken)
        {
            var targetName = session.GetTargetName();

            if (targetName == TargetNames.Ast || targetName == TargetNames.Explain)
            {
                var astTarget = _astTargets[session.LanguageName];
                var ast       = await astTarget.GetAstAsync(session, cancellationToken).ConfigureAwait(false);

                if (targetName == TargetNames.Explain)
                {
                    return(await _explainer.ExplainAsync(ast, session, cancellationToken).ConfigureAwait(false));
                }
                return(ast);
            }

            if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error))
            {
                return(null);
            }

            if (targetName == LanguageNames.VisualBasic)
            {
                return(VisualBasicNotAvailable);
            }

            if (targetName != TargetNames.Run && targetName != TargetNames.Verify && !_decompilers.ContainsKey(targetName))
            {
                throw new NotSupportedException($"Target '{targetName}' is not (yet?) supported by this branch.");
            }

            MemoryStream?assemblyStream = null;
            MemoryStream?symbolStream   = null;

            try {
                assemblyStream = _memoryStreamManager.GetStream();
                if (targetName == TargetNames.Run || targetName == TargetNames.IL)
                {
                    symbolStream = _memoryStreamManager.GetStream();
                }

                var compiled = await _compiler.TryCompileToStreamAsync(assemblyStream, symbolStream, session, diagnostics, cancellationToken).ConfigureAwait(false);

                if (!compiled.assembly)
                {
                    assemblyStream.Dispose();
                    symbolStream?.Dispose();
                    return(null);
                }

                if (targetName == TargetNames.Verify)
                {
                    assemblyStream.Dispose();
                    symbolStream?.Dispose();
                    return("✔️ Compilation completed.");
                }

                assemblyStream.Seek(0, SeekOrigin.Begin);
                symbolStream?.Seek(0, SeekOrigin.Begin);
                var streams = new CompilationStreamPair(assemblyStream, compiled.symbols ? symbolStream : null);
                if (targetName == TargetNames.Run)
                {
                    return(_executor.Execute(streams, session));
                }

                // it's fine not to Dispose() here -- MirrorSharp will dispose it after calling WriteResult()
                return(streams);
            }
            catch {
                assemblyStream?.Dispose();
                symbolStream?.Dispose();
                throw;
            }
        }