Skip to content

Commit

Permalink
Remove lodash (prettier#12628)
Browse files Browse the repository at this point in the history
* Replace `groupBy`

* Replace `partition`

* Replace `pick`

* Move `partition`

* Replace `uniqBy`

* Replace `fromPairs`

* Remove usage from website

* Reuse `partition`

* Remove from package.json

* Fix

* Use `ignore.default`

* Add `resolveConfig` to `FileInfoOptions`

* Explicit tuple types

* Make `cache` optional

* Fix cosmiconfig type

* Use `@ts-expect-error` for private property access

* Add type annotation for validate

* Fix type errors for `OptionInfo`

* Add `@ts-expect-error`

* Fix type of `normalizeOptions`

* Fix `OptionInfo` type

* Add `@ts-expect-error` for `option-normalizer`

* Avoid type error

* Fix typo

* Add types for lodash fns

Co-authored-by: fisker Cheung <lionkay@gmail.com>
  • Loading branch information
2 people authored and pull[bot] committed Dec 29, 2022
1 parent b60d17c commit cec9757
Show file tree
Hide file tree
Showing 19 changed files with 155 additions and 33 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
"leven": "4.0.0",
"lines-and-columns": "2.0.3",
"linguist-languages": "7.15.0",
"lodash": "4.17.21",
"mem": "9.0.2",
"meriyah": "4.2.1",
"micromatch": "4.0.5",
Expand Down
4 changes: 3 additions & 1 deletion src/cli/options/create-minimist-options.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"use strict";

const partition = require("lodash/partition");
const {
utils: { partition },
} = require("../prettier-internal.js");

module.exports = function createMinimistOptions(detailedOptions) {
const [boolean, string] = partition(
Expand Down
2 changes: 1 addition & 1 deletion src/cli/options/parse-cli-arguments.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"use strict";
const pick = require("lodash/pick");
const camelCase = require("camelcase");
const { pick } = require("../utils.js");
const getContextOptions = require("./get-context-options.js");
const minimist = require("./minimist.js");
const createMinimistOptions = require("./create-minimist-options.js");
Expand Down
2 changes: 1 addition & 1 deletion src/cli/usage.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"use strict";

const groupBy = require("lodash/groupBy");
const camelCase = require("camelcase");
const constant = require("./constant.js");
const { groupBy } = require("./utils.js");

const OPTION_USAGE_THRESHOLD = 25;
const CHOICE_USAGE_MARGIN = 3;
Expand Down
37 changes: 36 additions & 1 deletion src/cli/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,39 @@
// eslint-disable-next-line no-console
const printToScreen = console.log.bind(console);

module.exports = { printToScreen };
/**
* @template Obj
* @template Key
* @param {Array<Obj>} array
* @param {(value: Obj) => Key} iteratee
* @returns {{[p in Key]: T}}
*/
function groupBy(array, iteratee) {
const result = Object.create(null);

for (const value of array) {
const key = iteratee(value);

if (Array.isArray(result[key])) {
result[key].push(value);
} else {
result[key] = [value];
}
}

return result;
}

/**
* @template Obj
* @template {keyof Obj} Keys
* @param {Obj} object
* @param {Array<Keys>} keys
* @returns {{[key in Keys]: Obj[key]}}
*/
function pick(object, keys) {
const entries = keys.map((key) => [key, object[key]]);
return Object.fromEntries(entries);
}

module.exports = { printToScreen, groupBy, pick };
2 changes: 1 addition & 1 deletion src/common/create-ignorer.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";

const path = require("path");
const ignore = require("ignore");
const ignore = require("ignore").default;
const getFileContentOrNull = require("../utils/get-file-content-or-null.js");

/**
Expand Down
2 changes: 1 addition & 1 deletion src/common/get-file-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const config = require("../config/resolve-config.js");
const createIgnorer = require("./create-ignorer.js");

/**
* @typedef {{ ignorePath?: string, withNodeModules?: boolean, plugins: object }} FileInfoOptions
* @typedef {{ ignorePath?: string, withNodeModules?: boolean, plugins: object, resolveConfig?: boolean }} FileInfoOptions
* @typedef {{ ignored: boolean, inferredParser: string | null }} FileInfoResult
*/

Expand Down
6 changes: 3 additions & 3 deletions src/common/load-plugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

const fs = require("fs");
const path = require("path");
const uniqBy = require("lodash/uniqBy");
const partition = require("lodash/partition");
const fastGlob = require("fast-glob");
const partition = require("../utils/partition.js");
const uniqByKey = require("../utils/uniq-by-key.js");
const internalPlugins = require("../languages.js");
const { default: mem, memClear } = require("../../vendors/mem.js");
const thirdParty = require("./third-party.js");
Expand Down Expand Up @@ -91,7 +91,7 @@ function load(plugins, pluginSearchDirs) {
);

const externalPlugins = [
...uniqBy(
...uniqByKey(
[...externalManualLoadPluginInfos, ...externalAutoLoadPluginInfos],
"requirePath"
).map((externalPluginInfo) => ({
Expand Down
29 changes: 15 additions & 14 deletions src/config/resolve-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,21 @@ const thirdParty = require("../common/third-party.js");

const loadToml = require("../utils/load-toml.js");
const loadJson5 = require("../utils/load-json5.js");
const partition = require("../utils/partition.js");
const resolve = require("../common/resolve.js");
const { default: mem, memClear } = require("../../vendors/mem.js");
const resolveEditorConfig = require("./resolve-config-editorconfig.js");

/**
* @typedef {import("cosmiconfig/dist/Explorer").Explorer} Explorer
* @typedef {{sync: boolean; cache: boolean }} Options
* @typedef {ReturnType<import("cosmiconfig").cosmiconfig>} Explorer
* @typedef {ReturnType<import("cosmiconfig").cosmiconfigSync>} SyncExplorer
* @typedef {{sync?: boolean; cache?: boolean }} Options
*/

/**
* @type {(opts: Options) => Explorer}
* @template {Options} Opts
* @param {Opts} opts
* @return {Opts["sync"] extends true ? SyncExplorer : Explorer}
*/
const getExplorerMemoized = mem(
(opts) => {
Expand Down Expand Up @@ -67,8 +71,9 @@ const getExplorerMemoized = mem(
);

/**
* @param {Options} opts
* @return {Explorer}
* @template {Options} Opts
* @param {Opts} opts
* @return {Opts["sync"] extends true ? SyncExplorer : Explorer}
*/
function getExplorer(opts) {
// Normalize opts before passing to a memoized function
Expand All @@ -85,6 +90,7 @@ function _resolveConfig(filePath, opts, sync) {
};
const { load, search } = getExplorer(loadOpts);
const loadEditorConfig = resolveEditorConfig.getLoadFunction(loadOpts);
/** @type {[any, any]} */
const arr = [
opts.config ? load(opts.config) : search(filePath),
loadEditorConfig(filePath),
Expand Down Expand Up @@ -169,15 +175,10 @@ function pathMatchesGlobs(filePath, patterns, excludedPatterns) {
const patternList = Array.isArray(patterns) ? patterns : [patterns];
// micromatch always matches against basename when the option is enabled
// use only patterns without slashes with it to match minimatch behavior
const withSlashes = [];
const withoutSlashes = [];
for (const pattern of patternList) {
if (pattern.includes("/")) {
withSlashes.push(pattern);
} else {
withoutSlashes.push(pattern);
}
}
const [withSlashes, withoutSlashes] = partition(patternList, (pattern) =>
pattern.includes("/")
);

return (
micromatch.isMatch(filePath, withoutSlashes, {
ignore: excludedPatterns,
Expand Down
6 changes: 6 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ function _withPlugins(
};
}

/**
* @param {*} fn
* @param {*} optsArgIdx
* @returns {*}
*/
function withPlugins(fn, optsArgIdx) {
const resultingFn = _withPlugins(fn, optsArgIdx);
if (fn.sync) {
Expand Down Expand Up @@ -75,6 +80,7 @@ module.exports = {
utils: {
arrayify: require("./utils/arrayify.js"),
getLast: require("./utils/get-last.js"),
partition: require("./utils/partition.js"),
isNonEmptyArray: require("./common/util.js").isNonEmptyArray,
},
},
Expand Down
2 changes: 1 addition & 1 deletion src/main/core-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const CATEGORY_SPECIAL = "Special";
* @typedef {Object} OptionInfo
* @property {string} [since] - available since version
* @property {string} category
* @property {'int' | 'boolean' | 'choice' | 'path'} type
* @property {'int' | 'boolean' | 'choice' | 'path' | 'string' | 'flag'} type
* @property {boolean} [array] - indicate it's an array of the specified type
* @property {OptionValueInfo} [default]
* @property {OptionRangeInfo} [range] - for type int
Expand Down
2 changes: 2 additions & 0 deletions src/main/multiparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ function textToDoc(
const astComments = ast.comments;
delete ast.comments;
comments.attach(astComments, ast, text, nextOptions);
// @ts-expect-error -- Casting to `unique symbol` isn't allowed in JSDoc comment
nextOptions[Symbol.for("comments")] = astComments || [];
// @ts-expect-error -- Casting to `unique symbol` isn't allowed in JSDoc comment
nextOptions[Symbol.for("tokens")] = ast.tokens || [];

const doc = printAstToDoc(ast, nextOptions);
Expand Down
28 changes: 25 additions & 3 deletions src/main/options-normalizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
const vnopts = require("vnopts");
const getLast = require("../utils/get-last.js");

/**
* @typedef {import("./support").NamedOptionInfo} NamedOptionInfo
*/

const cliDescriptor = {
key: (key) => (key.length === 1 ? `-${key}` : `--${key}`),
value: (value) => vnopts.apiDescriptor.value(value),
Expand Down Expand Up @@ -55,15 +59,20 @@ const getFlagSchema = ({ colorsModule, levenshteinDistance }) =>

let hasDeprecationWarned;

/**
* @param {*} options
* @param {*} optionInfos
* @param {{ logger?: false; isCLI?: boolean; passThrough?: boolean; colorsModule?: any; levenshteinDistance?: any }} param2
*/
function normalizeOptions(
options,
optionInfos,
{
logger,
logger = false,
isCLI = false,
passThrough = false,
colorsModule,
levenshteinDistance,
colorsModule = null,
levenshteinDistance = null,
} = {}
) {
const unknown = !passThrough
Expand Down Expand Up @@ -95,12 +104,14 @@ function normalizeOptions(
const shouldSuppressDuplicateDeprecationWarnings = logger !== false;

if (shouldSuppressDuplicateDeprecationWarnings && hasDeprecationWarned) {
// @ts-expect-error
normalizer._hasDeprecationWarned = hasDeprecationWarned;
}

const normalized = normalizer.normalize(options);

if (shouldSuppressDuplicateDeprecationWarnings) {
// @ts-expect-error
hasDeprecationWarned = normalizer._hasDeprecationWarned;
}

Expand Down Expand Up @@ -134,6 +145,7 @@ function optionInfosToSchemas(
if (optionInfo.alias && isCLI) {
schemas.push(
vnopts.AliasSchema.create({
// @ts-expect-error
name: optionInfo.alias,
sourceName: optionInfo.name,
})
Expand All @@ -144,6 +156,11 @@ function optionInfosToSchemas(
return schemas;
}

/**
* @param {NamedOptionInfo} optionInfo
* @param {any} param1
* @returns
*/
function optionInfoToSchema(
optionInfo,
{ isCLI, optionInfos, colorsModule, levenshteinDistance }
Expand All @@ -152,6 +169,7 @@ function optionInfoToSchema(

if (name === "plugin-search-dir" || name === "pluginSearchDirs") {
return vnopts.AnySchema.create({
// @ts-expect-error
name,
preprocess(value) {
if (value === false) {
Expand All @@ -160,6 +178,9 @@ function optionInfoToSchema(
value = Array.isArray(value) ? value : [value];
return value;
},
/**
* @param {Array<unknown> | false} value
*/
validate(value) {
if (value === false) {
return true;
Expand Down Expand Up @@ -260,6 +281,7 @@ function optionInfoToSchema(
? vnopts.ArraySchema.create({
...(isCLI ? { preprocess: (v) => (Array.isArray(v) ? v : [v]) } : {}),
...handlers,
// @ts-expect-error
valueSchema: SchemaConstructor.create(parameters),
})
: SchemaConstructor.create({ ...parameters, ...handlers });
Expand Down
6 changes: 6 additions & 0 deletions src/main/support.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ const arrayify = require("../utils/arrayify.js");
const currentVersion = require("../../package.json").version;
const coreOptions = require("./core-options.js").options;

/**
* @typedef {import("./core-options").OptionInfo} OptionInfo
* @typedef {{ name: string; pluginDefaults: Array<any> } & OptionInfo} NamedOptionInfo
*/

/**
* Strings in `plugins` and `pluginSearchDirs` are handled by a wrapped version
* of this function created by `withPlugins`. Don't pass them here directly.
Expand All @@ -18,6 +23,7 @@ const coreOptions = require("./core-options.js").options;
* @param {boolean=} param0.showUnreleased
* @param {boolean=} param0.showDeprecated
* @param {boolean=} param0.showInternal
* @return {{ languages: Array<any>, options: Array<NamedOptionInfo> }}
*/
function getSupportInfo({
plugins = [],
Expand Down
20 changes: 20 additions & 0 deletions src/utils/partition.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
"use strict";

/**
* @template Element
* @param {Array<Element>} array
* @param {(value: Element) => boolean} predicate
* @returns {[Array<Element>, Array<Element>]}
*/
function partition(array, predicate) {
/** @type {[Array<Element>, Array<Element>]} */
const result = [[], []];

for (const value of array) {
result[predicate(value) ? 0 : 1].push(value);
}

return result;
}

module.exports = partition;
24 changes: 24 additions & 0 deletions src/utils/uniq-by-key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"use strict";

/**
* @template {object} Element
* @param {Array<Element>} array
* @param {string | number | symbol} key
* @returns
*/
function uniqByKey(array, key) {
const result = [];
const seen = new Set();

for (const element of array) {
const value = element[key];
if (!seen.has(value)) {
seen.add(value);
result.push(element);
}
}

return result;
}

module.exports = uniqByKey;
8 changes: 7 additions & 1 deletion tests/format/markdown/auto-link/jsfmt.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
const flat = require("lodash/flatten");
/**
* @template T
* @param {Array<Array<T>>} array
* @returns {Array<T>}
*/
// eslint-disable-next-line unicorn/prefer-spread
const flat = (array) => [].concat(...array);

const urls = [
"http://www.example.com:80/_a",
Expand Down

0 comments on commit cec9757

Please sign in to comment.