mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Merge remote-tracking branch 'origin/master' into tsserverVS-WIP-projectsystem
This commit is contained in:
commit
ec9a1ad5f8
@ -650,7 +650,7 @@ function runConsoleTests(defaultReporter: string, runInParallel: boolean, done:
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 100000;
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
const colors = cmdLineOptions["colors"];
|
||||
|
||||
@ -776,7 +776,7 @@ function runConsoleTests(defaultReporter, runInParallel) {
|
||||
}
|
||||
|
||||
if (tests && tests.toLocaleLowerCase() === "rwc") {
|
||||
testTimeout = 100000;
|
||||
testTimeout = 400000;
|
||||
}
|
||||
|
||||
colors = process.env.colors || process.env.color;
|
||||
|
||||
@ -13294,8 +13294,8 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const static = forEach(member.modifiers, m => m.kind === SyntaxKind.StaticKeyword);
|
||||
const names = static ? staticNames : instanceNames;
|
||||
const isStatic = forEach(member.modifiers, m => m.kind === SyntaxKind.StaticKeyword);
|
||||
const names = isStatic ? staticNames : instanceNames;
|
||||
|
||||
const memberName = member.name && getPropertyNameForPropertyNameNode(member.name);
|
||||
if (memberName) {
|
||||
@ -14560,7 +14560,10 @@ namespace ts {
|
||||
const local = node.locals[key];
|
||||
if (!local.isReferenced) {
|
||||
if (local.valueDeclaration && local.valueDeclaration.kind === SyntaxKind.Parameter) {
|
||||
if (compilerOptions.noUnusedParameters && !isParameterPropertyDeclaration(<ParameterDeclaration>local.valueDeclaration)) {
|
||||
const parameter = <ParameterDeclaration>local.valueDeclaration;
|
||||
if (compilerOptions.noUnusedParameters &&
|
||||
!isParameterPropertyDeclaration(parameter) &&
|
||||
!parameterNameStartsWithUnderscore(parameter)) {
|
||||
error(local.valueDeclaration.name, Diagnostics._0_is_declared_but_never_used, local.name);
|
||||
}
|
||||
}
|
||||
@ -14573,6 +14576,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parameterNameStartsWithUnderscore(parameter: ParameterDeclaration) {
|
||||
return parameter.name && parameter.name.kind === SyntaxKind.Identifier && (<Identifier>parameter.name).text.charCodeAt(0) === CharacterCodes._;
|
||||
}
|
||||
|
||||
function checkUnusedClassMembers(node: ClassDeclaration | ClassExpression): void {
|
||||
if (compilerOptions.noUnusedLocals && !isInAmbientContext(node)) {
|
||||
if (node.members) {
|
||||
|
||||
@ -891,6 +891,21 @@ namespace ts {
|
||||
*/
|
||||
const invalidMultipleRecursionPatterns = /(^|\/)\*\*\/(.*\/)?\*\*($|\/)/;
|
||||
|
||||
/**
|
||||
* Tests for a path where .. appears after a recursive directory wildcard.
|
||||
* Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
|
||||
*
|
||||
* NOTE: used \ in place of / above to avoid issues with multiline comments.
|
||||
*
|
||||
* Breakdown:
|
||||
* (^|\/) # matches either the beginning of the string or a directory separator.
|
||||
* \*\*\/ # matches a recursive directory wildcard "**" followed by a directory separator.
|
||||
* (.*\/)? # optionally matches any number of characters followed by a directory separator.
|
||||
* \.\. # matches a parent directory path component ".."
|
||||
* ($|\/) # matches either the end of the string or a directory separator.
|
||||
*/
|
||||
const invalidDotDotAfterRecursiveWildcardPattern = /(^|\/)\*\*\/(.*\/)?\.\.($|\/)/;
|
||||
|
||||
/**
|
||||
* Tests for a path containing a wildcard character in a directory component of the path.
|
||||
* Matches \*\, \?\, and \a*b\, but not \a\ or \a\*.
|
||||
@ -1023,6 +1038,9 @@ namespace ts {
|
||||
else if (invalidMultipleRecursionPatterns.test(spec)) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, spec));
|
||||
}
|
||||
else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, spec));
|
||||
}
|
||||
else {
|
||||
validSpecs.push(spec);
|
||||
}
|
||||
@ -1052,7 +1070,7 @@ namespace ts {
|
||||
if (include !== undefined) {
|
||||
const recursiveKeys: string[] = [];
|
||||
for (const file of include) {
|
||||
const name = combinePaths(path, file);
|
||||
const name = normalizePath(combinePaths(path, file));
|
||||
if (excludeRegex && excludeRegex.test(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1073,15 +1073,17 @@ namespace ts {
|
||||
// Storage for literal base paths amongst the include patterns.
|
||||
const includeBasePaths: string[] = [];
|
||||
for (const include of includes) {
|
||||
if (isRootedDiskPath(include)) {
|
||||
const wildcardOffset = indexOfAnyCharCode(include, wildcardCharCodes);
|
||||
const includeBasePath = wildcardOffset < 0
|
||||
? removeTrailingDirectorySeparator(getDirectoryPath(include))
|
||||
: include.substring(0, include.lastIndexOf(directorySeparator, wildcardOffset));
|
||||
// We also need to check the relative paths by converting them to absolute and normalizing
|
||||
// in case they escape the base path (e.g "..\somedirectory")
|
||||
const absolute: string = isRootedDiskPath(include) ? include : normalizePath(combinePaths(path, include));
|
||||
|
||||
// Append the literal and canonical candidate base paths.
|
||||
includeBasePaths.push(includeBasePath);
|
||||
}
|
||||
const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
|
||||
const includeBasePath = wildcardOffset < 0
|
||||
? removeTrailingDirectorySeparator(getDirectoryPath(absolute))
|
||||
: absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
|
||||
|
||||
// Append the literal and canonical candidate base paths.
|
||||
includeBasePaths.push(includeBasePath);
|
||||
}
|
||||
|
||||
// Sort the offsets array using either the literal or canonical path representations.
|
||||
|
||||
@ -2332,6 +2332,10 @@
|
||||
"category": "Error",
|
||||
"code": 5064
|
||||
},
|
||||
"File specification cannot contain a parent directory ('..') that appears after a recursive directory wildcard ('**'): '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 5065
|
||||
},
|
||||
"Concatenate and emit output to single file.": {
|
||||
"category": "Message",
|
||||
"code": 6001
|
||||
|
||||
@ -8,7 +8,12 @@ interface FileInformation {
|
||||
}
|
||||
|
||||
interface FindFileResult {
|
||||
}
|
||||
|
||||
interface IOLogFile {
|
||||
path: string;
|
||||
codepage: number;
|
||||
result?: FileInformation;
|
||||
}
|
||||
|
||||
interface IOLog {
|
||||
@ -17,11 +22,7 @@ interface IOLog {
|
||||
executingPath: string;
|
||||
currentDirectory: string;
|
||||
useCustomLibraryFile?: boolean;
|
||||
filesRead: {
|
||||
path: string;
|
||||
codepage: number;
|
||||
result?: FileInformation;
|
||||
}[];
|
||||
filesRead: IOLogFile[];
|
||||
filesWritten: {
|
||||
path: string;
|
||||
contents: string;
|
||||
@ -61,7 +62,7 @@ interface IOLog {
|
||||
}[];
|
||||
directoriesRead: {
|
||||
path: string,
|
||||
extension: string[],
|
||||
extensions: string[],
|
||||
exclude: string[],
|
||||
include: string[],
|
||||
result: string[]
|
||||
@ -170,8 +171,7 @@ namespace Playback {
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }),
|
||||
memoize(path => {
|
||||
// If we read from the file, it must exist
|
||||
const noResult = {};
|
||||
if (findResultByPath(wrapper, replayLog.filesRead, path, noResult) !== noResult) {
|
||||
if (findFileByPath(wrapper, replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@ -215,16 +215,30 @@ namespace Playback {
|
||||
recordLog.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
memoize(path => findResultByPath(wrapper, replayLog.filesRead, path).contents));
|
||||
memoize(path => findFileByPath(wrapper, replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extension, exclude, include) => {
|
||||
const result = (<ts.System>underlying).readDirectory(path, extension, exclude, include);
|
||||
const logEntry = { path, extension, exclude, include, result };
|
||||
(path, extensions, exclude, include) => {
|
||||
const result = (<ts.System>underlying).readDirectory(path, extensions, exclude, include);
|
||||
const logEntry = { path, extensions, exclude, include, result };
|
||||
recordLog.directoriesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
(path, extension, exclude) => findResultByPath(wrapper, replayLog.directoriesRead, path));
|
||||
(path, extensions, exclude) => {
|
||||
// Because extensions is an array of all allowed extension, we will want to merge each of the replayLog.directoriesRead into one
|
||||
// if each of the directoriesRead has matched path with the given path (directory with same path but different extension will considered
|
||||
// different entry).
|
||||
// TODO (yuisu): We can certainly remove these once we recapture the RWC using new API
|
||||
const normalizedPath = ts.normalizePath(path).toLowerCase();
|
||||
const result: string[] = [];
|
||||
for (const directory of replayLog.directoriesRead) {
|
||||
if (ts.normalizeSlashes(directory.path).toLowerCase() === normalizedPath) {
|
||||
result.push(...directory.result);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
|
||||
(path: string, contents: string) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path, contents, bom: false }),
|
||||
@ -279,30 +293,22 @@ namespace Playback {
|
||||
return results[0].result;
|
||||
}
|
||||
|
||||
function findResultByPath<T>(wrapper: { resolvePath(s: string): string }, logArray: { path: string; result?: T }[], expectedPath: string, defaultValue?: T): T {
|
||||
function findFileByPath(wrapper: { resolvePath(s: string): string }, logArray: IOLogFile[],
|
||||
expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
for (let i = 0; i < logArray.length; i++) {
|
||||
if (ts.normalizeSlashes(logArray[i].path).toLowerCase() === normalizedName) {
|
||||
return logArray[i].result;
|
||||
}
|
||||
}
|
||||
// Fallback, try to resolve the target paths as well
|
||||
if (replayLog.pathsResolved.length > 0) {
|
||||
const normalizedResolvedName = wrapper.resolvePath(expectedPath).toLowerCase();
|
||||
for (let i = 0; i < logArray.length; i++) {
|
||||
if (wrapper.resolvePath(logArray[i].path).toLowerCase() === normalizedResolvedName) {
|
||||
return logArray[i].result;
|
||||
}
|
||||
for (const log of logArray) {
|
||||
if (ts.normalizeSlashes(log.path).toLowerCase() === normalizedName) {
|
||||
return log.result;
|
||||
}
|
||||
}
|
||||
|
||||
// If we got here, we didn't find a match
|
||||
if (defaultValue === undefined) {
|
||||
if (throwFileNotFoundError) {
|
||||
throw new Error("No matching result in log array for path: " + expectedPath);
|
||||
}
|
||||
else {
|
||||
return defaultValue;
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
34
src/lib/es5.d.ts
vendored
34
src/lib/es5.d.ts
vendored
@ -1255,33 +1255,13 @@ declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | P
|
||||
|
||||
interface PromiseLike<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1, TResult2>(onfulfilled: (value: T) => TResult1 | PromiseLike<TResult1>, onrejected: (reason: any) => TResult2 | PromiseLike<TResult2>): PromiseLike<TResult1 | TResult2>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>, onrejected: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
|
||||
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled: (value: T) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
|
||||
|
||||
/**
|
||||
* Creates a new Promise with the same internal state of this Promise.
|
||||
* @returns A Promise.
|
||||
*/
|
||||
then(): PromiseLike<T>;
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
|
||||
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
|
||||
}
|
||||
|
||||
interface ArrayLike<T> {
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(2,12): error TS6133: 'a' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(2,19): error TS6133: 'c' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(2,27): error TS6133: 'd' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(2,29): error TS6133: 'e___' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(6,14): error TS6133: '_a' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(6,18): error TS6133: '___b' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(9,14): error TS6133: '_a' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(9,19): error TS6133: '___b' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(12,16): error TS6133: 'arg' is declared but never used.
|
||||
tests/cases/compiler/unusedParametersWithUnderscore.ts(18,13): error TS6133: 'arg' is declared but never used.
|
||||
|
||||
|
||||
==== tests/cases/compiler/unusedParametersWithUnderscore.ts (10 errors) ====
|
||||
|
||||
function f(a, _b, c, ___, d,e___, _f) {
|
||||
~
|
||||
!!! error TS6133: 'a' is declared but never used.
|
||||
~
|
||||
!!! error TS6133: 'c' is declared but never used.
|
||||
~
|
||||
!!! error TS6133: 'd' is declared but never used.
|
||||
~~~~
|
||||
!!! error TS6133: 'e___' is declared but never used.
|
||||
}
|
||||
|
||||
|
||||
function f2({_a, __b}) {
|
||||
~~
|
||||
!!! error TS6133: '_a' is declared but never used.
|
||||
~~~
|
||||
!!! error TS6133: '___b' is declared but never used.
|
||||
}
|
||||
|
||||
function f3([_a, ,__b]) {
|
||||
~~
|
||||
!!! error TS6133: '_a' is declared but never used.
|
||||
~~~
|
||||
!!! error TS6133: '___b' is declared but never used.
|
||||
}
|
||||
|
||||
function f4(...arg) {
|
||||
~~~
|
||||
!!! error TS6133: 'arg' is declared but never used.
|
||||
}
|
||||
|
||||
function f5(..._arg) {
|
||||
}
|
||||
|
||||
function f6(arg?, _arg?) {
|
||||
~~~
|
||||
!!! error TS6133: 'arg' is declared but never used.
|
||||
}
|
||||
|
||||
var f7 = _ => undefined;
|
||||
|
||||
var f8 = function (_) { };
|
||||
50
tests/baselines/reference/unusedParametersWithUnderscore.js
Normal file
50
tests/baselines/reference/unusedParametersWithUnderscore.js
Normal file
@ -0,0 +1,50 @@
|
||||
//// [unusedParametersWithUnderscore.ts]
|
||||
|
||||
function f(a, _b, c, ___, d,e___, _f) {
|
||||
}
|
||||
|
||||
|
||||
function f2({_a, __b}) {
|
||||
}
|
||||
|
||||
function f3([_a, ,__b]) {
|
||||
}
|
||||
|
||||
function f4(...arg) {
|
||||
}
|
||||
|
||||
function f5(..._arg) {
|
||||
}
|
||||
|
||||
function f6(arg?, _arg?) {
|
||||
}
|
||||
|
||||
var f7 = _ => undefined;
|
||||
|
||||
var f8 = function (_) { };
|
||||
|
||||
//// [unusedParametersWithUnderscore.js]
|
||||
function f(a, _b, c, ___, d, e___, _f) {
|
||||
}
|
||||
function f2(_c) {
|
||||
var _a = _c._a, __b = _c.__b;
|
||||
}
|
||||
function f3(_c) {
|
||||
var _a = _c[0], __b = _c[2];
|
||||
}
|
||||
function f4() {
|
||||
var arg = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
arg[_i - 0] = arguments[_i];
|
||||
}
|
||||
}
|
||||
function f5() {
|
||||
var _arg = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
_arg[_i - 0] = arguments[_i];
|
||||
}
|
||||
}
|
||||
function f6(arg, _arg) {
|
||||
}
|
||||
var f7 = function (_) { return undefined; };
|
||||
var f8 = function (_) { };
|
||||
25
tests/cases/compiler/unusedParametersWithUnderscore.ts
Normal file
25
tests/cases/compiler/unusedParametersWithUnderscore.ts
Normal file
@ -0,0 +1,25 @@
|
||||
//@noUnusedLocals:true
|
||||
//@noUnusedParameters:true
|
||||
|
||||
function f(a, _b, c, ___, d,e___, _f) {
|
||||
}
|
||||
|
||||
|
||||
function f2({_a, __b}) {
|
||||
}
|
||||
|
||||
function f3([_a, ,__b]) {
|
||||
}
|
||||
|
||||
function f4(...arg) {
|
||||
}
|
||||
|
||||
function f5(..._arg) {
|
||||
}
|
||||
|
||||
function f6(arg?, _arg?) {
|
||||
}
|
||||
|
||||
var f7 = _ => undefined;
|
||||
|
||||
var f8 = function (_) { };
|
||||
@ -24,7 +24,8 @@ namespace ts {
|
||||
"c:/dev/x/y/b.ts",
|
||||
"c:/dev/js/a.js",
|
||||
"c:/dev/js/b.js",
|
||||
"c:/ext/ext.ts"
|
||||
"c:/ext/ext.ts",
|
||||
"c:/ext/b/a..b.ts"
|
||||
]);
|
||||
|
||||
const caseSensitiveBasePath = "/dev/";
|
||||
@ -740,7 +741,7 @@ namespace ts {
|
||||
"c:/dev/a.ts",
|
||||
"c:/dev/b.ts",
|
||||
"c:/dev/c.d.ts",
|
||||
"c:/ext/ext.ts",
|
||||
"c:/ext/ext.ts"
|
||||
],
|
||||
wildcardDirectories: {
|
||||
"c:/dev": ts.WatchDirectoryFlags.None,
|
||||
@ -752,6 +753,97 @@ namespace ts {
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
it("include paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"*",
|
||||
"../ext/*"
|
||||
],
|
||||
exclude: [
|
||||
"**"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
fileNames: [
|
||||
"c:/ext/ext.ts"
|
||||
],
|
||||
wildcardDirectories: {
|
||||
"c:/ext": ts.WatchDirectoryFlags.None
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
it("exclude paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"c:/**/*"
|
||||
],
|
||||
exclude: [
|
||||
"../**"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
it("include files with .. in their name", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"c:/ext/b/a..b.ts"
|
||||
],
|
||||
exclude: [
|
||||
"**"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
fileNames: [
|
||||
"c:/ext/b/a..b.ts"
|
||||
],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
it("exclude files with .. in their name", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"c:/ext/**/*"
|
||||
],
|
||||
exclude: [
|
||||
"c:/ext/b/a..b.ts"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
fileNames: [
|
||||
"c:/ext/ext.ts",
|
||||
],
|
||||
wildcardDirectories: {
|
||||
"c:/ext": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
it("with jsx=none, allowJs=false", () => {
|
||||
const json = {
|
||||
compilerOptions: {
|
||||
@ -951,6 +1043,108 @@ namespace ts {
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with parent directory symbols after a recursive directory pattern", () => {
|
||||
it("in includes immediately after", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"**/../*"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
|
||||
it("in includes after a subdirectory", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"**/y/../*"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*")
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
|
||||
it("in excludes immediately after", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"**/a.ts"
|
||||
],
|
||||
exclude: [
|
||||
"**/.."
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/..")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
"c:/dev/x/a.ts",
|
||||
"c:/dev/x/y/a.ts",
|
||||
"c:/dev/z/a.ts"
|
||||
],
|
||||
wildcardDirectories: {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
|
||||
it("in excludes after a subdirectory", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"**/a.ts"
|
||||
],
|
||||
exclude: [
|
||||
"**/y/.."
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/..")
|
||||
],
|
||||
fileNames: [
|
||||
"c:/dev/a.ts",
|
||||
"c:/dev/x/a.ts",
|
||||
"c:/dev/x/y/a.ts",
|
||||
"c:/dev/z/a.ts"
|
||||
],
|
||||
wildcardDirectories: {
|
||||
"c:/dev": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user