Merge remote-tracking branch 'upstream/master' into phobos

This commit is contained in:
Sebastian Wilzbach 2018-03-30 11:20:38 +02:00
commit 766a9d2ea9
3 changed files with 96 additions and 22 deletions

View File

@ -14,7 +14,7 @@
"dependencies" : {
"libdparse": "~>0.8.0-alpha.5",
"dsymbol" : "~>0.3.0-alpha.3",
"inifiled" : ">=1.0.2",
"inifiled" : "~>1.1.0",
"emsi_containers" : "~>0.6.0",
"libddoc" : "~>0.3.0-beta.1",
"stdx-allocator" : "~>2.77.0"

View File

@ -119,8 +119,8 @@ class ProperlyDocumentedPublicFunctions : BaseAnalyzer
return;
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";
@ -187,29 +187,69 @@ private:
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)
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))
addErrorMessage(line, column, MISSING_PARAMS_KEY,
format(MISSING_PARAMS_MESSAGE, p.name.text));
else
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)
{
import std.algorithm.searching : canFind;
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
if (!lastSeenFun.ddocParams.canFind(name))
addErrorMessage(line, column, MISSING_PARAMS_KEY,
@ -694,7 +734,6 @@ string bar(string val){}
template bar(string val){}
}c, sac);
stderr.writeln("Unittest for ProperlyDocumentedPublicFunctions passed.");
}
unittest
@ -725,3 +764,38 @@ template abcde(Args ...) {
}
}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.");
}

View File

@ -476,7 +476,7 @@ string getConfigurationLocation()
/// Patch the INI file to v0.5.0 format.
//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.array : replace;
@ -486,12 +486,12 @@ bool hasWrongIniFileSection(string confiFilename, bool patch)
static immutable v1 = "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)
{
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("or restart D-Scanner with the `--patchConfig` option");
result = true;
@ -499,8 +499,8 @@ bool hasWrongIniFileSection(string confiFilename, bool patch)
else
{
c = replace(c, v1, v2);
std.file.write(confiFilename, c);
writeln("the configuration file `", confiFilename, "` has been updated correctly");
std.file.write(configFilename, c);
writeln("the configuration file `", configFilename, "` has been updated correctly");
}
}
catch(Exception e)