-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improvements to tsc --watch #17669
Improvements to tsc --watch #17669
Conversation
…issing host files
Also dont update filesByName array just to update missing file paths
…i is accessible all the time
…neration now that api has tests
…e file as that would involve more work) so the files are picked up
…ed module resolution
…es the errors of unchanged files
src/compiler/builder.ts
Outdated
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, _onError: (message: string) => void, sourceFiles: SourceFile[]) { | ||
outputFiles.push({ name: fileName, writeByteOrderMark, text }); | ||
if (isDetailed) { | ||
emittedSourceFiles = concatenate(emittedSourceFiles, sourceFiles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: use addRange
src/compiler/commandLineParser.ts
Outdated
@@ -1979,7 +1979,7 @@ namespace ts { | |||
* @param host The host used to resolve files and directories. | |||
* @param errors An array for diagnostic reporting. | |||
*/ | |||
export function getFileNamesFromConfigSpecs(spec: ConfigFileSpecs, basePath: string, options: CompilerOptions, host: ParseConfigHost, extraFileExtensions: ReadonlyArray<JsFileExtensionInfo>): ExpandResult { | |||
export function getFileNamesFromConfigSpecs(spec: ConfigFileSpecs, basePath: string, options: CompilerOptions, host: ParseConfigHost, extraFileExtensions: ReadonlyArray<JsFileExtensionInfo> = []): ExpandResult { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this last argument is always provided?
src/compiler/core.ts
Outdated
@@ -473,12 +473,14 @@ namespace ts { | |||
return result; | |||
} | |||
|
|||
export function flatMapIter<T, U>(iter: Iterator<T>, mapfn: (x: T) => U | U[] | undefined): U[] { | |||
const result: U[] = []; | |||
export function flatMapIter<T>(iter: Iterator<T>): T[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to modify this function, arrayFrom
already handles converting an iterator to an array.
src/compiler/core.ts
Outdated
@@ -1211,7 +1220,7 @@ namespace ts { | |||
} | |||
|
|||
/** Does nothing. */ | |||
export function noop(): void {} | |||
export function noop(): any {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using any
. Use () => false
if you need a function that always returns a falsy value.
src/compiler/core.ts
Outdated
@@ -2552,4 +2561,168 @@ namespace ts { | |||
export function isCheckJsEnabledForFile(sourceFile: SourceFile, compilerOptions: CompilerOptions) { | |||
return sourceFile.checkJsDirective ? sourceFile.checkJsDirective.enabled : compilerOptions.checkJs; | |||
} | |||
|
|||
export interface HostForCaching { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this inherit from something? These signatures look familar.
src/compiler/core.ts
Outdated
readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[]; | ||
} | ||
|
||
export interface CachedHost { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above.
src/compiler/program.ts
Outdated
export function updateWatchingWildcardDirectories(existingWatchedForWildcards: Map<WildCardDirectoryWatchers>, wildcardDirectories: Map<WatchDirectoryFlags>, | ||
watchDirectory: (directory: string, recursive: boolean) => FileWatcher, | ||
closeDirectoryWatcher: (directory: string, watcher: FileWatcher, recursive: boolean, recursiveChanged: boolean) => void) { | ||
return mutateExistingMap( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be more readable if mutateExistingMap
took an object, rather than many positional arguments.
src/compiler/program.ts
Outdated
@@ -473,10 +592,12 @@ namespace ts { | |||
} | |||
|
|||
const filesByName = createMap<SourceFile | undefined>(); | |||
let missingFilePaths: Path[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getMissingFilePaths
promises to return a defined result -- I would make this a ReadonlyArray<Path>
and make it emptyArray
by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Made it readonlyArray and added assert that it is always defined
src/compiler/types.ts
Outdated
@@ -3952,8 +3953,8 @@ namespace ts { | |||
} | |||
|
|||
export interface CompilerHost extends ModuleResolutionHost { | |||
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile; | |||
getSourceFileByPath?(fileName: string, path: Path, languageVersion: ScriptTarget, onError?: (message: string) => void): SourceFile; | |||
getSourceFile(fileName: string, languageVersion: ScriptTarget, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of having an onError
callback, why not return SourceFile | Error
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is existing public API
src/compiler/utilities.ts
Outdated
@@ -1394,6 +1394,10 @@ namespace ts { | |||
return SpecialPropertyAssignmentKind.None; | |||
} | |||
|
|||
export function isModuleWithStringLiteralName(node: Node): node is ModuleDeclaration { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Put this near isAmbientModule
since it's similar.
src/compiler/utilities.ts
Outdated
createNewValue: (key: string, valueInNewMap: U) => T, | ||
onDeleteExistingValue: (key: string, existingValue: T) => void, | ||
isSameValue?: (existingValue: T, valueInNewMap: U) => boolean, | ||
OnDeleteExistingMismatchValue?: (key: string, existingValue: T) => void, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer lower-case variable name
src/compiler/resolutionCache.ts
Outdated
/// <reference path="types.ts"/> | ||
/// <reference path="core.ts"/> | ||
|
||
namespace ts { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How does this relate to the caching already in moduleNameResolver.ts
?
src/compiler/resolutionCache.ts
Outdated
export interface ResolutionCache { | ||
setModuleResolutionHost(host: ModuleResolutionHost): void; | ||
|
||
startRecordingFilesWithChangedResolutions(): void; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of two separate functions, how about recordFilesWithChangedResolutions(action: () => void): Path[];
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not having to create lambdas seem better option.
src/compiler/resolutionCache.ts
Outdated
resolveWithGlobalCache?: ResolverWithGlobalCache): ResolutionCache { | ||
|
||
let host: ModuleResolutionHost; | ||
let filesWithChangedSetOfUnresolvedImports: Path[]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| undefined
, same for below
src/compiler/resolutionCache.ts
Outdated
type ResolverWithGlobalCache = (primaryResult: ResolvedModuleWithFailedLookupLocations, moduleName: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost) => ResolvedModuleWithFailedLookupLocations | undefined; | ||
|
||
/*@internal*/ | ||
export function resolveWithGlobalCache(primaryResult: ResolvedModuleWithFailedLookupLocations, moduleName: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string | undefined, projectName: string): ResolvedModuleWithFailedLookupLocations | undefined { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think globalCache
should always be defined, and if the caller can't provide it they shouldn't call this function at all.
Nit: put parameters on their own lines; also break up the first if
condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is coming from parameter: this.getTypeAcquisition().enable ? this.projectService.typingsInstaller.globalTypingsCacheLocation : undefined so it can be undefined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that would be more readable as:
if (this.getTypeAcquisition().enable) {
return resolveWithGlobalCache(primaryResult, moduleName, compilerOptions, host,
this.projectService.typingsInstaller.globalTypingsCacheLocation, this.getProjectName());
}
This will avoid that part of the code entirely if there's no global cache.
src/compiler/resolutionCache.ts
Outdated
getCompilerOptions: () => CompilerOptions, | ||
watchForFailedLookupLocation: (failedLookupLocation: string, containingFile: string, name: string) => FileWatcher, | ||
log: (s: string) => void, | ||
resolveWithGlobalCache?: ResolverWithGlobalCache): ResolutionCache { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the resolveWithGlobalCache
parmeter is always either undefined or the outer (shadowed) resolveWithGlobalCache
function -- you could just take the extra parameters needed by that that instead, and call it directly.
src/compiler/resolutionCache.ts
Outdated
} | ||
|
||
// Close all the watches that are still present in the existingWatches since those are not the locations looked up for buy new resolution | ||
existingWatches.forEach((failedLookupLocation, failedLookupLocationPath: Path) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Annotating a parameter type acts like a cast due to function bivariance. I would prefer a regular as Path
cast.
src/compiler/resolutionCache.ts
Outdated
cache: Map<Map<T>>, | ||
getResult: (s: T) => R, | ||
getResultFileName: (result: R) => string | undefined) { | ||
cache.forEach((value, path: Path) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
src/compiler/resolutionCache.ts
Outdated
}); | ||
} | ||
else if (value) { | ||
value.forEach((resolution, __name) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need to write out a second parameter if you don't use it
src/compiler/resolutionCache.ts
Outdated
cache: Map<Map<T>>) { | ||
cache.forEach((value, containingFile: Path) => { | ||
if (value) { | ||
value.forEach((resolution, __name) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment as above
src/compiler/resolutionCache.ts
Outdated
cache.forEach((value, containingFile: Path) => { | ||
if (value) { | ||
value.forEach((resolution, __name) => { | ||
if (resolution && !resolution.isInvalidated && contains(resolution.failedLookupLocations, failedLookupLocation)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should failedLookupLocations
be a Path[]
?
@@ -3,7 +3,7 @@ | |||
namespace ts { | |||
function verifyMissingFilePaths(missingPaths: ReadonlyArray<Path>, expected: ReadonlyArray<string>) { | |||
assert.isDefined(missingPaths); | |||
const map = arrayToMap(expected, k => k, _v => true); | |||
const map = arrayToSet(expected) as Map<boolean>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would keep this as a set, and map.delete(missing)
instead of map.set(missing, false)
. Then:
if (map.size) {
throw new Error(`Not found ${arrayFrom(map.keys())} in actual: ${missingPaths} expected: ${expected}`);
}
…e and non sensitive file system and fixing caching
…ase the file doesnt exist.
This helps in not having to deal with duplicate locations and checking if there exists watch Anyways the watches are refCount based so we would just addref and remove ref on the same watches
watchedFile.callback(watchedFile.fileName, FileWatcherEventKind.Changed); | ||
if (err.code === "ENOENT") { | ||
if (watchedFile.mtime.getTime() !== 0) { | ||
watchedFile.mtime = new Date(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we're using new Date(0)
as a special sigil value? Why not use undefined
for that purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sheetalkamat bump
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm. I was using same logic that was already present. But I will look into it.
{ "path": "/a/b/node_modules/.staging/rxjs-22375c61/bundles" }, | ||
{ "path": "/a/b/node_modules/.staging/rxjs-22375c61/operator" }, | ||
{ "path": "/a/b/node_modules/.staging/rxjs-22375c61/src/add/observable/dom" }, | ||
{ "path": "/a/b/node_modules/.staging/@types/lodash-e56c4fe7/index.d.ts", "content": "// Type definitions for Lo-Dash 4.14\n// Project: http://lodash.com/\n// Definitions by: Brian Zengel <https://github.com/bczengel>,\n// Ilya Mochalov <https://github.com/chrootsu>,\n// Stepan Mikhaylyuk <https://github.com/stepancar>,\n// Eric L Anderson <https://github.com/ericanderson>,\n// AJ Richardson <https://github.com/aj-r>,\n// Junyoung Clare Jang <https://github.com/ailrun>\n// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped\n// TypeScript Version: 2.2\n\n/**\n### 4.0.0 Changelog (https://github.com/lodash/lodash/wiki/Changelog)\n\n#### TODO:\nremoved:\n- [x] Removed _.support\n- [x] Removed _.findWhere in favor of _.find with iteratee shorthand\n- [x] Removed _.where in favor of _.filter with iteratee shorthand\n- [x] Removed _.pluck in favor of _.map with iteratee shorthand\n\nrenamed:\n- [x] Renamed _.first to _.head\n- [x] Renamed _.indexBy to _.keyBy\n- [x] Renamed _.invoke to _.invokeMap\n- [x] Renamed _.overArgs to _.overArgs\n- [x] Renamed _.padLeft & _.padRight to _.padStart & _.padEnd\n- [x] Renamed _.pairs to _.toPairs\n- [x] Renamed _.rest to _.tail\n- [x] Renamed _.restParam to _.rest\n- [x] Renamed _.sortByOrder to _.orderBy\n- [x] Renamed _.trimLeft & _.trimRight to _.trimStart & _.trimEnd\n- [x] Renamed _.trunc to _.truncate\n\nsplit:\n- [x] Split _.indexOf & _.lastIndexOf into _.sortedIndexOf & _.sortedLastIndexOf\n- [x] Split _.max & _.min into _.maxBy & _.minBy\n- [x] Split _.omit & _.pick into _.omitBy & _.pickBy\n- [x] Split _.sample into _.sampleSize\n- [x] Split _.sortedIndex into _.sortedIndexBy\n- [x] Split _.sortedLastIndex into _.sortedLastIndexBy\n- [x] Split _.uniq into _.sortedUniq, _.sortedUniqBy, & _.uniqBy\n\nchanges:\n- [x] Absorbed _.sortByAll into _.sortBy\n- [x] Changed the category of _.at to “Object”\n- [x] Changed the category of _.bindAll to “Utility”\n- [x] Made _.capitalize uppercase the first character & lowercase the rest\n- [x] Made _.functions return only own method names\n\nadded 23 array methods:\n- [x] _.concat\n- [x] _.differenceBy\n- [x] _.differenceWith\n- [x] _.flatMap\n- [x] _.fromPairs\n- [x] _.intersectionBy\n- [x] _.intersectionWith\n- [x] _.join\n- [x] _.pullAll\n- [x] _.pullAllBy\n- [x] _.reverse\n- [x] _.sortedIndexBy\n- [x] _.sortedIndexOf\n- [x] _.sortedLastIndexBy\n- [x] _.sortedLastIndexOf\n- [x] _.sortedUniq\n- [x] _.sortedUniqBy\n- [x] _.unionBy\n- [x] _.unionWith\n- [x] _.uniqBy\n- [x] _.uniqWith\n- [x] _.xorBy\n- [x] _.xorWith\n\nadded 20 lang methods:\n- [x] _.cloneDeepWith\n- [x] _.cloneWith\n- [x] _.eq\n- [x] _.isArrayLike\n- [x] _.isArrayLikeObject\n- [x] _.isEqualWith\n- [x] _.isInteger\n- [x] _.isLength\n- [x] _.isMatchWith\n- [x] _.isNil\n- [x] _.isObjectLike\n- [x] _.isSafeInteger\n- [x] _.isSymbol\n- [x] _.toInteger\n- [x] _.toLength\n- [x] _.toNumber\n- [x] _.toSafeInteger\n- [x] _.toString\n- [X] _.conforms\n- [X] _.conformsTo\n\nadded 13 object methods:\n- [x] _.assignIn\n- [x] _.assignInWith\n- [x] _.assignWith\n- [x] _.functionsIn\n- [x] _.hasIn\n- [x] _.mergeWith\n- [x] _.omitBy\n- [x] _.pickBy\n\nadded 8 string methods:\n- [x] _.lowerCase\n- [x] _.lowerFirst\n- [x] _.upperCase\n- [x] _.upperFirst\n- [x] _.toLower\n- [x] _.toUpper\n\nadded 8 utility methods:\n- [x] _.toPath\n\nadded 4 math methods:\n- [x] _.maxBy\n- [x] _.mean\n- [x] _.minBy\n- [x] _.sumBy\n\nadded 2 function methods:\n- [x] _.flip\n- [x] _.unary\n\nadded 2 number methods:\n- [x] _.clamp\n- [x] _.subtract\n\nadded collection method:\n- [x] _.sampleSize\n\nAdded 3 aliases\n\n- [x] _.first as an alias of _.head\n\nRemoved 17 aliases\n- [x] Removed aliase _.all\n- [x] Removed aliase _.any\n- [x] Removed aliase _.backflow\n- [x] Removed aliase _.callback\n- [x] Removed aliase _.collect\n- [x] Removed aliase _.compose\n- [x] Removed aliase _.contains\n- [x] Removed aliase _.detect\n- [x] Removed aliase _.foldl\n- [x] Removed aliase _.foldr\n- [x] Removed aliase _.include\n- [x] Removed aliase _.inject\n- [x] Removed aliase _.methods\n- [x] Removed aliase _.object\n- [x] Removed aliase _.run\n- [x] Removed aliase _.select\n- [x] Removed aliase _.unique\n\nOther changes\n- [x] Added support for array buffers to _.isEqual\n- [x] Added support for converting iterators to _.toArray\n- [x] Added support for deep paths to _.zipObject\n- [x] Changed UMD to export to window or self when available regardless of other exports\n- [x] Ensured debounce cancel clears args & thisArg references\n- [x] Ensured _.add, _.subtract, & _.sum don’t skip NaN values\n- [x] Ensured _.clone treats generators like functions\n- [x] Ensured _.clone produces clones with the source’s [[Prototype]]\n- [x] Ensured _.defaults assigns properties that shadow Object.prototype\n- [x] Ensured _.defaultsDeep doesn’t merge a string into an array\n- [x] Ensured _.defaultsDeep & _.merge don’t modify sources\n- [x] Ensured _.defaultsDeep works with circular references\n- [x] Ensured _.keys skips “length” on strict mode arguments objects in Safari 9\n- [x] Ensured _.merge doesn’t convert strings to arrays\n- [x] Ensured _.merge merges plain-objects onto non plain-objects\n- [x] Ensured _#plant resets iterator data of cloned sequences\n- [x] Ensured _.random swaps min & max if min is greater than max\n- [x] Ensured _.range preserves the sign of start of -0\n- [x] Ensured _.reduce & _.reduceRight use getIteratee in their array branch\n- [x] Fixed rounding issue with the precision param of _.floor\n- [x] Added flush method to debounced & throttled functions\n\n** LATER **\nMisc:\n- [ ] Made _.forEach, _.forIn, _.forOwn, & _.times implicitly end a chain sequence\n- [ ] Removed thisArg params from most methods\n- [ ] Made “By” methods provide a single param to iteratees\n- [ ] Made _.words chainable by default\n- [ ] Removed isDeep params from _.clone & _.flatten\n- [ ] Removed _.bindAll support for binding all methods when no names are provided\n- [ ] Removed func-first param signature from _.before & _.after\n- [ ] _.extend as an alias of _.assignIn\n- [ ] _.extendWith as an alias of _.assignInWith\n- [ ] Added clear method to _.memoize.Cache\n- [ ] Added support for ES6 maps, sets, & symbols to _.clone, _.isEqual, & _.toArray\n- [x] Enabled _.flow & _.flowRight to accept an array of functions\n- [ ] Ensured “Collection” methods treat functions as objects\n- [ ] Ensured _.assign, _.defaults, & _.merge coerce object values to objects\n- [ ] Ensured _.bindKey bound functions call object[key] when called with the new operator\n- [ ] Ensured _.isFunction returns true for generator functions\n- [ ] Ensured _.merge assigns typed arrays directly\n- [ ] Made _(...) an iterator & iterable\n- [ ] Made _.drop, _.take, & right forms coerce n of undefined to 0\n\nMethods:\n- [ ] _.concat\n- [ ] _.differenceBy\n- [ ] _.differenceWith\n- [ ] _.flatMap\n- [ ] _.fromPairs\n- [ ] _.intersectionBy\n- [ ] _.intersectionWith\n- [ ] _.join\n- [ ] _.pullAll\n- [ ] _.pullAllBy\n- [ ] _.reverse\n- [ ] _.sortedLastIndexOf\n- [ ] _.unionBy\n- [ ] _.unionWith\n- [ ] _.uniqWith\n- [ ] _.xorBy\n- [ ] _.xorWith\n- [ ] _.toString\n\n- [ ] _.invoke\n- [ ] _.setWith\n- [ ] _.toPairs\n- [ ] _.toPairsIn\n- [ ] _.unset\n\n- [ ] _.replace\n- [ ] _.split\n\n- [ ] _.cond\n- [ ] _.nthArg\n- [ ] _.over\n- [ ] _.overEvery\n- [ ] _.overSome\n- [ ] _.rangeRight\n\n- [ ] _.next\n*/\n\nexport = _;\nexport as namespace _;\n\ndeclare var _: _.LoDashStatic;\n\ntype PartialObject<T> = Partial<T>;\n\ndeclare namespace _ {\n type Many<T> = T | T[];\n\n interface LoDashStatic {\n /**\n * Creates a lodash object which wraps the given value to enable intuitive method chaining.\n *\n * In addition to Lo-Dash methods, wrappers also have the following Array methods:\n * concat, join, pop, push, reverse, shift, slice, sort, splice, and unshift\n *\n * Chaining is supported in custom builds as long as the value method is implicitly or\n * explicitly included in the build.\n *\n * The chainable wrapper functions are:\n * after, assign, bind, bindAll, bindKey, chain, chunk, compact, compose, concat, countBy,\n * createCallback, curry, debounce, defaults, defer, delay, difference, filter, flatten,\n * forEach, forEachRight, forIn, forInRight, forOwn, forOwnRight, functions, groupBy,\n * keyBy, initial, intersection, invert, invoke, keys, map, max, memoize, merge, min,\n * object, omit, once, pairs, partial, partialRight, pick, pluck, pull, push, range, reject,\n * remove, rest, reverse, sample, shuffle, slice, sort, sortBy, splice, tap, throttle, times,\n * toArray, transform, union, uniq, unset, unshift, unzip, values, where, without, wrap, and zip\n *\n * The non-chainable wrapper functions are:\n * clone, cloneDeep, contains, escape, every, find, findIndex, findKey, findLast,\n * findLastIndex, findLastKey, has, identity, indexOf, isArguments, isArray, isBoolean,\n * isDate, isElement, isEmpty, isEqual, isFinite, isFunction, isNaN, isNull, isNumber,\n * isObject, isPlainObject, isRegExp, isString, isUndefined, join, lastIndexOf, mixin,\n * noConflict, parseInt, pop, random, reduce, reduceRight, result, shift, size, some,\n * sortedIndex, runInContext, template, unescape, uniqueId, and value\n *\n * The wrapper functions first and last return wrapped values when n is provided, otherwise\n * they return unwrapped values.\n *\n * Explicit chaining can be enabled by using the _.chain method.\n **/\n (value: number): LoDashImplicitWrapper<number>;\n (value: string): LoDashImplicitStringWrapper;\n (value: boolean): LoDashImplicitWrapper<boolean>;\n (value: null | undefined): LoDashImplicitWrapper<null | undefined>;\n (value: number[]): LoDashImplicitNumberArrayWrapper;\n <T>(value: T[]): LoDashImplicitArrayWrapper<T>;\n <T>(value: T[] | null | undefined): LoDashImplicitNillableArrayWrapper<T>;\n <T extends {}>(value: T): LoDashImplicitObjectWrapper<T>;\n <T extends {}>(value: T | null | undefined): LoDashImplicitNillableObjectWrapper<T>;\n (value: any): LoDashImplicitWrapper<any>;\n\n /**\n * The semantic version number.\n **/\n VERSION: string;\n\n /**\n * By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby\n * (ERB). Change the following template settings to use alternative delimiters.\n **/\n templateSettings: TemplateSettings;\n }\n\n /**\n * By default, the template delimiters used by Lo-Dash are similar to those in embedded Ruby\n * (ERB). Change the following template settings to use alternative delimiters.\n **/\n interface TemplateSettings {\n /**\n * The \"escape\" delimiter.\n **/\n escape?: RegExp;\n\n /**\n * The \"evaluate\" delimiter.\n **/\n evaluate?: RegExp;\n\n /**\n * An object to import into the template as local variables.\n **/\n imports?: Dictionary<any>;\n\n /**\n * The \"interpolate\" delimiter.\n **/\n interpolate?: RegExp;\n\n /**\n * Used to reference the data object in the template text.\n **/\n variable?: string;\n }\n\n /**\n * Creates a cache object to store key/value pairs.\n */\n interface MapCache {\n /**\n * Removes `key` and its value from the cache.\n * @param key The key of the value to remove.\n * @return Returns `true` if the entry was removed successfully, else `false`.\n */\n delete(key: string): boolean;\n\n /**\n * Gets the cached value for `key`.\n * @param key The key of the value to get.\n * @return Returns the cached value.\n */\n get(key: string): any;\n\n /**\n * Checks if a cached value for `key` exists.\n * @param key The key of the entry to check.\n * @return Returns `true` if an entry for `key` exists, else `false`.\n */\n has(key: string): boolean;\n\n /**\n * Sets `value` to `key` of the cache.\n * @param key The key of the value to cache.\n * @param value The value to cache.\n * @return Returns the cache object.\n */\n set(key: string, value: any): _.Dictionary<any>;\n\n /**\n * Removes all key-value entries from the map.\n */\n clear(): void;\n }\n interface MapCacheConstructor {\n new (): MapCache;\n }\n\n interface LoDashWrapperBase<T, TWrapper> { }\n\n interface LoDashImplicitWrapperBase<T, TWrapper> extends LoDashWrapperBase<T, TWrapper> { }\n\n interface LoDashExplicitWrapperBase<T, TWrapper> extends LoDashWrapperBase<T, TWrapper> { }\n\n interface LoDashImplicitWrapper<T> extends LoDashImplicitWrapperBase<T, LoDashImplicitWrapper<T>> { }\n\n interface LoDashExplicitWrapper<T> extends LoDashExplicitWrapperBase<T, LoDashExplicitWrapper<T>> { }\n\n interface LoDashImplicitStringWrapper extends LoDashImplicitWrapper<string> { }\n\n interface LoDashExplicitStringWrapper extends LoDashExplicitWrapper<string> { }\n\n interface LoDashImplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> extends LoDashImplicitWrapperBase<TObject, TWrapper> { }\n\n interface LoDashImplicitObjectWrapper<T> extends LoDashImplicitObjectWrapperBase<T, T, LoDashImplicitObjectWrapper<T>> { }\n\n interface LoDashImplicitNillableObjectWrapper<T> extends LoDashImplicitObjectWrapperBase<T, T | null | undefined, LoDashImplicitNillableObjectWrapper<T>> { }\n\n interface LoDashExplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> extends LoDashExplicitWrapperBase<TObject, TWrapper> { }\n\n interface LoDashExplicitObjectWrapper<T> extends LoDashExplicitObjectWrapperBase<T, T, LoDashExplicitObjectWrapper<T>> { }\n\n interface LoDashExplicitNillableObjectWrapper<T> extends LoDashExplicitObjectWrapperBase<T, T | null | undefined, LoDashExplicitNillableObjectWrapper<T>> { }\n\n interface LoDashImplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> extends LoDashImplicitWrapperBase<TArray, TWrapper> {\n pop(): T | undefined;\n push(...items: T[]): TWrapper;\n shift(): T | undefined;\n sort(compareFn?: (a: T, b: T) => number): TWrapper;\n splice(start: number): TWrapper;\n splice(start: number, deleteCount: number, ...items: T[]): TWrapper;\n unshift(...items: T[]): TWrapper;\n }\n\n interface LoDashImplicitArrayWrapper<T> extends LoDashImplicitArrayWrapperBase<T, T[], LoDashImplicitArrayWrapper<T>> { }\n\n interface LoDashImplicitNillableArrayWrapper<T> extends LoDashImplicitArrayWrapperBase<T, T[] | null | undefined, LoDashImplicitNillableArrayWrapper<T>> { }\n\n interface LoDashImplicitNumberArrayWrapperBase<TArray extends number[] | null | undefined, TWrapper> extends LoDashImplicitArrayWrapperBase<number, TArray, TWrapper> { }\n\n interface LoDashImplicitNumberArrayWrapper extends LoDashImplicitArrayWrapper<number> { }\n\n interface LoDashExplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> extends LoDashExplicitWrapperBase<TArray, TWrapper> {\n pop(): LoDashExplicitObjectWrapper<T | undefined>;\n push(...items: T[]): TWrapper;\n shift(): LoDashExplicitObjectWrapper<T | undefined>;\n sort(compareFn?: (a: T, b: T) => number): TWrapper;\n splice(start: number): TWrapper;\n splice(start: number, deleteCount: number, ...items: T[]): TWrapper;\n unshift(...items: T[]): TWrapper;\n }\n\n interface LoDashExplicitArrayWrapper<T> extends LoDashExplicitArrayWrapperBase<T, T[], LoDashExplicitArrayWrapper<T>> { }\n\n interface LoDashExplicitNillableArrayWrapper<T> extends LoDashExplicitArrayWrapperBase<T, T[] | null | undefined, LoDashExplicitNillableArrayWrapper<T>> { }\n\n interface LoDashExplicitNumberArrayWrapper extends LoDashExplicitArrayWrapper<number> { }\n\n /*********\n * Array *\n *********/\n\n //_.chunk\n interface LoDashStatic {\n /**\n * Creates an array of elements split into groups the length of size. If collection can’t be split evenly, the\n * final chunk will be the remaining elements.\n *\n * @param array The array to process.\n * @param size The length of each chunk.\n * @return Returns the new array containing chunks.\n */\n chunk<T>(\n array: List<T> | null | undefined,\n size?: number\n ): T[][];\n }\n\n interface LoDashImplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.chunk\n */\n chunk(size?: number): LoDashImplicitArrayWrapper<T[]>;\n }\n\n interface LoDashImplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.chunk\n */\n chunk<TResult>(size?: number): LoDashImplicitArrayWrapper<TResult[]>;\n }\n\n interface LoDashExplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.chunk\n */\n chunk(size?: number): LoDashExplicitArrayWrapper<T[]>;\n }\n\n interface LoDashExplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.chunk\n */\n chunk<TResult>(size?: number): LoDashExplicitArrayWrapper<TResult[]>;\n }\n\n //_.compact\n interface LoDashStatic {\n /**\n * Creates an array with all falsey values removed. The values false, null, 0, \"\", undefined, and NaN are\n * falsey.\n *\n * @param array The array to compact.\n * @return (Array) Returns the new array of filtered values.\n */\n compact<T>(array?: List<T | null | undefined | false | \"\" | 0> | null | undefined): T[];\n }\n\n interface LoDashImplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.compact\n */\n compact(): LoDashImplicitArrayWrapper<T>;\n }\n\n interface LoDashImplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.compact\n */\n compact<TResult>(): LoDashImplicitArrayWrapper<TResult>;\n }\n\n interface LoDashExplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.compact\n */\n compact(): LoDashExplicitArrayWrapper<T>;\n }\n\n interface LoDashExplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.compact\n */\n compact<TResult>(): LoDashExplicitArrayWrapper<TResult>;\n }\n\n //_.concat DUMMY\n interface LoDashStatic {\n /**\n * Creates a new array concatenating `array` with any additional arrays\n * and/or values.\n *\n * @static\n * @memberOf _\n * @category Array\n * @param {Array} array The array to concatenate.\n * @param {...*} [values] The values to concatenate.\n * @returns {Array} Returns the new concatenated array.\n * @example\n *\n * var array = [1];\n * var other = _.concat(array, 2, [3], [[4]]);\n *\n * console.log(other);\n * // => [1, 2, 3, [4]]\n *\n * console.log(array);\n * // => [1]\n */\n concat<T>(array: List<T>, ...values: Array<T|List<T>>): T[];\n }\n\n //_.difference\n interface LoDashStatic {\n /**\n * Creates an array of unique array values not included in the other provided arrays using SameValueZero for\n * equality comparisons.\n *\n * @param array The array to inspect.\n * @param values The arrays of values to exclude.\n * @return Returns the new array of filtered values.\n */\n difference<T>(\n array: List<T> | null | undefined,\n ...values: Array<List<T>>\n ): T[];\n }\n\n interface LoDashImplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.difference\n */\n difference(...values: Array<List<T>>): LoDashImplicitArrayWrapper<T>;\n }\n\n interface LoDashImplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.difference\n */\n difference<TValue>(...values: Array<List<TValue>>): LoDashImplicitArrayWrapper<TValue>;\n }\n\n interface LoDashExplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.difference\n */\n difference(...values: Array<List<T>>): LoDashExplicitArrayWrapper<T>;\n }\n\n interface LoDashExplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.difference\n */\n difference<TValue>(...values: Array<List<TValue>>): LoDashExplicitArrayWrapper<TValue>;\n }\n\n //_.differenceBy\n interface LoDashStatic {\n /**\n * This method is like _.difference except that it accepts iteratee which is invoked for each element of array\n * and values to generate the criterion by which uniqueness is computed. The iteratee is invoked with one\n * argument: (value).\n *\n * @param array The array to inspect.\n * @param values The values to exclude.\n * @param iteratee The iteratee invoked per element.\n * @returns Returns the new array of filtered values.\n */\n differenceBy<T>(\n array: List<T> | null | undefined,\n values?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n array: List<T> | null | undefined,\n values?: List<T>,\n iteratee?: W\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: W\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: W\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: W\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n array: List<T> | null | undefined,\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: W\n ): T[];\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n array: List<T> | null | undefined,\n ...values: any[]\n ): T[];\n }\n\n interface LoDashImplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n ...values: any[]\n ): LoDashImplicitArrayWrapper<T>;\n }\n\n interface LoDashImplicitObjectWrapperBase<T, TObject extends T | null | undefined, TWrapper> {\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: W\n ): LoDashImplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n ...values: any[]\n ): LoDashImplicitArrayWrapper<T>;\n }\n\n interface LoDashExplicitArrayWrapperBase<T, TArray extends T[] | null | undefined, TWrapper> {\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values?: List<T>,\n iteratee?: W\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n iteratee?: W\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n iteratee?: W\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T, W extends Object>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n iteratee?: W\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * @see _.differenceBy\n */\n differenceBy<T>(\n values1?: List<T>,\n values2?: List<T>,\n values3?: List<T>,\n values4?: List<T>,\n values5?: List<T>,\n iteratee?: ((value: T) => any)|string\n ): LoDashExplicitArrayWrapper<T>;\n\n /**\n * |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a way to reproduce the bug this was testing for with a smaller file?
Event to notify project changes
This PR is based off of #17269
This uses builder to emit only changed/affected files because of the change. It also caches the semantic diagnostics and updating the errors when they are part of changed/affected list