PR Feedback

This commit is contained in:
Ron Buckton 2018-01-29 15:33:11 -08:00
parent 545868c56c
commit d0988b8078
11 changed files with 69 additions and 392 deletions

View file

@ -2,7 +2,7 @@ language: node_js
node_js:
- 'stable'
- 'lts/*'
- '8'
sudo: false

View file

@ -39,7 +39,7 @@
"@types/gulp-help": "latest",
"@types/gulp-newer": "latest",
"@types/gulp-sourcemaps": "latest",
"@types/jake": "0.0.30",
"@types/jake": "latest",
"@types/merge2": "latest",
"@types/minimatch": "latest",
"@types/minimist": "latest",
@ -48,7 +48,7 @@
"@types/node": "8.5.5",
"@types/q": "latest",
"@types/run-sequence": "latest",
"@types/source-map-support": "^0.4.0",
"@types/source-map-support": "latest",
"@types/through2": "latest",
"@types/xml2js": "^0.4.0",
"@typescript/vfs-path": "file:scripts/vfs-path",

View file

@ -5,9 +5,6 @@ import { Inject } from "./inject";
const weakHandler = new WeakMap<object, MockHandler<object>>();
const weakMock = new WeakMap<object, Mock<object>>();
function noop() {}
const empty = {};
export type Callable = (...args: any[]) => any;
export type Constructable = new (...args: any[]) => any;
@ -111,7 +108,7 @@ export class Mock<T extends object> {
public static spy<T extends { [P in K]: (...args: any[]) => any }, K extends keyof T>(object?: T, propertyKey?: K) {
return object !== undefined && propertyKey !== undefined
? new Spy(object, propertyKey)
: new Mock(object || noop);
: new Mock(object || function () {});
}
/**
@ -221,7 +218,7 @@ export class Spy<T extends { [P in K]: (...args: any[]) => any }, K extends keyo
class Recording {
public static readonly noThisArg = {};
public readonly trap: string;
public readonly trap: "apply" | "construct" | "invoke" | "get" | "set";
public readonly name: PropertyKey | undefined;
public readonly thisArg: any;
public readonly argArray: ReadonlyArray<any>;
@ -233,7 +230,7 @@ class Recording {
private _newTargetCondition: Arg | undefined;
private _conditions: ReadonlyArray<Arg> | undefined;
constructor(trap: string, name: PropertyKey | undefined, thisArg: any, argArray: ReadonlyArray<any>, newTarget: any, result: Partial<Returns<any> & Throws & Fallback> | undefined, callback: Callable | undefined) {
constructor(trap: "apply" | "construct" | "invoke" | "get" | "set", name: PropertyKey | undefined, thisArg: any, argArray: ReadonlyArray<any>, newTarget: any, result: Partial<Returns<any> & Throws & Fallback> | undefined, callback: Callable | undefined) {
this.trap = trap;
this.name = name;
this.thisArg = thisArg;
@ -450,7 +447,7 @@ class MockHandler<T extends object> implements ProxyHandler<T> {
}
protected capture<U>(callback: (value: T) => U, result: Setup<any> | undefined) {
return this.captureCore(<T>empty, new CapturingHandler<T, U>(result), callback);
return this.captureCore(<T>{}, new CapturingHandler<T, U>(result), callback);
}
protected captureCore<T extends object, U>(target: T, handler: CapturingHandler<T, U>, callback: (value: T) => U): Recording {
@ -471,7 +468,7 @@ class MockHandler<T extends object> implements ProxyHandler<T> {
const setups = this.setups;
this.setupMembers({
[name](...argArray: any[]) {
return Recording.evaluate(setups, "invoke", name, this, argArray, /*newTarget*/ undefined, noop);
return Recording.evaluate(setups, "invoke", name, this, argArray, /*newTarget*/ undefined, () => {});
}
});
}
@ -480,10 +477,10 @@ class MockHandler<T extends object> implements ProxyHandler<T> {
const setups = this.setups;
this.setupMembers({
get [name]() {
return Recording.evaluate(setups, "get", name, this, [], /*newTarget*/ undefined, noop);
return Recording.evaluate(setups, "get", name, this, [], /*newTarget*/ undefined, () => {});
},
set [name](value: any) {
Recording.evaluate(setups, "set", name, this, [value], /*newTarget*/ undefined, noop);
Recording.evaluate(setups, "set", name, this, [value], /*newTarget*/ undefined, () => {});
}
});
}
@ -519,7 +516,7 @@ class MockFunctionHandler<T extends Callable | Constructable> extends MockHandle
}
protected capture<U>(callback: (value: T) => U, result: Returns<any> & ThisArg | Returns<any> | Throws & ThisArg | Throws | ThisArg | undefined) {
return this.captureCore(<T>noop, new CapturingFunctionHandler<T, U>(result), callback);
return this.captureCore(<T>function() {}, new CapturingFunctionHandler<T, U>(result), callback);
}
}

View file

@ -37,8 +37,8 @@ namespace fakes {
}
export class FakeServerHost implements ts.server.ServerHost, ts.FormatDiagnosticsHost, ts.ModuleResolutionHost {
public static readonly dosExecutingFilePath = "c:/.ts/tsc.js";
public static readonly defaultExecutingFilePath = "/.ts/tsc.js";
public static readonly dosExecutingFilePath = vpath.combine(vfsutils.dosBuiltFolder, "tsc.js");
public static readonly defaultExecutingFilePath = vpath.combine(vfsutils.builtFolder, "tsc.js");
public static readonly dosDefaultCurrentDirectory = "c:/";
public static readonly defaultCurrentDirectory = "/";
public static readonly dosSafeListPath = "c:/safelist.json";
@ -53,8 +53,8 @@ namespace fakes {
` "chroma": "chroma-js"\n` +
`}`;
public static readonly dosLibPath = "c:/.ts/lib.d.ts";
public static readonly libPath = "/.ts/lib.d.ts";
public static readonly dosLibPath = vpath.combine(vfsutils.dosBuiltFolder, "lib.d.ts");
public static readonly libPath = vpath.combine(vfsutils.builtFolder, "lib.d.ts");
public static readonly libContent =
`/// <reference no-default-lib="true"/>\n` +
`interface Boolean {}\n` +

View file

@ -1220,7 +1220,7 @@ namespace Harness {
options.skipDefaultLibCheck = typeof options.skipDefaultLibCheck === "undefined" ? true : options.skipDefaultLibCheck;
if (typeof currentDirectory === "undefined") {
currentDirectory = "/.src";
currentDirectory = vfsutils.srcFolder;
}
// Parse settings
@ -1237,13 +1237,13 @@ namespace Harness {
// Files from built\local that are requested by test "@includeBuiltFiles" to be in the context.
// Treat them as library files, so include them in build, but not in baselines.
if (options.includeBuiltFile) {
programFileNames.push(vpath.combine("/.ts/", options.includeBuiltFile));
programFileNames.push(vpath.combine(vfsutils.builtFolder, options.includeBuiltFile));
}
// Files from tests\lib that are requested by "@libFiles"
if (options.libFiles) {
for (const fileName of options.libFiles.split(",")) {
programFileNames.push(vpath.combine("/.lib/", fileName));
programFileNames.push(vpath.combine(vfsutils.testLibFolder, fileName));
}
}
@ -2113,7 +2113,7 @@ namespace Harness {
export function isBuiltFile(filePath: string): boolean {
return filePath.indexOf(Harness.libFolder) === 0 ||
filePath.indexOf("/.ts/") === 0;
filePath.indexOf(vpath.addTrailingSeparator(vfsutils.builtFolder)) === 0;
}
export function getDefaultLibraryFile(filePath: string, io: Harness.IO): Harness.Compiler.TestFile {

View file

@ -100,7 +100,7 @@ namespace project {
public readDirectory(path: string, extensions: string[], excludes: string[], includes: string[], depth: number): string[] {
const result = super.readDirectory(path, extensions, excludes, includes, depth);
const projectRoot = vpath.resolve("/.src", this._testCase.projectRoot);
const projectRoot = vpath.resolve(vfsutils.srcFolder, this._testCase.projectRoot);
return result.map(item => vpath.relative(
projectRoot,
vpath.resolve(projectRoot, item),
@ -189,9 +189,9 @@ namespace project {
}
const fs = vfsutils.createFromFileSystem(/*useCaseSensitiveFileNames*/ true);
fs.mountSync(vpath.resolve(__dirname, "../../tests"), "/.src/tests", vfsutils.createResolver(Harness.IO));
fs.mkdirpSync(vpath.combine("/.src", testCase.projectRoot));
fs.chdir(vpath.combine("/.src", testCase.projectRoot));
fs.mountSync(vpath.resolve(__dirname, "../../tests"), vpath.combine(vfsutils.srcFolder, "tests"), vfsutils.createResolver(Harness.IO));
fs.mkdirpSync(vpath.combine(vfsutils.srcFolder, testCase.projectRoot));
fs.chdir(vpath.combine(vfsutils.srcFolder, testCase.projectRoot));
fs.makeReadonly();
return [
@ -389,7 +389,7 @@ namespace project {
});
const _vfs = vfsutils.createFromDocuments(/*useCaseSensitiveFileNames*/ true, allInputFiles, {
currentDirectory: vpath.combine("/.src", this.testCase.projectRoot)
currentDirectory: vpath.combine(vfsutils.srcFolder, this.testCase.projectRoot)
});
// Dont allow config files since we are compiling existing source options
@ -438,11 +438,11 @@ namespace project {
moduleResolution: ts.ModuleResolutionKind.Classic,
module: moduleKind,
mapRoot: testCase.resolveMapRoot && testCase.mapRoot
? vpath.resolve("/.src", testCase.mapRoot)
? vpath.resolve(vfsutils.srcFolder, testCase.mapRoot)
: testCase.mapRoot,
sourceRoot: testCase.resolveSourceRoot && testCase.sourceRoot
? vpath.resolve("/.src", testCase.sourceRoot)
? vpath.resolve(vfsutils.srcFolder, testCase.sourceRoot)
: testCase.sourceRoot
};

View file

@ -515,19 +515,21 @@ namespace ts.tscWatch {
});
it("correctly handles changes in lib section of config file", () => {
const es5LibPath = vpath.combine(vfsutils.builtFolder, "lib.es5.d.ts");
const es2015PromiseLibPath = vpath.combine(vfsutils.builtFolder, "lib.es2015.promise.d.ts");
const host = new fakes.FakeServerHost({}, /*files*/ {
"/.ts/lib.es5.d.ts": `declare const eval: any`,
"/.ts/lib.es2015.promise.d.ts": `declare class Promise<T> {}`,
[es5LibPath]: `declare const eval: any`,
[es2015PromiseLibPath]: `declare class Promise<T> {}`,
"/src/app.ts": `var x: Promise<string>;`,
"/src/tsconfig.json": `{ "compilerOptions": { "lib": ["es5"] } }`,
});
const watch = createWatchOfConfigFile("/src/tsconfig.json", host);
checkProgramActualFiles(watch(), ["/.ts/lib.es5.d.ts", "/src/app.ts"]);
checkProgramActualFiles(watch(), [es5LibPath, "/src/app.ts"]);
host.vfs.writeFileSync("/src/tsconfig.json", `{ "compilerOptions": { "lib": ["es5", "es2015.promise"] } }`);
host.checkTimeoutQueueLengthAndRun(1);
checkProgramActualFiles(watch(), ["/.ts/lib.es5.d.ts", "/.ts/lib.es2015.promise.d.ts", "/src/app.ts"]);
checkProgramActualFiles(watch(), [es5LibPath, es2015PromiseLibPath, "/src/app.ts"]);
});
it("should handle non-existing directories in config file", () => {

View file

@ -5762,7 +5762,7 @@ namespace ts.projectSystem {
content: "export class Cookie { }"
};
const es2016LibFile: FileOrFolder = {
path: "/.ts/lib.es2016.full.d.ts",
path: vpath.combine(vfsutils.builtFolder, "lib.es2016.full.d.ts"),
content: libFile.content
};
const typeRoots = ["types", "node_modules/@types"];

View file

@ -732,7 +732,7 @@ namespace ts.projectSystem {
checkNumberOfProjects(projectService, { configuredProjects: 1 });
const p = configuredProjectAt(projectService, 0);
checkProjectActualFiles(p, [app, jsconfig]);
host.checkWatchedFiles([jsconfig, "/bower_components", "/node_modules", "/.ts/lib.d.ts"]);
host.checkWatchedFiles([jsconfig, "/bower_components", "/node_modules", vpath.combine(vfsutils.builtFolder, "lib.d.ts")]);
installer.installAll(/*expectedCount*/ 1);

View file

@ -13,6 +13,36 @@ namespace vfsutils {
let builtLocalCI: vfs.FileSystem | undefined;
let builtLocalCS: vfs.FileSystem | undefined;
/**
* Posix-style path to the TypeScript compiler build outputs (including tsc.js, lib.d.ts, etc.)
*/
export const builtFolder = "/.ts";
/**
* Posix-style path to additional test libraries
*/
export const testLibFolder = "/.lib";
/**
* Posix-style path to sources under test
*/
export const srcFolder = "/.src";
/**
* DOS-style path to the TypeScript compiler build outputs (including tsc.js, lib.d.ts, etc.)
*/
export const dosBuiltFolder = "c:" + builtFolder;
/**
* DOS-style path to additional test libraries
*/
export const dosTestLibFolder = "c:" + testLibFolder;
/**
* DOS-style path to sources under test
*/
export const dosSrcFolder = "c:" + srcFolder;
export function createResolver(io: Harness.IO): vfs.FileSystemResolver {
return {
readdirSync(path: string): string[] {
@ -60,12 +90,12 @@ namespace vfsutils {
const resolver = createResolver(Harness.IO);
builtLocalCI = new vfs.FileSystem(/*ignoreCase*/ true, {
files: {
"/.ts": new vfs.Mount(__dirname, patchResolver(Harness.IO, resolver)),
"/.lib": new vfs.Mount(vpath.resolve(__dirname, "../../tests/lib"), resolver),
"/.src": {}
[builtFolder]: new vfs.Mount(__dirname, patchResolver(Harness.IO, resolver)),
[testLibFolder]: new vfs.Mount(vpath.resolve(__dirname, "../../tests/lib"), resolver),
[srcFolder]: {}
},
cwd: "/.src",
meta: { defaultLibLocation: "/.ts" }
cwd: srcFolder,
meta: { defaultLibLocation: builtFolder }
});
builtLocalCI.makeReadonly();
}

View file

@ -1,5 +1,3 @@
// /// <reference path="./harness.ts" />
// NOTE: The contents of this file are all exported from the namespace 'vpath'. This is to
// support the eventual conversion of harness into a modular system.
@ -66,353 +64,3 @@ declare module "vpath_" {
}
}
}
// /// <reference path="./harness.ts" />
// // NOTE: The contents of this file are all exported from the namespace 'vpath'. This is to
// // support the eventual conversion of harness into a modular system.
// // NOTE: Some of the functions here duplicate functionality from compiler/core.ts. They have been
// // added to reduce the number of direct dependencies on compiler and services to eventually
// // break away from depending directly on the compiler to speed up compilation time.
// namespace vpath {
// /**
// * Virtual path separator.
// */
// export const sep = "/";
// /**
// * Normalize path separators.
// */
// export function normalizeSeparators(path: string): string {
// return path.replace(/\s*[\\/]\s*/g, sep).trim();
// }
// const rootRegExp = /^[\\/]([\\/](.*?[\\/](.*?[\\/])?)?)?|^[a-zA-Z]:[\\/]?|^\w+:\/{2}[^\\/]*\/?/;
// function getRootLength(path: string) {
// const match = rootRegExp.exec(path);
// return match ? match[0].length : 0;
// }
// /**
// * Determines whether a path is an absolute path (e.g. starts with `/`, `\\`, or a dos path
// * like `c:`).
// */
// export function isAbsolute(path: string) {
// return rootRegExp.test(path);
// }
// const trailingSeperatorRegExp = /[\\/]$/;
// /**
// * Determines whether a path has a trailing separator (`/`).
// */
// export function hasTrailingSeparator(path: string) {
// return trailingSeperatorRegExp.test(path);
// }
// /**
// * Adds a trailing separator (`/`) to a path if it doesn't have one.
// */
// export function addTrailingSeparator(path: string) {
// return hasTrailingSeparator(path) ? path : path + "/";
// }
// /**
// * Removes a trailing separator (`/`) from a path if it has one.
// */
// export function removeTrailingSeparator(path: string) {
// return hasTrailingSeparator(path) ? path.slice(0, -1) : path;
// }
// function reduce(components: ReadonlyArray<string>) {
// const normalized = [components[0]];
// for (let i = 1; i < components.length; i++) {
// const component = components[i];
// if (component === ".") continue;
// if (component === ".." && normalized.length > 0 && normalized[normalized.length - 1] !== "..") {
// normalized.pop();
// }
// else {
// normalized.push(component);
// }
// }
// return normalized;
// }
// /**
// * Normalize a path containing path traversal components (`.` or `..`).
// */
// export function normalize(path: string): string {
// const components = reduce(parse(path));
// return components.length > 1 && hasTrailingSeparator(path) ? format(components) + sep : format(components);
// }
// /**
// * Combines two or more paths. If a path is absolute, it replaces any previous path.
// */
// export function combine(path: string, ...paths: string[]) {
// path = normalizeSeparators(path);
// for (let name of paths) {
// name = normalizeSeparators(name);
// if (name.length === 0) continue;
// path = path.length === 0 || isAbsolute(name) ? name :
// addTrailingSeparator(path) + name;
// }
// return path;
// }
// /**
// * Combines and normalizes two or more paths.
// */
// export function resolve(path: string, ...paths: string[]) {
// return normalize(combine(path, ...paths));
// }
// function relativeWorker(from: string, to: string, stringEqualityComparer: core.EqualityComparer<string>) {
// if (!isAbsolute(from)) throw new Error("Path not absolute");
// if (!isAbsolute(to)) throw new Error("Path not absolute");
// const fromComponents = reduce(parse(from));
// const toComponents = reduce(parse(to));
// let start: number;
// for (start = 0; start < fromComponents.length && start < toComponents.length; start++) {
// if (!stringEqualityComparer(fromComponents[start], toComponents[start])) {
// break;
// }
// }
// if (start === 0 || (start === 1 && fromComponents[0] === "/")) {
// return format(toComponents);
// }
// const components = toComponents.slice(start);
// for (; start < fromComponents.length; start++) {
// components.unshift("..");
// }
// return format(["", ...components]);
// }
// function relativeCaseSensitive(from: string, to: string) {
// return relativeWorker(from, to, core.equateStringsCaseSensitive);
// }
// function relativeCaseInsensitive(from: string, to: string) {
// return relativeWorker(from, to, core.equateStringsCaseInsensitive);
// }
// /**
// * Gets a relative path that can be used to traverse between `from` and `to`.
// */
// export function relative(from: string, to: string, ignoreCase: boolean) {
// return ignoreCase ? relativeCaseInsensitive(from, to) : relativeCaseSensitive(from, to);
// }
// function compareWorker(a: string, b: string, stringComparer: core.Comparer<string>) {
// if (a === b) return 0;
// a = removeTrailingSeparator(a);
// b = removeTrailingSeparator(b);
// if (a === b) return 0;
// const aComponents = reduce(parse(a));
// const bComponents = reduce(parse(b));
// const len = Math.min(aComponents.length, bComponents.length);
// for (let i = 0; i < len; i++) {
// const result = stringComparer(aComponents[i], bComponents[i]);
// if (result !== 0) return result;
// }
// return core.compareNumbers(aComponents.length, bComponents.length);
// }
// /**
// * Performs a case-sensitive comparison of two paths.
// */
// export function compareCaseSensitive(a: string, b: string) {
// return compareWorker(a, b, core.compareStringsCaseSensitive);
// }
// /**
// * Performs a case-insensitive comparison of two paths.
// */
// export function compareCaseInsensitive(a: string, b: string) {
// return compareWorker(a, b, core.compareStringsCaseInsensitive);
// }
// /**
// * Compare two paths.
// */
// export function compare(a: string, b: string, ignoreCase: boolean) {
// return ignoreCase ? compareCaseInsensitive(a, b) : compareCaseSensitive(a, b);
// }
// /**
// * Determines whether two strings are equal.
// */
// export function equals(a: string, b: string, ignoreCase: boolean) {
// if (!isAbsolute(a)) throw new Error("Path not absolute");
// if (!isAbsolute(b)) throw new Error("Path not absolute");
// if (a === b) return true;
// a = removeTrailingSeparator(a);
// b = removeTrailingSeparator(b);
// if (a === b) return true;
// a = normalize(a);
// b = normalize(b);
// if (a === b) return true;
// return ignoreCase && a.toUpperCase() === b.toUpperCase();
// }
// function beneathWorker(ancestor: string, descendant: string, stringEqualityComparer: ts.EqualityComparer<string>) {
// if (!isAbsolute(ancestor)) throw new Error("Path not absolute");
// if (!isAbsolute(descendant)) throw new Error("Path not absolute");
// const ancestorComponents = reduce(parse(ancestor));
// const descendantComponents = reduce(parse(descendant));
// if (descendantComponents.length < ancestorComponents.length) return false;
// for (let i = 0; i < ancestorComponents.length; i++) {
// if (!stringEqualityComparer(ancestorComponents[i], descendantComponents[i])) {
// return false;
// }
// }
// return true;
// }
// function beneathCaseSensitive(ancestor: string, descendant: string) {
// return beneathWorker(ancestor, descendant, core.equateStringsCaseSensitive);
// }
// function beneathCaseInsensitive(ancestor: string, descendant: string) {
// return beneathWorker(ancestor, descendant, core.equateStringsCaseInsensitive);
// }
// /**
// * Determines whether the path `descendant` is beneath the path `ancestor`.
// */
// export function beneath(ancestor: string, descendant: string, ignoreCase: boolean) {
// return ignoreCase ? beneathCaseInsensitive(ancestor, descendant) : beneathCaseSensitive(ancestor, descendant);
// }
// /**
// * Parse a path into a root component and zero or more path segments.
// * If the path is relative, the root component is `""`.
// * If the path is absolute, the root component includes the first path separator (`/`).
// */
// export function parse(path: string) {
// path = normalizeSeparators(path);
// const rootLength = getRootLength(path);
// const root = path.substring(0, rootLength);
// const rest = path.substring(rootLength).split(/\/+/g);
// if (rest.length && !rest[rest.length - 1]) rest.pop();
// return [root, ...rest.map(component => component.trim())];
// }
// /**
// * Formats a parsed path consisting of a root component and zero or more path segments.
// */
// export function format(components: ReadonlyArray<string>) {
// return components.length ? components[0] + components.slice(1).join(sep) : "";
// }
// /**
// * Gets the parent directory name of a path.
// */
// export function dirname(path: string) {
// path = normalizeSeparators(path);
// return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(sep)));
// }
// /**
// * Gets the portion of a path following the last separator (`/`).
// */
// export function basename(path: string): string;
// /**
// * Gets the portion of a path following the last separator (`/`).
// * If the base name has any one of the provided extensions, it is removed.
// */
// export function basename(path: string, extensions: string | ReadonlyArray<string>, ignoreCase: boolean): string;
// export function basename(path: string, extensions?: string | ReadonlyArray<string>, ignoreCase?: boolean) {
// path = normalizeSeparators(path);
// const name = path.substr(Math.max(getRootLength(path), path.lastIndexOf(sep) + 1));
// const extension = extensions ? extname(path, extensions, ignoreCase) : undefined;
// return extension ? name.slice(0, name.length - extension.length) : name;
// }
// function extnameWorker(path: string, extensions: string | ReadonlyArray<string>, stringEqualityComparer: core.EqualityComparer<string>) {
// const manyExtensions = Array.isArray(extensions) ? extensions : undefined;
// const singleExtension = Array.isArray(extensions) ? undefined : extensions;
// const length = manyExtensions ? manyExtensions.length : 1;
// for (let i = 0; i < length; i++) {
// let extension = manyExtensions ? manyExtensions[i] : singleExtension;
// if (!extension.startsWith(".")) extension = "." + extension;
// if (path.length >= extension.length && path.charAt(path.length - extension.length) === ".") {
// const pathExtension = path.slice(path.length - extension.length);
// if (stringEqualityComparer(pathExtension, extension)) {
// return pathExtension;
// }
// }
// }
// return "";
// }
// const extRegExp = /\.\w+$/;
// /**
// * Gets the file extension for a path.
// */
// export function extname(path: string): string;
// /**
// * Gets the file extension for a path, provided it is one of the provided extensions.
// */
// export function extname(path: string, extensions: string | ReadonlyArray<string>, ignoreCase: boolean): string;
// export function extname(path: string, extensions?: string | ReadonlyArray<string>, ignoreCase?: boolean) {
// if (extensions) {
// return extnameWorker(path, extensions, ignoreCase ? core.equateStringsCaseInsensitive : core.equateStringsCaseSensitive);
// }
// const match = extRegExp.exec(path);
// return match ? match[0] : "";
// }
// export function changeExtension(path: string, ext: string): string;
// export function changeExtension(path: string, ext: string, extensions: string | ReadonlyArray<string>, ignoreCase: boolean): string;
// export function changeExtension(path: string, ext: string, extensions?: string | ReadonlyArray<string>, ignoreCase?: boolean) {
// const pathext = extensions ? extname(path, extensions, ignoreCase) : extname(path);
// return pathext ? path.slice(0, path.length - pathext.length) + (ext.startsWith(".") ? ext : "." + ext) : path;
// }
// const typeScriptExtensions: ReadonlyArray<string> = [".ts", ".tsx"];
// export function isTypeScript(path: string) {
// return extname(path, typeScriptExtensions, /*ignoreCase*/ false).length > 0;
// }
// const javaScriptExtensions: ReadonlyArray<string> = [".js", ".jsx"];
// export function isJavaScript(path: string) {
// return extname(path, javaScriptExtensions, /*ignoreCase*/ false).length > 0;
// }
// export function isDeclaration(path: string) {
// return extname(path, ".d.ts", /*ignoreCase*/ false).length > 0;
// }
// export function isSourceMap(path: string) {
// return extname(path, ".map", /*ignoreCase*/ false).length > 0;
// }
// const javaScriptSourceMapExtensions: ReadonlyArray<string> = [".js.map", ".jsx.map"];
// export function isJavaScriptSourceMap(path: string) {
// return extname(path, javaScriptSourceMapExtensions, /*ignoreCase*/ false).length > 0;
// }
// export function isJson(path: string) {
// return extname(path, ".json", /*ignoreCase*/ false).length > 0;
// }
// export function isDefaultLibrary(path: string) {
// return isDeclaration(path)
// && basename(path).startsWith("lib.");
// }
// }