Merge remote-tracking branch 'upstream/master' into phobos
This commit is contained in:
commit
766a9d2ea9
2
dub.json
2
dub.json
|
@ -14,7 +14,7 @@
|
||||||
"dependencies" : {
|
"dependencies" : {
|
||||||
"libdparse": "~>0.8.0-alpha.5",
|
"libdparse": "~>0.8.0-alpha.5",
|
||||||
"dsymbol" : "~>0.3.0-alpha.3",
|
"dsymbol" : "~>0.3.0-alpha.3",
|
||||||
"inifiled" : ">=1.0.2",
|
"inifiled" : "~>1.1.0",
|
||||||
"emsi_containers" : "~>0.6.0",
|
"emsi_containers" : "~>0.6.0",
|
||||||
"libddoc" : "~>0.3.0-beta.1",
|
"libddoc" : "~>0.3.0-beta.1",
|
||||||
"stdx-allocator" : "~>2.77.0"
|
"stdx-allocator" : "~>2.77.0"
|
||||||
|
|
|
@ -119,8 +119,8 @@ class ProperlyDocumentedPublicFunctions : BaseAnalyzer
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto comment = setLastDdocParams(decl.name.line, decl.name.column, decl.comment);
|
auto comment = setLastDdocParams(decl.name.line, decl.name.column, decl.comment);
|
||||||
checkDdocParams(decl.name.line, decl.name.column, decl.parameters);
|
|
||||||
checkDdocParams(decl.name.line, decl.name.column, decl.templateParameters);
|
checkDdocParams(decl.name.line, decl.name.column, decl.parameters, decl.templateParameters);
|
||||||
|
|
||||||
enum voidType = tok!"void";
|
enum voidType = tok!"void";
|
||||||
|
|
||||||
|
@ -187,29 +187,69 @@ private:
|
||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkDdocParams(size_t line, size_t column, const Parameters params)
|
void checkDdocParams(size_t line, size_t column, const Parameters params,
|
||||||
|
const TemplateParameters templateParameters = null)
|
||||||
{
|
{
|
||||||
import std.algorithm.searching : canFind;
|
import std.array : array;
|
||||||
|
import std.algorithm.searching : canFind, countUntil;
|
||||||
|
import std.algorithm.iteration : map;
|
||||||
|
import std.algorithm.mutation : remove;
|
||||||
|
import std.range : indexed, iota;
|
||||||
|
|
||||||
|
// convert templateParameters into a string[] for faster access
|
||||||
|
const(TemplateParameter)[] templateList;
|
||||||
|
if (const tp = templateParameters)
|
||||||
|
if (const tpl = tp.templateParameterList)
|
||||||
|
templateList = tpl.items;
|
||||||
|
string[] tlList = templateList.map!(a => templateParamName(a)).array;
|
||||||
|
|
||||||
|
// make a copy of all parameters and remove the seen ones later during the loop
|
||||||
|
size_t[] unseenTemplates = templateList.length.iota.array;
|
||||||
|
|
||||||
if (lastSeenFun.active && params !is null)
|
if (lastSeenFun.active && params !is null)
|
||||||
foreach (p; params.parameters)
|
foreach (p; params.parameters)
|
||||||
{
|
{
|
||||||
|
string templateName;
|
||||||
|
if (const t = p.type)
|
||||||
|
if (const t2 = t.type2)
|
||||||
|
if (const tip = t2.typeIdentifierPart)
|
||||||
|
if (const iot = tip.identifierOrTemplateInstance)
|
||||||
|
templateName = iot.identifier.text;
|
||||||
|
|
||||||
|
const idx = tlList.countUntil(templateName);
|
||||||
|
if (idx >= 0)
|
||||||
|
{
|
||||||
|
unseenTemplates = unseenTemplates.remove(idx);
|
||||||
|
tlList = tlList.remove(idx);
|
||||||
|
// documenting template parameter should be allowed
|
||||||
|
lastSeenFun.params[templateName] = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!lastSeenFun.ddocParams.canFind(p.name.text))
|
if (!lastSeenFun.ddocParams.canFind(p.name.text))
|
||||||
addErrorMessage(line, column, MISSING_PARAMS_KEY,
|
addErrorMessage(line, column, MISSING_PARAMS_KEY,
|
||||||
format(MISSING_PARAMS_MESSAGE, p.name.text));
|
format(MISSING_PARAMS_MESSAGE, p.name.text));
|
||||||
else
|
else
|
||||||
lastSeenFun.params[p.name.text] = true;
|
lastSeenFun.params[p.name.text] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// now check the remaining, not used template parameters
|
||||||
|
auto unseenTemplatesArr = templateList.indexed(unseenTemplates).array;
|
||||||
|
checkDdocParams(line, column, unseenTemplatesArr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkDdocParams(size_t line, size_t column, const TemplateParameters templateParams)
|
void checkDdocParams(size_t line, size_t column, const TemplateParameters templateParams)
|
||||||
{
|
{
|
||||||
import std.algorithm.searching : canFind;
|
|
||||||
|
|
||||||
if (lastSeenFun.active && templateParams !is null && templateParams.templateParameterList !is null)
|
if (lastSeenFun.active && templateParams !is null && templateParams.templateParameterList !is null)
|
||||||
foreach (p; templateParams.templateParameterList.items)
|
checkDdocParams(line, column, templateParams.templateParameterList.items);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkDdocParams(size_t line, size_t column, const TemplateParameter[] templateParams)
|
||||||
{
|
{
|
||||||
auto name = templateParamName(p);
|
import std.algorithm.searching : canFind;
|
||||||
|
foreach (p; templateParams)
|
||||||
|
{
|
||||||
|
const name = templateParamName(p);
|
||||||
assert(name, "Invalid template parameter name."); // this shouldn't happen
|
assert(name, "Invalid template parameter name."); // this shouldn't happen
|
||||||
if (!lastSeenFun.ddocParams.canFind(name))
|
if (!lastSeenFun.ddocParams.canFind(name))
|
||||||
addErrorMessage(line, column, MISSING_PARAMS_KEY,
|
addErrorMessage(line, column, MISSING_PARAMS_KEY,
|
||||||
|
@ -694,7 +734,6 @@ string bar(string val){}
|
||||||
template bar(string val){}
|
template bar(string val){}
|
||||||
}c, sac);
|
}c, sac);
|
||||||
|
|
||||||
stderr.writeln("Unittest for ProperlyDocumentedPublicFunctions passed.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
|
@ -725,3 +764,38 @@ template abcde(Args ...) {
|
||||||
}
|
}
|
||||||
}c, sac);
|
}c, sac);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't force the documentation of the template parameter if it's a used type in the parameter list
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
StaticAnalysisConfig sac = disabledConfig;
|
||||||
|
sac.properly_documented_public_functions = Check.enabled;
|
||||||
|
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
/++
|
||||||
|
An awesome description.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
r = an input range.
|
||||||
|
|
||||||
|
Returns: Awesome values.
|
||||||
|
+/
|
||||||
|
string bar(R)(R r){}
|
||||||
|
}c, sac);
|
||||||
|
|
||||||
|
assertAnalyzerWarnings(q{
|
||||||
|
/++
|
||||||
|
An awesome description.
|
||||||
|
|
||||||
|
Params:
|
||||||
|
r = an input range.
|
||||||
|
|
||||||
|
Returns: Awesome values.
|
||||||
|
+/
|
||||||
|
string bar(P, R)(R r){}// [warn]: %s
|
||||||
|
}c.format(
|
||||||
|
ProperlyDocumentedPublicFunctions.MISSING_TEMPLATE_PARAMS_MESSAGE.format("P")
|
||||||
|
), sac);
|
||||||
|
|
||||||
|
stderr.writeln("Unittest for ProperlyDocumentedPublicFunctions passed.");
|
||||||
|
}
|
||||||
|
|
|
@ -476,7 +476,7 @@ string getConfigurationLocation()
|
||||||
|
|
||||||
/// Patch the INI file to v0.5.0 format.
|
/// Patch the INI file to v0.5.0 format.
|
||||||
//TODO: remove this from v0.6.0
|
//TODO: remove this from v0.6.0
|
||||||
bool hasWrongIniFileSection(string confiFilename, bool patch)
|
bool hasWrongIniFileSection(string configFilename, bool patch)
|
||||||
{
|
{
|
||||||
import std.string : indexOf;
|
import std.string : indexOf;
|
||||||
import std.array : replace;
|
import std.array : replace;
|
||||||
|
@ -486,12 +486,12 @@ bool hasWrongIniFileSection(string confiFilename, bool patch)
|
||||||
static immutable v1 = "analysis.config.StaticAnalysisConfig";
|
static immutable v1 = "analysis.config.StaticAnalysisConfig";
|
||||||
static immutable v2 = "dscanner.analysis.config.StaticAnalysisConfig";
|
static immutable v2 = "dscanner.analysis.config.StaticAnalysisConfig";
|
||||||
|
|
||||||
char[] c = cast(char[]) readFile(confiFilename);
|
char[] c = cast(char[]) readFile(configFilename);
|
||||||
try if (c.indexOf(v2) < 0)
|
try if (c.indexOf(v2) < 0)
|
||||||
{
|
{
|
||||||
if (!patch)
|
if (!patch)
|
||||||
{
|
{
|
||||||
writeln("warning, the configuration file `", confiFilename, "` contains an outdated property");
|
writeln("warning, the configuration file `", configFilename, "` contains an outdated property");
|
||||||
writeln("change manually [", v1, "] to [", v2, "]" );
|
writeln("change manually [", v1, "] to [", v2, "]" );
|
||||||
writeln("or restart D-Scanner with the `--patchConfig` option");
|
writeln("or restart D-Scanner with the `--patchConfig` option");
|
||||||
result = true;
|
result = true;
|
||||||
|
@ -499,8 +499,8 @@ bool hasWrongIniFileSection(string confiFilename, bool patch)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
c = replace(c, v1, v2);
|
c = replace(c, v1, v2);
|
||||||
std.file.write(confiFilename, c);
|
std.file.write(configFilename, c);
|
||||||
writeln("the configuration file `", confiFilename, "` has been updated correctly");
|
writeln("the configuration file `", configFilename, "` has been updated correctly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch(Exception e)
|
||||||
|
|
Loading…
Reference in New Issue