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;
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.");
}