1 // Copyright Brian Schott (Hackerpilot) 2014. 2 // Distributed under the Boost Software License, Version 1.0. 3 // (See accompanying file LICENSE_1_0.txt or copy at 4 // http://www.boost.org/LICENSE_1_0.txt) 5 6 module dscanner.analysis.numbers; 7 8 import std.stdio; 9 import std.regex; 10 import dparse.ast; 11 import dparse.lexer; 12 import dscanner.analysis.base; 13 import dscanner.analysis.helpers; 14 import dsymbol.scope_ : Scope; 15 16 /** 17 * Checks for long and hard-to-read number literals 18 */ 19 final class NumberStyleCheck : BaseAnalyzer 20 { 21 public: 22 alias visit = BaseAnalyzer.visit; 23 24 mixin AnalyzerInfo!"number_style_check"; 25 26 /** 27 * Constructs the style checker with the given file name. 28 */ 29 this(string fileName, const(Scope)* sc, bool skipTests = false) 30 { 31 super(fileName, sc, skipTests); 32 } 33 34 override void visit(const Token t) 35 { 36 import std.algorithm : startsWith; 37 38 if (isNumberLiteral(t.type) && !t.text.startsWith("0x") 39 && ((t.text.startsWith("0b") && !t.text.matchFirst(badBinaryRegex) 40 .empty) || !t.text.matchFirst(badDecimalRegex).empty)) 41 { 42 addErrorMessage(t.line, t.column, "dscanner.style.number_literals", 43 "Use underscores to improve number constant readability."); 44 } 45 } 46 47 private: 48 auto badBinaryRegex = ctRegex!(`^0b[01]{9,}`); 49 auto badDecimalRegex = ctRegex!(`^\d{5,}`); 50 } 51 52 unittest 53 { 54 import dscanner.analysis.config : StaticAnalysisConfig, Check, disabledConfig; 55 56 StaticAnalysisConfig sac = disabledConfig(); 57 sac.number_style_check = Check.enabled; 58 assertAnalyzerWarnings(q{ 59 void testNumbers() 60 { 61 int a; 62 a = 1; // ok 63 a = 10; // ok 64 a = 100; // ok 65 a = 1000; // FIXME: boom 66 a = 10000; // [warn]: Use underscores to improve number constant readability. 67 a = 100000; // [warn]: Use underscores to improve number constant readability. 68 a = 1000000; // [warn]: Use underscores to improve number constant readability. 69 } 70 }}, sac); 71 72 stderr.writeln("Unittest for NumberStyleCheck passed."); 73 }