From b115a6333a9b0f66da46b124f434aac8d09f846c Mon Sep 17 00:00:00 2001 From: WebFreak001 Date: Thu, 29 Jun 2023 16:43:13 +0200 Subject: [PATCH] also add byte indices to diagnostic ranges For tools wanting to read from the source file this makes it much easier to look up the code. --- src/dscanner/analysis/auto_function.d | 3 +- src/dscanner/analysis/base.d | 30 ++++++++++++------- src/dscanner/analysis/if_constraints_indent.d | 7 +++-- src/dscanner/analysis/line_length.d | 2 +- src/dscanner/analysis/run.d | 11 ++++--- 5 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/dscanner/analysis/auto_function.d b/src/dscanner/analysis/auto_function.d index a969039..cf9b14c 100644 --- a/src/dscanner/analysis/auto_function.d +++ b/src/dscanner/analysis/auto_function.d @@ -75,7 +75,8 @@ public: // highlight on the whitespace between attribute and function name auto tok = autoTokens[$ - 1]; auto whitespace = tok.column + (tok.text.length ? tok.text.length : str(tok.type).length); - addErrorMessage(tok.line, whitespace, whitespace + 1, KEY, MESSAGE_INSERT); + auto whitespaceIndex = tok.index + (tok.text.length ? tok.text.length : str(tok.type).length); + addErrorMessage([whitespaceIndex, whitespaceIndex + 1], tok.line, [whitespace, whitespace + 1], KEY, MESSAGE_INSERT); } else addErrorMessage(autoTokens, KEY, MESSAGE); diff --git a/src/dscanner/analysis/base.d b/src/dscanner/analysis/base.d index 91cd896..a853d60 100644 --- a/src/dscanner/analysis/base.d +++ b/src/dscanner/analysis/base.d @@ -13,6 +13,8 @@ struct Message { /// Name of the file where the warning was triggered. string fileName; + /// Byte index from start of file the warning was triggered. + size_t startIndex, endIndex; /// Line number where the warning was triggered, 1-based. size_t startLine, endLine; /// Column number where the warning was triggered. (in bytes) @@ -33,7 +35,11 @@ struct Message static Diagnostic from(string fileName, const Token token, string message) { auto text = token.text.length ? token.text : str(token.type); - return from(fileName, token.line, token.column, token.column + text.length, message); + return from(fileName, + [token.index, token.index + text.length], + token.line, + [token.column, token.column + text.length], + message); } static Diagnostic from(string fileName, const Token[] tokens, string message) @@ -41,17 +47,21 @@ struct Message auto start = tokens.length ? tokens[0] : Token.init; auto end = tokens.length ? tokens[$ - 1] : Token.init; auto endText = end.text.length ? end.text : str(end.type); - return from(fileName, start.line, end.line, start.column, end.column + endText.length, message); + return from(fileName, + [start.index, end.index + endText.length], + [start.line, end.line], + [start.column, end.column + endText.length], + message); } - static Diagnostic from(string fileName, size_t line, size_t startColumn, size_t endColumn, string message) + static Diagnostic from(string fileName, size_t[2] index, size_t line, size_t[2] columns, string message) { - return Message.Diagnostic(fileName, line, line, startColumn, endColumn, message); + return Message.Diagnostic(fileName, index[0], index[1], line, line, columns[0], columns[1], message); } - static Diagnostic from(string fileName, size_t startLine, size_t endLine, size_t startColumn, size_t endColumn, string message) + static Diagnostic from(string fileName, size_t[2] index, size_t[2] lines, size_t[2] columns, string message) { - return Message.Diagnostic(fileName, startLine, endLine, startColumn, endColumn, message); + return Message.Diagnostic(fileName, index[0], index[1], lines[0], lines[1], columns[0], columns[1], message); } } @@ -177,14 +187,14 @@ protected: addErrorMessage(Message.Diagnostic.from(fileName, tokens, message), key); } - void addErrorMessage(size_t line, size_t startColumn, size_t endColumn, string key, string message) + void addErrorMessage(size_t[2] index, size_t line, size_t[2] columns, string key, string message) { - addErrorMessage(line, line, startColumn, endColumn, key, message); + addErrorMessage(index, [line, line], columns, key, message); } - void addErrorMessage(size_t startLine, size_t endLine, size_t startColumn, size_t endColumn, string key, string message) + void addErrorMessage(size_t[2] index, size_t[2] lines, size_t[2] columns, string key, string message) { - auto d = Message.Diagnostic(fileName, startLine, endLine, startColumn, endColumn, message); + auto d = Message.Diagnostic.from(fileName, index, lines, columns, message); _messages.insert(Message(d, key, getName())); } diff --git a/src/dscanner/analysis/if_constraints_indent.d b/src/dscanner/analysis/if_constraints_indent.d index 25e8be1..2e66c9e 100644 --- a/src/dscanner/analysis/if_constraints_indent.d +++ b/src/dscanner/analysis/if_constraints_indent.d @@ -33,12 +33,12 @@ final class IfConstraintsIndentCheck : BaseAnalyzer // t.line (unsigned) may be 0 if the token is uninitialized/broken, so don't subtract from it // equivalent to: firstSymbolAtLine.length < t.line - 1 while (firstSymbolAtLine.length + 1 < t.line) - firstSymbolAtLine ~= Pos(1); + firstSymbolAtLine ~= Pos(1, t.index); // insert a new line with positions if new line is reached // (previous while pads skipped lines) if (firstSymbolAtLine.length < t.line) - firstSymbolAtLine ~= Pos(t.column, t.type == tok!"if"); + firstSymbolAtLine ~= Pos(t.column, t.index, t.type == tok!"if"); } } @@ -96,6 +96,7 @@ private: static struct Pos { size_t column; + size_t index; bool isIf; } @@ -123,7 +124,7 @@ private: if (r.empty) addErrorMessage(if_, KEY, MESSAGE); else if (pDecl.column != r.front.column) - addErrorMessage(if_.line, min(if_.column, pDecl.column), if_.column + 2, KEY, MESSAGE); + addErrorMessage([min(if_.index, pDecl.index), if_.index + 2], if_.line, [min(if_.column, pDecl.column), if_.column + 2], KEY, MESSAGE); } } diff --git a/src/dscanner/analysis/line_length.d b/src/dscanner/analysis/line_length.d index 2f55aaf..67bde8f 100644 --- a/src/dscanner/analysis/line_length.d +++ b/src/dscanner/analysis/line_length.d @@ -62,7 +62,7 @@ private: if (tok.line != lastErrorLine) { - addErrorMessage(tok.line, maxLineLength, max(maxLineLength + 1, tok.column + 1), KEY, message); + addErrorMessage([0, 0], tok.line, [maxLineLength, max(maxLineLength + 1, tok.column + 1)], KEY, message); lastErrorLine = tok.line; } } diff --git a/src/dscanner/analysis/run.d b/src/dscanner/analysis/run.d index 792ec82..407757c 100644 --- a/src/dscanner/analysis/run.d +++ b/src/dscanner/analysis/run.d @@ -139,7 +139,7 @@ void messageFunction(Message message, bool isError) void messageFunctionJSON(string fileName, size_t line, size_t column, string message, bool) { - writeJSON(Message(Message.Diagnostic.from(fileName, line, column, column, message), "dscanner.syntax")); + writeJSON(Message(Message.Diagnostic.from(fileName, [0, 0], line, [column, column], message), "dscanner.syntax")); } void writeJSON(Message message) @@ -199,8 +199,9 @@ void generateReport(string[] fileNames, const StaticAnalysisConfig config, auto reporter = new DScannerJsonReporter(); auto writeMessages = delegate void(string fileName, size_t line, size_t column, string message, bool isError){ + // TODO: proper index and column ranges reporter.addMessage( - Message(Message.Diagnostic.from(fileName, line, column, column, message), "dscanner.syntax"), + Message(Message.Diagnostic.from(fileName, [0, 0], line, [column, column], message), "dscanner.syntax"), isError); }; @@ -239,8 +240,9 @@ void generateSonarQubeGenericIssueDataReport(string[] fileNames, const StaticAna auto reporter = new SonarQubeGenericIssueDataReporter(); auto writeMessages = delegate void(string fileName, size_t line, size_t column, string message, bool isError){ + // TODO: proper index and column ranges reporter.addMessage( - Message(Message.Diagnostic.from(fileName, line, column, column, message), "dscanner.syntax"), + Message(Message.Diagnostic.from(fileName, [0, 0], line, [column, column], message), "dscanner.syntax"), isError); }; @@ -327,8 +329,9 @@ const(Module) parseModule(string fileName, ubyte[] code, RollbackAllocator* p, ulong* linesOfCode = null, uint* errorCount = null, uint* warningCount = null) { auto writeMessages = delegate(string fileName, size_t line, size_t column, string message, bool isError){ + // TODO: proper index and column ranges return messageFunctionFormat(errorFormat, - Message(Message.Diagnostic.from(fileName, line, column, column, message), "dscanner.syntax"), + Message(Message.Diagnostic.from(fileName, [0, 0], line, [column, column], message), "dscanner.syntax"), isError); };