diff --git a/analysis/pokemon.d b/analysis/pokemon.d index 0937bfe..f699234 100644 --- a/analysis/pokemon.d +++ b/analysis/pokemon.d @@ -25,6 +25,8 @@ import analysis.helpers; */ class PokemonExceptionCheck : BaseAnalyzer { + enum message = "Catching Error or Throwable is almost always a bad idea"; + alias visit = BaseAnalyzer.visit; this(string fileName) @@ -32,6 +34,12 @@ class PokemonExceptionCheck : BaseAnalyzer super(fileName); } + override void visit(const LastCatch lc) + { + addErrorMessage(lc.line, lc.column, message); + lc.accept(this); + } + override void visit(const Catch c) { if (c.type.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances.length != 1) @@ -50,7 +58,7 @@ class PokemonExceptionCheck : BaseAnalyzer { immutable column = identOrTemplate.identifier.column; immutable line = identOrTemplate.identifier.line; - addErrorMessage(line, column, "Catching Error or Throwable is a really bad idea."); + addErrorMessage(line, column, message); } c.accept(this); } @@ -73,14 +81,17 @@ unittest { } - catch(Error err) // [warn]: Catching Error or Throwable is a really bad idea. + catch(Error err) // [warn]: Catching Error or Throwable is almost always a bad idea { } - catch(Throwable err) // [warn]: Catching Error or Throwable is a really bad idea. + catch(Throwable err) // [warn]: Catching Error or Throwable is almost always a bad idea { } + catch // [warn]: Catching Error or Throwable is almost always a bad idea + { + } } }c, analysis.run.AnalyzerCheck.exception_check); diff --git a/std/d/ast.d b/std/d/ast.d index a43fb82..8549aa0 100644 --- a/std/d/ast.d +++ b/std/d/ast.d @@ -1871,6 +1871,8 @@ public: mixin (visitIfNotNull!(statementNoCaseNoDefault)); } /** */ StatementNoCaseNoDefault statementNoCaseNoDefault; + size_t line; + size_t column; mixin OpEquals; } diff --git a/std/d/parser.d b/std/d/parser.d index 6aa08f3..3db48d0 100644 --- a/std/d/parser.d +++ b/std/d/parser.d @@ -3405,7 +3405,10 @@ invariant() foo(); { mixin(traceEnterAndExit!(__FUNCTION__)); auto node = allocate!LastCatch; - if (expect(tok!"catch") is null) return null; + auto t = expect(tok!"catch"); + if (t is null) return null; + node.line = t.line; + node.column = t.column; if ((node.statementNoCaseNoDefault = parseStatementNoCaseNoDefault()) is null) return null; return node;