예제 #1
0
파일: Snippets.cs 프로젝트: vxfield/iqsharp
        /// <summary>
        /// Compiles the given code.
        /// If the operations defined in this code are already defined
        /// in existing Snippets, those Snippets are skipped.
        /// If successful, this updates the AssemblyInfo
        /// with the new operations found in the Snippet.
        /// If errors are found during compilation, a `CompilationErrorsException` is triggered
        /// with the list of errors found.
        /// If successful, the list of snippets is updated to include those that were part of the
        /// compilation and it will return a new Snippet with the warnings and Q# elements
        /// reported by the compiler.
        /// </summary>
        public Snippet Compile(string code)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentNullException(nameof(code));
            }

            var duration = Stopwatch.StartNew();

            // We add exactly one line of boilerplate code at the beginning of each snippet,
            // so tell the logger to subtract one from all displayed line numbers.
            var logger = new QSharpLogger(Logger, lineNrOffset: -1);

            try
            {
                var snippets = SelectSnippetsToCompile(code).ToArray();
                var assembly = Compiler.BuildSnippets(snippets, _metadata.Value, logger, Path.Combine(Workspace.CacheFolder, "__snippets__.dll"));

                if (logger.HasErrors)
                {
                    throw new CompilationErrorsException(logger.Errors.ToArray());
                }

                foreach (var entry in Compiler.IdentifyOpenedNamespaces(code))
                {
                    Compiler.AutoOpenNamespaces[entry.Key] = entry.Value;
                }

                // populate the original snippet with the results of the compilation:
                Snippet populate(Snippet s) =>
                new Snippet()
                {
                    id       = string.IsNullOrWhiteSpace(s.id) ? Guid.NewGuid().ToString() : s.id,
                    code     = s.code,
                    warnings = logger.Logs
                               .Where(m => m.Source == CompilationUnitManager.GetFileId(s.Uri).Value)
                               .Select(logger.Format)
                               .ToArray(),
                    Elements = assembly?.SyntaxTree?
                               .SelectMany(ns => ns.Elements)
                               .Where(c => c.SourceFile() == CompilationUnitManager.GetFileId(s.Uri).Value)
                               .ToArray()
                };

                AssemblyInfo = assembly;
                Items        = snippets.Select(populate).ToArray();

                return(Items.Last());
            }
            finally
            {
                duration.Stop();
                var status   = logger.HasErrors ? "error" : "ok";
                var errorIds = logger.ErrorIds.ToArray();
                SnippetCompiled?.Invoke(this, new SnippetCompiledEventArgs(status, errorIds, Compiler.AutoOpenNamespaces.Keys.ToArray(), duration.Elapsed));
            }
        }
예제 #2
0
        /// <summary>
        /// Compiles the given code.
        /// If the operations defined in this code are already defined
        /// in existing Snippets, those Snippets are skipped.
        /// If successful, this updates the AssemblyInfo
        /// with the new operations found in the Snippet.
        /// If errors are found during compilation, a `CompilationErrorsException` is triggered
        /// with the list of errors found.
        /// If successful, the list of snippets is updated to include those that were part of the
        /// compilation and it will return a new Snippet with the warnings and Q# elements
        /// reported by the compiler.
        /// </summary>
        public Snippet Compile(string code)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentNullException(nameof(code));
            }

            var duration           = Stopwatch.StartNew();
            var errorCodesToIgnore = new List <QsCompiler.Diagnostics.ErrorCode>()
            {
                QsCompiler.Diagnostics.ErrorCode.EntryPointInLibrary,   // Ignore any @EntryPoint() attributes found in snippets.
            };
            var logger = new QSharpLogger(Logger, errorCodesToIgnore);

            try
            {
                var snippets = SelectSnippetsToCompile(code).ToArray();
                var assembly = Compiler.BuildSnippets(snippets, _metadata.Value, logger, Path.Combine(Workspace.CacheFolder, "__snippets__.dll"));

                if (logger.HasErrors)
                {
                    throw new CompilationErrorsException(logger.Errors.ToArray());
                }

                // populate the original snippet with the results of the compilation:
                Snippet populate(Snippet s) =>
                new Snippet()
                {
                    id       = string.IsNullOrWhiteSpace(s.id) ? Guid.NewGuid().ToString() : s.id,
                    code     = s.code,
                    warnings = logger.Logs.Where(m => m.Source == s.Uri.AbsolutePath).Select(logger.Format).ToArray(),
                    Elements = assembly?.SyntaxTree?
                               .SelectMany(ns => ns.Elements)
                               .Where(c => c.SourceFile() == s.Uri.AbsolutePath)
                               .ToArray()
                };

                AssemblyInfo = assembly;
                Items        = snippets.Select(populate).ToArray();

                return(Items.Last());
            }
            finally
            {
                duration.Stop();
                var status   = logger.HasErrors ? "error" : "ok";
                var errorIds = logger.ErrorIds.ToArray();
                SnippetCompiled?.Invoke(this, new SnippetCompiledEventArgs(status, errorIds, duration.Elapsed));
            }
        }
예제 #3
0
        /// <summary>
        /// Compiles the given code.
        /// If the operations defined in this code are already defined
        /// in existing Snippets, those Snippets are skipped.
        /// If successful, this updates the AssemblyInfo
        /// with the new operations found in the Snippet.
        /// If errors are found during compilation, a `CompilationErrorsException` is triggered
        /// with the list of errors found.
        /// If successful, the list of snippets is updated to include those that were part of the
        /// compilation and it will return a new Snippet with the warnings and Q# elements
        /// reported by the compiler.
        /// </summary>
        public Snippet Compile(string code)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentNullException(nameof(code));
            }

            var duration = Stopwatch.StartNew();
            var logger   = new QSharpLogger(Logger);

            try
            {
                var snippets   = SelectSnippetsToCompile(code).ToArray();
                var references = Workspace.HasErrors
                    ? GlobalReferences.CompilerMetadata
                    : GlobalReferences?.CompilerMetadata.WithAssemblies(Workspace.AssemblyInfo);
                var assembly = Compiler.BuildSnippets(snippets, references, logger, Path.Combine(Workspace.CacheFolder, "__snippets__.dll"));

                if (logger.HasErrors)
                {
                    throw new CompilationErrorsException(logger.Errors.ToArray());
                }

                // populate the original snippet with the results of the compilation:
                Snippet populate(Snippet s) =>
                new Snippet()
                {
                    id       = string.IsNullOrWhiteSpace(s.id) ? System.Guid.NewGuid().ToString() : s.id,
                    code     = s.code,
                    warnings = logger.Logs.Where(m => m.Source == s.Uri.AbsolutePath).Select(logger.Format).ToArray(),
                    Elements = assembly?.SyntaxTree?
                               .SelectMany(ns => ns.Elements)
                               .Where(c => c.SourceFile() == s.Uri.AbsolutePath)
                               .ToArray()
                };

                AssemblyInfo = assembly;
                Items        = snippets.Select(populate).ToArray();

                return(Items.Last());
            }
            finally
            {
                duration.Stop();
                var status   = logger.HasErrors ? "error" : "ok";
                var errorIds = logger.ErrorIds.ToArray();
                SnippetCompiled?.Invoke(this, new SnippetCompiledEventArgs(status, errorIds, duration.Elapsed));
            }
        }