Run static analysis checks in parallel. Implement #130

This commit is contained in:
Hackerpilot 2014-03-03 23:09:20 -08:00
parent 3a10d4bb72
commit 7288514a1b
2 changed files with 42 additions and 35 deletions

View File

@ -1,7 +1,21 @@
module analysis.base; module analysis.base;
import std.container;
import std.string; import std.string;
import stdx.d.ast; import stdx.d.ast;
import std.array;
struct Message
{
string fileName;
size_t line;
size_t column;
string message;
}
enum comparitor = q{ a.line < b.line || a.line < b.line };
alias MessageSet = RedBlackTree!(Message, comparitor);
abstract class BaseAnalyzer : ASTVisitor abstract class BaseAnalyzer : ASTVisitor
{ {
@ -9,11 +23,12 @@ public:
this(string fileName) this(string fileName)
{ {
this.fileName = fileName; this.fileName = fileName;
_messages = new MessageSet;
} }
string[] messages() Message[] messages()
{ {
return _messages; return _messages[].array;
} }
protected: protected:
@ -34,7 +49,7 @@ protected:
void addErrorMessage(size_t line, size_t column, string message) void addErrorMessage(size_t line, size_t column, string message)
{ {
_messages ~= format("%s(%d:%d)[warn]: %s", fileName, line, column, message); _messages.insert(Message(fileName, line, column, message));
} }
/** /**
@ -42,8 +57,5 @@ protected:
*/ */
string fileName; string fileName;
/** MessageSet _messages;
* Map of file names to warning messages for that file
*/
string[] _messages;
} }

View File

@ -35,6 +35,7 @@ void syntaxCheck(File output, string[] fileNames)
void analyze(File output, string[] fileNames, bool staticAnalyze = true) void analyze(File output, string[] fileNames, bool staticAnalyze = true)
{ {
import std.parallelism;
foreach (fileName; fileNames) foreach (fileName; fileNames)
{ {
File f = File(fileName); File f = File(fileName);
@ -54,41 +55,35 @@ void analyze(File output, string[] fileNames, bool staticAnalyze = true)
message.isError); message.isError);
} }
Module m = parseModule(app.data, fileName, &messageFunction); ParseAllocator p = new ParseAllocator;
Module m = parseModule(app.data, fileName, p, &messageFunction);
if (!staticAnalyze) if (!staticAnalyze)
return; return;
auto style = new StyleChecker(fileName); BaseAnalyzer[] checks;
style.visit(m); checks ~= new StyleChecker(fileName);
checks ~= new EnumArrayLiteralCheck(fileName);
checks ~= new PokemonExceptionCheck(fileName);
checks ~= new DeleteCheck(fileName);
checks ~= new FloatOperatorCheck(fileName);
checks ~= new NumberStyleCheck(fileName);
checks ~= new ObjectConstCheck(fileName);
checks ~= new BackwardsRangeCheck(fileName);
auto enums = new EnumArrayLiteralCheck(fileName); foreach (check; checks)
enums.visit(m);
auto pokemon = new PokemonExceptionCheck(fileName);
pokemon.visit(m);
auto del = new DeleteCheck(fileName);
del.visit(m);
auto fish = new FloatOperatorCheck(fileName);
fish.visit(m);
auto numbers = new NumberStyleCheck(fileName);
numbers.visit(m);
auto objConst = new ObjectConstCheck(fileName);
objConst.visit(m);
auto backwardsRange = new BackwardsRangeCheck(fileName);
backwardsRange.visit(m);
foreach (message; sort(chain(enums.messages, style.messages,
pokemon.messages, del.messages, fish.messages, numbers.messages,
objConst.messages, backwardsRange.messages).array))
{ {
writeln(message); check.visit(m);
} }
MessageSet set = new MessageSet;
foreach(check; checks)
foreach (message; check.messages)
set.insert(message);
foreach (message; set[])
writefln("%s(%d:%d)[warn]: %s", message.fileName, message.line,
message.column, message.message);
p.deallocateAll();
} }
} }