UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

85 lines 6.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DEPRECATED_FUNCTIONS = void 0; const vertex_1 = require("../../dataflow/graph/vertex"); const df_helper_1 = require("../../dataflow/graph/df-helper"); const identifier_1 = require("../../dataflow/environments/identifier"); const flowr_search_builder_1 = require("../../search/flowr-search-builder"); const search_enrichers_1 = require("../../search/search-executor/search-enrichers"); const range_1 = require("../../util/range"); const linter_format_1 = require("../linter-format"); const linter_tags_1 = require("../linter-tags"); const function_finder_util_1 = require("./function-finder-util"); exports.DEPRECATED_FUNCTIONS = { // unlike functionFinderUtil.createSearch(config.fns), this does not pre-filter to the hardcoded list: the // sigdb-driven pass below needs every resolved call, so the `fns` filtering happens in processSearchResult instead createSearch: (_config) => flowr_search_builder_1.Q.all().filter(vertex_1.VertexType.FunctionCall).with(search_enrichers_1.Enrichment.CallTargets, { onlyBuiltin: true, qualifyNames: false // we don't use qualified names for this rule yet }), processSearchResult: async (elements, config, data) => { const matchesConfiguredFns = identifier_1.Identifier.regex(...config.fns); const hardcoded = await function_finder_util_1.functionFinderUtil.processSearchResult(elements, config, data, es => es.filter(e => (0, search_enrichers_1.enrichmentContent)(e, search_enrichers_1.Enrichment.CallTargets)?.targets .some(t => typeof t === 'string' && matchesConfiguredFns.test(t)))); const deps = data.inspectContext().deps; if (deps.signatureSources().length === 0) { return hardcoded; } // sigdb-driven detection: flag any resolved call whose signature-database entry marks it deprecated, // even when it is not part of the hardcoded `fns` list above const graph = (await data.dataflow()).graph; const alreadyFlagged = new Set(hardcoded.results.map(r => r.involvedId)); const deprecatedByName = new Map(); const sigdbFlagged = []; for (const element of elements.getElements()) { const id = element.node.info.id; if (alreadyFlagged.has(id)) { continue; } const qualified = df_helper_1.Dataflow.qualify(id, graph); if (qualified === undefined) { continue; } const name = identifier_1.Identifier.toString(qualified); let deprecated = deprecatedByName.get(name); if (deprecated === undefined) { deprecated = deps.signatureOf(qualified)?.props.includes('deprecated') === true; deprecatedByName.set(name, deprecated); } if (!deprecated) { continue; } const loc = range_1.SourceLocation.fromNode(element.node); if (loc === undefined) { continue; } alreadyFlagged.add(id); sigdbFlagged.push({ certainty: linter_format_1.LintingResultCertainty.Certain, involvedId: id, function: name, loc }); } return { results: [...hardcoded.results, ...sigdbFlagged], '.meta': { totalCalls: hardcoded['.meta'].totalCalls + sigdbFlagged.length, totalFunctionDefinitions: hardcoded['.meta'].totalFunctionDefinitions + sigdbFlagged.length } }; }, prettyPrint: function_finder_util_1.functionFinderUtil.prettyPrint('deprecated'), info: { name: 'Deprecated Functions', tags: [linter_tags_1.LintingRuleTag.Deprecated, linter_tags_1.LintingRuleTag.Smell, linter_tags_1.LintingRuleTag.Usability, linter_tags_1.LintingRuleTag.Reproducibility], // the hardcoded `fns` list ensures every reported hit is real, but the list is pre-crawled and hence // incomplete; the signature-database pass above adds recall for whichever packages are resolved certainty: linter_format_1.LintingRuleCertainty.BestEffort, description: 'Marks deprecated functions that should not be used anymore.', defaultConfig: { fns: ['all_equal', 'arrange_all', 'distinct_all', 'filter_all', 'group_by_all', 'summarise_all', 'mutate_all', 'select_all', 'vars', 'all_vars', 'id', 'failwith', 'select_vars', 'rename_vars', 'select_var', 'current_vars', 'bench_tbls', 'compare_tbls', 'compare_tbls2', 'eval_tbls', 'eval_tbls2', 'location', 'changes', 'combine', 'do', 'funs', 'add_count_', 'add_tally_', 'arrange_', 'count_', 'distinct_', 'do_', 'filter_', 'funs_', 'group_by_', 'group_indices_', 'mutate_', 'tally_', 'transmute_', 'rename_', 'rename_vars_', 'select_', 'select_vars_', 'slice_', 'summarise_', 'summarize_', 'summarise_each', 'src_local', 'tbl_df', 'add_rownames', 'group_nest', 'group_split', 'with_groups', 'nest_by', 'progress_estimated', 'recode', 'sample_n', 'top_n', 'transmute', 'fct_explicit_na', 'aes_', 'aes_auto', 'annotation_logticks', 'is.Coord', 'coord_flip', 'coord_map', 'is.facet', 'fortify', 'is.ggproto', 'guide_train', 'is.ggplot', 'qplot', 'is.theme', 'gg_dep', 'liply', 'isplit2', 'list_along', 'cross', 'invoke', 'at_depth', 'prepend', 'rerun', 'splice', '`%@%`', 'rbernoulli', 'rdunif', 'when', 'update_list', 'map_raw', 'accumulate', 'reduce_right', 'flatten', 'map_dfr', 'as_vector', 'transpose', 'melt_delim', 'melt_fwf', 'melt_table', 'read_table2', 'str_interp', 'as_tibble', 'data_frame', 'tibble_', 'data_frame_', 'lst_', 'as_data_frame', 'as.tibble', 'frame_data', 'trunc_mat', 'is.tibble', 'tidy_names', 'set_tidy_names', 'repair_names', 'extract_numeric', 'complete_', 'drop_na_', 'expand_', 'crossing_', 'nesting_', 'extract_', 'fill_', 'gather_', 'nest_', 'separate_rows_', 'separate_', 'spread_', 'unite_', 'unnest_', 'extract', 'gather', 'nest_legacy', 'separate_rows', 'separate', 'spread'] } } }; //# sourceMappingURL=deprecated-functions.js.map