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 analysis.numbers; 7 8 import std.stdio; 9 import std.regex; 10 import std.d.ast; 11 import std.d.lexer; 12 import analysis.base; 13 import analysis.helpers; 14 15 /** 16 * Checks for long and hard-to-read number literals 17 */ 18 class NumberStyleCheck : BaseAnalyzer 19 { 20 public: 21 alias visit = BaseAnalyzer.visit; 22 23 /** 24 * Constructs the style checker with the given file name. 25 */ 26 this(string fileName) 27 { 28 super(fileName); 29 } 30 31 override void visit(const Token t) 32 { 33 import std.algorithm : startsWith; 34 if (isNumberLiteral(t.type) && !t.text.startsWith("0x") 35 && ((t.text.startsWith("0b") && !t.text.matchFirst(badBinaryRegex).empty) 36 || !t.text.matchFirst(badDecimalRegex).empty)) 37 { 38 addErrorMessage(t.line, t.column, "dscanner.style.number_literals", 39 "Use underscores to improve number constant readability."); 40 } 41 } 42 private: 43 auto badBinaryRegex = ctRegex!(`^0b[01]{9,}`); 44 auto badDecimalRegex = ctRegex!(`^\d{5,}`); 45 } 46 47 unittest 48 { 49 import analysis.config : StaticAnalysisConfig; 50 StaticAnalysisConfig sac; 51 sac.number_style_check = true; 52 assertAnalyzerWarnings(q{ 53 void testNumbers() 54 { 55 int a; 56 a = 1; // ok 57 a = 10; // ok 58 a = 100; // ok 59 a = 1000; // FIXME: boom 60 a = 10000; // [warn]: Use underscores to improve number constant readability. 61 a = 100000; // [warn]: Use underscores to improve number constant readability. 62 a = 1000000; // [warn]: Use underscores to improve number constant readability. 63 } 64 }}, sac); 65 66 stderr.writeln("Unittest for NumberStyleCheck passed."); 67 } 68