/// <summary> /// Function for the diagnostic thread. loops untill running is set false displaying anything enqueed into diagnostic items to the diagnostic file. /// </summary> public void DiagnosticThread() { while (running) { try { if (DiagnosticItems.Count > 0) { DiagnosticItem Result = new DiagnosticItem("Diagnostic Threading Issue.", 1); DiagnosticItems.TryDequeue(out Result); if (Result.message != "Diagnostic Threading Issue.") { string DiagnosticMessage = Result.message.Replace(",", "");; //message to be output to the File DiagnosticMessage += ", TimeStamp:" + DateTime.Now.ToString() + ", LoggingLevelNeeded: " + Result.logginglevel.ToString() + ", LoggingLevelSelected" + LogggingLevel.ToString(); //add all sorts of diagnostic datas if (Result.logginglevel <= LogggingLevel) //if we are asking to see this data { using (StreamWriter DiagnosticWriter = File.AppendText(ConfigurationManager.AppSettings["DiagnosticFile"])) // @"C:\Users\d.paddock\Desktop\Diagnostic.csv")) defualt { DiagnosticWriter.WriteLine(DiagnosticMessage); //output it to file } } } } else { Thread.Sleep(100); //if there is no diagnostic items sleep for a bit to reduce thread load. } } catch { } //catch any errors and cry becouse we cant log them. } }
// 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 };
// 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 };
/// <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 });
/// <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 });
// 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 });
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 } }); }
// 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 } }); }
// 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 } }); }
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 } }); }
// 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() } }); }
/// <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); }
/// <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); } }
private int CompareErrorLists() { GetExpectedErrors(); for (int i = SeenErrors.Count - 1; i >= 0; --i) { DiagnosticItem seenError = SeenErrors[i]; // Check whether we had more than one error on line. In that case // we can neglect the exact ordering. for (int j = ExpectedErrors.Count - 1; j >= 0; --j) { DiagnosticItem expectedError = ExpectedErrors[j]; // If the messages and lines correspond to each other we // pop the pair (seen-expected) from the lists. if (seenError.Line == expectedError.Line) { if (seenError.Message == expectedError.Message) { SeenErrors.Remove(seenError); ExpectedErrors.Remove(expectedError); // Make sure that if we have repeating expected errors // we are removing only one of them. break; } } } } // Dump the diffs if (SeenErrors.Count > 0) { DumpSeenErrors(); } if (ExpectedErrors.Count > 0) { DumpExpectedErrors(); } return(SeenErrors.Count + ExpectedErrors.Count); }
/// <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; } }