From 3c3fbe67255e864edab2dd9cfb62bfe0054ffbac Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Thu, 9 Mar 2017 14:19:26 -0800 Subject: [PATCH] Fix #416 --- src/analysis/line_length.d | 65 ++++++++++++++++++++++++++++++-------- 1 file changed, 51 insertions(+), 14 deletions(-) diff --git a/src/analysis/line_length.d b/src/analysis/line_length.d index 94ac173..ab16b6c 100644 --- a/src/analysis/line_length.d +++ b/src/analysis/line_length.d @@ -5,10 +5,13 @@ module analysis.line_length; -import dparse.lexer; -import dparse.ast; import analysis.base : BaseAnalyzer; +import dparse.ast; +import dparse.lexer; + +import std.typecons : tuple, Tuple; + /** * Checks for lines longer than 120 characters */ @@ -24,9 +27,20 @@ class LineLengthCheck : BaseAnalyzer override void visit(const Module) { ulong lastErrorLine = ulong.max; - foreach (token; tokens) + size_t endColumn = 0; + foreach (i, token; tokens) { - if (tokenEndColumn(token) > MAX_LINE_LENGTH && token.line != lastErrorLine) + immutable info = tokenLength(token, i > 0 ? tokens[i - 1].line : 0); + if (info[1]) + endColumn = info[0] + token.column; + else + { + immutable wsChange = i > 0 + ? token.column - (tokens[i - 1].column + tokenByteLength(tokens[i - 1])) + : 0; + endColumn += wsChange + info[0]; + } + if (endColumn > MAX_LINE_LENGTH && token.line != lastErrorLine) { addErrorMessage(token.line, token.column, KEY, MESSAGE); lastErrorLine = token.line; @@ -38,19 +52,27 @@ class LineLengthCheck : BaseAnalyzer private: - static ulong tokenEndColumn(ref const Token tok) + static size_t tokenByteLength(ref const Token tok) + { + return tok.text is null ? str(tok.type).length : tok.text.length; + } + + static Tuple!(size_t, bool) tokenLength(ref const Token tok, size_t prevLine) { import std.uni : lineSep, paraSep; - ulong endColumn = tok.column; - foreach (dchar c; tok.text) - { - if (c == lineSep || c == '\n' || c == '\v' || c == '\r' || c == paraSep) - endColumn = 0; - else - endColumn++; - } - return endColumn; + size_t endColumn = 0; + if (tok.text is null) + endColumn += str(tok.type).length; + else + foreach (dchar c; tok.text) + { + if (c == lineSep || c == '\n' || c == '\v' || c == '\r' || c == paraSep) + endColumn = 0; + else + endColumn++; + } + return tuple(endColumn, tok.line > prevLine); } import std.conv : to; @@ -60,3 +82,18 @@ private: enum MAX_LINE_LENGTH = 120; const(Token)[] tokens; } + +@system unittest +{ + import analysis.config : Check, StaticAnalysisConfig; + import analysis.helpers : assertAnalyzerWarnings; + import std.stdio : stderr; + + StaticAnalysisConfig sac; + sac.long_line_check = Check.enabled; + assertAnalyzerWarnings(q{ +Window window = Platform.instance.createWindow("Дистанционное управление сварочным оборудованием", null); + }c, sac); + + stderr.writeln("Unittest for LineLengthCheck passed."); +}