Update to new libdparse
This commit is contained in:
parent
f00026fde7
commit
d1a7424a36
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4e270c212daf0d2b55843604ecbdd1dcbd399a37
|
Subproject commit ccd01946add011c49e5cf92667cca1e1acd2bc33
|
||||||
|
|
@ -102,27 +102,23 @@ class DuplicateAttributeCheck : BaseAnalyzer
|
||||||
{
|
{
|
||||||
// Get the name from the attribute identifier
|
// Get the name from the attribute identifier
|
||||||
if (attribute
|
if (attribute
|
||||||
&& attribute.storageClass
|
&& attribute.atAttribute
|
||||||
&& attribute.storageClass.atAttribute
|
&& attribute.atAttribute.identifier !is Token.init
|
||||||
&& attribute.storageClass.atAttribute.identifier !is Token.init
|
&& attribute.atAttribute.identifier.text
|
||||||
&& attribute.storageClass.atAttribute.identifier.text
|
&& attribute.atAttribute.identifier.text.length)
|
||||||
&& attribute.storageClass.atAttribute.identifier.text.length)
|
|
||||||
{
|
{
|
||||||
auto token = attribute.storageClass.atAttribute.identifier;
|
auto token = attribute.atAttribute.identifier;
|
||||||
line = token.line;
|
line = token.line;
|
||||||
column = token.column;
|
column = token.column;
|
||||||
return token.text;
|
return token.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the attribute from the storage class token
|
// Get the attribute from the storage class token
|
||||||
if (attribute
|
if (attribute && attribute.attribute.type != tok!"")
|
||||||
&& attribute.storageClass
|
|
||||||
&& attribute.storageClass.token !is Token.init)
|
|
||||||
{
|
{
|
||||||
auto token = attribute.storageClass.token;
|
line = attribute.attribute.line;
|
||||||
line = token.line;
|
column = attribute.attribute.column;
|
||||||
column = token.column;
|
return attribute.attribute.type.str;
|
||||||
return token.type.str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
|
|
@ -27,23 +27,9 @@ class EnumArrayLiteralCheck : BaseAnalyzer
|
||||||
mixin visitTemplate!UnionDeclaration;
|
mixin visitTemplate!UnionDeclaration;
|
||||||
mixin visitTemplate!StructDeclaration;
|
mixin visitTemplate!StructDeclaration;
|
||||||
|
|
||||||
override void visit(const Declaration dec)
|
|
||||||
{
|
|
||||||
if (inAggregate) foreach (attr; dec.attributes)
|
|
||||||
{
|
|
||||||
if (attr.storageClass !is null &&
|
|
||||||
attr.storageClass.token == tok!"enum")
|
|
||||||
{
|
|
||||||
looking = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dec.accept(this);
|
|
||||||
looking = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
override void visit(const AutoDeclaration autoDec)
|
override void visit(const AutoDeclaration autoDec)
|
||||||
{
|
{
|
||||||
if (looking)
|
if (autoDec.storageClass && autoDec.storageClass.token == tok!"enum")
|
||||||
{
|
{
|
||||||
foreach (i, initializer; autoDec.initializers)
|
foreach (i, initializer; autoDec.initializers)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,10 @@ class FunctionAttributeCheck : BaseAnalyzer
|
||||||
|
|
||||||
override void visit(const AttributeDeclaration dec)
|
override void visit(const AttributeDeclaration dec)
|
||||||
{
|
{
|
||||||
if (inInterface > 0 && dec.attribute.storageClass !is null
|
if (inInterface > 0 && dec.attribute.attribute == tok!"abstract")
|
||||||
&& dec.attribute.storageClass.token == tok!"abstract")
|
|
||||||
{
|
{
|
||||||
addErrorMessage(dec.attribute.storageClass.token.line,
|
addErrorMessage(dec.attribute.attribute.line,
|
||||||
dec.attribute.storageClass.token.column, KEY, ABSTRACT_MESSAGE);
|
dec.attribute.attribute.column, KEY, ABSTRACT_MESSAGE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,21 +61,21 @@ class FunctionAttributeCheck : BaseAnalyzer
|
||||||
goto end;
|
goto end;
|
||||||
foreach (attr; dec.attributes)
|
foreach (attr; dec.attributes)
|
||||||
{
|
{
|
||||||
if (attr.storageClass is null)
|
if (attr.attribute.type == tok!"")
|
||||||
continue;
|
continue;
|
||||||
if (attr.storageClass.token == tok!"abstract" && inInterface)
|
if (attr.attribute == tok!"abstract" && inInterface)
|
||||||
{
|
{
|
||||||
addErrorMessage(attr.storageClass.token.line,
|
addErrorMessage(attr.attribute.line,
|
||||||
attr.storageClass.token.column, KEY, ABSTRACT_MESSAGE);
|
attr.attribute.column, KEY, ABSTRACT_MESSAGE);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dec.functionDeclaration !is null
|
if (dec.functionDeclaration !is null
|
||||||
&& (attr.storageClass.token == tok!"const"
|
&& (attr.attribute == tok!"const"
|
||||||
|| attr.storageClass.token == tok!"inout"
|
|| attr.attribute == tok!"inout"
|
||||||
|| attr.storageClass.token == tok!"immutable"))
|
|| attr.attribute == tok!"immutable"))
|
||||||
{
|
{
|
||||||
import std.string : format;
|
import std.string : format;
|
||||||
immutable string attrString = str(attr.storageClass.token.type);
|
immutable string attrString = str(attr.attribute.type);
|
||||||
addErrorMessage(dec.functionDeclaration.name.line,
|
addErrorMessage(dec.functionDeclaration.name.line,
|
||||||
dec.functionDeclaration.name.column, KEY,
|
dec.functionDeclaration.name.column, KEY,
|
||||||
format("'%s' is not an attribute of the return type."
|
format("'%s' is not an attribute of the return type."
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class LocalImportCheck : BaseAnalyzer
|
||||||
}
|
}
|
||||||
foreach (attr; dec.attributes)
|
foreach (attr; dec.attributes)
|
||||||
{
|
{
|
||||||
if (attr.storageClass !is null && attr.storageClass.token == tok!"static")
|
if (attr.attribute == tok!"static")
|
||||||
isStatic = true;
|
isStatic = true;
|
||||||
}
|
}
|
||||||
dec.accept(this);
|
dec.accept(this);
|
||||||
|
|
|
||||||
|
|
@ -46,14 +46,13 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
|
|
||||||
private static bool hasConst(const Attribute[] attributes)
|
private static bool hasConst(const Attribute[] attributes)
|
||||||
{
|
{
|
||||||
import std.algorithm;
|
import std.algorithm : any;
|
||||||
return attributes.any!(a => a.attribute == tok!"const"
|
return attributes.any!(a => a.attribute == tok!"const");
|
||||||
|| (a.storageClass !is null && a.storageClass.token == tok!"const"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool hasConst(const MemberFunctionAttribute[] attributes)
|
private static bool hasConst(const MemberFunctionAttribute[] attributes)
|
||||||
{
|
{
|
||||||
import std.algorithm;
|
import std.algorithm : any;
|
||||||
return attributes.any!(a => a.tokenType == tok!"const"
|
return attributes.any!(a => a.tokenType == tok!"const"
|
||||||
|| a.tokenType == tok!"immutable"
|
|| a.tokenType == tok!"immutable"
|
||||||
|| a.tokenType == tok!"inout");
|
|| a.tokenType == tok!"inout");
|
||||||
|
|
@ -71,7 +70,7 @@ class ObjectConstCheck : BaseAnalyzer
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
import analysis.config;
|
import analysis.config : StaticAnalysisConfig;
|
||||||
StaticAnalysisConfig sac;
|
StaticAnalysisConfig sac;
|
||||||
sac.object_const_check = true;
|
sac.object_const_check = true;
|
||||||
assertAnalyzerWarnings(q{
|
assertAnalyzerWarnings(q{
|
||||||
|
|
|
||||||
|
|
@ -69,10 +69,10 @@ void writeJSON(string key, string fileName, size_t line, size_t column, string m
|
||||||
write( " }");
|
write( " }");
|
||||||
}
|
}
|
||||||
|
|
||||||
void syntaxCheck(string[] fileNames)
|
bool syntaxCheck(string[] fileNames)
|
||||||
{
|
{
|
||||||
StaticAnalysisConfig config = defaultStaticAnalysisConfig();
|
StaticAnalysisConfig config = defaultStaticAnalysisConfig();
|
||||||
analyze(fileNames, config, false);
|
return analyze(fileNames, config, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateReport(string[] fileNames, const StaticAnalysisConfig config)
|
void generateReport(string[] fileNames, const StaticAnalysisConfig config)
|
||||||
|
|
@ -112,8 +112,10 @@ void generateReport(string[] fileNames, const StaticAnalysisConfig config)
|
||||||
}
|
}
|
||||||
|
|
||||||
// For multiple files
|
// For multiple files
|
||||||
void analyze(string[] fileNames, const StaticAnalysisConfig config, bool staticAnalyze = true)
|
// Returns: true if there were errors
|
||||||
|
bool analyze(string[] fileNames, const StaticAnalysisConfig config, bool staticAnalyze = true)
|
||||||
{
|
{
|
||||||
|
bool hasErrors = false;
|
||||||
foreach (fileName; fileNames)
|
foreach (fileName; fileNames)
|
||||||
{
|
{
|
||||||
File f = File(fileName);
|
File f = File(fileName);
|
||||||
|
|
@ -122,7 +124,12 @@ void analyze(string[] fileNames, const StaticAnalysisConfig config, bool staticA
|
||||||
f.rawRead(code);
|
f.rawRead(code);
|
||||||
ParseAllocator p = new ParseAllocator;
|
ParseAllocator p = new ParseAllocator;
|
||||||
StringCache cache = StringCache(StringCache.defaultBucketCount);
|
StringCache cache = StringCache(StringCache.defaultBucketCount);
|
||||||
const Module m = parseModule(fileName, code, p, cache, false);
|
uint errorCount = 0;
|
||||||
|
const Module m = parseModule(fileName, code, p, cache, false, null,
|
||||||
|
&errorCount, null);
|
||||||
|
assert (m);
|
||||||
|
if (errorCount > 0)
|
||||||
|
hasErrors = true;
|
||||||
MessageSet results = analyze(fileName, m, config, staticAnalyze);
|
MessageSet results = analyze(fileName, m, config, staticAnalyze);
|
||||||
if (results is null)
|
if (results is null)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -130,10 +137,12 @@ void analyze(string[] fileNames, const StaticAnalysisConfig config, bool staticA
|
||||||
writefln("%s(%d:%d)[warn]: %s", result.fileName, result.line,
|
writefln("%s(%d:%d)[warn]: %s", result.fileName, result.line,
|
||||||
result.column, result.message);
|
result.column, result.message);
|
||||||
}
|
}
|
||||||
|
return hasErrors;
|
||||||
}
|
}
|
||||||
|
|
||||||
const(Module) parseModule(string fileName, ubyte[] code, ParseAllocator p,
|
const(Module) parseModule(string fileName, ubyte[] code, ParseAllocator p,
|
||||||
ref StringCache cache, bool report, ulong* linesOfCode = null)
|
ref StringCache cache, bool report, ulong* linesOfCode = null,
|
||||||
|
uint* errorCount = null, uint* warningCount = null)
|
||||||
{
|
{
|
||||||
import stats : isLineOfCode;
|
import stats : isLineOfCode;
|
||||||
auto lexer = byToken(code);
|
auto lexer = byToken(code);
|
||||||
|
|
@ -153,7 +162,8 @@ const(Module) parseModule(string fileName, ubyte[] code, ParseAllocator p,
|
||||||
message.isError);
|
message.isError);
|
||||||
}
|
}
|
||||||
return std.d.parser.parseModule(tokens, fileName, p,
|
return std.d.parser.parseModule(tokens, fileName, p,
|
||||||
report ? &messageFunctionJSON : &messageFunction);
|
report ? &messageFunctionJSON : &messageFunction,
|
||||||
|
errorCount, warningCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageSet analyze(string fileName, const Module m,
|
MessageSet analyze(string fileName, const Module m,
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,9 @@ class UndocumentedDeclarationCheck : BaseAnalyzer
|
||||||
if (dec.attributeDeclaration)
|
if (dec.attributeDeclaration)
|
||||||
{
|
{
|
||||||
auto attr = dec.attributeDeclaration.attribute;
|
auto attr = dec.attributeDeclaration.attribute;
|
||||||
if (isProtection(attr.attribute))
|
if (isProtection(attr.attribute.type))
|
||||||
set(attr.attribute);
|
set(attr.attribute.type);
|
||||||
else if (dec.attributeDeclaration.attribute.storageClass !is null
|
else if (attr.attribute == tok!"override")
|
||||||
&& dec.attributeDeclaration.attribute.storageClass.token == tok!"override")
|
|
||||||
{
|
{
|
||||||
setOverride(true);
|
setOverride(true);
|
||||||
}
|
}
|
||||||
|
|
@ -50,16 +49,13 @@ class UndocumentedDeclarationCheck : BaseAnalyzer
|
||||||
bool ovr = false;
|
bool ovr = false;
|
||||||
foreach (attribute; dec.attributes)
|
foreach (attribute; dec.attributes)
|
||||||
{
|
{
|
||||||
if (isProtection(attribute.attribute))
|
if (isProtection(attribute.attribute.type))
|
||||||
{
|
{
|
||||||
shouldPop = true;
|
shouldPop = true;
|
||||||
push(attribute.attribute);
|
push(attribute.attribute.type);
|
||||||
}
|
}
|
||||||
else if (attribute.storageClass !is null
|
else if (attribute.attribute == tok!"override")
|
||||||
&& attribute.storageClass.token == tok!"override")
|
|
||||||
{
|
|
||||||
ovr = true;
|
ovr = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (ovr)
|
if (ovr)
|
||||||
setOverride(true);
|
setOverride(true);
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,7 @@ class UnusedVariableCheck : BaseAnalyzer
|
||||||
override void visit(const Declaration declaration)
|
override void visit(const Declaration declaration)
|
||||||
{
|
{
|
||||||
if (!isOverride) foreach (attribute; declaration.attributes)
|
if (!isOverride) foreach (attribute; declaration.attributes)
|
||||||
isOverride = isOverride || (attribute.storageClass !is null &&
|
isOverride = isOverride || (attribute.attribute == tok!"override");
|
||||||
attribute.storageClass.token == tok!"override");
|
|
||||||
declaration.accept(this);
|
declaration.accept(this);
|
||||||
isOverride = false;
|
isOverride = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1994
src/astprinter.d
1994
src/astprinter.d
File diff suppressed because it is too large
Load Diff
|
|
@ -72,9 +72,7 @@ class CTagsPrinter : ASTVisitor
|
||||||
|
|
||||||
override void visit(const TemplateDeclaration dec)
|
override void visit(const TemplateDeclaration dec)
|
||||||
{
|
{
|
||||||
auto name = dec.eponymousTemplateDeclaration is null ? dec.name
|
tagLines ~= "%s\t%s\t%d;\"\tT%s\n".format(dec.name.text, fileName, dec.name.line, context);
|
||||||
: dec.eponymousTemplateDeclaration.name;
|
|
||||||
tagLines ~= "%s\t%s\t%d;\"\tT%s\n".format(name.text, fileName, name.line, context);
|
|
||||||
auto c = context;
|
auto c = context;
|
||||||
context = "\ttemplate:" ~ dec.name.text;
|
context = "\ttemplate:" ~ dec.name.text;
|
||||||
dec.accept(this);
|
dec.accept(this);
|
||||||
|
|
|
||||||
|
|
@ -175,7 +175,7 @@ int run(string[] args)
|
||||||
}
|
}
|
||||||
else if (syntaxCheck)
|
else if (syntaxCheck)
|
||||||
{
|
{
|
||||||
.syntaxCheck(expandArgs(args));
|
return .syntaxCheck(expandArgs(args));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue