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.comma_expression;
7 
8 import dparse.ast;
9 import dparse.lexer;
10 import dscanner.analysis.base;
11 import dsymbol.scope_;
12 
13 /**
14  * Check for uses of the comma expression.
15  */
16 final class CommaExpressionCheck : BaseAnalyzer
17 {
18 	alias visit = BaseAnalyzer.visit;
19 
20 	mixin AnalyzerInfo!"comma_expression_check";
21 
22 	this(string fileName, const(Scope)* sc, bool skipTests = false)
23 	{
24 		super(fileName, sc, skipTests);
25 	}
26 
27 	override void visit(const Expression ex)
28 	{
29 		if (ex.items.length > 1 && interest > 0)
30 		{
31 			addErrorMessage(ex.line, ex.column, KEY, "Avoid using the comma expression.");
32 		}
33 		ex.accept(this);
34 	}
35 
36 	override void visit(const AssignExpression ex)
37 	{
38 		++interest;
39 		ex.accept(this);
40 		--interest;
41 	}
42 
43 	// Dconf 2016
44 	override void visit(const SynchronizedStatement ss)
45 	{
46 		if (ss.expression !is null)
47 		{
48 			++interest;
49 			visit(ss.expression);
50 			--interest;
51 		}
52 		visit(ss.statementNoCaseNoDefault);
53 	}
54 
55 	invariant
56 	{
57 		assert(interest >= 0);
58 	}
59 
60 	int interest;
61 
62 	private enum string KEY = "dscanner.suspicious.comma_expression";
63 }