Пример #1
0
        /// <summary>
        /// Logs the generated Q# code for the part of the given evaluated syntax tree that corresponds to each file
        /// in the given compilation as Information using the given logger.
        /// If the given evaluated tree is null, queries the tree contained in the given compilation instead.
        /// If the id of a file is consistent with the one assigned to a code snippet,
        /// strips the lines of code that correspond to the wrapping defined by WrapSnippet.
        /// Throws an ArgumentException if this is not possible because the given syntax tree is inconsistent with that wrapping.
        /// Throws an ArgumentNullException if the given compilation is null.
        /// </summary>
        private static void PrintGeneratedQs(IEnumerable <QsNamespace> evaluatedTree, Compilation compilation, ILogger logger)
        {
            if (compilation == null)
            {
                throw new ArgumentNullException(nameof(compilation));
            }
            evaluatedTree = evaluatedTree ?? compilation.SyntaxTree.Values;

            foreach (var file in compilation.SourceFiles)
            {
                if (Options.IsCodeSnippet(file))
                {
                    var subtree = evaluatedTree.Select(ns => FilterBySourceFile.Apply(ns, file)).Where(ns => ns.Elements.Any());
                    var code = new string[] { "" }.Concat(StripSnippetWrapping(subtree).Select(FormatCompilation.FormatStatement));
                    logger.Log(InformationCode.FormattedQsCode, Enumerable.Empty <string>(), messageParam: code.ToArray());
                }
                else
                {
                    var imports = evaluatedTree.ToImmutableDictionary(ns => ns.Name, ns => compilation.OpenDirectives(file, ns.Name).ToImmutableArray());
                    SyntaxTreeToQs.Apply(out List <ImmutableDictionary <NonNullable <string>, string> > generated, evaluatedTree, (file, imports));
                    var code = new string[] { "" }.Concat(generated.Single().Values.Select(nsCode => $"{nsCode}{Environment.NewLine}"));
                    logger.Log(InformationCode.FormattedQsCode, Enumerable.Empty <string>(), file.Value, messageParam: code.ToArray());
                };
            }
        }
Пример #2
0
        /// <summary>
        /// Generates formatted Q# code based on the part of the syntax tree that corresponds to each file in the given compilation.
        /// If the id of a file is consistent with the one assigned to a code snippet,
        /// strips the lines of code that correspond to the wrapping defined by WrapSnippet.
        /// Throws an ArgumentException if this is not possible because the given syntax tree is inconsistent with that wrapping.
        /// Throws an ArgumentNullException if the given compilation is null.
        /// </summary>
        private static IEnumerable <string> GenerateQsCode(Compilation compilation, NonNullable <string> file, ILogger logger)
        {
            if (compilation == null)
            {
                throw new ArgumentNullException(nameof(compilation));
            }
            if (Options.IsCodeSnippet(file))
            {
                var subtree = compilation.SyntaxTree.Values.Select(ns => FilterBySourceFile.Apply(ns, file)).Where(ns => ns.Elements.Any());
                return(DiagnoseCompilation.StripSnippetWrapping(subtree).Select(FormatStatement));
            }
            else
            {
                var imports = compilation.SyntaxTree.Values
                              .ToImmutableDictionary(ns => ns.Name, ns => compilation.OpenDirectives(file, ns.Name).ToImmutableArray());
                var success = SyntaxTreeToQs.Apply(out List <ImmutableDictionary <NonNullable <string>, string> > generated, compilation.SyntaxTree.Values, (file, imports));
                if (!success)
                {
                    logger?.Log(WarningCode.UnresolvedItemsInGeneratedQs, Enumerable.Empty <string>(), file.Value);
                }

                return(generated.Single().Select(entry =>
                {
                    var nsComments = compilation.NamespaceComments(file, entry.Key);
                    string FormatComments(IEnumerable <string> comments) =>
                    String.Join(Environment.NewLine,
                                comments.Select(line => line.Trim()).Select(line => String.IsNullOrWhiteSpace(line) ? "" : $"// {line}")
                                ).Trim();
                    var leadingComments = entry.Value.StartsWith("///")
                        ? $"{FormatComments(nsComments.OpeningComments)}{Environment.NewLine}"
                        : FormatComments(nsComments.OpeningComments);
                    var trailingComments = FormatComments(nsComments.ClosingComments);

                    var code = new string[] { leadingComments, entry.Value, trailingComments }.Where(s => !String.IsNullOrWhiteSpace(s));
                    return String.Join(Environment.NewLine, code);
                }));
            };
        }