Merge branch 'new_branch_name'
Conflicts: analysis/run.d stdx/d/ast.d
This commit is contained in:
commit
39f14f89f5
|
@ -0,0 +1,43 @@
|
|||
// Copyright Brian Schott (Sir Alaran) 2014.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
module analysis.ifelsesame;
|
||||
|
||||
import stdx.d.ast;
|
||||
import stdx.d.lexer;
|
||||
import analysis.base;
|
||||
|
||||
/**
|
||||
* Checks for if statements whose "then" block is the same as the "else" block
|
||||
*/
|
||||
class IfElseSameCheck : BaseAnalyzer
|
||||
{
|
||||
alias visit = BaseAnalyzer.visit;
|
||||
|
||||
this(string fileName)
|
||||
{
|
||||
super(fileName);
|
||||
}
|
||||
|
||||
override void visit(const IfStatement ifStatement)
|
||||
{
|
||||
if (ifStatement.thenStatement == ifStatement.elseStatement)
|
||||
addErrorMessage(ifStatement.line, ifStatement.column,
|
||||
"\"Else\" branch is identical to \"Then\" branch.");
|
||||
ifStatement.accept(this);
|
||||
}
|
||||
|
||||
override void visit(const AssignExpression assignExpression)
|
||||
{
|
||||
const AssignExpression e = cast(const AssignExpression) assignExpression.assignExpression;
|
||||
if (e !is null && assignExpression.operator == tok!"="
|
||||
&& e.ternaryExpression == assignExpression.ternaryExpression)
|
||||
{
|
||||
addErrorMessage(assignExpression.line, assignExpression.column,
|
||||
"Left side of assignment operatior is identical to the right side");
|
||||
}
|
||||
assignExpression.accept(this);
|
||||
}
|
||||
}
|
|
@ -64,24 +64,37 @@ class BackwardsRangeCheck : BaseAnalyzer
|
|||
|
||||
override void visit(const PrimaryExpression primary)
|
||||
{
|
||||
import std.conv;
|
||||
import std.string;
|
||||
if (state == State.ignore || !isNumberLiteral(primary.primary.type))
|
||||
return;
|
||||
if (state == State.left)
|
||||
{
|
||||
line = primary.primary.line;
|
||||
this.column = primary.primary.column;
|
||||
left = to!long(primary.primary.text.removechars("_uUlL"));
|
||||
left = parseNumber(primary.primary.text);
|
||||
hasLeft = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
right = to!long(primary.primary.text.removechars("_uUlL"));
|
||||
right = parseNumber(primary.primary.text);
|
||||
hasRight = true;
|
||||
}
|
||||
}
|
||||
|
||||
long parseNumber(string te)
|
||||
{
|
||||
import std.conv;
|
||||
import std.string;
|
||||
string t = te.removechars("_uUlL");
|
||||
if (t.length > 2)
|
||||
{
|
||||
if (t[1] == 'x' || t[1] == 'X')
|
||||
return to!long(t[2..$], 16);
|
||||
if (t[1] == 'b' || t[1] == 'B')
|
||||
return to!long(t[2..$], 2);
|
||||
}
|
||||
return to!long(t);
|
||||
}
|
||||
|
||||
override void visit(const SliceExpression sliceExpression)
|
||||
{
|
||||
if (sliceExpression.lower !is null && sliceExpression.upper !is null)
|
||||
|
|
|
@ -21,6 +21,7 @@ import analysis.numbers;
|
|||
import analysis.objectconst;
|
||||
import analysis.range;
|
||||
import analysis.constructors;
|
||||
import analysis.ifelsesame;
|
||||
|
||||
void messageFunction(string fileName, size_t line, size_t column, string message,
|
||||
bool isError)
|
||||
|
@ -71,6 +72,7 @@ void analyze(File output, string[] fileNames, bool staticAnalyze = true)
|
|||
checks ~= new NumberStyleCheck(fileName);
|
||||
checks ~= new ObjectConstCheck(fileName);
|
||||
checks ~= new BackwardsRangeCheck(fileName);
|
||||
checks ~= new IfElseSameCheck(fileName);
|
||||
checks ~= new ConstructorCheck(fileName);
|
||||
|
||||
foreach (check; checks)
|
||||
|
|
2
build.sh
2
build.sh
|
@ -12,7 +12,7 @@ dmd\
|
|||
analysis/*.d\
|
||||
-ofdscanner\
|
||||
-m64 -g\
|
||||
-O -release -noboundscheck -inline
|
||||
-O -release
|
||||
|
||||
#gdc\
|
||||
# main.d\
|
||||
|
|
368
stdx/d/ast.d
368
stdx/d/ast.d
File diff suppressed because it is too large
Load Diff
|
@ -557,7 +557,7 @@ public struct DLexer
|
|||
Token lexNumber() pure nothrow
|
||||
{
|
||||
mixin (tokenStart);
|
||||
if (range.canPeek(1) && range.front == '0')
|
||||
if (range.front == '0' && range.canPeek(1))
|
||||
{
|
||||
auto ahead = range.peek(1)[1];
|
||||
switch (ahead)
|
||||
|
|
|
@ -674,6 +674,8 @@ alias core.sys.posix.stdio.fileno fileno;
|
|||
{
|
||||
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||
auto node = allocate!AssignExpression;
|
||||
node.line = current().line;
|
||||
node.column = current().column;
|
||||
node.ternaryExpression = parseTernaryExpression();
|
||||
if (currentIsOneOf(tok!"=", tok!">>>=",
|
||||
tok!">>=", tok!"<<=",
|
||||
|
@ -2781,6 +2783,8 @@ body {} // six
|
|||
{
|
||||
mixin(traceEnterAndExit!(__FUNCTION__));
|
||||
auto node = allocate!IfStatement;
|
||||
node.line = current().line;
|
||||
node.column = current().column;
|
||||
if (expect(tok!"if") is null) return null;
|
||||
node.startIndex = current().index;
|
||||
if (expect(tok!"(") is null) return null;
|
||||
|
|
|
@ -249,6 +249,11 @@ struct TokenStructure(IdType, string extraFields = "")
|
|||
{
|
||||
public:
|
||||
|
||||
bool opEquals(ref const typeof(this) other) const pure nothrow @safe
|
||||
{
|
||||
return this.type == other.type && this.text == other.text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returs: true if the token has the given type, false otherwise.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue