예제 #1
0
        // errors 70**

        internal static Diagnostic LoadError(ErrorCode code, IEnumerable <string> args, string source) =>
        new Diagnostic
        {
            Severity = DiagnosticSeverity.Error,
            Code     = Errors.Code(code),
            Source   = source,
            Message  = DiagnosticItem.Message(code, args ?? Enumerable.Empty <string>()),
            Range    = null
        };
예제 #2
0
        // warnings 70**

        public static Diagnostic LoadWarning(WarningCode code, IEnumerable <string> args, string source) =>
        new Diagnostic
        {
            Severity = DiagnosticSeverity.Warning,
            Code     = Warnings.Code(code),
            Source   = source,
            Message  = DiagnosticItem.Message(code, args ?? Enumerable.Empty <string>()),
            Range    = null
        };
예제 #3
0
 /// <summary>
 /// Logs a a diagnostic message based on the given warning code,
 /// with the given source as the file for which the error occurred.
 /// </summary>
 public void Log(WarningCode code, IEnumerable <string> args, string source = null, LSP.Range range = null) =>
 this.Log(new Diagnostic
 {
     Severity = DiagnosticSeverity.Warning,
     Code     = Warnings.Code(code),
     Source   = source,
     Message  = DiagnosticItem.Message(code, args ?? Enumerable.Empty <string>()),
     Range    = range
 });
예제 #4
0
 /// <summary>
 /// Generates a Diagnostic message based on the given information code,
 /// with any message parameters appended on a new line to the message defined by the information code.
 /// The given source is listed as the file for which the error occurred.
 /// </summary>
 public void Log(InformationCode code, IEnumerable <string> args, string source = null, LSP.Range range = null, params string[] messageParam) =>
 this.Log(new Diagnostic
 {
     Severity = DiagnosticSeverity.Information,
     Code     = null, // do not show a code for infos
     Source   = source,
     Message  = $"{DiagnosticItem.Message(code, args ?? Enumerable.Empty<string>())}{Environment.NewLine}{string.Join(Environment.NewLine, messageParam)}",
     Range    = range
 });
예제 #5
0
        // routines for convenience

        /// <summary>
        /// Logs a diagnostic message based on the given error code,
        /// with the given source as the file for which the error occurred.
        /// </summary>
        public void Log(ErrorCode code, IEnumerable <string> args, string?source = null, LSP.Range?range = null) =>
        this.Log(new Diagnostic
        {
            Severity = DiagnosticSeverity.Error,
            Code     = Errors.Code(code),
            Source   = source,
            Message  = DiagnosticItem.Message(code, args ?? Enumerable.Empty <string>()),
            Range    = range ?? EmptyRange
        });
예제 #6
0
 internal static Diagnostic MissingStringDelimiterError(string filename, Position pos)
 {
     return(new Diagnostic
     {
         Severity = DiagnosticSeverity.Error,
         Code = ErrorCode.MissingStringDelimiterError.Code(),
         Source = filename,
         Message = DiagnosticItem.Message(ErrorCode.MissingStringDelimiterError, Enumerable.Empty <string>()),
         Range = pos == null ? null : new Range {
             Start = pos, End = pos
         }
     });
 }
예제 #7
0
        // errors 20**

        internal static Diagnostic InvalidFragmentEnding(string filename, ErrorCode code, Position pos)
        {
            return(new Diagnostic
            {
                Severity = DiagnosticSeverity.Error,
                Code = Code(code),
                Source = filename,
                Message = DiagnosticItem.Message(code, Enumerable.Empty <string>()),
                Range = pos == null ? null : new Range {
                    Start = pos, End = pos
                }
            });
        }
예제 #8
0
        // warnings 20**

        internal static Diagnostic EmptyStatementWarning(string filename, Position pos)
        {
            return(new Diagnostic
            {
                Severity = DiagnosticSeverity.Warning,
                Code = WarningCode.ExcessSemicolon.Code(),
                Source = filename,
                Message = DiagnosticItem.Message(WarningCode.ExcessSemicolon, Enumerable.Empty <string>()),
                Range = pos == null ? null : new Range {
                    Start = pos, End = pos
                }
            });
        }
예제 #9
0
 internal static Diagnostic MisplacedOpeningBracketError(string filename, Position pos)
 {
     return(new Diagnostic
     {
         Severity = DiagnosticSeverity.Error,
         Code = ErrorCode.MisplacedOpeningBracket.Code(),
         Source = filename,
         Message = DiagnosticItem.Message(ErrorCode.MisplacedOpeningBracket, Enumerable.Empty <string>()),
         Range = pos == null ? null : new LSP.Range {
             Start = pos, End = pos
         }
     });
 }
예제 #10
0
        // errors 10**

        internal static Diagnostic ExcessBracketError(string filename, Position pos)
        {
            return(new Diagnostic
            {
                Severity = DiagnosticSeverity.Error,
                Code = ErrorCode.ExcessBracketError.Code(),
                Source = filename,
                Message = DiagnosticItem.Message(ErrorCode.ExcessBracketError, Enumerable.Empty <string>()),
                Range = pos == null ? null : new Lsp.Range {
                    Start = pos.ToLsp(), End = pos.ToLsp()
                }
            });
        }
예제 #11
0
        /// <inheritdoc/>
        public bool Transformation(QsCompilation compilation, out QsCompilation transformed)
        {
            transformed = InferTargetInstructions.ReplaceSelfAdjointSpecializations(compilation);
            transformed = InferTargetInstructions.LiftIntrinsicSpecializations(transformed);
            var allAttributesAdded = InferTargetInstructions.TryAddMissingTargetInstructionAttributes(transformed, out transformed);

            if (!allAttributesAdded)
            {
                this.diagnostics.Add(new IRewriteStep.Diagnostic
                {
                    Severity = DiagnosticSeverity.Warning,
                    Message  = DiagnosticItem.Message(WarningCode.MissingTargetInstructionName, Array.Empty <string>()),
                    Stage    = IRewriteStep.Stage.Transformation,
                });
            }
            return(true);
        }
예제 #12
0
 /// <inheritdoc/>
 public bool PreconditionVerification(QsCompilation compilation)
 {
     try
     {
         ValidateMonomorphization.Apply(compilation);
         return(true);
     }
     catch
     {
         this.diagnostics.Add(new IRewriteStep.Diagnostic
         {
             Severity = DiagnosticSeverity.Error,
             Stage    = IRewriteStep.Stage.PreconditionVerification,
             Message  = DiagnosticItem.Message(ErrorCode.SyntaxTreeNotMonomorphized, Array.Empty <string>()),
             Source   = Assembly.GetExecutingAssembly().Location
         });
         return(false);
     }
 }
예제 #13
0
        /// <summary>
        /// Constructs a DocComment instance from the documentation comments
        /// associated with a source code element.
        /// </summary>
        /// <param name="docComments">The doc comments from the source code</param>
        /// <param name="name">The name of the element</param>
        /// <param name="deprecated">Flag indicating whether or not the element had a Deprecated attribute</param>
        /// <param name="replacement">The name of the replacement element for deprecated elements, if given</param>
        public DocComment(IEnumerable <string> docComments, string name, bool deprecated, string replacement)
        {
            string GetHeadingText(HeadingBlock heading)
            {
                var sb = new StringBuilder();

                foreach (var item in heading.Inline)
                {
                    sb.Append(item.ToString());
                }
                return(sb.ToString());
            }

            string GetParagraphText(LeafBlock leaf)
            {
                var sb = new StringBuilder();

                foreach (var item in leaf.Inline)
                {
                    sb.Append(item.ToString());
                }
                return(sb.ToString());
            }

            string ToMarkdown(IEnumerable <Block> blocks)
            {
                var writer   = new StringWriter();
                var renderer = new NormalizeRenderer(writer);
                var pipeline = new MarkdownPipelineBuilder().Build();

                pipeline.Setup(renderer);
                foreach (var block in blocks)
                {
                    renderer.Render(block);
                }
                // We convert \n to \r because the YAML serialization will eventually
                // output \n\n for \n, but \r\n for \r.
                return(writer.ToString().TrimEnd().Replace('\n', '\r'));
            }

            List <ValueTuple <string, List <Block> > > BreakIntoSections(IEnumerable <Block> blocks, int level)
            {
                var key    = "";
                var accum  = new List <Block>();
                var result = new List <ValueTuple <string, List <Block> > >();

                foreach (var block in blocks)
                {
                    if (block is HeadingBlock heading)
                    {
                        if (heading.Level == level)
                        {
                            if (accum.Count > 0)
                            {
                                result.Add(new ValueTuple <string, List <Block> >(key, accum));
                                accum = new List <Block>();
                            }
                            key = GetHeadingText(heading);
                        }
                        else
                        {
                            accum.Add(block);
                        }
                    }
                    else
                    {
                        accum.Add(block);
                    }
                }

                if (accum.Count > 0)
                {
                    result.Add(new ValueTuple <string, List <Block> >(key, accum));
                }

                return(result);
            }

            void ParseListSection(IEnumerable <Block> blocks, List <string> accum, bool lowerCase)
            {
                foreach (var block in blocks)
                {
                    if (block is ListBlock list)
                    {
                        foreach (var sub in block.Descendants())
                        {
                            if (sub is ListItemBlock item)
                            {
                                // Some special treatment for funky doc comments in some of the Canon
                                if (item.Count == 1 && item.LastChild is LeafBlock leaf && leaf.Inline != null &&
                                    leaf.Inline.FirstChild is LiteralInline literal)
                                {
                                    var itemText = lowerCase ? GetParagraphText(leaf).ToLowerInvariant() : GetParagraphText(leaf);
                                    if (itemText.StartsWith("@\"") && itemText.EndsWith("\""))
                                    {
                                        itemText = itemText.Substring(2, itemText.Length - 3);
                                    }
                                    literal.Content = new Markdig.Helpers.StringSlice(itemText.ToLowerInvariant());
                                }
                                accum.Add(ToMarkdown(new Block[] { item }));
                            }
                        }
                    }
                }
            }

            void ParseMapSection(IEnumerable <Block> blocks, Dictionary <string, string> accum)
            {
                var subsections = BreakIntoSections(blocks, 2);

                foreach ((var key, var subs) in subsections)
                {
                    // TODO: when we add the ability to flag warnings from the doc comment builder,
                    // we should check here for duplicate keys and generate a warning if appropriate.
                    accum[key] = ToMarkdown(subs);
                }
            }

            // First element is not matching, second is matching
            (List <Block>, List <Block>) PartitionNestedSection(IEnumerable <Block> blocks, int level, string name)
            {
                var inMatch = false;
                var result  = (new List <Block>(), new List <Block>());

                foreach (var block in blocks)
                {
                    var skip = false;
                    if ((block is HeadingBlock heading) && (heading.Level == level))
                    {
                        inMatch = GetHeadingText(heading).Equals(name);
                        skip    = true;
                    }
                    if (inMatch)
                    {
                        if (!skip)
                        {
                            result.Item2.Add(block);
                        }
                    }
                    else
                    {
                        result.Item1.Add(block);
                    }
                }

                return(result);
            }

            // Initialize to safe empty values
            this.Summary        = "";
            this.Description    = "";
            this.ShortSummary   = "";
            this.Documentation  = "";
            this.Input          = new Dictionary <string, string>();
            this.Output         = "";
            this.TypeParameters = new Dictionary <string, string>();
            this.Example        = "";
            this.Remarks        = "";
            this.SeeAlso        = new List <string>();
            this.References     = "";

            var deprecationSummary = String.IsNullOrWhiteSpace(replacement)
                                    ? DiagnosticItem.Message(WarningCode.DeprecationWithoutRedirect, new string[] { name })
                                    : DiagnosticItem.Message(WarningCode.DeprecationWithRedirect, new string[] { name, "@\"" + replacement + "\"" });
            var deprecationDetails = "";

            var text = String.Join("\n", docComments);

            // Only parse if there are comments to parse
            if (!string.IsNullOrWhiteSpace(text))
            {
                var          doc                = Markdown.Parse(text);
                var          sections           = BreakIntoSections(doc, 1);
                List <Block> summarySection     = new List <Block>();
                List <Block> descriptionSection = new List <Block>();

                foreach ((var tag, var section) in sections)
                {
                    switch (tag)
                    {
                    case "Summary":
                        this.Summary = ToMarkdown(section);
                        summarySection.AddRange(section);
                        // For now, the short hover information gets the first paragraph of the summary.
                        this.ShortSummary = ToMarkdown(section.GetRange(0, 1));
                        break;

                    case "Deprecated":
                        if (String.IsNullOrWhiteSpace(name))
                        {
                            deprecationSummary = ToMarkdown(section.GetRange(0, 1));
                            if (section.Count > 1)
                            {
                                deprecationDetails = ToMarkdown(section.GetRange(1, section.Count - 1));
                            }
                        }
                        else
                        {
                            deprecationDetails = ToMarkdown(section);
                        }
                        deprecated = true;
                        break;

                    case "Description":
                        this.Description   = ToMarkdown(section);
                        descriptionSection = section;
                        break;

                    case "Input":
                        ParseMapSection(section, this.Input);
                        break;

                    case "Output":
                        this.Output = ToMarkdown(section);
                        break;

                    case "Type Parameters":
                        ParseMapSection(section, this.TypeParameters);
                        break;

                    case "Example":
                        this.Example = ToMarkdown(section);
                        break;

                    case "Remarks":
                        (var remarks, var examples) = PartitionNestedSection(section, 2, "Example");
                        if ((examples.Count > 0) && (this.Example == ""))
                        {
                            this.Example = ToMarkdown(examples);
                        }
                        this.Remarks = ToMarkdown(remarks);
                        break;

                    case "See Also":
                        // seeAlso is a list of UIDs, which are all lower case,
                        // so pass true to lowercase all strings found in this section
                        ParseListSection(section, this.SeeAlso, true);
                        break;

                    case "References":
                        this.References = ToMarkdown(section);
                        break;

                    default:
                        // TODO: add diagnostic warning about unknown tag
                        break;
                    }
                }


                this.Documentation = ToMarkdown(summarySection.Concat(descriptionSection));
            }

            if (deprecated)
            {
                var shortDeprecationText = DeprecatedWarning + "\r" + deprecationSummary;
                var longDeprecationText  = shortDeprecationText + (String.IsNullOrWhiteSpace(deprecationDetails) ? "" : "\r") + deprecationDetails;
                this.Summary      += "\r" + longDeprecationText;
                this.ShortSummary  = shortDeprecationText;
                this.Documentation = deprecationSummary;
            }
        }