Skip to content

Commit

Permalink
refactor: prefer native methods to lodash where possible (#328)
Browse files Browse the repository at this point in the history
- _.endsWith -> String.endsWith

- _.concat -> Array.concat
- _.each -> Array.forEach
- _.filter -> Array.filter
- _.map -> Array.map
- _.some -> Array.some

- _.has -> `key in Object`
- _.defaults -> Object.assign
- _.get -> `?.` and `??` (optional chaining and nullish coalescing)

- refactor: replace fairly complicated `expandIncludeWithDirs` func to
  just use a few simple `forEach`s
  - not as FP anymore, more imperative, but much simpler to read IMO
- refactor: add a `getDiagnostics` helper to DRY up some code
  - also aids readability IMO

- a few places are still using lodash, but this paves the way toward
  removing it or replacing it with much smaller individual deps
  - _.compact still used because Array.filter heavily complicates the
    type-checking currently
  - _.isFunction still used because while it's a one-liner natively,
    need to import a function in several places
    - also the package `lodash.isFunction` is lodash v3 and quite
      different from the v4 implementation, so couldn't replace with it
      unfortunately
  - _.merge is a deep merge, so there's no native version of this
    - but we may remove deep merges entirely in the future (as tsconfig
      doesn't quite perform a deep merge), or could replace this with a
      smaller `lodash.merge` package or similar

- see also https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore
  • Loading branch information
agilgur5 committed May 16, 2022
1 parent 529c853 commit 197061b
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 74 deletions.
25 changes: 11 additions & 14 deletions src/get-options-overrides.ts
Expand Up @@ -2,7 +2,6 @@ import { createFilter as createRollupFilter} from "@rollup/pluginutils";
import { tsModule } from "./tsproxy";
import * as tsTypes from "typescript";
import { IOptions } from "./ioptions";
import * as _ from "lodash";
import { join } from "path";
import { IContext } from "./context";

Expand Down Expand Up @@ -39,17 +38,15 @@ export function getOptionsOverrides({ useTsconfigDeclarationDir, cacheRoot }: IO

function expandIncludeWithDirs(include: string | string[], dirs: string[])
{
return _
.chain(dirs)
.flatMap((root) =>
{
if (include instanceof Array)
return include.map((x) => join(root, x));
else
return join(root, include);
})
.uniq()
.value();
const newDirs: string[] = [];

dirs.forEach(root => {
if (include instanceof Array)
include.forEach(x => newDirs.push(join(root, x)));
else
newDirs.push(join(root, include));
});
return newDirs;
}

export function createFilter(context: IContext, pluginOptions: IOptions, parsedConfig: tsTypes.ParsedCommandLine)
Expand All @@ -65,8 +62,8 @@ export function createFilter(context: IContext, pluginOptions: IOptions, parsedC

if (parsedConfig.projectReferences)
{
included = _.concat(included, expandIncludeWithDirs(included, parsedConfig.projectReferences.map((x) => x.path)));
excluded = _.concat(excluded, expandIncludeWithDirs(excluded, parsedConfig.projectReferences.map((x) => x.path)));
included = expandIncludeWithDirs(included, parsedConfig.projectReferences.map((x) => x.path)).concat(included);
excluded = expandIncludeWithDirs(excluded, parsedConfig.projectReferences.map((x) => x.path)).concat(excluded);
}

context.debug(() => `included:\n${JSON.stringify(included, undefined, 4)}`);
Expand Down
9 changes: 4 additions & 5 deletions src/host.ts
@@ -1,6 +1,5 @@
import { tsModule } from "./tsproxy";
import * as tsTypes from "typescript";
import * as _ from "lodash";
import { normalizePath as normalize } from "@rollup/pluginutils";
import { TransformerFactoryCreator } from "./ioptions";

Expand Down Expand Up @@ -44,7 +43,7 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
{
fileName = normalize(fileName);

if (_.has(this.snapshots, fileName))
if (fileName in this.snapshots)
return this.snapshots[fileName];

const source = tsModule.sys.readFile(fileName);
Expand Down Expand Up @@ -136,11 +135,11 @@ export class LanguageServiceHost implements tsTypes.LanguageServiceHost
{
const factory = creator(this.service);
if (factory.before)
transformer.before = _.concat(transformer.before!, factory.before);
transformer.before = transformer.before!.concat(factory.before);
if (factory.after)
transformer.after = _.concat(transformer.after!, factory.after);
transformer.after = transformer.after!.concat(factory.after);
if (factory.afterDeclarations)
transformer.afterDeclarations = _.concat(transformer.afterDeclarations!, factory.afterDeclarations);
transformer.afterDeclarations = transformer.afterDeclarations!.concat(factory.afterDeclarations);
}

return transformer;
Expand Down
61 changes: 21 additions & 40 deletions src/index.ts
Expand Up @@ -46,9 +46,18 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
return _cache;
};

const pluginOptions = { ...options } as IOptions;
const getDiagnostics = (id: string, snapshot: tsTypes.IScriptSnapshot) =>
{
return cache().getSyntacticDiagnostics(id, snapshot, () =>
{
return service.getSyntacticDiagnostics(id);
}).concat(cache().getSemanticDiagnostics(id, snapshot, () =>
{
return service.getSemanticDiagnostics(id);
}));
}

_.defaults(pluginOptions,
const pluginOptions: IOptions = Object.assign({},
{
check: true,
verbosity: VerbosityLevel.Warning,
Expand All @@ -65,7 +74,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
tsconfigDefaults: {},
objectHashIgnoreUnknownHack: false,
cwd: process.cwd(),
});
}, options as IOptions);

if (!pluginOptions.typescript) {
pluginOptions.typescript = require("typescript");
Expand All @@ -87,7 +96,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>

if (generateRound === 0)
{
parsedConfig.fileNames.forEach((fileName) => { allImportedFiles.add(fileName); });
parsedConfig.fileNames.map(allImportedFiles.add, allImportedFiles);

context.info(`typescript version: ${tsModule.version}`);
context.info(`tslib version: ${tslibVersion}`);
Expand Down Expand Up @@ -151,7 +160,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
if (filter(result.resolvedModule.resolvedFileName))
cache().setDependency(result.resolvedModule.resolvedFileName, importer);

if (_.endsWith(result.resolvedModule.resolvedFileName, ".d.ts"))
if (result.resolvedModule.resolvedFileName.endsWith(".d.ts"))
return;

const resolved = pluginOptions.rollupCommonJSResolveHack
Expand Down Expand Up @@ -198,16 +207,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
noErrors = false;

// always checking on fatal errors, even if options.check is set to false
const diagnostics = _.concat(
cache().getSyntacticDiagnostics(id, snapshot, () =>
{
return service.getSyntacticDiagnostics(id);
}),
cache().getSemanticDiagnostics(id, snapshot, () =>
{
return service.getSemanticDiagnostics(id);
}),
);
const diagnostics = getDiagnostics(id, snapshot);
printDiagnostics(contextWrapper, diagnostics, parsedConfig.options.pretty === true);

// since no output was generated, aborting compilation
Expand All @@ -222,17 +222,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>

if (pluginOptions.check)
{
const diagnostics = _.concat(
cache().getSyntacticDiagnostics(id, snapshot, () =>
{
return service.getSyntacticDiagnostics(id);
}),
cache().getSemanticDiagnostics(id, snapshot, () =>
{
return service.getSemanticDiagnostics(id);
}),
);

const diagnostics = getDiagnostics(id, snapshot);
if (diagnostics.length > 0)
noErrors = false;

Expand Down Expand Up @@ -295,17 +285,7 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
if (!snapshot)
return;

const diagnostics = _.concat(
cache().getSyntacticDiagnostics(id, snapshot, () =>
{
return service.getSyntacticDiagnostics(id);
}),
cache().getSemanticDiagnostics(id, snapshot, () =>
{
return service.getSemanticDiagnostics(id);
}),
);

const diagnostics = getDiagnostics(id, snapshot);
printDiagnostics(context, diagnostics, parsedConfig.options.pretty === true);
});
}
Expand All @@ -323,10 +303,10 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
if (!parsedConfig.options.declaration)
return;

_.each(parsedConfig.fileNames, (name) =>
parsedConfig.fileNames.forEach((name) =>
{
const key = normalize(name);
if (_.has(declarations, key))
if (key in declarations)
return;
if (!allImportedFiles.has(key))
{
Expand Down Expand Up @@ -390,8 +370,9 @@ const typescript: PluginImpl<RPT2Options> = (options) =>
}
};

_.each(declarations, ({ type, map }, key) =>
Object.keys(declarations).forEach((key) =>
{
const { type, map } = declarations[key];
emitDeclaration(key, ".d.ts", type);
emitDeclaration(key, ".d.ts.map", map);
});
Expand Down
2 changes: 1 addition & 1 deletion src/parse-tsconfig.ts
Expand Up @@ -27,7 +27,7 @@ export function parseTsConfig(context: IContext, pluginOptions: IOptions)
throw new Error(`rpt2: failed to read '${fileName}'`);

const result = tsModule.parseConfigFileTextToJson(fileName, text);
pretty = _.get(result.config, "pretty", pretty);
pretty = result.config?.pretty ?? pretty;

if (result.error !== undefined)
{
Expand Down
3 changes: 1 addition & 2 deletions src/print-diagnostics.ts
Expand Up @@ -2,11 +2,10 @@ import { tsModule } from "./tsproxy";
import { red, white, yellow } from "colors/safe";
import { IContext } from "./context";
import { IDiagnostics } from "./tscache";
import * as _ from "lodash";

export function printDiagnostics(context: IContext, diagnostics: IDiagnostics[], pretty: boolean): void
{
_.each(diagnostics, (diagnostic) =>
diagnostics.forEach((diagnostic) =>
{
let print;
let color;
Expand Down
25 changes: 13 additions & 12 deletions src/tscache.ts
Expand Up @@ -47,11 +47,11 @@ export function convertEmitOutput(output: tsTypes.EmitOutput, references?: strin

output.outputFiles.forEach((e) =>
{
if (_.endsWith(e.name, ".d.ts"))
if (e.name.endsWith(".d.ts"))
out.dts = e;
else if (_.endsWith(e.name, ".d.ts.map"))
else if (e.name.endsWith(".d.ts.map"))
out.dtsmap = e;
else if (_.endsWith(e.name, ".map"))
else if (e.name.endsWith(".map"))
out.map = e.text;
else
out.code = e.text;
Expand All @@ -67,7 +67,7 @@ export function getAllReferences(importer: string, snapshot: tsTypes.IScriptSnap

const info = tsModule.preProcessFile(snapshot.getText(0, snapshot.getLength()), true, true);

return _.compact(_.concat(info.referencedFiles, info.importedFiles).map((reference) =>
return _.compact(info.referencedFiles.concat(info.importedFiles).map((reference) =>
{
const resolved = tsModule.nodeModuleNameResolver(reference.fileName, importer, options, tsModule.sys);
return resolved.resolvedModule ? resolved.resolvedModule.resolvedFileName : undefined;
Expand All @@ -76,7 +76,7 @@ export function getAllReferences(importer: string, snapshot: tsTypes.IScriptSnap

export function convertDiagnostic(type: string, data: tsTypes.Diagnostic[]): IDiagnostics[]
{
return _.map(data, (diagnostic) =>
return data.map((diagnostic) =>
{
const entry: IDiagnostics =
{
Expand Down Expand Up @@ -131,11 +131,11 @@ export class TsCache
this.dependencyTree = new Graph({ directed: true });
this.dependencyTree.setDefaultNodeLabel((_node: string) => ({ dirty: false }));

const automaticTypes = _.map(tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys), (entry) => tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys))
const automaticTypes = tsModule.getAutomaticTypeDirectiveNames(options, tsModule.sys).map((entry) => tsModule.resolveTypeReferenceDirective(entry, undefined, options, tsModule.sys))
.filter((entry) => entry.resolvedTypeReferenceDirective && entry.resolvedTypeReferenceDirective.resolvedFileName)
.map((entry) => entry.resolvedTypeReferenceDirective!.resolvedFileName!);

this.ambientTypes = _.filter(rootFilenames, (file) => _.endsWith(file, ".d.ts"))
this.ambientTypes = rootFilenames.filter(file => file.endsWith(".d.ts"))
.concat(automaticTypes)
.map((id) => ({ id, snapshot: this.host.getScriptSnapshot(id) }));

Expand Down Expand Up @@ -180,13 +180,13 @@ export class TsCache

if (acyclic)
{
_.each(alg.topsort(this.dependencyTree), (id: string) => cb(id));
alg.topsort(this.dependencyTree).forEach(id => cb(id));
return;
}

this.context.info(yellow("import tree has cycles"));

_.each(this.dependencyTree.nodes(), (id: string) => cb(id));
this.dependencyTree.nodes().forEach(id => cb(id));
}

public done()
Expand Down Expand Up @@ -252,7 +252,7 @@ export class TsCache
}

this.context.debug(blue("Ambient types:"));
const typeNames = _.filter(this.ambientTypes, (snapshot) => snapshot.snapshot !== undefined)
const typeNames = this.ambientTypes.filter((snapshot) => snapshot.snapshot !== undefined)
.map((snapshot) =>
{
this.context.debug(` ${snapshot.id}`);
Expand All @@ -264,7 +264,7 @@ export class TsCache
if (this.ambientTypesDirty)
this.context.info(yellow("ambient types changed, redoing all semantic diagnostics"));

_.each(typeNames, (name) => this.typesCache.touch(name));
typeNames.forEach(this.typesCache.touch, this);
}

private getDiagnostics(type: string, cache: ICache<IDiagnostics[]>, id: string, snapshot: tsTypes.IScriptSnapshot, check: () => tsTypes.Diagnostic[]): IDiagnostics[]
Expand Down Expand Up @@ -342,8 +342,9 @@ export class TsCache

const dependencies = alg.dijkstra(this.dependencyTree, id);

return _.some(dependencies, (dependency, node) =>
return Object.keys(dependencies).some(node =>
{
const dependency = dependencies[node];
if (!node || dependency.distance === Infinity)
return false;

Expand Down

0 comments on commit 197061b

Please sign in to comment.