diff --git a/analysis/base.d b/analysis/base.d index 74fb113..58b0c08 100644 --- a/analysis/base.d +++ b/analysis/base.d @@ -1,7 +1,21 @@ module analysis.base; +import std.container; import std.string; 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 { @@ -9,11 +23,12 @@ public: this(string fileName) { this.fileName = fileName; + _messages = new MessageSet; } - string[] messages() + Message[] messages() { - return _messages; + return _messages[].array; } protected: @@ -34,7 +49,7 @@ protected: 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; - /** - * Map of file names to warning messages for that file - */ - string[] _messages; + MessageSet _messages; } diff --git a/analysis/run.d b/analysis/run.d index 3b5bad6..74971e1 100644 --- a/analysis/run.d +++ b/analysis/run.d @@ -35,6 +35,7 @@ void syntaxCheck(File output, string[] fileNames) void analyze(File output, string[] fileNames, bool staticAnalyze = true) { + import std.parallelism; foreach (fileName; fileNames) { File f = File(fileName); @@ -54,41 +55,35 @@ void analyze(File output, string[] fileNames, bool staticAnalyze = true) message.isError); } - Module m = parseModule(app.data, fileName, &messageFunction); + ParseAllocator p = new ParseAllocator; + Module m = parseModule(app.data, fileName, p, &messageFunction); if (!staticAnalyze) return; - auto style = new StyleChecker(fileName); - style.visit(m); + BaseAnalyzer[] checks; + 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); - 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)) + foreach (check; checks) { - 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(); } }