@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
100 lines • 5.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ROXYGEN_ARGS = void 0;
const linter_format_1 = require("../linter-format");
const range_1 = require("../../util/range");
const flowr_search_builder_1 = require("../../search/flowr-search-builder");
const linter_tags_1 = require("../linter-tags");
const assert_1 = require("../../util/assert");
const vertex_1 = require("../../dataflow/graph/vertex");
const roxygen_ast_1 = require("../../r-bridge/roxygen2/roxygen-ast");
const r_function_definition_1 = require("../../r-bridge/lang-4.x/ast/model/nodes/r-function-definition");
const documentation_provider_1 = require("../../r-bridge/roxygen2/documentation-provider");
function getDocumentation(id, idMap) {
const comment = (0, documentation_provider_1.getDocumentationOf)(id, idMap);
if (comment === undefined) {
return undefined;
}
return Array.isArray(comment) ? comment : [comment];
}
function calculateArgumentDiff(inheritedParams, functionParam, roxygenParam) {
//match documented against existing params
let underDocumented = new Set(functionParam);
const notOverDocumented = underDocumented.has('...');
let overDocumented = new Set(roxygenParam);
const commonParams = underDocumented.intersection(overDocumented);
underDocumented = underDocumented.difference(commonParams);
overDocumented = overDocumented.difference(commonParams);
//case: '...', overdocumentation not possible
if (notOverDocumented) {
//if still remaining overdocumented parameters, "..." doesn't need to be documented
if (overDocumented.size > 0) {
underDocumented.delete('...');
}
//can't be overdocumented
overDocumented.clear();
}
//inherited params removed from list of overdocumented params
overDocumented = overDocumented.difference(new Set(inheritedParams));
return underDocumented.size === 0 && overDocumented.size === 0 ? false : { under: Array.from(underDocumented), over: Array.from(overDocumented) };
}
exports.ROXYGEN_ARGS = {
createSearch: () => flowr_search_builder_1.Q.all().filter(vertex_1.VertexType.FunctionDefinition),
processSearchResult: (elements, _config, { normalize }) => {
return {
results: elements.getElements()
.map(element => ({
element,
underDocumented: [],
overDocumented: []
}))
.filter(({ element: { node }, underDocumented, overDocumented }) => {
const comments = getDocumentation(node.info.id, normalize.idMap);
if (!comments) {
return false;
}
const parameters = getParameters(node);
//get parameter names
const functionParamNames = parameters.map(p => p.name.content.toString());
const inheritedParams = comments.filter(tag => (tag?.inherited && tag.type === roxygen_ast_1.KnownRoxygenTags.Param)).map(tag => (tag.value.name));
const roxygenParamNames = comments
.filter(tag => tag.type === roxygen_ast_1.KnownRoxygenTags.Param)
.map(tag => tag.value.name);
if (functionParamNames === null || roxygenParamNames == null) {
return false;
}
const result = calculateArgumentDiff(inheritedParams, functionParamNames, roxygenParamNames);
if (result === false) {
return false;
}
underDocumented.push(...result.under);
overDocumented.push(...result.over);
return true;
})
.map(({ element, overDocumented, underDocumented }) => ({
certainty: linter_format_1.LintingResultCertainty.Uncertain,
involvedId: element.node.info.id,
loc: range_1.SourceLocation.fromNode(element.node),
underDocumented: underDocumented,
overDocumented: overDocumented
}))
.filter(element => (0, assert_1.isNotUndefined)(element.loc)),
'.meta': {}
};
},
prettyPrint: {
[linter_format_1.LintingPrettyPrintContext.Query]: result => `Code at ${range_1.SourceLocation.format(result.loc)}`,
[linter_format_1.LintingPrettyPrintContext.Full]: result => `Code at ${range_1.SourceLocation.format(result.loc)} has undocumented parameters: ${result.underDocumented?.join()} and overdocumented parameters: ${result.overDocumented?.join()}`
},
info: {
name: 'Roxygen Arguments',
tags: [linter_tags_1.LintingRuleTag.Smell, linter_tags_1.LintingRuleTag.Documentation, linter_tags_1.LintingRuleTag.Style],
certainty: linter_format_1.LintingRuleCertainty.BestEffort,
description: 'Checks whether a function has undocumented or overdocumented parameters',
defaultConfig: {}
}
};
function getParameters(node) {
return r_function_definition_1.RFunctionDefinition.is(node) ? node.parameters : [];
}
//# sourceMappingURL=roxygen-arguments.js.map