This commit is contained in:
Hackerpilot 2017-03-09 14:19:26 -08:00
parent 43772fcc15
commit 3c3fbe6725
1 changed files with 51 additions and 14 deletions

View File

@ -5,10 +5,13 @@
module analysis.line_length; module analysis.line_length;
import dparse.lexer;
import dparse.ast;
import analysis.base : BaseAnalyzer; import analysis.base : BaseAnalyzer;
import dparse.ast;
import dparse.lexer;
import std.typecons : tuple, Tuple;
/** /**
* Checks for lines longer than 120 characters * Checks for lines longer than 120 characters
*/ */
@ -24,9 +27,20 @@ class LineLengthCheck : BaseAnalyzer
override void visit(const Module) override void visit(const Module)
{ {
ulong lastErrorLine = ulong.max; 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); addErrorMessage(token.line, token.column, KEY, MESSAGE);
lastErrorLine = token.line; lastErrorLine = token.line;
@ -38,11 +52,19 @@ class LineLengthCheck : BaseAnalyzer
private: 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; import std.uni : lineSep, paraSep;
ulong endColumn = tok.column; size_t endColumn = 0;
if (tok.text is null)
endColumn += str(tok.type).length;
else
foreach (dchar c; tok.text) foreach (dchar c; tok.text)
{ {
if (c == lineSep || c == '\n' || c == '\v' || c == '\r' || c == paraSep) if (c == lineSep || c == '\n' || c == '\v' || c == '\r' || c == paraSep)
@ -50,7 +72,7 @@ private:
else else
endColumn++; endColumn++;
} }
return endColumn; return tuple(endColumn, tok.line > prevLine);
} }
import std.conv : to; import std.conv : to;
@ -60,3 +82,18 @@ private:
enum MAX_LINE_LENGTH = 120; enum MAX_LINE_LENGTH = 120;
const(Token)[] tokens; 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.");
}