Fix #238
This commit is contained in:
parent
27a423e3fa
commit
dffed0ab24
|
@ -44,35 +44,52 @@ class LabelVarNameCheck : BaseAnalyzer
|
||||||
override void visit(const VariableDeclaration var)
|
override void visit(const VariableDeclaration var)
|
||||||
{
|
{
|
||||||
foreach (dec; var.declarators)
|
foreach (dec; var.declarators)
|
||||||
duplicateCheck(dec.name, false);
|
duplicateCheck(dec.name, false, conditionalDepth > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const LabeledStatement labeledStatement)
|
override void visit(const LabeledStatement labeledStatement)
|
||||||
{
|
{
|
||||||
duplicateCheck(labeledStatement.identifier, true);
|
duplicateCheck(labeledStatement.identifier, true, conditionalDepth > 0);
|
||||||
if (labeledStatement.declarationOrStatement !is null)
|
if (labeledStatement.declarationOrStatement !is null)
|
||||||
labeledStatement.declarationOrStatement.accept(this);
|
labeledStatement.declarationOrStatement.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override void visit(const ConditionalDeclaration condition)
|
||||||
|
{
|
||||||
|
if (condition.falseDeclaration)
|
||||||
|
++conditionalDepth;
|
||||||
|
condition.accept(this);
|
||||||
|
if (condition.falseDeclaration)
|
||||||
|
--conditionalDepth;
|
||||||
|
}
|
||||||
|
|
||||||
alias visit = BaseAnalyzer.visit;
|
alias visit = BaseAnalyzer.visit;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
Thing[string][] stack;
|
Thing[string][] stack;
|
||||||
|
|
||||||
void duplicateCheck(const Token name, bool fromLabel)
|
void duplicateCheck(const Token name, bool fromLabel, bool isConditional)
|
||||||
{
|
{
|
||||||
import std.conv : to;
|
import std.conv : to;
|
||||||
const(Thing)* thing = name.text in currentScope;
|
import std.range : retro;
|
||||||
if (thing is null)
|
|
||||||
currentScope[name.text] = Thing(name.text, name.line, name.column, false);
|
size_t i = 0;
|
||||||
else
|
foreach (s; retro(stack))
|
||||||
{
|
{
|
||||||
immutable thisKind = fromLabel ? "Label" : "Variable";
|
const(Thing)* thing = name.text in s;
|
||||||
immutable otherKind = thing.isVar ? "variable" : "label";
|
if (thing is null)
|
||||||
addErrorMessage(name.line, name.column, "dscanner.suspicious.label_var_same_name",
|
currentScope[name.text] = Thing(name.text, name.line, name.column,
|
||||||
thisKind ~ " \"" ~ name.text ~ "\" has the same name as a "
|
!fromLabel/+, isConditional+/);
|
||||||
~ otherKind ~ " defined on line " ~ to!string(thing.line) ~ ".");
|
else if (i != 0 || !isConditional)
|
||||||
|
{
|
||||||
|
immutable thisKind = fromLabel ? "Label" : "Variable";
|
||||||
|
immutable otherKind = thing.isVar ? "variable" : "label";
|
||||||
|
addErrorMessage(name.line, name.column, "dscanner.suspicious.label_var_same_name",
|
||||||
|
thisKind ~ " \"" ~ name.text ~ "\" has the same name as a "
|
||||||
|
~ otherKind ~ " defined on line " ~ to!string(thing.line) ~ ".");
|
||||||
|
}
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,6 +99,7 @@ private:
|
||||||
size_t line;
|
size_t line;
|
||||||
size_t column;
|
size_t column;
|
||||||
bool isVar;
|
bool isVar;
|
||||||
|
//bool isConditional;
|
||||||
}
|
}
|
||||||
|
|
||||||
ref currentScope() @property
|
ref currentScope() @property
|
||||||
|
@ -98,6 +116,8 @@ private:
|
||||||
{
|
{
|
||||||
stack.length--;
|
stack.length--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int conditionalDepth;
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
@ -114,6 +134,29 @@ blah:
|
||||||
int blah; // [warn]: Variable "blah" has the same name as a label defined on line 4.
|
int blah; // [warn]: Variable "blah" has the same name as a label defined on line 4.
|
||||||
}
|
}
|
||||||
int blah;
|
int blah;
|
||||||
}c, sac);
|
unittest
|
||||||
|
{
|
||||||
|
static if (stuff)
|
||||||
|
int a;
|
||||||
|
int a; // [warn]: Variable "a" has the same name as a variable defined on line 11.
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
static if (stuff)
|
||||||
|
int a = 10;
|
||||||
|
else
|
||||||
|
int a = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
static if (stuff)
|
||||||
|
int a = 10;
|
||||||
|
else
|
||||||
|
int a = 20;
|
||||||
|
int a; // [warn]: Variable "a" has the same name as a variable defined on line 28.
|
||||||
|
}
|
||||||
|
}c, sac);
|
||||||
stderr.writeln("Unittest for LabelVarNameCheck passed.");
|
stderr.writeln("Unittest for LabelVarNameCheck passed.");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue