mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
+1
-1
@@ -15,7 +15,7 @@ matrix:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- release-2.0
|
||||
- release-2.1
|
||||
|
||||
install:
|
||||
- npm uninstall typescript
|
||||
|
||||
@@ -183,5 +183,3 @@ jake baseline-accept
|
||||
```
|
||||
|
||||
to establish the new baselines as the desired behavior. This will change the files in `tests\baselines\reference`, which should be included as part of your commit. It's important to carefully validate changes in the baselines.
|
||||
|
||||
**Note** that `baseline-accept` should only be run after a full test run! Accepting baselines after running a subset of tests will delete baseline files for the tests that didn't run.
|
||||
|
||||
+11
-6
@@ -70,14 +70,15 @@ var compilerSources = [
|
||||
"visitor.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
@@ -105,14 +106,15 @@ var servicesSources = [
|
||||
"visitor.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/jsx.ts",
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/module/es2015.ts",
|
||||
"transformers/module/system.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformer.ts",
|
||||
"sourcemap.ts",
|
||||
"comments.ts",
|
||||
@@ -355,6 +357,7 @@ function concatenateFiles(destinationFile, sourceFiles) {
|
||||
if (!fs.existsSync(sourceFiles[i])) {
|
||||
fail(sourceFiles[i] + " does not exist!");
|
||||
}
|
||||
fs.appendFileSync(temp, "\n\n");
|
||||
fs.appendFileSync(temp, fs.readFileSync(sourceFiles[i]));
|
||||
}
|
||||
// Move the file to the final destination
|
||||
@@ -445,6 +448,8 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, opts
|
||||
options += " --stripInternal";
|
||||
}
|
||||
|
||||
options += " --target es5 --noUnusedLocals --noUnusedParameters";
|
||||
|
||||
var cmd = host + " " + compilerPath + " " + options + " ";
|
||||
cmd = cmd + sources.join(" ");
|
||||
console.log(cmd + "\n");
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Set up NVM
|
||||
export NVM_DIR="/home/dotnet-bot/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
|
||||
|
||||
nvm install $1
|
||||
|
||||
npm uninstall typescript
|
||||
npm uninstall tslint
|
||||
npm install
|
||||
npm update
|
||||
npm test
|
||||
@@ -39,3 +39,5 @@ function createCancellationToken(args) {
|
||||
};
|
||||
}
|
||||
module.exports = createCancellationToken;
|
||||
|
||||
//# sourceMappingURL=cancellationToken.js.map
|
||||
|
||||
Vendored
+11
-1
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// ECMAScript APIs
|
||||
/////////////////////////////
|
||||
@@ -4149,6 +4153,8 @@ interface Date {
|
||||
*/
|
||||
toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// IE DOM APIs
|
||||
@@ -18774,12 +18780,16 @@ type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
|
||||
type IDBValidKey = number | string | Date | IDBArrayKey;
|
||||
type BufferSource = ArrayBuffer | ArrayBufferView;
|
||||
type MouseWheelEvent = WheelEvent;
|
||||
type ScrollRestoration = "auto" | "manual";
|
||||
type ScrollRestoration = "auto" | "manual";
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// WorkerGlobalScope APIs
|
||||
/////////////////////////////
|
||||
// These are only available in a Web Worker
|
||||
declare function importScripts(...urls: string[]): void;
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// IE DOM APIs
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.dom.d.ts" />
|
||||
|
||||
interface DOMTokenList {
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface Map<K, V> {
|
||||
clear(): void;
|
||||
delete(key: K): boolean;
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
declare type PropertyKey = string | number | symbol;
|
||||
|
||||
interface Array<T> {
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.es2015.core.d.ts" />
|
||||
/// <reference path="lib.es2015.collection.d.ts" />
|
||||
/// <reference path="lib.es2015.generator.d.ts" />
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface GeneratorFunction extends Function { }
|
||||
|
||||
interface GeneratorFunctionConstructor {
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface ProxyHandler<T> {
|
||||
getPrototypeOf? (target: T): any;
|
||||
setPrototypeOf? (target: T, v: any): boolean;
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
declare namespace Reflect {
|
||||
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
|
||||
function construct(target: Function, argumentsList: ArrayLike<any>, newTarget?: any): any;
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface Symbol {
|
||||
/** Returns a string representation of an object. */
|
||||
toString(): string;
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface Array<T> {
|
||||
/**
|
||||
* Determines whether an array includes a certain element, returning true or false as appropriate.
|
||||
|
||||
Vendored
+4
@@ -13,6 +13,10 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.es2015.d.ts" />
|
||||
/// <reference path="lib.es2016.array.include.d.ts" />
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.es2016.d.ts" />
|
||||
/// <reference path="lib.es2017.object.d.ts" />
|
||||
/// <reference path="lib.es2017.sharedmemory.d.ts" />
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
interface ObjectConstructor {
|
||||
/**
|
||||
* Returns an array of values of the enumerable properties of an object
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
/// <reference path="lib.es2015.symbol.wellknown.d.ts" />
|
||||
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// ECMAScript APIs
|
||||
/////////////////////////////
|
||||
|
||||
Vendored
+37
-7
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// ECMAScript APIs
|
||||
/////////////////////////////
|
||||
@@ -4149,6 +4153,8 @@ interface Date {
|
||||
*/
|
||||
toLocaleTimeString(locales?: string | string[], options?: Intl.DateTimeFormatOptions): string;
|
||||
}
|
||||
|
||||
|
||||
declare type PropertyKey = string | number | symbol;
|
||||
|
||||
interface Array<T> {
|
||||
@@ -4673,6 +4679,8 @@ interface StringConstructor {
|
||||
*/
|
||||
raw(template: TemplateStringsArray, ...substitutions: any[]): string;
|
||||
}
|
||||
|
||||
|
||||
interface Map<K, V> {
|
||||
clear(): void;
|
||||
delete(key: K): boolean;
|
||||
@@ -4745,6 +4753,8 @@ interface WeakSetConstructor {
|
||||
readonly prototype: WeakSet<any>;
|
||||
}
|
||||
declare var WeakSet: WeakSetConstructor;
|
||||
|
||||
|
||||
interface GeneratorFunction extends Function { }
|
||||
|
||||
interface GeneratorFunctionConstructor {
|
||||
@@ -4757,6 +4767,8 @@ interface GeneratorFunctionConstructor {
|
||||
readonly prototype: GeneratorFunction;
|
||||
}
|
||||
declare var GeneratorFunction: GeneratorFunctionConstructor;
|
||||
|
||||
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
@@ -5201,7 +5213,9 @@ interface Float64ArrayConstructor {
|
||||
* @param thisArg Value of 'this' used to invoke the mapfn.
|
||||
*/
|
||||
from(arrayLike: Iterable<number>, mapfn?: (v: number, k: number) => number, thisArg?: any): Float64Array;
|
||||
}/**
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the completion of an asynchronous operation
|
||||
*/
|
||||
interface Promise<T> {
|
||||
@@ -5454,7 +5468,9 @@ interface PromiseConstructor {
|
||||
resolve(): Promise<void>;
|
||||
}
|
||||
|
||||
declare var Promise: PromiseConstructor;interface ProxyHandler<T> {
|
||||
declare var Promise: PromiseConstructor;
|
||||
|
||||
interface ProxyHandler<T> {
|
||||
getPrototypeOf? (target: T): any;
|
||||
setPrototypeOf? (target: T, v: any): boolean;
|
||||
isExtensible? (target: T): boolean;
|
||||
@@ -5475,7 +5491,9 @@ interface ProxyConstructor {
|
||||
revocable<T>(target: T, handler: ProxyHandler<T>): { proxy: T; revoke: () => void; };
|
||||
new <T>(target: T, handler: ProxyHandler<T>): T
|
||||
}
|
||||
declare var Proxy: ProxyConstructor;declare namespace Reflect {
|
||||
declare var Proxy: ProxyConstructor;
|
||||
|
||||
declare namespace Reflect {
|
||||
function apply(target: Function, thisArgument: any, argumentsList: ArrayLike<any>): any;
|
||||
function construct(target: Function, argumentsList: ArrayLike<any>, newTarget?: any): any;
|
||||
function defineProperty(target: any, propertyKey: PropertyKey, attributes: PropertyDescriptor): boolean;
|
||||
@@ -5489,7 +5507,9 @@ declare var Proxy: ProxyConstructor;declare namespace Reflect {
|
||||
function preventExtensions(target: any): boolean;
|
||||
function set(target: any, propertyKey: PropertyKey, value: any, receiver?: any): boolean;
|
||||
function setPrototypeOf(target: any, proto: any): boolean;
|
||||
}interface Symbol {
|
||||
}
|
||||
|
||||
interface Symbol {
|
||||
/** Returns a string representation of an object. */
|
||||
toString(): string;
|
||||
|
||||
@@ -5524,7 +5544,9 @@ interface SymbolConstructor {
|
||||
keyFor(sym: symbol): string | undefined;
|
||||
}
|
||||
|
||||
declare var Symbol: SymbolConstructor;/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
declare var Symbol: SymbolConstructor;
|
||||
|
||||
/// <reference path="lib.es2015.symbol.d.ts" />
|
||||
|
||||
interface SymbolConstructor {
|
||||
/**
|
||||
@@ -5850,7 +5872,9 @@ interface Float32Array {
|
||||
*/
|
||||
interface Float64Array {
|
||||
readonly [Symbol.toStringTag]: "Float64Array";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// IE DOM APIs
|
||||
/////////////////////////////
|
||||
@@ -20475,12 +20499,16 @@ type ScrollLogicalPosition = "start" | "center" | "end" | "nearest";
|
||||
type IDBValidKey = number | string | Date | IDBArrayKey;
|
||||
type BufferSource = ArrayBuffer | ArrayBufferView;
|
||||
type MouseWheelEvent = WheelEvent;
|
||||
type ScrollRestoration = "auto" | "manual";
|
||||
type ScrollRestoration = "auto" | "manual";
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// WorkerGlobalScope APIs
|
||||
/////////////////////////////
|
||||
// These are only available in a Web Worker
|
||||
declare function importScripts(...urls: string[]): void;
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
@@ -20772,6 +20800,8 @@ interface DateConstructor {
|
||||
interface Date {
|
||||
getVarDate: () => VarDate;
|
||||
}
|
||||
|
||||
|
||||
/// <reference path="lib.dom.d.ts" />
|
||||
|
||||
interface DOMTokenList {
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
|
||||
Vendored
+4
@@ -13,7 +13,11 @@ See the Apache Version 2.0 License for specific language governing permissions
|
||||
and limitations under the License.
|
||||
***************************************************************************** */
|
||||
|
||||
|
||||
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
/// IE Worker APIs
|
||||
|
||||
+9355
-7693
File diff suppressed because it is too large
Load Diff
+11868
-10039
File diff suppressed because one or more lines are too long
Vendored
+1180
-8158
File diff suppressed because one or more lines are too long
+11861
-10034
File diff suppressed because one or more lines are too long
Vendored
+267
-261
@@ -47,241 +47,241 @@ declare namespace ts {
|
||||
ConflictMarkerTrivia = 7,
|
||||
NumericLiteral = 8,
|
||||
StringLiteral = 9,
|
||||
RegularExpressionLiteral = 10,
|
||||
NoSubstitutionTemplateLiteral = 11,
|
||||
TemplateHead = 12,
|
||||
TemplateMiddle = 13,
|
||||
TemplateTail = 14,
|
||||
OpenBraceToken = 15,
|
||||
CloseBraceToken = 16,
|
||||
OpenParenToken = 17,
|
||||
CloseParenToken = 18,
|
||||
OpenBracketToken = 19,
|
||||
CloseBracketToken = 20,
|
||||
DotToken = 21,
|
||||
DotDotDotToken = 22,
|
||||
SemicolonToken = 23,
|
||||
CommaToken = 24,
|
||||
LessThanToken = 25,
|
||||
LessThanSlashToken = 26,
|
||||
GreaterThanToken = 27,
|
||||
LessThanEqualsToken = 28,
|
||||
GreaterThanEqualsToken = 29,
|
||||
EqualsEqualsToken = 30,
|
||||
ExclamationEqualsToken = 31,
|
||||
EqualsEqualsEqualsToken = 32,
|
||||
ExclamationEqualsEqualsToken = 33,
|
||||
EqualsGreaterThanToken = 34,
|
||||
PlusToken = 35,
|
||||
MinusToken = 36,
|
||||
AsteriskToken = 37,
|
||||
AsteriskAsteriskToken = 38,
|
||||
SlashToken = 39,
|
||||
PercentToken = 40,
|
||||
PlusPlusToken = 41,
|
||||
MinusMinusToken = 42,
|
||||
LessThanLessThanToken = 43,
|
||||
GreaterThanGreaterThanToken = 44,
|
||||
GreaterThanGreaterThanGreaterThanToken = 45,
|
||||
AmpersandToken = 46,
|
||||
BarToken = 47,
|
||||
CaretToken = 48,
|
||||
ExclamationToken = 49,
|
||||
TildeToken = 50,
|
||||
AmpersandAmpersandToken = 51,
|
||||
BarBarToken = 52,
|
||||
QuestionToken = 53,
|
||||
ColonToken = 54,
|
||||
AtToken = 55,
|
||||
EqualsToken = 56,
|
||||
PlusEqualsToken = 57,
|
||||
MinusEqualsToken = 58,
|
||||
AsteriskEqualsToken = 59,
|
||||
AsteriskAsteriskEqualsToken = 60,
|
||||
SlashEqualsToken = 61,
|
||||
PercentEqualsToken = 62,
|
||||
LessThanLessThanEqualsToken = 63,
|
||||
GreaterThanGreaterThanEqualsToken = 64,
|
||||
GreaterThanGreaterThanGreaterThanEqualsToken = 65,
|
||||
AmpersandEqualsToken = 66,
|
||||
BarEqualsToken = 67,
|
||||
CaretEqualsToken = 68,
|
||||
Identifier = 69,
|
||||
BreakKeyword = 70,
|
||||
CaseKeyword = 71,
|
||||
CatchKeyword = 72,
|
||||
ClassKeyword = 73,
|
||||
ConstKeyword = 74,
|
||||
ContinueKeyword = 75,
|
||||
DebuggerKeyword = 76,
|
||||
DefaultKeyword = 77,
|
||||
DeleteKeyword = 78,
|
||||
DoKeyword = 79,
|
||||
ElseKeyword = 80,
|
||||
EnumKeyword = 81,
|
||||
ExportKeyword = 82,
|
||||
ExtendsKeyword = 83,
|
||||
FalseKeyword = 84,
|
||||
FinallyKeyword = 85,
|
||||
ForKeyword = 86,
|
||||
FunctionKeyword = 87,
|
||||
IfKeyword = 88,
|
||||
ImportKeyword = 89,
|
||||
InKeyword = 90,
|
||||
InstanceOfKeyword = 91,
|
||||
NewKeyword = 92,
|
||||
NullKeyword = 93,
|
||||
ReturnKeyword = 94,
|
||||
SuperKeyword = 95,
|
||||
SwitchKeyword = 96,
|
||||
ThisKeyword = 97,
|
||||
ThrowKeyword = 98,
|
||||
TrueKeyword = 99,
|
||||
TryKeyword = 100,
|
||||
TypeOfKeyword = 101,
|
||||
VarKeyword = 102,
|
||||
VoidKeyword = 103,
|
||||
WhileKeyword = 104,
|
||||
WithKeyword = 105,
|
||||
ImplementsKeyword = 106,
|
||||
InterfaceKeyword = 107,
|
||||
LetKeyword = 108,
|
||||
PackageKeyword = 109,
|
||||
PrivateKeyword = 110,
|
||||
ProtectedKeyword = 111,
|
||||
PublicKeyword = 112,
|
||||
StaticKeyword = 113,
|
||||
YieldKeyword = 114,
|
||||
AbstractKeyword = 115,
|
||||
AsKeyword = 116,
|
||||
AnyKeyword = 117,
|
||||
AsyncKeyword = 118,
|
||||
AwaitKeyword = 119,
|
||||
BooleanKeyword = 120,
|
||||
ConstructorKeyword = 121,
|
||||
DeclareKeyword = 122,
|
||||
GetKeyword = 123,
|
||||
IsKeyword = 124,
|
||||
ModuleKeyword = 125,
|
||||
NamespaceKeyword = 126,
|
||||
NeverKeyword = 127,
|
||||
ReadonlyKeyword = 128,
|
||||
RequireKeyword = 129,
|
||||
NumberKeyword = 130,
|
||||
SetKeyword = 131,
|
||||
StringKeyword = 132,
|
||||
SymbolKeyword = 133,
|
||||
TypeKeyword = 134,
|
||||
UndefinedKeyword = 135,
|
||||
FromKeyword = 136,
|
||||
GlobalKeyword = 137,
|
||||
OfKeyword = 138,
|
||||
QualifiedName = 139,
|
||||
ComputedPropertyName = 140,
|
||||
TypeParameter = 141,
|
||||
Parameter = 142,
|
||||
Decorator = 143,
|
||||
PropertySignature = 144,
|
||||
PropertyDeclaration = 145,
|
||||
MethodSignature = 146,
|
||||
MethodDeclaration = 147,
|
||||
Constructor = 148,
|
||||
GetAccessor = 149,
|
||||
SetAccessor = 150,
|
||||
CallSignature = 151,
|
||||
ConstructSignature = 152,
|
||||
IndexSignature = 153,
|
||||
TypePredicate = 154,
|
||||
TypeReference = 155,
|
||||
FunctionType = 156,
|
||||
ConstructorType = 157,
|
||||
TypeQuery = 158,
|
||||
TypeLiteral = 159,
|
||||
ArrayType = 160,
|
||||
TupleType = 161,
|
||||
UnionType = 162,
|
||||
IntersectionType = 163,
|
||||
ParenthesizedType = 164,
|
||||
ThisType = 165,
|
||||
LiteralType = 166,
|
||||
ObjectBindingPattern = 167,
|
||||
ArrayBindingPattern = 168,
|
||||
BindingElement = 169,
|
||||
ArrayLiteralExpression = 170,
|
||||
ObjectLiteralExpression = 171,
|
||||
PropertyAccessExpression = 172,
|
||||
ElementAccessExpression = 173,
|
||||
CallExpression = 174,
|
||||
NewExpression = 175,
|
||||
TaggedTemplateExpression = 176,
|
||||
TypeAssertionExpression = 177,
|
||||
ParenthesizedExpression = 178,
|
||||
FunctionExpression = 179,
|
||||
ArrowFunction = 180,
|
||||
DeleteExpression = 181,
|
||||
TypeOfExpression = 182,
|
||||
VoidExpression = 183,
|
||||
AwaitExpression = 184,
|
||||
PrefixUnaryExpression = 185,
|
||||
PostfixUnaryExpression = 186,
|
||||
BinaryExpression = 187,
|
||||
ConditionalExpression = 188,
|
||||
TemplateExpression = 189,
|
||||
YieldExpression = 190,
|
||||
SpreadElementExpression = 191,
|
||||
ClassExpression = 192,
|
||||
OmittedExpression = 193,
|
||||
ExpressionWithTypeArguments = 194,
|
||||
AsExpression = 195,
|
||||
NonNullExpression = 196,
|
||||
TemplateSpan = 197,
|
||||
SemicolonClassElement = 198,
|
||||
Block = 199,
|
||||
VariableStatement = 200,
|
||||
EmptyStatement = 201,
|
||||
ExpressionStatement = 202,
|
||||
IfStatement = 203,
|
||||
DoStatement = 204,
|
||||
WhileStatement = 205,
|
||||
ForStatement = 206,
|
||||
ForInStatement = 207,
|
||||
ForOfStatement = 208,
|
||||
ContinueStatement = 209,
|
||||
BreakStatement = 210,
|
||||
ReturnStatement = 211,
|
||||
WithStatement = 212,
|
||||
SwitchStatement = 213,
|
||||
LabeledStatement = 214,
|
||||
ThrowStatement = 215,
|
||||
TryStatement = 216,
|
||||
DebuggerStatement = 217,
|
||||
VariableDeclaration = 218,
|
||||
VariableDeclarationList = 219,
|
||||
FunctionDeclaration = 220,
|
||||
ClassDeclaration = 221,
|
||||
InterfaceDeclaration = 222,
|
||||
TypeAliasDeclaration = 223,
|
||||
EnumDeclaration = 224,
|
||||
ModuleDeclaration = 225,
|
||||
ModuleBlock = 226,
|
||||
CaseBlock = 227,
|
||||
NamespaceExportDeclaration = 228,
|
||||
ImportEqualsDeclaration = 229,
|
||||
ImportDeclaration = 230,
|
||||
ImportClause = 231,
|
||||
NamespaceImport = 232,
|
||||
NamedImports = 233,
|
||||
ImportSpecifier = 234,
|
||||
ExportAssignment = 235,
|
||||
ExportDeclaration = 236,
|
||||
NamedExports = 237,
|
||||
ExportSpecifier = 238,
|
||||
MissingDeclaration = 239,
|
||||
ExternalModuleReference = 240,
|
||||
JsxElement = 241,
|
||||
JsxSelfClosingElement = 242,
|
||||
JsxOpeningElement = 243,
|
||||
JsxText = 244,
|
||||
JsxText = 10,
|
||||
RegularExpressionLiteral = 11,
|
||||
NoSubstitutionTemplateLiteral = 12,
|
||||
TemplateHead = 13,
|
||||
TemplateMiddle = 14,
|
||||
TemplateTail = 15,
|
||||
OpenBraceToken = 16,
|
||||
CloseBraceToken = 17,
|
||||
OpenParenToken = 18,
|
||||
CloseParenToken = 19,
|
||||
OpenBracketToken = 20,
|
||||
CloseBracketToken = 21,
|
||||
DotToken = 22,
|
||||
DotDotDotToken = 23,
|
||||
SemicolonToken = 24,
|
||||
CommaToken = 25,
|
||||
LessThanToken = 26,
|
||||
LessThanSlashToken = 27,
|
||||
GreaterThanToken = 28,
|
||||
LessThanEqualsToken = 29,
|
||||
GreaterThanEqualsToken = 30,
|
||||
EqualsEqualsToken = 31,
|
||||
ExclamationEqualsToken = 32,
|
||||
EqualsEqualsEqualsToken = 33,
|
||||
ExclamationEqualsEqualsToken = 34,
|
||||
EqualsGreaterThanToken = 35,
|
||||
PlusToken = 36,
|
||||
MinusToken = 37,
|
||||
AsteriskToken = 38,
|
||||
AsteriskAsteriskToken = 39,
|
||||
SlashToken = 40,
|
||||
PercentToken = 41,
|
||||
PlusPlusToken = 42,
|
||||
MinusMinusToken = 43,
|
||||
LessThanLessThanToken = 44,
|
||||
GreaterThanGreaterThanToken = 45,
|
||||
GreaterThanGreaterThanGreaterThanToken = 46,
|
||||
AmpersandToken = 47,
|
||||
BarToken = 48,
|
||||
CaretToken = 49,
|
||||
ExclamationToken = 50,
|
||||
TildeToken = 51,
|
||||
AmpersandAmpersandToken = 52,
|
||||
BarBarToken = 53,
|
||||
QuestionToken = 54,
|
||||
ColonToken = 55,
|
||||
AtToken = 56,
|
||||
EqualsToken = 57,
|
||||
PlusEqualsToken = 58,
|
||||
MinusEqualsToken = 59,
|
||||
AsteriskEqualsToken = 60,
|
||||
AsteriskAsteriskEqualsToken = 61,
|
||||
SlashEqualsToken = 62,
|
||||
PercentEqualsToken = 63,
|
||||
LessThanLessThanEqualsToken = 64,
|
||||
GreaterThanGreaterThanEqualsToken = 65,
|
||||
GreaterThanGreaterThanGreaterThanEqualsToken = 66,
|
||||
AmpersandEqualsToken = 67,
|
||||
BarEqualsToken = 68,
|
||||
CaretEqualsToken = 69,
|
||||
Identifier = 70,
|
||||
BreakKeyword = 71,
|
||||
CaseKeyword = 72,
|
||||
CatchKeyword = 73,
|
||||
ClassKeyword = 74,
|
||||
ConstKeyword = 75,
|
||||
ContinueKeyword = 76,
|
||||
DebuggerKeyword = 77,
|
||||
DefaultKeyword = 78,
|
||||
DeleteKeyword = 79,
|
||||
DoKeyword = 80,
|
||||
ElseKeyword = 81,
|
||||
EnumKeyword = 82,
|
||||
ExportKeyword = 83,
|
||||
ExtendsKeyword = 84,
|
||||
FalseKeyword = 85,
|
||||
FinallyKeyword = 86,
|
||||
ForKeyword = 87,
|
||||
FunctionKeyword = 88,
|
||||
IfKeyword = 89,
|
||||
ImportKeyword = 90,
|
||||
InKeyword = 91,
|
||||
InstanceOfKeyword = 92,
|
||||
NewKeyword = 93,
|
||||
NullKeyword = 94,
|
||||
ReturnKeyword = 95,
|
||||
SuperKeyword = 96,
|
||||
SwitchKeyword = 97,
|
||||
ThisKeyword = 98,
|
||||
ThrowKeyword = 99,
|
||||
TrueKeyword = 100,
|
||||
TryKeyword = 101,
|
||||
TypeOfKeyword = 102,
|
||||
VarKeyword = 103,
|
||||
VoidKeyword = 104,
|
||||
WhileKeyword = 105,
|
||||
WithKeyword = 106,
|
||||
ImplementsKeyword = 107,
|
||||
InterfaceKeyword = 108,
|
||||
LetKeyword = 109,
|
||||
PackageKeyword = 110,
|
||||
PrivateKeyword = 111,
|
||||
ProtectedKeyword = 112,
|
||||
PublicKeyword = 113,
|
||||
StaticKeyword = 114,
|
||||
YieldKeyword = 115,
|
||||
AbstractKeyword = 116,
|
||||
AsKeyword = 117,
|
||||
AnyKeyword = 118,
|
||||
AsyncKeyword = 119,
|
||||
AwaitKeyword = 120,
|
||||
BooleanKeyword = 121,
|
||||
ConstructorKeyword = 122,
|
||||
DeclareKeyword = 123,
|
||||
GetKeyword = 124,
|
||||
IsKeyword = 125,
|
||||
ModuleKeyword = 126,
|
||||
NamespaceKeyword = 127,
|
||||
NeverKeyword = 128,
|
||||
ReadonlyKeyword = 129,
|
||||
RequireKeyword = 130,
|
||||
NumberKeyword = 131,
|
||||
SetKeyword = 132,
|
||||
StringKeyword = 133,
|
||||
SymbolKeyword = 134,
|
||||
TypeKeyword = 135,
|
||||
UndefinedKeyword = 136,
|
||||
FromKeyword = 137,
|
||||
GlobalKeyword = 138,
|
||||
OfKeyword = 139,
|
||||
QualifiedName = 140,
|
||||
ComputedPropertyName = 141,
|
||||
TypeParameter = 142,
|
||||
Parameter = 143,
|
||||
Decorator = 144,
|
||||
PropertySignature = 145,
|
||||
PropertyDeclaration = 146,
|
||||
MethodSignature = 147,
|
||||
MethodDeclaration = 148,
|
||||
Constructor = 149,
|
||||
GetAccessor = 150,
|
||||
SetAccessor = 151,
|
||||
CallSignature = 152,
|
||||
ConstructSignature = 153,
|
||||
IndexSignature = 154,
|
||||
TypePredicate = 155,
|
||||
TypeReference = 156,
|
||||
FunctionType = 157,
|
||||
ConstructorType = 158,
|
||||
TypeQuery = 159,
|
||||
TypeLiteral = 160,
|
||||
ArrayType = 161,
|
||||
TupleType = 162,
|
||||
UnionType = 163,
|
||||
IntersectionType = 164,
|
||||
ParenthesizedType = 165,
|
||||
ThisType = 166,
|
||||
LiteralType = 167,
|
||||
ObjectBindingPattern = 168,
|
||||
ArrayBindingPattern = 169,
|
||||
BindingElement = 170,
|
||||
ArrayLiteralExpression = 171,
|
||||
ObjectLiteralExpression = 172,
|
||||
PropertyAccessExpression = 173,
|
||||
ElementAccessExpression = 174,
|
||||
CallExpression = 175,
|
||||
NewExpression = 176,
|
||||
TaggedTemplateExpression = 177,
|
||||
TypeAssertionExpression = 178,
|
||||
ParenthesizedExpression = 179,
|
||||
FunctionExpression = 180,
|
||||
ArrowFunction = 181,
|
||||
DeleteExpression = 182,
|
||||
TypeOfExpression = 183,
|
||||
VoidExpression = 184,
|
||||
AwaitExpression = 185,
|
||||
PrefixUnaryExpression = 186,
|
||||
PostfixUnaryExpression = 187,
|
||||
BinaryExpression = 188,
|
||||
ConditionalExpression = 189,
|
||||
TemplateExpression = 190,
|
||||
YieldExpression = 191,
|
||||
SpreadElementExpression = 192,
|
||||
ClassExpression = 193,
|
||||
OmittedExpression = 194,
|
||||
ExpressionWithTypeArguments = 195,
|
||||
AsExpression = 196,
|
||||
NonNullExpression = 197,
|
||||
TemplateSpan = 198,
|
||||
SemicolonClassElement = 199,
|
||||
Block = 200,
|
||||
VariableStatement = 201,
|
||||
EmptyStatement = 202,
|
||||
ExpressionStatement = 203,
|
||||
IfStatement = 204,
|
||||
DoStatement = 205,
|
||||
WhileStatement = 206,
|
||||
ForStatement = 207,
|
||||
ForInStatement = 208,
|
||||
ForOfStatement = 209,
|
||||
ContinueStatement = 210,
|
||||
BreakStatement = 211,
|
||||
ReturnStatement = 212,
|
||||
WithStatement = 213,
|
||||
SwitchStatement = 214,
|
||||
LabeledStatement = 215,
|
||||
ThrowStatement = 216,
|
||||
TryStatement = 217,
|
||||
DebuggerStatement = 218,
|
||||
VariableDeclaration = 219,
|
||||
VariableDeclarationList = 220,
|
||||
FunctionDeclaration = 221,
|
||||
ClassDeclaration = 222,
|
||||
InterfaceDeclaration = 223,
|
||||
TypeAliasDeclaration = 224,
|
||||
EnumDeclaration = 225,
|
||||
ModuleDeclaration = 226,
|
||||
ModuleBlock = 227,
|
||||
CaseBlock = 228,
|
||||
NamespaceExportDeclaration = 229,
|
||||
ImportEqualsDeclaration = 230,
|
||||
ImportDeclaration = 231,
|
||||
ImportClause = 232,
|
||||
NamespaceImport = 233,
|
||||
NamedImports = 234,
|
||||
ImportSpecifier = 235,
|
||||
ExportAssignment = 236,
|
||||
ExportDeclaration = 237,
|
||||
NamedExports = 238,
|
||||
ExportSpecifier = 239,
|
||||
MissingDeclaration = 240,
|
||||
ExternalModuleReference = 241,
|
||||
JsxElement = 242,
|
||||
JsxSelfClosingElement = 243,
|
||||
JsxOpeningElement = 244,
|
||||
JsxClosingElement = 245,
|
||||
JsxAttribute = 246,
|
||||
JsxSpreadAttribute = 247,
|
||||
@@ -327,31 +327,31 @@ declare namespace ts {
|
||||
NotEmittedStatement = 287,
|
||||
PartiallyEmittedExpression = 288,
|
||||
Count = 289,
|
||||
FirstAssignment = 56,
|
||||
LastAssignment = 68,
|
||||
FirstCompoundAssignment = 57,
|
||||
LastCompoundAssignment = 68,
|
||||
FirstReservedWord = 70,
|
||||
LastReservedWord = 105,
|
||||
FirstKeyword = 70,
|
||||
LastKeyword = 138,
|
||||
FirstFutureReservedWord = 106,
|
||||
LastFutureReservedWord = 114,
|
||||
FirstTypeNode = 154,
|
||||
LastTypeNode = 166,
|
||||
FirstPunctuation = 15,
|
||||
LastPunctuation = 68,
|
||||
FirstAssignment = 57,
|
||||
LastAssignment = 69,
|
||||
FirstCompoundAssignment = 58,
|
||||
LastCompoundAssignment = 69,
|
||||
FirstReservedWord = 71,
|
||||
LastReservedWord = 106,
|
||||
FirstKeyword = 71,
|
||||
LastKeyword = 139,
|
||||
FirstFutureReservedWord = 107,
|
||||
LastFutureReservedWord = 115,
|
||||
FirstTypeNode = 155,
|
||||
LastTypeNode = 167,
|
||||
FirstPunctuation = 16,
|
||||
LastPunctuation = 69,
|
||||
FirstToken = 0,
|
||||
LastToken = 138,
|
||||
LastToken = 139,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
LastLiteralToken = 11,
|
||||
FirstTemplateToken = 11,
|
||||
LastTemplateToken = 14,
|
||||
FirstBinaryOperator = 25,
|
||||
LastBinaryOperator = 68,
|
||||
FirstNode = 139,
|
||||
LastLiteralToken = 12,
|
||||
FirstTemplateToken = 12,
|
||||
LastTemplateToken = 15,
|
||||
FirstBinaryOperator = 26,
|
||||
LastBinaryOperator = 69,
|
||||
FirstNode = 140,
|
||||
FirstJSDocNode = 257,
|
||||
LastJSDocNode = 282,
|
||||
FirstJSDocTagNode = 273,
|
||||
@@ -406,6 +406,7 @@ declare namespace ts {
|
||||
AccessibilityModifier = 28,
|
||||
ParameterPropertyModifier = 92,
|
||||
NonPublicAccessibilityModifier = 24,
|
||||
TypeScriptModifier = 2270,
|
||||
}
|
||||
enum JsxFlags {
|
||||
None = 0,
|
||||
@@ -1351,8 +1352,9 @@ declare namespace ts {
|
||||
TrueCondition = 32,
|
||||
FalseCondition = 64,
|
||||
SwitchClause = 128,
|
||||
Referenced = 256,
|
||||
Shared = 512,
|
||||
ArrayMutation = 256,
|
||||
Referenced = 512,
|
||||
Shared = 1024,
|
||||
Label = 12,
|
||||
Condition = 96,
|
||||
}
|
||||
@@ -1380,6 +1382,10 @@ declare namespace ts {
|
||||
clauseEnd: number;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowArrayMutation extends FlowNode {
|
||||
node: CallExpression | BinaryExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
type FlowType = Type | IncompleteType;
|
||||
interface IncompleteType {
|
||||
flags: TypeFlags;
|
||||
@@ -1913,7 +1919,6 @@ declare namespace ts {
|
||||
AMD = 2,
|
||||
UMD = 3,
|
||||
System = 4,
|
||||
ES6 = 5,
|
||||
ES2015 = 5,
|
||||
}
|
||||
enum JsxEmit {
|
||||
@@ -1939,9 +1944,10 @@ declare namespace ts {
|
||||
enum ScriptTarget {
|
||||
ES3 = 0,
|
||||
ES5 = 1,
|
||||
ES6 = 2,
|
||||
ES2015 = 2,
|
||||
Latest = 2,
|
||||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
Latest = 4,
|
||||
}
|
||||
enum LanguageVariant {
|
||||
Standard = 0,
|
||||
|
||||
+11950
-11233
File diff suppressed because it is too large
Load Diff
Vendored
+267
-261
@@ -47,241 +47,241 @@ declare namespace ts {
|
||||
ConflictMarkerTrivia = 7,
|
||||
NumericLiteral = 8,
|
||||
StringLiteral = 9,
|
||||
RegularExpressionLiteral = 10,
|
||||
NoSubstitutionTemplateLiteral = 11,
|
||||
TemplateHead = 12,
|
||||
TemplateMiddle = 13,
|
||||
TemplateTail = 14,
|
||||
OpenBraceToken = 15,
|
||||
CloseBraceToken = 16,
|
||||
OpenParenToken = 17,
|
||||
CloseParenToken = 18,
|
||||
OpenBracketToken = 19,
|
||||
CloseBracketToken = 20,
|
||||
DotToken = 21,
|
||||
DotDotDotToken = 22,
|
||||
SemicolonToken = 23,
|
||||
CommaToken = 24,
|
||||
LessThanToken = 25,
|
||||
LessThanSlashToken = 26,
|
||||
GreaterThanToken = 27,
|
||||
LessThanEqualsToken = 28,
|
||||
GreaterThanEqualsToken = 29,
|
||||
EqualsEqualsToken = 30,
|
||||
ExclamationEqualsToken = 31,
|
||||
EqualsEqualsEqualsToken = 32,
|
||||
ExclamationEqualsEqualsToken = 33,
|
||||
EqualsGreaterThanToken = 34,
|
||||
PlusToken = 35,
|
||||
MinusToken = 36,
|
||||
AsteriskToken = 37,
|
||||
AsteriskAsteriskToken = 38,
|
||||
SlashToken = 39,
|
||||
PercentToken = 40,
|
||||
PlusPlusToken = 41,
|
||||
MinusMinusToken = 42,
|
||||
LessThanLessThanToken = 43,
|
||||
GreaterThanGreaterThanToken = 44,
|
||||
GreaterThanGreaterThanGreaterThanToken = 45,
|
||||
AmpersandToken = 46,
|
||||
BarToken = 47,
|
||||
CaretToken = 48,
|
||||
ExclamationToken = 49,
|
||||
TildeToken = 50,
|
||||
AmpersandAmpersandToken = 51,
|
||||
BarBarToken = 52,
|
||||
QuestionToken = 53,
|
||||
ColonToken = 54,
|
||||
AtToken = 55,
|
||||
EqualsToken = 56,
|
||||
PlusEqualsToken = 57,
|
||||
MinusEqualsToken = 58,
|
||||
AsteriskEqualsToken = 59,
|
||||
AsteriskAsteriskEqualsToken = 60,
|
||||
SlashEqualsToken = 61,
|
||||
PercentEqualsToken = 62,
|
||||
LessThanLessThanEqualsToken = 63,
|
||||
GreaterThanGreaterThanEqualsToken = 64,
|
||||
GreaterThanGreaterThanGreaterThanEqualsToken = 65,
|
||||
AmpersandEqualsToken = 66,
|
||||
BarEqualsToken = 67,
|
||||
CaretEqualsToken = 68,
|
||||
Identifier = 69,
|
||||
BreakKeyword = 70,
|
||||
CaseKeyword = 71,
|
||||
CatchKeyword = 72,
|
||||
ClassKeyword = 73,
|
||||
ConstKeyword = 74,
|
||||
ContinueKeyword = 75,
|
||||
DebuggerKeyword = 76,
|
||||
DefaultKeyword = 77,
|
||||
DeleteKeyword = 78,
|
||||
DoKeyword = 79,
|
||||
ElseKeyword = 80,
|
||||
EnumKeyword = 81,
|
||||
ExportKeyword = 82,
|
||||
ExtendsKeyword = 83,
|
||||
FalseKeyword = 84,
|
||||
FinallyKeyword = 85,
|
||||
ForKeyword = 86,
|
||||
FunctionKeyword = 87,
|
||||
IfKeyword = 88,
|
||||
ImportKeyword = 89,
|
||||
InKeyword = 90,
|
||||
InstanceOfKeyword = 91,
|
||||
NewKeyword = 92,
|
||||
NullKeyword = 93,
|
||||
ReturnKeyword = 94,
|
||||
SuperKeyword = 95,
|
||||
SwitchKeyword = 96,
|
||||
ThisKeyword = 97,
|
||||
ThrowKeyword = 98,
|
||||
TrueKeyword = 99,
|
||||
TryKeyword = 100,
|
||||
TypeOfKeyword = 101,
|
||||
VarKeyword = 102,
|
||||
VoidKeyword = 103,
|
||||
WhileKeyword = 104,
|
||||
WithKeyword = 105,
|
||||
ImplementsKeyword = 106,
|
||||
InterfaceKeyword = 107,
|
||||
LetKeyword = 108,
|
||||
PackageKeyword = 109,
|
||||
PrivateKeyword = 110,
|
||||
ProtectedKeyword = 111,
|
||||
PublicKeyword = 112,
|
||||
StaticKeyword = 113,
|
||||
YieldKeyword = 114,
|
||||
AbstractKeyword = 115,
|
||||
AsKeyword = 116,
|
||||
AnyKeyword = 117,
|
||||
AsyncKeyword = 118,
|
||||
AwaitKeyword = 119,
|
||||
BooleanKeyword = 120,
|
||||
ConstructorKeyword = 121,
|
||||
DeclareKeyword = 122,
|
||||
GetKeyword = 123,
|
||||
IsKeyword = 124,
|
||||
ModuleKeyword = 125,
|
||||
NamespaceKeyword = 126,
|
||||
NeverKeyword = 127,
|
||||
ReadonlyKeyword = 128,
|
||||
RequireKeyword = 129,
|
||||
NumberKeyword = 130,
|
||||
SetKeyword = 131,
|
||||
StringKeyword = 132,
|
||||
SymbolKeyword = 133,
|
||||
TypeKeyword = 134,
|
||||
UndefinedKeyword = 135,
|
||||
FromKeyword = 136,
|
||||
GlobalKeyword = 137,
|
||||
OfKeyword = 138,
|
||||
QualifiedName = 139,
|
||||
ComputedPropertyName = 140,
|
||||
TypeParameter = 141,
|
||||
Parameter = 142,
|
||||
Decorator = 143,
|
||||
PropertySignature = 144,
|
||||
PropertyDeclaration = 145,
|
||||
MethodSignature = 146,
|
||||
MethodDeclaration = 147,
|
||||
Constructor = 148,
|
||||
GetAccessor = 149,
|
||||
SetAccessor = 150,
|
||||
CallSignature = 151,
|
||||
ConstructSignature = 152,
|
||||
IndexSignature = 153,
|
||||
TypePredicate = 154,
|
||||
TypeReference = 155,
|
||||
FunctionType = 156,
|
||||
ConstructorType = 157,
|
||||
TypeQuery = 158,
|
||||
TypeLiteral = 159,
|
||||
ArrayType = 160,
|
||||
TupleType = 161,
|
||||
UnionType = 162,
|
||||
IntersectionType = 163,
|
||||
ParenthesizedType = 164,
|
||||
ThisType = 165,
|
||||
LiteralType = 166,
|
||||
ObjectBindingPattern = 167,
|
||||
ArrayBindingPattern = 168,
|
||||
BindingElement = 169,
|
||||
ArrayLiteralExpression = 170,
|
||||
ObjectLiteralExpression = 171,
|
||||
PropertyAccessExpression = 172,
|
||||
ElementAccessExpression = 173,
|
||||
CallExpression = 174,
|
||||
NewExpression = 175,
|
||||
TaggedTemplateExpression = 176,
|
||||
TypeAssertionExpression = 177,
|
||||
ParenthesizedExpression = 178,
|
||||
FunctionExpression = 179,
|
||||
ArrowFunction = 180,
|
||||
DeleteExpression = 181,
|
||||
TypeOfExpression = 182,
|
||||
VoidExpression = 183,
|
||||
AwaitExpression = 184,
|
||||
PrefixUnaryExpression = 185,
|
||||
PostfixUnaryExpression = 186,
|
||||
BinaryExpression = 187,
|
||||
ConditionalExpression = 188,
|
||||
TemplateExpression = 189,
|
||||
YieldExpression = 190,
|
||||
SpreadElementExpression = 191,
|
||||
ClassExpression = 192,
|
||||
OmittedExpression = 193,
|
||||
ExpressionWithTypeArguments = 194,
|
||||
AsExpression = 195,
|
||||
NonNullExpression = 196,
|
||||
TemplateSpan = 197,
|
||||
SemicolonClassElement = 198,
|
||||
Block = 199,
|
||||
VariableStatement = 200,
|
||||
EmptyStatement = 201,
|
||||
ExpressionStatement = 202,
|
||||
IfStatement = 203,
|
||||
DoStatement = 204,
|
||||
WhileStatement = 205,
|
||||
ForStatement = 206,
|
||||
ForInStatement = 207,
|
||||
ForOfStatement = 208,
|
||||
ContinueStatement = 209,
|
||||
BreakStatement = 210,
|
||||
ReturnStatement = 211,
|
||||
WithStatement = 212,
|
||||
SwitchStatement = 213,
|
||||
LabeledStatement = 214,
|
||||
ThrowStatement = 215,
|
||||
TryStatement = 216,
|
||||
DebuggerStatement = 217,
|
||||
VariableDeclaration = 218,
|
||||
VariableDeclarationList = 219,
|
||||
FunctionDeclaration = 220,
|
||||
ClassDeclaration = 221,
|
||||
InterfaceDeclaration = 222,
|
||||
TypeAliasDeclaration = 223,
|
||||
EnumDeclaration = 224,
|
||||
ModuleDeclaration = 225,
|
||||
ModuleBlock = 226,
|
||||
CaseBlock = 227,
|
||||
NamespaceExportDeclaration = 228,
|
||||
ImportEqualsDeclaration = 229,
|
||||
ImportDeclaration = 230,
|
||||
ImportClause = 231,
|
||||
NamespaceImport = 232,
|
||||
NamedImports = 233,
|
||||
ImportSpecifier = 234,
|
||||
ExportAssignment = 235,
|
||||
ExportDeclaration = 236,
|
||||
NamedExports = 237,
|
||||
ExportSpecifier = 238,
|
||||
MissingDeclaration = 239,
|
||||
ExternalModuleReference = 240,
|
||||
JsxElement = 241,
|
||||
JsxSelfClosingElement = 242,
|
||||
JsxOpeningElement = 243,
|
||||
JsxText = 244,
|
||||
JsxText = 10,
|
||||
RegularExpressionLiteral = 11,
|
||||
NoSubstitutionTemplateLiteral = 12,
|
||||
TemplateHead = 13,
|
||||
TemplateMiddle = 14,
|
||||
TemplateTail = 15,
|
||||
OpenBraceToken = 16,
|
||||
CloseBraceToken = 17,
|
||||
OpenParenToken = 18,
|
||||
CloseParenToken = 19,
|
||||
OpenBracketToken = 20,
|
||||
CloseBracketToken = 21,
|
||||
DotToken = 22,
|
||||
DotDotDotToken = 23,
|
||||
SemicolonToken = 24,
|
||||
CommaToken = 25,
|
||||
LessThanToken = 26,
|
||||
LessThanSlashToken = 27,
|
||||
GreaterThanToken = 28,
|
||||
LessThanEqualsToken = 29,
|
||||
GreaterThanEqualsToken = 30,
|
||||
EqualsEqualsToken = 31,
|
||||
ExclamationEqualsToken = 32,
|
||||
EqualsEqualsEqualsToken = 33,
|
||||
ExclamationEqualsEqualsToken = 34,
|
||||
EqualsGreaterThanToken = 35,
|
||||
PlusToken = 36,
|
||||
MinusToken = 37,
|
||||
AsteriskToken = 38,
|
||||
AsteriskAsteriskToken = 39,
|
||||
SlashToken = 40,
|
||||
PercentToken = 41,
|
||||
PlusPlusToken = 42,
|
||||
MinusMinusToken = 43,
|
||||
LessThanLessThanToken = 44,
|
||||
GreaterThanGreaterThanToken = 45,
|
||||
GreaterThanGreaterThanGreaterThanToken = 46,
|
||||
AmpersandToken = 47,
|
||||
BarToken = 48,
|
||||
CaretToken = 49,
|
||||
ExclamationToken = 50,
|
||||
TildeToken = 51,
|
||||
AmpersandAmpersandToken = 52,
|
||||
BarBarToken = 53,
|
||||
QuestionToken = 54,
|
||||
ColonToken = 55,
|
||||
AtToken = 56,
|
||||
EqualsToken = 57,
|
||||
PlusEqualsToken = 58,
|
||||
MinusEqualsToken = 59,
|
||||
AsteriskEqualsToken = 60,
|
||||
AsteriskAsteriskEqualsToken = 61,
|
||||
SlashEqualsToken = 62,
|
||||
PercentEqualsToken = 63,
|
||||
LessThanLessThanEqualsToken = 64,
|
||||
GreaterThanGreaterThanEqualsToken = 65,
|
||||
GreaterThanGreaterThanGreaterThanEqualsToken = 66,
|
||||
AmpersandEqualsToken = 67,
|
||||
BarEqualsToken = 68,
|
||||
CaretEqualsToken = 69,
|
||||
Identifier = 70,
|
||||
BreakKeyword = 71,
|
||||
CaseKeyword = 72,
|
||||
CatchKeyword = 73,
|
||||
ClassKeyword = 74,
|
||||
ConstKeyword = 75,
|
||||
ContinueKeyword = 76,
|
||||
DebuggerKeyword = 77,
|
||||
DefaultKeyword = 78,
|
||||
DeleteKeyword = 79,
|
||||
DoKeyword = 80,
|
||||
ElseKeyword = 81,
|
||||
EnumKeyword = 82,
|
||||
ExportKeyword = 83,
|
||||
ExtendsKeyword = 84,
|
||||
FalseKeyword = 85,
|
||||
FinallyKeyword = 86,
|
||||
ForKeyword = 87,
|
||||
FunctionKeyword = 88,
|
||||
IfKeyword = 89,
|
||||
ImportKeyword = 90,
|
||||
InKeyword = 91,
|
||||
InstanceOfKeyword = 92,
|
||||
NewKeyword = 93,
|
||||
NullKeyword = 94,
|
||||
ReturnKeyword = 95,
|
||||
SuperKeyword = 96,
|
||||
SwitchKeyword = 97,
|
||||
ThisKeyword = 98,
|
||||
ThrowKeyword = 99,
|
||||
TrueKeyword = 100,
|
||||
TryKeyword = 101,
|
||||
TypeOfKeyword = 102,
|
||||
VarKeyword = 103,
|
||||
VoidKeyword = 104,
|
||||
WhileKeyword = 105,
|
||||
WithKeyword = 106,
|
||||
ImplementsKeyword = 107,
|
||||
InterfaceKeyword = 108,
|
||||
LetKeyword = 109,
|
||||
PackageKeyword = 110,
|
||||
PrivateKeyword = 111,
|
||||
ProtectedKeyword = 112,
|
||||
PublicKeyword = 113,
|
||||
StaticKeyword = 114,
|
||||
YieldKeyword = 115,
|
||||
AbstractKeyword = 116,
|
||||
AsKeyword = 117,
|
||||
AnyKeyword = 118,
|
||||
AsyncKeyword = 119,
|
||||
AwaitKeyword = 120,
|
||||
BooleanKeyword = 121,
|
||||
ConstructorKeyword = 122,
|
||||
DeclareKeyword = 123,
|
||||
GetKeyword = 124,
|
||||
IsKeyword = 125,
|
||||
ModuleKeyword = 126,
|
||||
NamespaceKeyword = 127,
|
||||
NeverKeyword = 128,
|
||||
ReadonlyKeyword = 129,
|
||||
RequireKeyword = 130,
|
||||
NumberKeyword = 131,
|
||||
SetKeyword = 132,
|
||||
StringKeyword = 133,
|
||||
SymbolKeyword = 134,
|
||||
TypeKeyword = 135,
|
||||
UndefinedKeyword = 136,
|
||||
FromKeyword = 137,
|
||||
GlobalKeyword = 138,
|
||||
OfKeyword = 139,
|
||||
QualifiedName = 140,
|
||||
ComputedPropertyName = 141,
|
||||
TypeParameter = 142,
|
||||
Parameter = 143,
|
||||
Decorator = 144,
|
||||
PropertySignature = 145,
|
||||
PropertyDeclaration = 146,
|
||||
MethodSignature = 147,
|
||||
MethodDeclaration = 148,
|
||||
Constructor = 149,
|
||||
GetAccessor = 150,
|
||||
SetAccessor = 151,
|
||||
CallSignature = 152,
|
||||
ConstructSignature = 153,
|
||||
IndexSignature = 154,
|
||||
TypePredicate = 155,
|
||||
TypeReference = 156,
|
||||
FunctionType = 157,
|
||||
ConstructorType = 158,
|
||||
TypeQuery = 159,
|
||||
TypeLiteral = 160,
|
||||
ArrayType = 161,
|
||||
TupleType = 162,
|
||||
UnionType = 163,
|
||||
IntersectionType = 164,
|
||||
ParenthesizedType = 165,
|
||||
ThisType = 166,
|
||||
LiteralType = 167,
|
||||
ObjectBindingPattern = 168,
|
||||
ArrayBindingPattern = 169,
|
||||
BindingElement = 170,
|
||||
ArrayLiteralExpression = 171,
|
||||
ObjectLiteralExpression = 172,
|
||||
PropertyAccessExpression = 173,
|
||||
ElementAccessExpression = 174,
|
||||
CallExpression = 175,
|
||||
NewExpression = 176,
|
||||
TaggedTemplateExpression = 177,
|
||||
TypeAssertionExpression = 178,
|
||||
ParenthesizedExpression = 179,
|
||||
FunctionExpression = 180,
|
||||
ArrowFunction = 181,
|
||||
DeleteExpression = 182,
|
||||
TypeOfExpression = 183,
|
||||
VoidExpression = 184,
|
||||
AwaitExpression = 185,
|
||||
PrefixUnaryExpression = 186,
|
||||
PostfixUnaryExpression = 187,
|
||||
BinaryExpression = 188,
|
||||
ConditionalExpression = 189,
|
||||
TemplateExpression = 190,
|
||||
YieldExpression = 191,
|
||||
SpreadElementExpression = 192,
|
||||
ClassExpression = 193,
|
||||
OmittedExpression = 194,
|
||||
ExpressionWithTypeArguments = 195,
|
||||
AsExpression = 196,
|
||||
NonNullExpression = 197,
|
||||
TemplateSpan = 198,
|
||||
SemicolonClassElement = 199,
|
||||
Block = 200,
|
||||
VariableStatement = 201,
|
||||
EmptyStatement = 202,
|
||||
ExpressionStatement = 203,
|
||||
IfStatement = 204,
|
||||
DoStatement = 205,
|
||||
WhileStatement = 206,
|
||||
ForStatement = 207,
|
||||
ForInStatement = 208,
|
||||
ForOfStatement = 209,
|
||||
ContinueStatement = 210,
|
||||
BreakStatement = 211,
|
||||
ReturnStatement = 212,
|
||||
WithStatement = 213,
|
||||
SwitchStatement = 214,
|
||||
LabeledStatement = 215,
|
||||
ThrowStatement = 216,
|
||||
TryStatement = 217,
|
||||
DebuggerStatement = 218,
|
||||
VariableDeclaration = 219,
|
||||
VariableDeclarationList = 220,
|
||||
FunctionDeclaration = 221,
|
||||
ClassDeclaration = 222,
|
||||
InterfaceDeclaration = 223,
|
||||
TypeAliasDeclaration = 224,
|
||||
EnumDeclaration = 225,
|
||||
ModuleDeclaration = 226,
|
||||
ModuleBlock = 227,
|
||||
CaseBlock = 228,
|
||||
NamespaceExportDeclaration = 229,
|
||||
ImportEqualsDeclaration = 230,
|
||||
ImportDeclaration = 231,
|
||||
ImportClause = 232,
|
||||
NamespaceImport = 233,
|
||||
NamedImports = 234,
|
||||
ImportSpecifier = 235,
|
||||
ExportAssignment = 236,
|
||||
ExportDeclaration = 237,
|
||||
NamedExports = 238,
|
||||
ExportSpecifier = 239,
|
||||
MissingDeclaration = 240,
|
||||
ExternalModuleReference = 241,
|
||||
JsxElement = 242,
|
||||
JsxSelfClosingElement = 243,
|
||||
JsxOpeningElement = 244,
|
||||
JsxClosingElement = 245,
|
||||
JsxAttribute = 246,
|
||||
JsxSpreadAttribute = 247,
|
||||
@@ -327,31 +327,31 @@ declare namespace ts {
|
||||
NotEmittedStatement = 287,
|
||||
PartiallyEmittedExpression = 288,
|
||||
Count = 289,
|
||||
FirstAssignment = 56,
|
||||
LastAssignment = 68,
|
||||
FirstCompoundAssignment = 57,
|
||||
LastCompoundAssignment = 68,
|
||||
FirstReservedWord = 70,
|
||||
LastReservedWord = 105,
|
||||
FirstKeyword = 70,
|
||||
LastKeyword = 138,
|
||||
FirstFutureReservedWord = 106,
|
||||
LastFutureReservedWord = 114,
|
||||
FirstTypeNode = 154,
|
||||
LastTypeNode = 166,
|
||||
FirstPunctuation = 15,
|
||||
LastPunctuation = 68,
|
||||
FirstAssignment = 57,
|
||||
LastAssignment = 69,
|
||||
FirstCompoundAssignment = 58,
|
||||
LastCompoundAssignment = 69,
|
||||
FirstReservedWord = 71,
|
||||
LastReservedWord = 106,
|
||||
FirstKeyword = 71,
|
||||
LastKeyword = 139,
|
||||
FirstFutureReservedWord = 107,
|
||||
LastFutureReservedWord = 115,
|
||||
FirstTypeNode = 155,
|
||||
LastTypeNode = 167,
|
||||
FirstPunctuation = 16,
|
||||
LastPunctuation = 69,
|
||||
FirstToken = 0,
|
||||
LastToken = 138,
|
||||
LastToken = 139,
|
||||
FirstTriviaToken = 2,
|
||||
LastTriviaToken = 7,
|
||||
FirstLiteralToken = 8,
|
||||
LastLiteralToken = 11,
|
||||
FirstTemplateToken = 11,
|
||||
LastTemplateToken = 14,
|
||||
FirstBinaryOperator = 25,
|
||||
LastBinaryOperator = 68,
|
||||
FirstNode = 139,
|
||||
LastLiteralToken = 12,
|
||||
FirstTemplateToken = 12,
|
||||
LastTemplateToken = 15,
|
||||
FirstBinaryOperator = 26,
|
||||
LastBinaryOperator = 69,
|
||||
FirstNode = 140,
|
||||
FirstJSDocNode = 257,
|
||||
LastJSDocNode = 282,
|
||||
FirstJSDocTagNode = 273,
|
||||
@@ -406,6 +406,7 @@ declare namespace ts {
|
||||
AccessibilityModifier = 28,
|
||||
ParameterPropertyModifier = 92,
|
||||
NonPublicAccessibilityModifier = 24,
|
||||
TypeScriptModifier = 2270,
|
||||
}
|
||||
enum JsxFlags {
|
||||
None = 0,
|
||||
@@ -1351,8 +1352,9 @@ declare namespace ts {
|
||||
TrueCondition = 32,
|
||||
FalseCondition = 64,
|
||||
SwitchClause = 128,
|
||||
Referenced = 256,
|
||||
Shared = 512,
|
||||
ArrayMutation = 256,
|
||||
Referenced = 512,
|
||||
Shared = 1024,
|
||||
Label = 12,
|
||||
Condition = 96,
|
||||
}
|
||||
@@ -1380,6 +1382,10 @@ declare namespace ts {
|
||||
clauseEnd: number;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
interface FlowArrayMutation extends FlowNode {
|
||||
node: CallExpression | BinaryExpression;
|
||||
antecedent: FlowNode;
|
||||
}
|
||||
type FlowType = Type | IncompleteType;
|
||||
interface IncompleteType {
|
||||
flags: TypeFlags;
|
||||
@@ -1913,7 +1919,6 @@ declare namespace ts {
|
||||
AMD = 2,
|
||||
UMD = 3,
|
||||
System = 4,
|
||||
ES6 = 5,
|
||||
ES2015 = 5,
|
||||
}
|
||||
enum JsxEmit {
|
||||
@@ -1939,9 +1944,10 @@ declare namespace ts {
|
||||
enum ScriptTarget {
|
||||
ES3 = 0,
|
||||
ES5 = 1,
|
||||
ES6 = 2,
|
||||
ES2015 = 2,
|
||||
Latest = 2,
|
||||
ES2016 = 3,
|
||||
ES2017 = 4,
|
||||
Latest = 4,
|
||||
}
|
||||
enum LanguageVariant {
|
||||
Standard = 0,
|
||||
|
||||
+11950
-11233
File diff suppressed because it is too large
Load Diff
+1280
-320
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,22 @@
|
||||
// Import the utility functionality.
|
||||
import jobs.generation.Utilities;
|
||||
|
||||
// Defines a the new of the repo, used elsewhere in the file
|
||||
def project = GithubProject
|
||||
def branch = GithubBranchName
|
||||
|
||||
def nodeVersions = ['stable', '4']
|
||||
|
||||
nodeVersions.each { nodeVer ->
|
||||
|
||||
def newJobName = "typescript_node.${nodeVer}"
|
||||
def newJob = job(Utilities.getFullJobName(project, newJobName, true)) {
|
||||
steps {
|
||||
shell("./jenkins.sh ${nodeVer}")
|
||||
}
|
||||
}
|
||||
|
||||
Utilities.standardJobSetup(newJob, project, true, "*/${branch}")
|
||||
Utilities.setMachineAffinity(newJob, 'Ubuntu', '20161020')
|
||||
Utilities.addGithubPRTriggerForBranch(newJob, branch, "TypeScript Test Run ${newJobName}")
|
||||
}
|
||||
+1
-1
@@ -76,7 +76,7 @@
|
||||
"travis-fold": "latest",
|
||||
"ts-node": "latest",
|
||||
"tsd": "latest",
|
||||
"tslint": "next",
|
||||
"tslint": "4.0.0-dev.0",
|
||||
"typescript": "next"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
+52
-17
@@ -10,6 +10,8 @@ function endsWith(s: string, suffix: string) {
|
||||
class DeclarationsWalker {
|
||||
private visitedTypes: ts.Type[] = [];
|
||||
private text = "";
|
||||
private removedTypes: ts.Type[] = [];
|
||||
|
||||
private constructor(private typeChecker: ts.TypeChecker, private protocolFile: ts.SourceFile) {
|
||||
}
|
||||
|
||||
@@ -17,9 +19,18 @@ class DeclarationsWalker {
|
||||
let text = "declare namespace ts.server.protocol {\n";
|
||||
var walker = new DeclarationsWalker(typeChecker, protocolFile);
|
||||
walker.visitTypeNodes(protocolFile);
|
||||
return walker.text
|
||||
text = walker.text
|
||||
? `declare namespace ts.server.protocol {\n${walker.text}}`
|
||||
: "";
|
||||
if (walker.removedTypes) {
|
||||
text += "\ndeclare namespace ts {\n";
|
||||
text += " // these types are empty stubs for types from services and should not be used directly\n"
|
||||
for (const type of walker.removedTypes) {
|
||||
text += ` export type ${type.symbol.name} = never;\n`;
|
||||
}
|
||||
text += "}"
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private processType(type: ts.Type): void {
|
||||
@@ -41,19 +52,18 @@ class DeclarationsWalker {
|
||||
if (sourceFile === this.protocolFile || path.basename(sourceFile.fileName) === "lib.d.ts") {
|
||||
return;
|
||||
}
|
||||
// splice declaration in final d.ts file
|
||||
let text = decl.getFullText();
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration && !(decl.flags & ts.NodeFlags.Const)) {
|
||||
// patch enum declaration to make them constan
|
||||
const declStart = decl.getStart() - decl.getFullStart();
|
||||
const prefix = text.substring(0, declStart);
|
||||
const suffix = text.substring(declStart + "enum".length, decl.getEnd() - decl.getFullStart());
|
||||
text = prefix + "const enum" + suffix;
|
||||
if (decl.kind === ts.SyntaxKind.EnumDeclaration) {
|
||||
this.removedTypes.push(type);
|
||||
return;
|
||||
}
|
||||
this.text += `${text}\n`;
|
||||
else {
|
||||
// splice declaration in final d.ts file
|
||||
let text = decl.getFullText();
|
||||
this.text += `${text}\n`;
|
||||
// recursively pull all dependencies into result dts file
|
||||
|
||||
// recursively pull all dependencies into result dts file
|
||||
this.visitTypeNodes(decl);
|
||||
this.visitTypeNodes(decl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -69,15 +79,37 @@ class DeclarationsWalker {
|
||||
case ts.SyntaxKind.Parameter:
|
||||
case ts.SyntaxKind.IndexSignature:
|
||||
if (((<ts.VariableDeclaration | ts.MethodDeclaration | ts.PropertyDeclaration | ts.ParameterDeclaration | ts.PropertySignature | ts.MethodSignature | ts.IndexSignatureDeclaration>node.parent).type) === node) {
|
||||
const type = this.typeChecker.getTypeAtLocation(node);
|
||||
if (type && !(type.flags & ts.TypeFlags.TypeParameter)) {
|
||||
this.processType(type);
|
||||
}
|
||||
this.processTypeOfNode(node);
|
||||
}
|
||||
break;
|
||||
case ts.SyntaxKind.InterfaceDeclaration:
|
||||
const heritageClauses = (<ts.InterfaceDeclaration>node.parent).heritageClauses;
|
||||
if (heritageClauses) {
|
||||
if (heritageClauses[0].token !== ts.SyntaxKind.ExtendsKeyword) {
|
||||
throw new Error(`Unexpected kind of heritage clause: ${ts.SyntaxKind[heritageClauses[0].kind]}`);
|
||||
}
|
||||
for (const type of heritageClauses[0].types) {
|
||||
this.processTypeOfNode(type);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ts.forEachChild(node, n => this.visitTypeNodes(n));
|
||||
}
|
||||
|
||||
private processTypeOfNode(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.UnionType) {
|
||||
for (const t of (<ts.UnionTypeNode>node).types) {
|
||||
this.processTypeOfNode(t);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const type = this.typeChecker.getTypeAtLocation(node);
|
||||
if (type && !(type.flags & (ts.TypeFlags.TypeParameter))) {
|
||||
this.processType(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,9 +160,12 @@ function generateProtocolFile(protocolTs: string, typeScriptServicesDts: string)
|
||||
if (extraDeclarations) {
|
||||
protocolDts += extraDeclarations;
|
||||
}
|
||||
protocolDts += "\nimport protocol = ts.server.protocol;";
|
||||
protocolDts += "\nexport = protocol;";
|
||||
protocolDts += "\nexport as namespace protocol;";
|
||||
// do sanity check and try to compile generated text as standalone program
|
||||
const sanityCheckProgram = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ false);
|
||||
const diagnostics = [...program.getSyntacticDiagnostics(), ...program.getSemanticDiagnostics(), ...program.getGlobalDiagnostics()];
|
||||
const diagnostics = [...sanityCheckProgram.getSyntacticDiagnostics(), ...sanityCheckProgram.getSemanticDiagnostics(), ...sanityCheckProgram.getGlobalDiagnostics()];
|
||||
if (diagnostics.length) {
|
||||
const flattenedDiagnostics = diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, "\n")).join("\n");
|
||||
throw new Error(`Unexpected errors during sanity check: ${flattenedDiagnostics}`);
|
||||
|
||||
+94
-37
@@ -54,6 +54,11 @@ namespace ts {
|
||||
const body = (<ModuleDeclaration>node).body;
|
||||
return body ? getModuleInstanceState(body) : ModuleInstanceState.Instantiated;
|
||||
}
|
||||
// Only jsdoc typedef definition can exist in jsdoc namespace, and it should
|
||||
// be considered the same as type alias
|
||||
else if (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace) {
|
||||
return ModuleInstanceState.NonInstantiated;
|
||||
}
|
||||
else {
|
||||
return ModuleInstanceState.Instantiated;
|
||||
}
|
||||
@@ -429,7 +434,11 @@ namespace ts {
|
||||
// during global merging in the checker. Why? The only case when ambient module is permitted inside another module is module augmentation
|
||||
// and this case is specially handled. Module augmentations should only be merged with original module definition
|
||||
// and should never be merged directly with other augmentation, and the latter case would be possible if automatic merge is allowed.
|
||||
if (!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) {
|
||||
const isJSDocTypedefInJSDocNamespace = node.kind === SyntaxKind.JSDocTypedefTag &&
|
||||
node.name &&
|
||||
node.name.kind === SyntaxKind.Identifier &&
|
||||
(<Identifier>node.name).isInJSDocNamespace;
|
||||
if ((!isAmbientModule(node) && (hasExportModifier || container.flags & NodeFlags.ExportContext)) || isJSDocTypedefInJSDocNamespace) {
|
||||
const exportKind =
|
||||
(symbolFlags & SymbolFlags.Value ? SymbolFlags.ExportValue : 0) |
|
||||
(symbolFlags & SymbolFlags.Type ? SymbolFlags.ExportType : 0) |
|
||||
@@ -490,8 +499,8 @@ namespace ts {
|
||||
const saveReturnTarget = currentReturnTarget;
|
||||
const saveActiveLabels = activeLabels;
|
||||
const saveHasExplicitReturn = hasExplicitReturn;
|
||||
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !!getImmediatelyInvokedFunctionExpression(node);
|
||||
// An IIFE is considered part of the containing control flow. Return statements behave
|
||||
const isIIFE = containerFlags & ContainerFlags.IsFunctionExpression && !hasModifier(node, ModifierFlags.Async) && !!getImmediatelyInvokedFunctionExpression(node);
|
||||
// A non-async IIFE is considered part of the containing control flow. Return statements behave
|
||||
// similarly to break statements that exit to a label just past the statement body.
|
||||
if (isIIFE) {
|
||||
currentReturnTarget = createBranchLabel();
|
||||
@@ -883,8 +892,13 @@ namespace ts {
|
||||
|
||||
function bindDoStatement(node: DoStatement): void {
|
||||
const preDoLabel = createLoopLabel();
|
||||
const preConditionLabel = createBranchLabel();
|
||||
const postDoLabel = createBranchLabel();
|
||||
const enclosingLabeledStatement = node.parent.kind === SyntaxKind.LabeledStatement
|
||||
? lastOrUndefined(activeLabels)
|
||||
: undefined;
|
||||
// if do statement is wrapped in labeled statement then target labels for break/continue with or without
|
||||
// label should be the same
|
||||
const preConditionLabel = enclosingLabeledStatement ? enclosingLabeledStatement.continueTarget : createBranchLabel();
|
||||
const postDoLabel = enclosingLabeledStatement ? enclosingLabeledStatement.breakTarget : createBranchLabel();
|
||||
addAntecedent(preDoLabel, currentFlow);
|
||||
currentFlow = preDoLabel;
|
||||
bindIterativeStatement(node.statement, postDoLabel, preConditionLabel);
|
||||
@@ -984,24 +998,44 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindTryStatement(node: TryStatement): void {
|
||||
const postFinallyLabel = createBranchLabel();
|
||||
const preFinallyLabel = createBranchLabel();
|
||||
const preTryFlow = currentFlow;
|
||||
// TODO: Every statement in try block is potentially an exit point!
|
||||
bind(node.tryBlock);
|
||||
addAntecedent(postFinallyLabel, currentFlow);
|
||||
addAntecedent(preFinallyLabel, currentFlow);
|
||||
|
||||
const flowAfterTry = currentFlow;
|
||||
let flowAfterCatch = unreachableFlow;
|
||||
|
||||
if (node.catchClause) {
|
||||
currentFlow = preTryFlow;
|
||||
bind(node.catchClause);
|
||||
addAntecedent(postFinallyLabel, currentFlow);
|
||||
addAntecedent(preFinallyLabel, currentFlow);
|
||||
|
||||
flowAfterCatch = currentFlow;
|
||||
}
|
||||
if (node.finallyBlock) {
|
||||
currentFlow = preTryFlow;
|
||||
// in finally flow is combined from pre-try/flow from try/flow from catch
|
||||
// pre-flow is necessary to make sure that finally is reachable even if finally flows in both try and finally blocks are unreachable
|
||||
addAntecedent(preFinallyLabel, preTryFlow);
|
||||
currentFlow = finishFlowLabel(preFinallyLabel);
|
||||
bind(node.finallyBlock);
|
||||
// if flow after finally is unreachable - keep it
|
||||
// otherwise check if flows after try and after catch are unreachable
|
||||
// if yes - convert current flow to unreachable
|
||||
// i.e.
|
||||
// try { return "1" } finally { console.log(1); }
|
||||
// console.log(2); // this line should be unreachable even if flow falls out of finally block
|
||||
if (!(currentFlow.flags & FlowFlags.Unreachable)) {
|
||||
if ((flowAfterTry.flags & FlowFlags.Unreachable) && (flowAfterCatch.flags & FlowFlags.Unreachable)) {
|
||||
currentFlow = flowAfterTry === reportedUnreachableFlow || flowAfterCatch === reportedUnreachableFlow
|
||||
? reportedUnreachableFlow
|
||||
: unreachableFlow;
|
||||
}
|
||||
}
|
||||
}
|
||||
// if try statement has finally block and flow after finally block is unreachable - keep it
|
||||
// otherwise use whatever flow was accumulated at postFinallyLabel
|
||||
if (!node.finallyBlock || !(currentFlow.flags & FlowFlags.Unreachable)) {
|
||||
currentFlow = finishFlowLabel(postFinallyLabel);
|
||||
else {
|
||||
currentFlow = finishFlowLabel(preFinallyLabel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1082,8 +1116,11 @@ namespace ts {
|
||||
if (!activeLabel.referenced && !options.allowUnusedLabels) {
|
||||
file.bindDiagnostics.push(createDiagnosticForNode(node.label, Diagnostics.Unused_label));
|
||||
}
|
||||
addAntecedent(postStatementLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(postStatementLabel);
|
||||
if (!node.statement || node.statement.kind !== SyntaxKind.DoStatement) {
|
||||
// do statement sets current flow inside bindDoStatement
|
||||
addAntecedent(postStatementLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(postStatementLabel);
|
||||
}
|
||||
}
|
||||
|
||||
function bindDestructuringTargetFlow(node: Expression) {
|
||||
@@ -1172,9 +1209,9 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
forEachChild(node, bind);
|
||||
if (operator === SyntaxKind.EqualsToken && !isAssignmentTarget(node)) {
|
||||
if (isAssignmentOperator(operator) && !isAssignmentTarget(node)) {
|
||||
bindAssignmentTargetFlow(node.left);
|
||||
if (node.left.kind === SyntaxKind.ElementAccessExpression) {
|
||||
if (operator === SyntaxKind.EqualsToken && node.left.kind === SyntaxKind.ElementAccessExpression) {
|
||||
const elementAccess = <ElementAccessExpression>node.left;
|
||||
if (isNarrowableOperand(elementAccess.expression)) {
|
||||
currentFlow = createFlowArrayMutation(currentFlow, node);
|
||||
@@ -1197,9 +1234,11 @@ namespace ts {
|
||||
const postExpressionLabel = createBranchLabel();
|
||||
bindCondition(node.condition, trueLabel, falseLabel);
|
||||
currentFlow = finishFlowLabel(trueLabel);
|
||||
bind(node.questionToken);
|
||||
bind(node.whenTrue);
|
||||
addAntecedent(postExpressionLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(falseLabel);
|
||||
bind(node.colonToken);
|
||||
bind(node.whenFalse);
|
||||
addAntecedent(postExpressionLabel, currentFlow);
|
||||
currentFlow = finishFlowLabel(postExpressionLabel);
|
||||
@@ -1808,6 +1847,17 @@ namespace ts {
|
||||
switch (node.kind) {
|
||||
/* Strict mode checks */
|
||||
case SyntaxKind.Identifier:
|
||||
// for typedef type names with namespaces, bind the new jsdoc type symbol here
|
||||
// because it requires all containing namespaces to be in effect, namely the
|
||||
// current "blockScopeContainer" needs to be set to its immediate namespace parent.
|
||||
if ((<Identifier>node).isInJSDocNamespace) {
|
||||
let parentNode = node.parent;
|
||||
while (parentNode && parentNode.kind !== SyntaxKind.JSDocTypedefTag) {
|
||||
parentNode = parentNode.parent;
|
||||
}
|
||||
bindBlockScopedDeclaration(<Declaration>parentNode, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.ThisKeyword:
|
||||
if (currentFlow && (isExpression(node) || parent.kind === SyntaxKind.ShorthandPropertyAssignment)) {
|
||||
node.flowNode = currentFlow;
|
||||
@@ -1931,6 +1981,10 @@ namespace ts {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.Interface, SymbolFlags.InterfaceExcludes);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
if (!(<JSDocTypedefTag>node).fullName || (<JSDocTypedefTag>node).fullName.kind === SyntaxKind.Identifier) {
|
||||
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
}
|
||||
break;
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
return bindBlockScopedDeclaration(<Declaration>node, SymbolFlags.TypeAlias, SymbolFlags.TypeAliasExcludes);
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
@@ -2052,7 +2106,9 @@ namespace ts {
|
||||
function setCommonJsModuleIndicator(node: Node) {
|
||||
if (!file.commonJsModuleIndicator) {
|
||||
file.commonJsModuleIndicator = node;
|
||||
bindSourceFileAsExternalModule();
|
||||
if (!file.externalModuleIndicator) {
|
||||
bindSourceFileAsExternalModule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2399,6 +2455,9 @@ namespace ts {
|
||||
case SyntaxKind.HeritageClause:
|
||||
return computeHeritageClause(<HeritageClause>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.CatchClause:
|
||||
return computeCatchClause(<CatchClause>node, subtreeFlags);
|
||||
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return computeExpressionWithTypeArguments(<ExpressionWithTypeArguments>node, subtreeFlags);
|
||||
|
||||
@@ -2485,7 +2544,7 @@ namespace ts {
|
||||
&& (leftKind === SyntaxKind.ObjectLiteralExpression
|
||||
|| leftKind === SyntaxKind.ArrayLiteralExpression)) {
|
||||
// Destructuring assignments are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.DestructuringAssignment;
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertDestructuringAssignment;
|
||||
}
|
||||
else if (operatorTokenKind === SyntaxKind.AsteriskAsteriskToken
|
||||
|| operatorTokenKind === SyntaxKind.AsteriskAsteriskEqualsToken) {
|
||||
@@ -2566,9 +2625,9 @@ namespace ts {
|
||||
|
||||
// A class with a parameter property assignment, property initializer, or decorator is
|
||||
// TypeScript syntax.
|
||||
// An exported declaration may be TypeScript syntax.
|
||||
// An exported declaration may be TypeScript syntax, but is handled by the visitor
|
||||
// for a namespace declaration.
|
||||
if ((subtreeFlags & TransformFlags.TypeScriptClassSyntaxMask)
|
||||
|| (modifierFlags & ModifierFlags.Export)
|
||||
|| node.typeParameters) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript;
|
||||
}
|
||||
@@ -2628,6 +2687,17 @@ namespace ts {
|
||||
return transformFlags & ~TransformFlags.NodeExcludes;
|
||||
}
|
||||
|
||||
function computeCatchClause(node: CatchClause, subtreeFlags: TransformFlags) {
|
||||
let transformFlags = subtreeFlags;
|
||||
|
||||
if (node.variableDeclaration && isBindingPattern(node.variableDeclaration.name)) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
node.transformFlags = transformFlags | TransformFlags.HasComputedFlags;
|
||||
return transformFlags & ~TransformFlags.NodeExcludes;
|
||||
}
|
||||
|
||||
function computeExpressionWithTypeArguments(node: ExpressionWithTypeArguments, subtreeFlags: TransformFlags) {
|
||||
// An ExpressionWithTypeArguments is ES6 syntax, as it is used in the
|
||||
// extends clause of a class.
|
||||
@@ -2727,11 +2797,6 @@ namespace ts {
|
||||
else {
|
||||
transformFlags = subtreeFlags | TransformFlags.ContainsHoistedDeclarationOrCompletion;
|
||||
|
||||
// If a FunctionDeclaration is exported, then it is either ES6 or TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Export) {
|
||||
transformFlags |= TransformFlags.AssertTypeScript | TransformFlags.AssertES2015;
|
||||
}
|
||||
|
||||
// TypeScript-specific modifiers, type parameters, and type annotations are TypeScript
|
||||
// syntax.
|
||||
if (modifierFlags & ModifierFlags.TypeScriptModifier
|
||||
@@ -2873,11 +2938,6 @@ namespace ts {
|
||||
else {
|
||||
transformFlags = subtreeFlags;
|
||||
|
||||
// If a VariableStatement is exported, then it is either ES6 or TypeScript syntax.
|
||||
if (modifierFlags & ModifierFlags.Export) {
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript;
|
||||
}
|
||||
|
||||
if (declarationListTransformFlags & TransformFlags.ContainsBindingPattern) {
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
}
|
||||
@@ -2994,12 +3054,6 @@ namespace ts {
|
||||
transformFlags |= TransformFlags.AssertJsx;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportKeyword:
|
||||
// This node is both ES6 and TypeScript syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015 | TransformFlags.AssertTypeScript;
|
||||
break;
|
||||
|
||||
case SyntaxKind.DefaultKeyword:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
case SyntaxKind.TemplateMiddle:
|
||||
@@ -3008,6 +3062,7 @@ namespace ts {
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
// These nodes are ES6 syntax.
|
||||
transformFlags |= TransformFlags.AssertES2015;
|
||||
break;
|
||||
@@ -3044,6 +3099,8 @@ namespace ts {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
case SyntaxKind.ThisType:
|
||||
case SyntaxKind.TypeOperator:
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
case SyntaxKind.LiteralType:
|
||||
// Types and signatures are TypeScript syntax, and exclude all other facts.
|
||||
transformFlags = TransformFlags.AssertTypeScript;
|
||||
|
||||
+835
-614
File diff suppressed because it is too large
Load Diff
@@ -515,10 +515,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticForInvalidCustomType(opt: CommandLineOptionOfCustomType): Diagnostic {
|
||||
const namesOfType: string[] = [];
|
||||
for (const key in opt.type) {
|
||||
namesOfType.push(` '${key}'`);
|
||||
}
|
||||
const namesOfType = Object.keys(opt.type).map(key => `'${key}'`).join(", ");
|
||||
return createCompilerDiagnostic(Diagnostics.Argument_for_0_option_must_be_Colon_1, `--${opt.name}`, namesOfType);
|
||||
}
|
||||
|
||||
@@ -602,7 +599,13 @@ namespace ts {
|
||||
i++;
|
||||
break;
|
||||
case "boolean":
|
||||
options[opt.name] = true;
|
||||
// boolean flag has optional value true, false, others
|
||||
let optValue = args[i];
|
||||
options[opt.name] = optValue !== "false";
|
||||
// consume next argument as boolean flag value
|
||||
if (optValue === "false" || optValue === "true") {
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
case "string":
|
||||
options[opt.name] = args[i] || "";
|
||||
@@ -909,6 +912,9 @@ namespace ts {
|
||||
if (hasProperty(json, "files")) {
|
||||
if (isArray(json["files"])) {
|
||||
fileNames = <string[]>json["files"];
|
||||
if (fileNames.length === 0) {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.The_files_list_in_config_file_0_is_empty, configFileName || "tsconfig.json"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
errors.push(createCompilerDiagnostic(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "files", "Array"));
|
||||
@@ -951,7 +957,18 @@ namespace ts {
|
||||
includeSpecs = ["**/*"];
|
||||
}
|
||||
|
||||
return matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors);
|
||||
const result = matchFileNames(fileNames, includeSpecs, excludeSpecs, basePath, options, host, errors);
|
||||
|
||||
if (result.fileNames.length === 0 && !hasProperty(json, "files") && resolutionStack.length === 0) {
|
||||
errors.push(
|
||||
createCompilerDiagnostic(
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
configFileName || "tsconfig.json",
|
||||
JSON.stringify(includeSpecs || []),
|
||||
JSON.stringify(excludeSpecs || [])));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -991,9 +1008,7 @@ namespace ts {
|
||||
function convertTypingOptionsFromJsonWorker(jsonOptions: any,
|
||||
basePath: string, errors: Diagnostic[], configFileName?: string): TypingOptions {
|
||||
|
||||
const options: TypingOptions = getBaseFileName(configFileName) === "jsconfig.json"
|
||||
? { enableAutoDiscovery: true, include: [], exclude: [] }
|
||||
: { enableAutoDiscovery: false, include: [], exclude: [] };
|
||||
const options: TypingOptions = { enableAutoDiscovery: getBaseFileName(configFileName) === "jsconfig.json", include: [], exclude: [] };
|
||||
convertOptionsFromJson(typingOptionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_typing_option_0, errors);
|
||||
return options;
|
||||
}
|
||||
@@ -1246,12 +1261,13 @@ namespace ts {
|
||||
/**
|
||||
* Gets directories in a set of include patterns that should be watched for changes.
|
||||
*/
|
||||
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean) {
|
||||
function getWildcardDirectories(include: string[], exclude: string[], path: string, useCaseSensitiveFileNames: boolean): Map<WatchDirectoryFlags> {
|
||||
// We watch a directory recursively if it contains a wildcard anywhere in a directory segment
|
||||
// of the pattern:
|
||||
//
|
||||
// /a/b/**/d - Watch /a/b recursively to catch changes to any d in any subfolder recursively
|
||||
// /a/b/*/d - Watch /a/b recursively to catch any d in any immediate subfolder, even if a new subfolder is added
|
||||
// /a/b - Watch /a/b recursively to catch changes to anything in any recursive subfoler
|
||||
//
|
||||
// We watch a directory without recursion if it contains a wildcard in the file segment of
|
||||
// the pattern:
|
||||
@@ -1264,15 +1280,14 @@ namespace ts {
|
||||
if (include !== undefined) {
|
||||
const recursiveKeys: string[] = [];
|
||||
for (const file of include) {
|
||||
const name = normalizePath(combinePaths(path, file));
|
||||
if (excludeRegex && excludeRegex.test(name)) {
|
||||
const spec = normalizePath(combinePaths(path, file));
|
||||
if (excludeRegex && excludeRegex.test(spec)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const match = wildcardDirectoryPattern.exec(name);
|
||||
const match = getWildcardDirectoryFromSpec(spec, useCaseSensitiveFileNames);
|
||||
if (match) {
|
||||
const key = useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase();
|
||||
const flags = watchRecursivePattern.test(name) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None;
|
||||
const { key, flags } = match;
|
||||
const existingFlags = wildcardDirectories[key];
|
||||
if (existingFlags === undefined || existingFlags < flags) {
|
||||
wildcardDirectories[key] = flags;
|
||||
@@ -1296,6 +1311,20 @@ namespace ts {
|
||||
return wildcardDirectories;
|
||||
}
|
||||
|
||||
function getWildcardDirectoryFromSpec(spec: string, useCaseSensitiveFileNames: boolean): { key: string, flags: WatchDirectoryFlags } | undefined {
|
||||
const match = wildcardDirectoryPattern.exec(spec);
|
||||
if (match) {
|
||||
return {
|
||||
key: useCaseSensitiveFileNames ? match[0] : match[0].toLowerCase(),
|
||||
flags: watchRecursivePattern.test(spec) ? WatchDirectoryFlags.Recursive : WatchDirectoryFlags.None
|
||||
};
|
||||
}
|
||||
if (isImplicitGlob(spec)) {
|
||||
return { key: spec, flags: WatchDirectoryFlags.Recursive };
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a literal or wildcard file has already been included that has a higher
|
||||
* extension priority.
|
||||
|
||||
@@ -188,7 +188,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitLeadingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
function emitLeadingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean, rangePos: number) {
|
||||
if (!hasWrittenComment) {
|
||||
emitNewLineBeforeLeadingCommentOfPosition(currentLineMap, writer, rangePos, commentPos);
|
||||
hasWrittenComment = true;
|
||||
@@ -211,7 +211,7 @@ namespace ts {
|
||||
forEachTrailingCommentToEmit(pos, emitTrailingComment);
|
||||
}
|
||||
|
||||
function emitTrailingComment(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
function emitTrailingComment(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
// trailing comments are emitted at space/*trailing comment1 */space/*trailing comment2*/
|
||||
if (!writer.isAtStartOfLine()) {
|
||||
writer.write(" ");
|
||||
@@ -242,7 +242,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
function emitTrailingCommentOfPosition(commentPos: number, commentEnd: number, _kind: SyntaxKind, hasTrailingNewLine: boolean) {
|
||||
// trailing comments of a position are emitted at /*trailing comment1 */space/*trailing comment*/space
|
||||
|
||||
emitPos(commentPos);
|
||||
|
||||
+297
-118
@@ -124,6 +124,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function zipWith<T, U>(arrayA: T[], arrayB: U[], callback: (a: T, b: U, index: number) => void): void {
|
||||
Debug.assert(arrayA.length === arrayB.length);
|
||||
for (let i = 0; i < arrayA.length; i++) {
|
||||
callback(arrayA[i], arrayB[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through `array` by index and performs the callback on each element of array until the callback
|
||||
* returns a falsey value, then returns false.
|
||||
@@ -424,18 +431,23 @@ namespace ts {
|
||||
|
||||
export function some<T>(array: T[], predicate?: (value: T) => boolean): boolean {
|
||||
if (array) {
|
||||
for (const v of array) {
|
||||
if (!predicate || predicate(v)) {
|
||||
return true;
|
||||
if (predicate) {
|
||||
for (const v of array) {
|
||||
if (predicate(v)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
return array.length > 0;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function concatenate<T>(array1: T[], array2: T[]): T[] {
|
||||
if (!array2 || !array2.length) return array1;
|
||||
if (!array1 || !array1.length) return array2;
|
||||
if (!some(array2)) return array1;
|
||||
if (!some(array1)) return array2;
|
||||
return [...array1, ...array2];
|
||||
}
|
||||
|
||||
@@ -456,6 +468,44 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equaler?: (a: T, b: T) => boolean): boolean {
|
||||
if (!array1 || !array2) {
|
||||
return array1 === array2;
|
||||
}
|
||||
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.length; i++) {
|
||||
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
|
||||
if (!equals) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean {
|
||||
return !oldOptions ||
|
||||
(oldOptions.module !== newOptions.module) ||
|
||||
(oldOptions.moduleResolution !== newOptions.moduleResolution) ||
|
||||
(oldOptions.noResolve !== newOptions.noResolve) ||
|
||||
(oldOptions.target !== newOptions.target) ||
|
||||
(oldOptions.noLib !== newOptions.noLib) ||
|
||||
(oldOptions.jsx !== newOptions.jsx) ||
|
||||
(oldOptions.allowJs !== newOptions.allowJs) ||
|
||||
(oldOptions.rootDir !== newOptions.rootDir) ||
|
||||
(oldOptions.configFilePath !== newOptions.configFilePath) ||
|
||||
(oldOptions.baseUrl !== newOptions.baseUrl) ||
|
||||
(oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
|
||||
!arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
|
||||
!arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
|
||||
!arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
|
||||
!equalOwnProperties(oldOptions.paths, newOptions.paths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compacts an array, removing any falsey elements.
|
||||
*/
|
||||
@@ -477,6 +527,27 @@ namespace ts {
|
||||
return result || array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the relative complement of `arrayA` with respect to `b`, returning the elements that
|
||||
* are not present in `arrayA` but are present in `arrayB`. Assumes both arrays are sorted
|
||||
* based on the provided comparer.
|
||||
*/
|
||||
export function relativeComplement<T>(arrayA: T[] | undefined, arrayB: T[] | undefined, comparer: (x: T, y: T) => Comparison = compareValues, offsetA = 0, offsetB = 0): T[] | undefined {
|
||||
if (!arrayB || !arrayA || arrayB.length === 0 || arrayA.length === 0) return arrayB;
|
||||
const result: T[] = [];
|
||||
outer: for (; offsetB < arrayB.length; offsetB++) {
|
||||
inner: for (; offsetA < arrayA.length; offsetA++) {
|
||||
switch (comparer(arrayB[offsetB], arrayA[offsetA])) {
|
||||
case Comparison.LessThan: break inner;
|
||||
case Comparison.EqualTo: continue outer;
|
||||
case Comparison.GreaterThan: continue inner;
|
||||
}
|
||||
}
|
||||
result.push(arrayB[offsetB]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function sum(array: any[], prop: string): number {
|
||||
let result = 0;
|
||||
for (const v of array) {
|
||||
@@ -485,14 +556,35 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function addRange<T>(to: T[], from: T[]): void {
|
||||
if (to && from) {
|
||||
for (const v of from) {
|
||||
if (v !== undefined) {
|
||||
to.push(v);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Appends a value to an array, returning the array.
|
||||
*
|
||||
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
|
||||
* is created if `value` was appended.
|
||||
* @param value The value to append to the array. If `value` is `undefined`, nothing is
|
||||
* appended.
|
||||
*/
|
||||
export function append<T>(to: T[] | undefined, value: T | undefined): T[] | undefined {
|
||||
if (value === undefined) return to;
|
||||
if (to === undefined) to = [];
|
||||
to.push(value);
|
||||
return to;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a range of value to an array, returning the array.
|
||||
*
|
||||
* @param to The array to which `value` is to be appended. If `to` is `undefined`, a new array
|
||||
* is created if `value` was appended.
|
||||
* @param from The values to append to the array. If `from` is `undefined`, nothing is
|
||||
* appended. If an element of `from` is `undefined`, that element is not appended.
|
||||
*/
|
||||
export function addRange<T>(to: T[] | undefined, from: T[] | undefined): T[] | undefined {
|
||||
if (from === undefined) return to;
|
||||
for (const v of from) {
|
||||
to = append(to, v);
|
||||
}
|
||||
return to;
|
||||
}
|
||||
|
||||
export function rangeEquals<T>(array1: T[], array2: T[], pos: number, end: number) {
|
||||
@@ -505,31 +597,47 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first element of an array if non-empty, `undefined` otherwise.
|
||||
*/
|
||||
export function firstOrUndefined<T>(array: T[]): T {
|
||||
return array && array.length > 0
|
||||
? array[0]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element of an array if non-empty, `undefined` otherwise.
|
||||
*/
|
||||
export function lastOrUndefined<T>(array: T[]): T {
|
||||
return array && array.length > 0
|
||||
? array[array.length - 1]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the only element of an array if it contains only one element, `undefined` otherwise.
|
||||
*/
|
||||
export function singleOrUndefined<T>(array: T[]): T {
|
||||
return array && array.length === 1
|
||||
? array[0]
|
||||
: undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the only element of an array if it contains only one element; otheriwse, returns the
|
||||
* array.
|
||||
*/
|
||||
export function singleOrMany<T>(array: T[]): T | T[] {
|
||||
return array && array.length === 1
|
||||
? array[0]
|
||||
: array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last element of an array if non-empty, undefined otherwise.
|
||||
*/
|
||||
export function lastOrUndefined<T>(array: T[]): T {
|
||||
return array && array.length > 0
|
||||
? array[array.length - 1]
|
||||
: undefined;
|
||||
export function replaceElement<T>(array: T[], index: number, value: T): T[] {
|
||||
const result = array.slice(0);
|
||||
result[index] = value;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -539,12 +647,12 @@ namespace ts {
|
||||
* @param array A sorted array whose first element must be no larger than number
|
||||
* @param number The value to be searched for in the array.
|
||||
*/
|
||||
export function binarySearch<T>(array: T[], value: T, comparer?: (v1: T, v2: T) => number): number {
|
||||
export function binarySearch<T>(array: T[], value: T, comparer?: (v1: T, v2: T) => number, offset?: number): number {
|
||||
if (!array || array.length === 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
let low = 0;
|
||||
let low = offset || 0;
|
||||
let high = array.length - 1;
|
||||
comparer = comparer !== undefined
|
||||
? comparer
|
||||
@@ -815,7 +923,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
export function extend<T1, T2>(first: T1 , second: T2): T1 & T2 {
|
||||
export function extend<T1, T2>(first: T1, second: T2): T1 & T2 {
|
||||
const result: T1 & T2 = <any>{};
|
||||
for (const id in second) if (hasOwnProperty.call(second, id)) {
|
||||
(result as any)[id] = (second as any)[id];
|
||||
@@ -830,7 +938,7 @@ namespace ts {
|
||||
* Adds the value to an array of values associated with the key, and returns the array.
|
||||
* Creates the array if it does not already exist.
|
||||
*/
|
||||
export function multiMapAdd<V>(map: Map<V[]>, key: string, value: V): V[] {
|
||||
export function multiMapAdd<V>(map: Map<V[]>, key: string | number, value: V): V[] {
|
||||
const values = map[key];
|
||||
if (values) {
|
||||
values.push(value);
|
||||
@@ -863,6 +971,14 @@ namespace ts {
|
||||
return Array.isArray ? Array.isArray(value) : value instanceof Array;
|
||||
}
|
||||
|
||||
/** Does nothing. */
|
||||
export function noop(): void {}
|
||||
|
||||
/** Throws an error because a function is not implemented. */
|
||||
export function notImplemented(): never {
|
||||
throw new Error("Not implemented");
|
||||
}
|
||||
|
||||
export function memoize<T>(callback: () => T): () => T {
|
||||
let value: T;
|
||||
return () => {
|
||||
@@ -903,7 +1019,7 @@ namespace ts {
|
||||
return t => compose(a(t));
|
||||
}
|
||||
else {
|
||||
return t => u => u;
|
||||
return _ => u => u;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -940,10 +1056,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function formatStringFromArgs(text: string, args: { [index: number]: any; }, baseIndex?: number): string {
|
||||
function formatStringFromArgs(text: string, args: { [index: number]: string; }, baseIndex?: number): string {
|
||||
baseIndex = baseIndex || 0;
|
||||
|
||||
return text.replace(/{(\d+)}/g, (match, index?) => args[+index + baseIndex]);
|
||||
return text.replace(/{(\d+)}/g, (_match, index?) => args[+index + baseIndex]);
|
||||
}
|
||||
|
||||
export let localizedDiagnosticMessages: Map<string> = undefined;
|
||||
@@ -952,7 +1068,7 @@ namespace ts {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): Diagnostic {
|
||||
const end = start + length;
|
||||
|
||||
@@ -960,8 +1076,8 @@ namespace ts {
|
||||
Debug.assert(length >= 0, "length must be non-negative, is " + length);
|
||||
|
||||
if (file) {
|
||||
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${ start } > ${ file.text.length }`);
|
||||
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${ end } > ${ file.text.length }`);
|
||||
Debug.assert(start <= file.text.length, `start must be within the bounds of the file. ${start} > ${file.text.length}`);
|
||||
Debug.assert(end <= file.text.length, `end must be the bounds of the file. ${end} > ${file.text.length}`);
|
||||
}
|
||||
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -982,7 +1098,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* internal */
|
||||
export function formatMessage(dummy: any, message: DiagnosticMessage): string {
|
||||
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
if (arguments.length > 2) {
|
||||
@@ -992,7 +1108,7 @@ namespace ts {
|
||||
return text;
|
||||
}
|
||||
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: any[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -1011,6 +1127,18 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
|
||||
return {
|
||||
file: undefined,
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
|
||||
code: chain.code,
|
||||
category: chain.category,
|
||||
messageText: chain.next ? chain : chain.messageText
|
||||
};
|
||||
}
|
||||
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage, ...args: any[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -1217,7 +1345,7 @@ namespace ts {
|
||||
*/
|
||||
export function getDirectoryPath(path: Path): Path;
|
||||
export function getDirectoryPath(path: string): string;
|
||||
export function getDirectoryPath(path: string): any {
|
||||
export function getDirectoryPath(path: string): string {
|
||||
return path.substr(0, Math.max(getRootLength(path), path.lastIndexOf(directorySeparator)));
|
||||
}
|
||||
|
||||
@@ -1477,6 +1605,10 @@ namespace ts {
|
||||
return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
|
||||
}
|
||||
|
||||
export function hasExtension(fileName: string): boolean {
|
||||
return getBaseFileName(fileName).indexOf(".") >= 0;
|
||||
}
|
||||
|
||||
export function fileExtensionIs(path: string, extension: string): boolean {
|
||||
return path.length > extension.length && endsWith(path, extension);
|
||||
}
|
||||
@@ -1511,7 +1643,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther;
|
||||
const replaceWildcardCharacter = usage === "files" ? replaceWildCardCharacterFiles : replaceWildCardCharacterOther;
|
||||
const singleAsteriskRegexFragment = usage === "files" ? singleAsteriskRegexFragmentFiles : singleAsteriskRegexFragmentOther;
|
||||
|
||||
/**
|
||||
@@ -1522,73 +1654,21 @@ namespace ts {
|
||||
|
||||
let pattern = "";
|
||||
let hasWrittenSubpattern = false;
|
||||
spec: for (const spec of specs) {
|
||||
for (const spec of specs) {
|
||||
if (!spec) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let subpattern = "";
|
||||
let hasRecursiveDirectoryWildcard = false;
|
||||
let hasWrittenComponent = false;
|
||||
const components = getNormalizedPathComponents(spec, basePath);
|
||||
if (usage !== "exclude" && components[components.length - 1] === "**") {
|
||||
continue spec;
|
||||
}
|
||||
|
||||
// getNormalizedPathComponents includes the separator for the root component.
|
||||
// We need to remove to create our regex correctly.
|
||||
components[0] = removeTrailingDirectorySeparator(components[0]);
|
||||
|
||||
let optionalCount = 0;
|
||||
for (let component of components) {
|
||||
if (component === "**") {
|
||||
if (hasRecursiveDirectoryWildcard) {
|
||||
continue spec;
|
||||
}
|
||||
|
||||
subpattern += doubleAsteriskRegexFragment;
|
||||
hasRecursiveDirectoryWildcard = true;
|
||||
hasWrittenComponent = true;
|
||||
}
|
||||
else {
|
||||
if (usage === "directories") {
|
||||
subpattern += "(";
|
||||
optionalCount++;
|
||||
}
|
||||
|
||||
if (hasWrittenComponent) {
|
||||
subpattern += directorySeparator;
|
||||
}
|
||||
|
||||
if (usage !== "exclude") {
|
||||
// The * and ? wildcards should not match directories or files that start with . if they
|
||||
// appear first in a component. Dotted directories and files can be included explicitly
|
||||
// like so: **/.*/.*
|
||||
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
|
||||
subpattern += "([^./]" + singleAsteriskRegexFragment + ")?";
|
||||
component = component.substr(1);
|
||||
}
|
||||
else if (component.charCodeAt(0) === CharacterCodes.question) {
|
||||
subpattern += "[^./]";
|
||||
component = component.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
|
||||
hasWrittenComponent = true;
|
||||
}
|
||||
}
|
||||
|
||||
while (optionalCount > 0) {
|
||||
subpattern += ")?";
|
||||
optionalCount--;
|
||||
const subPattern = getSubPatternFromSpec(spec, basePath, usage, singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter);
|
||||
if (subPattern === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (hasWrittenSubpattern) {
|
||||
pattern += "|";
|
||||
}
|
||||
|
||||
pattern += "(" + subpattern + ")";
|
||||
pattern += "(" + subPattern + ")";
|
||||
hasWrittenSubpattern = true;
|
||||
}
|
||||
|
||||
@@ -1596,7 +1676,83 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return "^(" + pattern + (usage === "exclude" ? ")($|/)" : ")$");
|
||||
// If excluding, match "foo/bar/baz...", but if including, only allow "foo".
|
||||
const terminator = usage === "exclude" ? "($|/)" : "$";
|
||||
return `^(${pattern})${terminator}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
|
||||
* and does not contain any glob characters itself.
|
||||
*/
|
||||
export function isImplicitGlob(lastPathComponent: string): boolean {
|
||||
return !/[.*?]/.test(lastPathComponent);
|
||||
}
|
||||
|
||||
function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", singleAsteriskRegexFragment: string, doubleAsteriskRegexFragment: string, replaceWildcardCharacter: (match: string) => string): string | undefined {
|
||||
let subpattern = "";
|
||||
let hasRecursiveDirectoryWildcard = false;
|
||||
let hasWrittenComponent = false;
|
||||
const components = getNormalizedPathComponents(spec, basePath);
|
||||
const lastComponent = lastOrUndefined(components);
|
||||
if (usage !== "exclude" && lastComponent === "**") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// getNormalizedPathComponents includes the separator for the root component.
|
||||
// We need to remove to create our regex correctly.
|
||||
components[0] = removeTrailingDirectorySeparator(components[0]);
|
||||
|
||||
if (isImplicitGlob(lastComponent)) {
|
||||
components.push("**", "*");
|
||||
}
|
||||
|
||||
let optionalCount = 0;
|
||||
for (let component of components) {
|
||||
if (component === "**") {
|
||||
if (hasRecursiveDirectoryWildcard) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
subpattern += doubleAsteriskRegexFragment;
|
||||
hasRecursiveDirectoryWildcard = true;
|
||||
}
|
||||
else {
|
||||
if (usage === "directories") {
|
||||
subpattern += "(";
|
||||
optionalCount++;
|
||||
}
|
||||
|
||||
if (hasWrittenComponent) {
|
||||
subpattern += directorySeparator;
|
||||
}
|
||||
|
||||
if (usage !== "exclude") {
|
||||
// The * and ? wildcards should not match directories or files that start with . if they
|
||||
// appear first in a component. Dotted directories and files can be included explicitly
|
||||
// like so: **/.*/.*
|
||||
if (component.charCodeAt(0) === CharacterCodes.asterisk) {
|
||||
subpattern += "([^./]" + singleAsteriskRegexFragment + ")?";
|
||||
component = component.substr(1);
|
||||
}
|
||||
else if (component.charCodeAt(0) === CharacterCodes.question) {
|
||||
subpattern += "[^./]";
|
||||
component = component.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
|
||||
}
|
||||
|
||||
hasWrittenComponent = true;
|
||||
}
|
||||
|
||||
while (optionalCount > 0) {
|
||||
subpattern += ")?";
|
||||
optionalCount--;
|
||||
}
|
||||
|
||||
return subpattern;
|
||||
}
|
||||
|
||||
function replaceWildCardCharacterFiles(match: string) {
|
||||
@@ -1623,7 +1779,7 @@ namespace ts {
|
||||
basePaths: string[];
|
||||
}
|
||||
|
||||
export function getFileMatcherPatterns(path: string, extensions: string[], excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
export function getFileMatcherPatterns(path: string, excludes: string[], includes: string[], useCaseSensitiveFileNames: boolean, currentDirectory: string): FileMatcherPatterns {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
const absolutePath = combinePaths(currentDirectory, path);
|
||||
@@ -1640,7 +1796,7 @@ namespace ts {
|
||||
path = normalizePath(path);
|
||||
currentDirectory = normalizePath(currentDirectory);
|
||||
|
||||
const patterns = getFileMatcherPatterns(path, extensions, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
|
||||
const patterns = getFileMatcherPatterns(path, excludes, includes, useCaseSensitiveFileNames, currentDirectory);
|
||||
|
||||
const regexFlag = useCaseSensitiveFileNames ? "" : "i";
|
||||
const includeFileRegex = patterns.includeFilePattern && new RegExp(patterns.includeFilePattern, regexFlag);
|
||||
@@ -1683,6 +1839,7 @@ namespace ts {
|
||||
function getBasePaths(path: string, includes: string[], useCaseSensitiveFileNames: boolean) {
|
||||
// Storage for our results in the form of literal paths (e.g. the paths as written by the user).
|
||||
const basePaths: string[] = [path];
|
||||
|
||||
if (includes) {
|
||||
// Storage for literal base paths amongst the include patterns.
|
||||
const includeBasePaths: string[] = [];
|
||||
@@ -1690,14 +1847,8 @@ namespace ts {
|
||||
// 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));
|
||||
|
||||
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);
|
||||
includeBasePaths.push(getIncludeBasePath(absolute));
|
||||
}
|
||||
|
||||
// Sort the offsets array using either the literal or canonical path representations.
|
||||
@@ -1705,21 +1856,27 @@ namespace ts {
|
||||
|
||||
// Iterate over each include base path and include unique base paths that are not a
|
||||
// subpath of an existing base path
|
||||
include: for (let i = 0; i < includeBasePaths.length; i++) {
|
||||
const includeBasePath = includeBasePaths[i];
|
||||
for (let j = 0; j < basePaths.length; j++) {
|
||||
if (containsPath(basePaths[j], includeBasePath, path, !useCaseSensitiveFileNames)) {
|
||||
continue include;
|
||||
}
|
||||
for (const includeBasePath of includeBasePaths) {
|
||||
if (ts.every(basePaths, basePath => !containsPath(basePath, includeBasePath, path, !useCaseSensitiveFileNames))) {
|
||||
basePaths.push(includeBasePath);
|
||||
}
|
||||
|
||||
basePaths.push(includeBasePath);
|
||||
}
|
||||
}
|
||||
|
||||
return basePaths;
|
||||
}
|
||||
|
||||
function getIncludeBasePath(absolute: string): string {
|
||||
const wildcardOffset = indexOfAnyCharCode(absolute, wildcardCharCodes);
|
||||
if (wildcardOffset < 0) {
|
||||
// No "*" or "?" in the path
|
||||
return !hasExtension(absolute)
|
||||
? absolute
|
||||
: removeTrailingDirectorySeparator(getDirectoryPath(absolute));
|
||||
}
|
||||
return absolute.substring(0, absolute.lastIndexOf(directorySeparator, wildcardOffset));
|
||||
}
|
||||
|
||||
export function ensureScriptKind(fileName: string, scriptKind?: ScriptKind): ScriptKind {
|
||||
// Using scriptKind as a condition handles both:
|
||||
// - 'scriptKind' is unspecified and thus it is `undefined`
|
||||
@@ -1753,7 +1910,7 @@ namespace ts {
|
||||
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
|
||||
export const supportedTypescriptExtensionsForExtractExtension = [".d.ts", ".ts", ".tsx"];
|
||||
export const supportedJavascriptExtensions = [".js", ".jsx"];
|
||||
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
|
||||
const allSupportedExtensions = supportedTypeScriptExtensions.concat(supportedJavascriptExtensions);
|
||||
|
||||
export function getSupportedExtensions(options?: CompilerOptions): string[] {
|
||||
return options && options.allowJs ? allSupportedExtensions : supportedTypeScriptExtensions;
|
||||
@@ -1850,10 +2007,6 @@ namespace ts {
|
||||
return path.substring(0, path.length - extension.length);
|
||||
}
|
||||
|
||||
export function isJsxOrTsxExtension(ext: string): boolean {
|
||||
return ext === ".jsx" || ext === ".tsx";
|
||||
}
|
||||
|
||||
export function changeExtension<T extends string | Path>(path: T, newExtension: string): T {
|
||||
return <T>(removeFileExtension(path) + newExtension);
|
||||
}
|
||||
@@ -1874,11 +2027,11 @@ namespace ts {
|
||||
this.declarations = undefined;
|
||||
}
|
||||
|
||||
function Type(this: Type, checker: TypeChecker, flags: TypeFlags) {
|
||||
function Type(this: Type, _checker: TypeChecker, flags: TypeFlags) {
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
function Signature(checker: TypeChecker) {
|
||||
function Signature() {
|
||||
}
|
||||
|
||||
function Node(this: Node, kind: SyntaxKind, pos: number, end: number) {
|
||||
@@ -1911,9 +2064,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
export namespace Debug {
|
||||
declare var process: any;
|
||||
declare var require: any;
|
||||
|
||||
export let currentAssertionLevel = AssertionLevel.None;
|
||||
|
||||
export function shouldAssert(level: AssertionLevel): boolean {
|
||||
@@ -2049,4 +2199,33 @@ namespace ts {
|
||||
// pos === undefined || pos === null || isNaN(pos) || pos < 0;
|
||||
return !(pos >= 0);
|
||||
}
|
||||
|
||||
/** True if an extension is one of the supported TypeScript extensions. */
|
||||
export function extensionIsTypeScript(ext: Extension): boolean {
|
||||
return ext <= Extension.LastTypeScriptExtension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the extension from a path.
|
||||
* Path must have a valid extension.
|
||||
*/
|
||||
export function extensionFromPath(path: string): Extension {
|
||||
if (fileExtensionIs(path, ".d.ts")) {
|
||||
return Extension.Dts;
|
||||
}
|
||||
if (fileExtensionIs(path, ".ts")) {
|
||||
return Extension.Ts;
|
||||
}
|
||||
if (fileExtensionIs(path, ".tsx")) {
|
||||
return Extension.Tsx;
|
||||
}
|
||||
if (fileExtensionIs(path, ".js")) {
|
||||
return Extension.Js;
|
||||
}
|
||||
if (fileExtensionIs(path, ".jsx")) {
|
||||
return Extension.Jsx;
|
||||
}
|
||||
Debug.fail(`File ${path} has unknown extension.`);
|
||||
return Extension.Js;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace ts {
|
||||
let isCurrentFileExternalModule: boolean;
|
||||
let reportedDeclarationError = false;
|
||||
let errorNameNode: DeclarationName;
|
||||
const emitJsDocComments = compilerOptions.removeComments ? function (declaration: Node) { } : writeJsDocComments;
|
||||
const emitJsDocComments = compilerOptions.removeComments ? noop : writeJsDocComments;
|
||||
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
|
||||
let noDeclare: boolean;
|
||||
|
||||
@@ -413,6 +413,10 @@ namespace ts {
|
||||
return emitIntersectionType(<IntersectionTypeNode>type);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
return emitParenType(<ParenthesizedTypeNode>type);
|
||||
case SyntaxKind.TypeOperator:
|
||||
return emitTypeOperator(<TypeOperatorNode>type);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return emitPropertyAccessType(<IndexedAccessTypeNode>type);
|
||||
case SyntaxKind.FunctionType:
|
||||
case SyntaxKind.ConstructorType:
|
||||
return emitSignatureDeclarationWithJsDocComments(<FunctionOrConstructorTypeNode>type);
|
||||
@@ -506,6 +510,19 @@ namespace ts {
|
||||
write(")");
|
||||
}
|
||||
|
||||
function emitTypeOperator(type: TypeOperatorNode) {
|
||||
write(tokenToString(type.operator));
|
||||
write(" ");
|
||||
emitType(type.type);
|
||||
}
|
||||
|
||||
function emitPropertyAccessType(node: IndexedAccessTypeNode) {
|
||||
emitType(node.objectType);
|
||||
write("[");
|
||||
emitType(node.indexType);
|
||||
write("]");
|
||||
}
|
||||
|
||||
function emitTypeLiteral(type: TypeLiteralNode) {
|
||||
write("{");
|
||||
if (type.members.length) {
|
||||
@@ -580,7 +597,7 @@ namespace ts {
|
||||
writeAsynchronousModuleElements(nodes);
|
||||
}
|
||||
|
||||
function getDefaultExportAccessibilityDiagnostic(diagnostic: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getDefaultExportAccessibilityDiagnostic(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Default_export_of_the_module_has_or_is_using_private_name_0,
|
||||
errorNode: node
|
||||
@@ -710,7 +727,7 @@ namespace ts {
|
||||
}
|
||||
writer.writeLine();
|
||||
|
||||
function getImportEntityNameVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getImportEntityNameVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Import_declaration_0_is_using_private_name_1,
|
||||
errorNode: node,
|
||||
@@ -888,7 +905,7 @@ namespace ts {
|
||||
writeLine();
|
||||
enclosingDeclaration = prevEnclosingDeclaration;
|
||||
|
||||
function getTypeAliasDeclarationVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getTypeAliasDeclarationVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
return {
|
||||
diagnosticMessage: Diagnostics.Exported_type_alias_0_has_or_is_using_private_name_1,
|
||||
errorNode: node.type,
|
||||
@@ -955,7 +972,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeParameterConstraintVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
// Type parameter constraints are named by user so we should always be able to name it
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
switch (node.parent.kind) {
|
||||
@@ -1029,7 +1046,7 @@ namespace ts {
|
||||
resolver.writeBaseConstructorTypeOfClass(<ClassLikeDeclaration>enclosingDeclaration, enclosingDeclaration, TypeFormatFlags.UseTypeOfFunction | TypeFormatFlags.UseTypeAliasValue, writer);
|
||||
}
|
||||
|
||||
function getHeritageClauseVisibilityError(symbolAccessibilityResult: SymbolAccessibilityResult): SymbolAccessibilityDiagnostic {
|
||||
function getHeritageClauseVisibilityError(): SymbolAccessibilityDiagnostic {
|
||||
let diagnosticMessage: DiagnosticMessage;
|
||||
// Heritage clause is written by user so it can always be named
|
||||
if (node.parent.parent.kind === SyntaxKind.ClassDeclaration) {
|
||||
@@ -1743,7 +1760,7 @@ namespace ts {
|
||||
}
|
||||
return addedBundledEmitReference;
|
||||
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
function getDeclFileName(emitFileNames: EmitFileNames, _sourceFiles: SourceFile[], isBundledEmit: boolean) {
|
||||
// Dont add reference path to this file if it is a bundled emit and caller asked not emit bundled file path
|
||||
if (isBundledEmit && !addBundledFileReference) {
|
||||
return;
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
"category": "Error",
|
||||
"code": 1054
|
||||
},
|
||||
"Type '{0}' is not a valid async function return type.": {
|
||||
"Type '{0}' is not a valid async function return type in ES5/ES3 because it does not refer to a Promise-compatible constructor value.": {
|
||||
"category": "Error",
|
||||
"code": 1055
|
||||
},
|
||||
@@ -603,10 +603,6 @@
|
||||
"category": "Error",
|
||||
"code": 1194
|
||||
},
|
||||
"Catch clause variable name must be an identifier.": {
|
||||
"category": "Error",
|
||||
"code": 1195
|
||||
},
|
||||
"Catch clause variable cannot have a type annotation.": {
|
||||
"category": "Error",
|
||||
"code": 1196
|
||||
@@ -1075,7 +1071,7 @@
|
||||
"category": "Error",
|
||||
"code": 2356
|
||||
},
|
||||
"The operand of an increment or decrement operator must be a variable, property or indexer.": {
|
||||
"The operand of an increment or decrement operator must be a variable or a property access.": {
|
||||
"category": "Error",
|
||||
"code": 2357
|
||||
},
|
||||
@@ -1103,7 +1099,7 @@
|
||||
"category": "Error",
|
||||
"code": 2363
|
||||
},
|
||||
"Invalid left-hand side of assignment expression.": {
|
||||
"The left-hand side of an assignment expression must be a variable or a property access.": {
|
||||
"category": "Error",
|
||||
"code": 2364
|
||||
},
|
||||
@@ -1263,7 +1259,7 @@
|
||||
"category": "Error",
|
||||
"code": 2405
|
||||
},
|
||||
"Invalid left-hand side in 'for...in' statement.": {
|
||||
"The left-hand side of a 'for...in' statement must be a variable or a property access.": {
|
||||
"category": "Error",
|
||||
"code": 2406
|
||||
},
|
||||
@@ -1415,14 +1411,6 @@
|
||||
"category": "Error",
|
||||
"code": 2448
|
||||
},
|
||||
"The operand of an increment or decrement operator cannot be a constant or a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2449
|
||||
},
|
||||
"Left-hand side of assignment expression cannot be a constant or a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2450
|
||||
},
|
||||
"Cannot redeclare block-scoped variable '{0}'.": {
|
||||
"category": "Error",
|
||||
"code": 2451
|
||||
@@ -1555,15 +1543,7 @@
|
||||
"category": "Error",
|
||||
"code": 2484
|
||||
},
|
||||
"The left-hand side of a 'for...of' statement cannot be a constant or a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2485
|
||||
},
|
||||
"The left-hand side of a 'for...in' statement cannot be a constant or a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2486
|
||||
},
|
||||
"Invalid left-hand side in 'for...of' statement.": {
|
||||
"The left-hand side of a 'for...of' statement must be a variable or a property access.": {
|
||||
"category": "Error",
|
||||
"code": 2487
|
||||
},
|
||||
@@ -1751,6 +1731,34 @@
|
||||
"category": "Error",
|
||||
"code": 2535
|
||||
},
|
||||
"Type '{0}' is not constrained to 'keyof {1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2536
|
||||
},
|
||||
"Type '{0}' has no matching index signature for type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2537
|
||||
},
|
||||
"Type '{0}' cannot be used as an index type.": {
|
||||
"category": "Error",
|
||||
"code": 2538
|
||||
},
|
||||
"Cannot assign to '{0}' because it is not a variable.": {
|
||||
"category": "Error",
|
||||
"code": 2539
|
||||
},
|
||||
"Cannot assign to '{0}' because it is a constant or a read-only property.": {
|
||||
"category": "Error",
|
||||
"code": 2540
|
||||
},
|
||||
"The target of an assignment must be a variable or a property access.": {
|
||||
"category": "Error",
|
||||
"code": 2541
|
||||
},
|
||||
"Index signature in type '{0}' only permits reading.": {
|
||||
"category": "Error",
|
||||
"code": 2542
|
||||
},
|
||||
"JSX element attributes type '{0}' may not be a union type.": {
|
||||
"category": "Error",
|
||||
"code": 2600
|
||||
@@ -1843,6 +1851,10 @@
|
||||
"category": "Error",
|
||||
"code": 2664
|
||||
},
|
||||
"Invalid module name in augmentation. Module '{0}' resolves to an untyped module at '{1}', which cannot be augmented.": {
|
||||
"category": "Error",
|
||||
"code": 2665
|
||||
},
|
||||
"Exports and export assignments are not permitted in module augmentations.": {
|
||||
"category": "Error",
|
||||
"code": 2666
|
||||
@@ -1967,10 +1979,18 @@
|
||||
"category": "Error",
|
||||
"code": 2696
|
||||
},
|
||||
<<<<<<< HEAD
|
||||
"Static property '{0}' conflicts with built-in property 'Function.{0}' of constructor function '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2699
|
||||
},
|
||||
=======
|
||||
"An async function or method must return a 'Promise'. Make sure you have a declaration for 'Promise' or include 'ES2015' in your `--lib` option.": {
|
||||
"category": "Error",
|
||||
"code": 2697
|
||||
},
|
||||
|
||||
>>>>>>> upstream/master
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 4000
|
||||
@@ -2699,7 +2719,7 @@
|
||||
"category": "Message",
|
||||
"code": 6099
|
||||
},
|
||||
"'package.json' does not have 'types' field.": {
|
||||
"'package.json' does not have a 'types' or 'main' field.": {
|
||||
"category": "Message",
|
||||
"code": 6100
|
||||
},
|
||||
@@ -2847,7 +2867,7 @@
|
||||
"category": "Message",
|
||||
"code": 6136
|
||||
},
|
||||
"No types specified in 'package.json' but 'allowJs' is set, so returning 'main' value of '{0}'": {
|
||||
"No types specified in 'package.json', so returning 'main' value of '{0}'": {
|
||||
"category": "Message",
|
||||
"code": 6137
|
||||
},
|
||||
@@ -2867,6 +2887,22 @@
|
||||
"category": "Message",
|
||||
"code": 6141
|
||||
},
|
||||
"Module '{0}' was resolved to '{1}', but '--jsx' is not set.": {
|
||||
"category": "Error",
|
||||
"code": 6142
|
||||
},
|
||||
"Module '{0}' was resolved to '{1}', but '--allowJs' is not set.": {
|
||||
"category": "Error",
|
||||
"code": 6143
|
||||
},
|
||||
"Module '{0}' was resolved as locally declared ambient module in file '{1}'.": {
|
||||
"category": "Message",
|
||||
"code": 6144
|
||||
},
|
||||
"Module '{0}' was resolved as ambient module declared in '{1}' since this file was not modified.": {
|
||||
"category": "Message",
|
||||
"code": 6145
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type.": {
|
||||
"category": "Error",
|
||||
"code": 7005
|
||||
@@ -2899,7 +2935,11 @@
|
||||
"category": "Error",
|
||||
"code": 7015
|
||||
},
|
||||
"Index signature of object type implicitly has an 'any' type.": {
|
||||
"Could not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.": {
|
||||
"category": "Error",
|
||||
"code": 7016
|
||||
},
|
||||
"Element implicitly has an 'any' type because type '{0}' has no index signature.": {
|
||||
"category": "Error",
|
||||
"code": 7017
|
||||
},
|
||||
@@ -3079,6 +3119,7 @@
|
||||
"category": "Error",
|
||||
"code": 17010
|
||||
},
|
||||
|
||||
"Circularity detected while resolving configuration: {0}": {
|
||||
"category": "Error",
|
||||
"code": 18000
|
||||
@@ -3087,6 +3128,15 @@
|
||||
"category": "Error",
|
||||
"code": 18001
|
||||
},
|
||||
"The 'files' list in config file '{0}' is empty.": {
|
||||
"category": "Error",
|
||||
"code": 18002
|
||||
},
|
||||
"No inputs were found in config file '{0}'. Specified 'include' paths were '{1}' and 'exclude' paths were '{2}'.": {
|
||||
"category": "Error",
|
||||
"code": 18003
|
||||
},
|
||||
|
||||
"Add missing 'super()' call.": {
|
||||
"category": "Message",
|
||||
"code": 90001
|
||||
@@ -3114,5 +3164,9 @@
|
||||
"Implement inherited abstract class": {
|
||||
"category": "Message",
|
||||
"code": 90007
|
||||
},
|
||||
"Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig": {
|
||||
"category": "Error",
|
||||
"code": 90009
|
||||
}
|
||||
}
|
||||
|
||||
+30
-13
@@ -14,7 +14,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const id = (s: SourceFile) => s;
|
||||
const nullTransformers: Transformer[] = [ctx => id];
|
||||
const nullTransformers: Transformer[] = [_ => id];
|
||||
|
||||
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
|
||||
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean): EmitResult {
|
||||
@@ -593,7 +593,11 @@ const _super = (function (geti, seti) {
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return emitExpressionWithTypeArguments(<ExpressionWithTypeArguments>node);
|
||||
case SyntaxKind.ThisType:
|
||||
return emitThisType(<ThisTypeNode>node);
|
||||
return emitThisType();
|
||||
case SyntaxKind.TypeOperator:
|
||||
return emitTypeOperator(<TypeOperatorNode>node);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return emitPropertyAccessType(<IndexedAccessTypeNode>node);
|
||||
case SyntaxKind.LiteralType:
|
||||
return emitLiteralType(<LiteralTypeNode>node);
|
||||
|
||||
@@ -609,7 +613,7 @@ const _super = (function (geti, seti) {
|
||||
case SyntaxKind.TemplateSpan:
|
||||
return emitTemplateSpan(<TemplateSpan>node);
|
||||
case SyntaxKind.SemicolonClassElement:
|
||||
return emitSemicolonClassElement(<SemicolonClassElement>node);
|
||||
return emitSemicolonClassElement();
|
||||
|
||||
// Statements
|
||||
case SyntaxKind.Block:
|
||||
@@ -617,7 +621,7 @@ const _super = (function (geti, seti) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
return emitVariableStatement(<VariableStatement>node);
|
||||
case SyntaxKind.EmptyStatement:
|
||||
return emitEmptyStatement(<EmptyStatement>node);
|
||||
return emitEmptyStatement();
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
return emitExpressionStatement(<ExpressionStatement>node);
|
||||
case SyntaxKind.IfStatement:
|
||||
@@ -1014,7 +1018,7 @@ const _super = (function (geti, seti) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
function emitSemicolonClassElement(node: SemicolonClassElement) {
|
||||
function emitSemicolonClassElement() {
|
||||
write(";");
|
||||
}
|
||||
|
||||
@@ -1084,10 +1088,23 @@ const _super = (function (geti, seti) {
|
||||
write(")");
|
||||
}
|
||||
|
||||
function emitThisType(node: ThisTypeNode) {
|
||||
function emitThisType() {
|
||||
write("this");
|
||||
}
|
||||
|
||||
function emitTypeOperator(node: TypeOperatorNode) {
|
||||
writeTokenText(node.operator);
|
||||
write(" ");
|
||||
emit(node.type);
|
||||
}
|
||||
|
||||
function emitPropertyAccessType(node: IndexedAccessTypeNode) {
|
||||
emit(node.objectType);
|
||||
write("[");
|
||||
emit(node.indexType);
|
||||
write("]");
|
||||
}
|
||||
|
||||
function emitLiteralType(node: LiteralTypeNode) {
|
||||
emitExpression(node.literal);
|
||||
}
|
||||
@@ -1397,7 +1414,7 @@ const _super = (function (geti, seti) {
|
||||
// Statements
|
||||
//
|
||||
|
||||
function emitBlock(node: Block, format?: ListFormat) {
|
||||
function emitBlock(node: Block) {
|
||||
if (isSingleLineEmptyBlock(node)) {
|
||||
writeToken(SyntaxKind.OpenBraceToken, node.pos, /*contextNode*/ node);
|
||||
write(" ");
|
||||
@@ -1425,7 +1442,7 @@ const _super = (function (geti, seti) {
|
||||
write(";");
|
||||
}
|
||||
|
||||
function emitEmptyStatement(node: EmptyStatement) {
|
||||
function emitEmptyStatement() {
|
||||
write(";");
|
||||
}
|
||||
|
||||
@@ -1623,13 +1640,13 @@ const _super = (function (geti, seti) {
|
||||
|
||||
if (getEmitFlags(node) & EmitFlags.ReuseTempVariableScope) {
|
||||
emitSignatureHead(node);
|
||||
emitBlockFunctionBody(node, body);
|
||||
emitBlockFunctionBody(body);
|
||||
}
|
||||
else {
|
||||
const savedTempFlags = tempFlags;
|
||||
tempFlags = 0;
|
||||
emitSignatureHead(node);
|
||||
emitBlockFunctionBody(node, body);
|
||||
emitBlockFunctionBody(body);
|
||||
tempFlags = savedTempFlags;
|
||||
}
|
||||
|
||||
@@ -1656,7 +1673,7 @@ const _super = (function (geti, seti) {
|
||||
emitWithPrefix(": ", node.type);
|
||||
}
|
||||
|
||||
function shouldEmitBlockFunctionBodyOnSingleLine(parentNode: Node, body: Block) {
|
||||
function shouldEmitBlockFunctionBodyOnSingleLine(body: Block) {
|
||||
// We must emit a function body as a single-line body in the following case:
|
||||
// * The body has NodeEmitFlags.SingleLine specified.
|
||||
|
||||
@@ -1694,12 +1711,12 @@ const _super = (function (geti, seti) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function emitBlockFunctionBody(parentNode: Node, body: Block) {
|
||||
function emitBlockFunctionBody(body: Block) {
|
||||
write(" {");
|
||||
increaseIndent();
|
||||
|
||||
emitBodyWithDetachedComments(body, body.statements,
|
||||
shouldEmitBlockFunctionBodyOnSingleLine(parentNode, body)
|
||||
shouldEmitBlockFunctionBodyOnSingleLine(body)
|
||||
? emitBlockFunctionBodyOnSingleLine
|
||||
: emitBlockFunctionBodyWorker);
|
||||
|
||||
|
||||
+155
-46
@@ -109,12 +109,12 @@ namespace ts {
|
||||
export function createLiteral(value: string | number | boolean, location?: TextRange): PrimaryExpression;
|
||||
export function createLiteral(value: string | number | boolean | StringLiteral | Identifier, location?: TextRange): PrimaryExpression {
|
||||
if (typeof value === "number") {
|
||||
const node = <LiteralExpression>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
|
||||
const node = <NumericLiteral>createNode(SyntaxKind.NumericLiteral, location, /*flags*/ undefined);
|
||||
node.text = value.toString();
|
||||
return node;
|
||||
}
|
||||
else if (typeof value === "boolean") {
|
||||
return <PrimaryExpression>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined);
|
||||
return <BooleanLiteral>createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, location, /*flags*/ undefined);
|
||||
}
|
||||
else if (typeof value === "string") {
|
||||
const node = <StringLiteral>createNode(SyntaxKind.StringLiteral, location, /*flags*/ undefined);
|
||||
@@ -226,20 +226,7 @@ namespace ts {
|
||||
|
||||
// Signature elements
|
||||
|
||||
export function createParameter(name: string | Identifier | BindingPattern, initializer?: Expression, location?: TextRange) {
|
||||
return createParameterDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
initializer,
|
||||
location
|
||||
);
|
||||
}
|
||||
|
||||
export function createParameterDeclaration(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken: QuestionToken, type: TypeNode, initializer: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
export function createParameter(decorators: Decorator[], modifiers: Modifier[], dotDotDotToken: DotDotDotToken, name: string | Identifier | BindingPattern, questionToken?: QuestionToken, type?: TypeNode, initializer?: Expression, location?: TextRange, flags?: NodeFlags) {
|
||||
const node = <ParameterDeclaration>createNode(SyntaxKind.Parameter, location, flags);
|
||||
node.decorators = decorators ? createNodeArray(decorators) : undefined;
|
||||
node.modifiers = modifiers ? createNodeArray(modifiers) : undefined;
|
||||
@@ -251,9 +238,9 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function updateParameterDeclaration(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
|
||||
export function updateParameter(node: ParameterDeclaration, decorators: Decorator[], modifiers: Modifier[], name: BindingName, type: TypeNode, initializer: Expression) {
|
||||
if (node.decorators !== decorators || node.modifiers !== modifiers || node.name !== name || node.type !== type || node.initializer !== initializer) {
|
||||
return updateNode(createParameterDeclaration(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
|
||||
return updateNode(createParameter(decorators, modifiers, node.dotDotDotToken, name, node.questionToken, type, initializer, /*location*/ node, /*flags*/ node.flags), node);
|
||||
}
|
||||
|
||||
return node;
|
||||
@@ -1474,6 +1461,28 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a synthetic element to act as a placeholder for the end of an emitted declaration in
|
||||
* order to properly emit exports.
|
||||
*/
|
||||
export function createEndOfDeclarationMarker(original: Node) {
|
||||
const node = <EndOfDeclarationMarker>createNode(SyntaxKind.EndOfDeclarationMarker);
|
||||
node.emitNode = {};
|
||||
node.original = original;
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a synthetic element to act as a placeholder for the beginning of a merged declaration in
|
||||
* order to properly emit exports.
|
||||
*/
|
||||
export function createMergeDeclarationMarker(original: Node) {
|
||||
const node = <MergeDeclarationMarker>createNode(SyntaxKind.MergeDeclarationMarker);
|
||||
node.emitNode = {};
|
||||
node.original = original;
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a synthetic expression to act as a placeholder for a not-emitted expression in
|
||||
* order to preserve comments or sourcemap positions.
|
||||
@@ -1557,18 +1566,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function createRestParameter(name: string | Identifier) {
|
||||
return createParameterDeclaration(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
createToken(SyntaxKind.DotDotDotToken),
|
||||
name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined
|
||||
);
|
||||
}
|
||||
|
||||
export function createFunctionCall(func: Expression, thisArg: Expression, argumentsList: Expression[], location?: TextRange) {
|
||||
return createCall(
|
||||
createPropertyAccess(func, "call"),
|
||||
@@ -1625,7 +1622,9 @@ namespace ts {
|
||||
// flag and setting a parent node.
|
||||
const react = createIdentifier(reactNamespace || "React");
|
||||
react.flags &= ~NodeFlags.Synthesized;
|
||||
react.parent = parent;
|
||||
// Set the parent that is in parse tree
|
||||
// this makes sure that parent chain is intact for checker to traverse complete scope tree
|
||||
react.parent = getParseTreeNode(parent);
|
||||
return react;
|
||||
}
|
||||
|
||||
@@ -1662,6 +1661,18 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
export function createExportDefault(expression: Expression) {
|
||||
return createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, expression);
|
||||
}
|
||||
|
||||
export function createExternalModuleExport(exportName: Identifier) {
|
||||
return createExportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createNamedExports([createExportSpecifier(exportName)]));
|
||||
}
|
||||
|
||||
export function createLetStatement(name: Identifier, initializer: Expression, location?: TextRange) {
|
||||
return createVariableStatement(/*modifiers*/ undefined, createLetDeclarationList([createVariableDeclaration(name, /*type*/ undefined, initializer)]), location);
|
||||
}
|
||||
|
||||
export function createLetDeclarationList(declarations: VariableDeclaration[], location?: TextRange) {
|
||||
return createVariableDeclarationList(declarations, location, NodeFlags.Let);
|
||||
}
|
||||
@@ -1781,13 +1792,10 @@ namespace ts {
|
||||
return createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter("name")],
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name")],
|
||||
/*type*/ undefined,
|
||||
/*equalsGreaterThanToken*/ undefined,
|
||||
createElementAccess(
|
||||
target,
|
||||
createIdentifier("name")
|
||||
)
|
||||
createToken(SyntaxKind.EqualsGreaterThanToken),
|
||||
createElementAccess(target, createIdentifier("name"))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1797,11 +1805,11 @@ namespace ts {
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[
|
||||
createParameter("name"),
|
||||
createParameter("value")
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name"),
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "value")
|
||||
],
|
||||
/*type*/ undefined,
|
||||
/*equalsGreaterThanToken*/ undefined,
|
||||
createToken(SyntaxKind.EqualsGreaterThanToken),
|
||||
createAssignment(
|
||||
createElementAccess(
|
||||
target,
|
||||
@@ -1853,7 +1861,7 @@ namespace ts {
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
"value",
|
||||
[createParameter("v")],
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "v")],
|
||||
createBlock([
|
||||
createStatement(
|
||||
createCall(
|
||||
@@ -1873,9 +1881,9 @@ namespace ts {
|
||||
createArrowFunction(
|
||||
/*modifiers*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter("name")],
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "name")],
|
||||
/*type*/ undefined,
|
||||
/*equalsGreaterThanToken*/ undefined,
|
||||
createToken(SyntaxKind.EqualsGreaterThanToken),
|
||||
createLogicalOr(
|
||||
createElementAccess(
|
||||
createIdentifier("cache"),
|
||||
@@ -1915,8 +1923,8 @@ namespace ts {
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[
|
||||
createParameter("geti"),
|
||||
createParameter("seti")
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "geti"),
|
||||
createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "seti")
|
||||
],
|
||||
/*type*/ undefined,
|
||||
createBlock([
|
||||
@@ -2193,6 +2201,107 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local name of a declaration. This is primarily used for declarations that can be
|
||||
* referred to by name in the declaration's immediate scope (classes, enums, namespaces). A
|
||||
* local name will *never* be prefixed with an module or namespace export modifier like
|
||||
* "exports." when emitted as an expression.
|
||||
*
|
||||
* @param node The declaration.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
export function getLocalName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
|
||||
return getName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether an identifier should only be referred to by its local name.
|
||||
*/
|
||||
export function isLocalName(node: Identifier) {
|
||||
return (getEmitFlags(node) & EmitFlags.LocalName) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the export name of a declaration. This is primarily used for declarations that can be
|
||||
* referred to by name in the declaration's immediate scope (classes, enums, namespaces). An
|
||||
* export name will *always* be prefixed with an module or namespace export modifier like
|
||||
* `"exports."` when emitted as an expression if the name points to an exported symbol.
|
||||
*
|
||||
* @param node The declaration.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
export function getExportName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier {
|
||||
return getName(node, allowComments, allowSourceMaps, EmitFlags.ExportName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether an identifier should only be referred to by its export representation if the
|
||||
* name points to an exported symbol.
|
||||
*/
|
||||
export function isExportName(node: Identifier) {
|
||||
return (getEmitFlags(node) & EmitFlags.ExportName) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a declaration for use in declarations.
|
||||
*
|
||||
* @param node The declaration.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
export function getDeclarationName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean) {
|
||||
return getName(node, allowComments, allowSourceMaps);
|
||||
}
|
||||
|
||||
function getName(node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
if (node.name && isIdentifier(node.name) && !isGeneratedIdentifier(node.name)) {
|
||||
const name = getMutableClone(node.name);
|
||||
emitFlags |= getEmitFlags(node.name);
|
||||
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
|
||||
if (!allowComments) emitFlags |= EmitFlags.NoComments;
|
||||
if (emitFlags) setEmitFlags(name, emitFlags);
|
||||
return name;
|
||||
}
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the exported name of a declaration for use in expressions.
|
||||
*
|
||||
* An exported name will *always* be prefixed with an module or namespace export modifier like
|
||||
* "exports." if the name points to an exported symbol.
|
||||
*
|
||||
* @param ns The namespace identifier.
|
||||
* @param node The declaration.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
export function getExternalModuleOrNamespaceExportName(ns: Identifier | undefined, node: Declaration, allowComments?: boolean, allowSourceMaps?: boolean): Identifier | PropertyAccessExpression {
|
||||
if (ns && hasModifier(node, ModifierFlags.Export)) {
|
||||
return getNamespaceMemberName(ns, getName(node), allowComments, allowSourceMaps);
|
||||
}
|
||||
return getExportName(node, allowComments, allowSourceMaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a namespace-qualified name for use in expressions.
|
||||
*
|
||||
* @param ns The namespace identifier.
|
||||
* @param name The name.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
export function getNamespaceMemberName(ns: Identifier, name: Identifier, allowComments?: boolean, allowSourceMaps?: boolean): PropertyAccessExpression {
|
||||
const qualifiedName = createPropertyAccess(ns, nodeIsSynthesized(name) ? name : getSynthesizedClone(name), /*location*/ name);
|
||||
let emitFlags: EmitFlags;
|
||||
if (!allowSourceMaps) emitFlags |= EmitFlags.NoSourceMap;
|
||||
if (!allowComments) emitFlags |= EmitFlags.NoComments;
|
||||
if (emitFlags) setEmitFlags(qualifiedName, emitFlags);
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
// Utilities
|
||||
|
||||
function isUseStrictPrologue(node: ExpressionStatement): boolean {
|
||||
@@ -2246,7 +2355,7 @@ namespace ts {
|
||||
|
||||
/**
|
||||
* Ensures "use strict" directive is added
|
||||
*
|
||||
*
|
||||
* @param node source file
|
||||
*/
|
||||
export function ensureUseStrict(node: SourceFile): SourceFile {
|
||||
|
||||
+210
-156
@@ -5,7 +5,7 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage, ...args: any[]): void;
|
||||
export function trace(host: ModuleResolutionHost, message: DiagnosticMessage): void {
|
||||
export function trace(host: ModuleResolutionHost): void {
|
||||
host.trace(formatMessage.apply(undefined, arguments));
|
||||
}
|
||||
|
||||
@@ -14,27 +14,77 @@ namespace ts {
|
||||
return compilerOptions.traceResolution && host.trace !== undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
return { resolvedModule: resolvedFileName ? { resolvedFileName, isExternalLibraryImport } : undefined, failedLookupLocations };
|
||||
/**
|
||||
* Result of trying to resolve a module.
|
||||
* At least one of `ts` and `js` should be defined, or the whole thing should be `undefined`.
|
||||
*/
|
||||
interface Resolved {
|
||||
path: string;
|
||||
extension: Extension;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kinds of file that we are currently looking for.
|
||||
* Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript.
|
||||
*/
|
||||
const enum Extensions {
|
||||
TypeScript, /** '.ts', '.tsx', or '.d.ts' */
|
||||
JavaScript, /** '.js' or '.jsx' */
|
||||
DtsOnly /** Only '.d.ts' */
|
||||
}
|
||||
|
||||
/** Used with `Extensions.DtsOnly` to extract the path from TypeScript results. */
|
||||
function resolvedTypeScriptOnly(resolved: Resolved | undefined): string | undefined {
|
||||
if (!resolved) {
|
||||
return undefined;
|
||||
}
|
||||
Debug.assert(extensionIsTypeScript(resolved.extension));
|
||||
return resolved.path;
|
||||
}
|
||||
|
||||
/** Create Resolved from a file with unknown extension. */
|
||||
function resolvedFromAnyFile(path: string): Resolved | undefined {
|
||||
return { path, extension: extensionFromPath(path) };
|
||||
}
|
||||
|
||||
/** Adds `isExernalLibraryImport` to a Resolved to get a ResolvedModule. */
|
||||
function resolvedModuleFromResolved({ path, extension }: Resolved, isExternalLibraryImport: boolean): ResolvedModuleFull {
|
||||
return { resolvedFileName: path, extension, isExternalLibraryImport };
|
||||
}
|
||||
|
||||
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
|
||||
return { resolvedModule: resolved && resolvedModuleFromResolved(resolved, isExternalLibraryImport), failedLookupLocations };
|
||||
}
|
||||
|
||||
function moduleHasNonRelativeName(moduleName: string): boolean {
|
||||
return !(isRootedDiskPath(moduleName) || isExternalModuleNameRelative(moduleName));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface ModuleResolutionState {
|
||||
interface ModuleResolutionState {
|
||||
host: ModuleResolutionHost;
|
||||
compilerOptions: CompilerOptions;
|
||||
// We only use this subset of the compiler options.
|
||||
compilerOptions: { rootDirs?: string[], baseUrl?: string, paths?: MapLike<string[]> };
|
||||
traceEnabled: boolean;
|
||||
// skip .tsx files if jsx is not enabled
|
||||
skipTsx: boolean;
|
||||
}
|
||||
|
||||
function tryReadTypesSection(packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
function tryReadTypesSection(extensions: Extensions, packageJsonPath: string, baseDirectory: string, state: ModuleResolutionState): string {
|
||||
const jsonContent = readJson(packageJsonPath, state.host);
|
||||
|
||||
switch (extensions) {
|
||||
case Extensions.DtsOnly:
|
||||
case Extensions.TypeScript:
|
||||
return tryReadFromField("typings") || tryReadFromField("types");
|
||||
|
||||
case Extensions.JavaScript:
|
||||
if (typeof jsonContent.main === "string") {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.No_types_specified_in_package_json_so_returning_main_value_of_0, jsonContent.main);
|
||||
}
|
||||
return normalizePath(combinePaths(baseDirectory, jsonContent.main));
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryReadFromField(fieldName: string) {
|
||||
if (hasProperty(jsonContent, fieldName)) {
|
||||
const typesFile = (<any>jsonContent)[fieldName];
|
||||
@@ -52,21 +102,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const typesFilePath = tryReadFromField("typings") || tryReadFromField("types");
|
||||
if (typesFilePath) {
|
||||
return typesFilePath;
|
||||
}
|
||||
|
||||
// Use the main module for inferring types if no types package specified and the allowJs is set
|
||||
if (state.compilerOptions.allowJs && jsonContent.main && typeof jsonContent.main === "string") {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.No_types_specified_in_package_json_but_allowJs_is_set_so_returning_main_value_of_0, jsonContent.main);
|
||||
}
|
||||
const mainFilePath = normalizePath(combinePaths(baseDirectory, jsonContent.main));
|
||||
return mainFilePath;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function readJson(path: string, host: ModuleResolutionHost): { typings?: string, types?: string, main?: string } {
|
||||
@@ -80,8 +115,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
const typeReferenceExtensions = [".d.ts"];
|
||||
|
||||
export function getEffectiveTypeRoots(options: CompilerOptions, host: { directoryExists?: (directoryName: string) => boolean, getCurrentDirectory?: () => string }): string[] | undefined {
|
||||
if (options.typeRoots) {
|
||||
return options.typeRoots;
|
||||
@@ -132,12 +165,11 @@ namespace ts {
|
||||
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
|
||||
* is assumed to be the same as root directory of the project.
|
||||
*/
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(options, host);
|
||||
const moduleResolutionState: ModuleResolutionState = {
|
||||
compilerOptions: options,
|
||||
host: host,
|
||||
skipTsx: true,
|
||||
traceEnabled
|
||||
};
|
||||
|
||||
@@ -168,19 +200,20 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
|
||||
}
|
||||
const primarySearchPaths = typeRoots;
|
||||
for (const typeRoot of primarySearchPaths) {
|
||||
for (const typeRoot of typeRoots) {
|
||||
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName);
|
||||
const candidateDirectory = getDirectoryPath(candidate);
|
||||
const resolvedFile = loadNodeModuleFromDirectory(typeReferenceExtensions, candidate, failedLookupLocations,
|
||||
!directoryProbablyExists(candidateDirectory, host), moduleResolutionState);
|
||||
|
||||
if (resolvedFile) {
|
||||
const resolved = resolvedTypeScriptOnly(
|
||||
loadNodeModuleFromDirectory(Extensions.DtsOnly, candidate, failedLookupLocations,
|
||||
!directoryProbablyExists(candidateDirectory, host), moduleResolutionState));
|
||||
|
||||
if (resolved) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, true);
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved, true);
|
||||
}
|
||||
return {
|
||||
resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolvedFile },
|
||||
resolvedTypeReferenceDirective: { primary: true, resolvedFileName: resolved },
|
||||
failedLookupLocations
|
||||
};
|
||||
}
|
||||
@@ -193,17 +226,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
let resolvedFile: string;
|
||||
let initialLocationForSecondaryLookup: string;
|
||||
if (containingFile) {
|
||||
initialLocationForSecondaryLookup = getDirectoryPath(containingFile);
|
||||
}
|
||||
const initialLocationForSecondaryLookup = containingFile && getDirectoryPath(containingFile);
|
||||
|
||||
if (initialLocationForSecondaryLookup !== undefined) {
|
||||
// check secondary locations
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
|
||||
}
|
||||
resolvedFile = loadModuleFromNodeModules(typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false);
|
||||
resolvedFile = resolvedTypeScriptOnly(loadModuleFromNodeModules(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, failedLookupLocations, moduleResolutionState, /*checkOneLevel*/ false));
|
||||
if (traceEnabled) {
|
||||
if (resolvedFile) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFile, false);
|
||||
@@ -219,9 +249,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
return {
|
||||
resolvedTypeReferenceDirective: resolvedFile
|
||||
? { primary: false, resolvedFileName: resolvedFile }
|
||||
: undefined,
|
||||
resolvedTypeReferenceDirective: resolvedFile ? { primary: false, resolvedFileName: resolvedFile } : undefined,
|
||||
failedLookupLocations
|
||||
};
|
||||
}
|
||||
@@ -313,7 +341,7 @@ namespace ts {
|
||||
* 'typings' entry or file 'index' with some supported extension
|
||||
* - Classic loader will only try to interpret '/a/b/c' as file.
|
||||
*/
|
||||
type ResolutionKindSpecificLoader = (candidate: string, extensions: string[], failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState) => string;
|
||||
type ResolutionKindSpecificLoader = (extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState) => Resolved | undefined;
|
||||
|
||||
/**
|
||||
* Any module resolution kind can be augmented with optional settings: 'baseUrl', 'paths' and 'rootDirs' - they are used to
|
||||
@@ -375,19 +403,19 @@ namespace ts {
|
||||
* be converted to a path relative to found rootDir entry './content/protocols/file2' (*). As a last step compiler will check all remaining
|
||||
* entries in 'rootDirs', use them to build absolute path out of (*) and try to resolve module from this location.
|
||||
*/
|
||||
function tryLoadModuleUsingOptionalResolutionSettings(moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
failedLookupLocations: string[], supportedExtensions: string[], state: ModuleResolutionState): string {
|
||||
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
return tryLoadModuleUsingBaseUrl(moduleName, loader, failedLookupLocations, supportedExtensions, state);
|
||||
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, failedLookupLocations, state);
|
||||
}
|
||||
else {
|
||||
return tryLoadModuleUsingRootDirs(moduleName, containingDirectory, loader, failedLookupLocations, supportedExtensions, state);
|
||||
return tryLoadModuleUsingRootDirs(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
|
||||
}
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingRootDirs(moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
failedLookupLocations: string[], supportedExtensions: string[], state: ModuleResolutionState): string {
|
||||
function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
if (!state.compilerOptions.rootDirs) {
|
||||
return undefined;
|
||||
@@ -432,7 +460,7 @@ namespace ts {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, matchedNormalizedPrefix, candidate);
|
||||
}
|
||||
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
|
||||
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(containingDirectory, state.host), state);
|
||||
if (resolvedFileName) {
|
||||
return resolvedFileName;
|
||||
}
|
||||
@@ -451,7 +479,7 @@ namespace ts {
|
||||
trace(state.host, Diagnostics.Loading_0_from_the_root_dir_1_candidate_location_2, suffix, rootDir, candidate);
|
||||
}
|
||||
const baseDirectory = getDirectoryPath(candidate);
|
||||
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
|
||||
const resolvedFileName = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(baseDirectory, state.host), state);
|
||||
if (resolvedFileName) {
|
||||
return resolvedFileName;
|
||||
}
|
||||
@@ -463,9 +491,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingBaseUrl(moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: string[],
|
||||
supportedExtensions: string[], state: ModuleResolutionState): string {
|
||||
|
||||
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
|
||||
if (!state.compilerOptions.baseUrl) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -494,9 +520,9 @@ namespace ts {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Trying_substitution_0_candidate_module_location_Colon_1, subst, path);
|
||||
}
|
||||
const resolvedFileName = loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
|
||||
if (resolvedFileName) {
|
||||
return resolvedFileName;
|
||||
const resolved = loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@@ -508,56 +534,64 @@ namespace ts {
|
||||
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, state.compilerOptions.baseUrl, candidate);
|
||||
}
|
||||
|
||||
return loader(candidate, supportedExtensions, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
|
||||
return loader(extensions, candidate, failedLookupLocations, !directoryProbablyExists(getDirectoryPath(candidate), state.host), state);
|
||||
}
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions);
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state = { compilerOptions, host, traceEnabled, skipTsx: false };
|
||||
let resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, nodeLoadModuleByRelativeName,
|
||||
failedLookupLocations, supportedExtensions, state);
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
|
||||
|
||||
const result = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
|
||||
if (result) {
|
||||
const { resolved, isExternalLibraryImport } = result;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved && resolvedWithRealpath(resolved, host, traceEnabled), isExternalLibraryImport, failedLookupLocations);
|
||||
}
|
||||
return { resolvedModule: undefined, failedLookupLocations };
|
||||
|
||||
function tryResolve(extensions: Extensions): { resolved: Resolved, isExternalLibraryImport: boolean } | undefined {
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, nodeLoadModuleByRelativeName, failedLookupLocations, state);
|
||||
if (resolved) {
|
||||
return { resolved, isExternalLibraryImport: false };
|
||||
}
|
||||
|
||||
let isExternalLibraryImport = false;
|
||||
if (!resolvedFileName) {
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder, moduleName);
|
||||
}
|
||||
resolvedFileName = loadModuleFromNodeModules(moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
|
||||
isExternalLibraryImport = resolvedFileName !== undefined;
|
||||
const resolved = loadModuleFromNodeModules(extensions, moduleName, containingDirectory, failedLookupLocations, state, /*checkOneLevel*/ false);
|
||||
return resolved && { resolved, isExternalLibraryImport: true };
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
resolvedFileName = nodeLoadModuleByRelativeName(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
const resolved = nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
return resolved && { resolved, isExternalLibraryImport: false };
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedFileName && host.realpath) {
|
||||
const originalFileName = resolvedFileName;
|
||||
resolvedFileName = normalizePath(host.realpath(resolvedFileName));
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_real_path_for_0_result_1, originalFileName, resolvedFileName);
|
||||
}
|
||||
}
|
||||
|
||||
return createResolvedModule(resolvedFileName, isExternalLibraryImport, failedLookupLocations);
|
||||
}
|
||||
|
||||
function nodeLoadModuleByRelativeName(candidate: string, supportedExtensions: string[], failedLookupLocations: string[],
|
||||
onlyRecordFailures: boolean, state: ModuleResolutionState): string {
|
||||
function resolvedWithRealpath(resolved: Resolved, host: ModuleResolutionHost, traceEnabled: boolean): Resolved {
|
||||
if (!host.realpath) {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
const real = normalizePath(host.realpath(resolved.path));
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_real_path_for_0_result_1, resolved.path, real);
|
||||
}
|
||||
return { path: real, extension: resolved.extension };
|
||||
}
|
||||
|
||||
function nodeLoadModuleByRelativeName(extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Loading_module_as_file_Slash_folder_candidate_module_location_0, candidate);
|
||||
}
|
||||
|
||||
const resolvedFileName = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, onlyRecordFailures, state);
|
||||
|
||||
return resolvedFileName || loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, onlyRecordFailures, state);
|
||||
const resolvedFromFile = !pathEndsWithDirectorySeparator(candidate) && loadModuleFromFile(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
|
||||
return resolvedFromFile || loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, onlyRecordFailures, state);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -570,9 +604,9 @@ namespace ts {
|
||||
* @param {boolean} onlyRecordFailures - if true then function won't try to actually load files but instead record all attempts as failures. This flag is necessary
|
||||
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
|
||||
*/
|
||||
function loadModuleFromFile(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
|
||||
function loadModuleFromFile(extensions: Extensions, candidate: string, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
|
||||
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocation, onlyRecordFailures, state);
|
||||
const resolvedByAddingExtension = tryAddingExtensions(candidate, extensions, failedLookupLocations, onlyRecordFailures, state);
|
||||
if (resolvedByAddingExtension) {
|
||||
return resolvedByAddingExtension;
|
||||
}
|
||||
@@ -585,12 +619,12 @@ namespace ts {
|
||||
const extension = candidate.substring(extensionless.length);
|
||||
trace(state.host, Diagnostics.File_name_0_has_a_1_extension_stripping_it, candidate, extension);
|
||||
}
|
||||
return tryAddingExtensions(extensionless, extensions, failedLookupLocation, onlyRecordFailures, state);
|
||||
return tryAddingExtensions(extensionless, extensions, failedLookupLocations, onlyRecordFailures, state);
|
||||
}
|
||||
}
|
||||
|
||||
/** Try to return an existing file that adds one of the `extensions` to `candidate`. */
|
||||
function tryAddingExtensions(candidate: string, extensions: string[], failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string | undefined {
|
||||
function tryAddingExtensions(candidate: string, extensions: Extensions, failedLookupLocations: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
if (!onlyRecordFailures) {
|
||||
// check if containing folder exists - if it doesn't then just record failures for all supported extensions without disk probing
|
||||
const directory = getDirectoryPath(candidate);
|
||||
@@ -598,8 +632,20 @@ namespace ts {
|
||||
onlyRecordFailures = !directoryProbablyExists(directory, state.host);
|
||||
}
|
||||
}
|
||||
return forEach(extensions, ext =>
|
||||
!(state.skipTsx && isJsxOrTsxExtension(ext)) && tryFile(candidate + ext, failedLookupLocation, onlyRecordFailures, state));
|
||||
|
||||
switch (extensions) {
|
||||
case Extensions.DtsOnly:
|
||||
return tryExtension(".d.ts", Extension.Dts);
|
||||
case Extensions.TypeScript:
|
||||
return tryExtension(".ts", Extension.Ts) || tryExtension(".tsx", Extension.Tsx) || tryExtension(".d.ts", Extension.Dts);
|
||||
case Extensions.JavaScript:
|
||||
return tryExtension(".js", Extension.Js) || tryExtension(".jsx", Extension.Jsx);
|
||||
}
|
||||
|
||||
function tryExtension(ext: string, extension: Extension): Resolved | undefined {
|
||||
const path = tryFile(candidate + ext, failedLookupLocations, onlyRecordFailures, state);
|
||||
return path && { path, extension };
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the file if it exists. */
|
||||
@@ -619,26 +665,31 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectory(extensions: string[], candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): string {
|
||||
function loadNodeModuleFromDirectory(extensions: Extensions, candidate: string, failedLookupLocation: string[], onlyRecordFailures: boolean, state: ModuleResolutionState): Resolved | undefined {
|
||||
const packageJsonPath = pathToPackageJson(candidate);
|
||||
const directoryExists = !onlyRecordFailures && directoryProbablyExists(candidate, state.host);
|
||||
|
||||
if (directoryExists && state.host.fileExists(packageJsonPath)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Found_package_json_at_0, packageJsonPath);
|
||||
}
|
||||
const typesFile = tryReadTypesSection(packageJsonPath, candidate, state);
|
||||
const typesFile = tryReadTypesSection(extensions, packageJsonPath, candidate, state);
|
||||
if (typesFile) {
|
||||
const onlyRecordFailures = !directoryProbablyExists(getDirectoryPath(typesFile), state.host);
|
||||
// A package.json "typings" may specify an exact filename, or may choose to omit an extension.
|
||||
const result = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state) ||
|
||||
tryAddingExtensions(typesFile, extensions, failedLookupLocation, onlyRecordFailures, state);
|
||||
if (result) {
|
||||
return result;
|
||||
const fromFile = tryFile(typesFile, failedLookupLocation, onlyRecordFailures, state);
|
||||
if (fromFile) {
|
||||
// Note: this would allow a package.json to specify a ".js" file as typings. Maybe that should be forbidden.
|
||||
return resolvedFromAnyFile(fromFile);
|
||||
}
|
||||
const x = tryAddingExtensions(typesFile, Extensions.TypeScript, failedLookupLocation, onlyRecordFailures, state);
|
||||
if (x) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.package_json_does_not_have_types_field);
|
||||
trace(state.host, Diagnostics.package_json_does_not_have_a_types_or_main_field);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -650,104 +701,90 @@ namespace ts {
|
||||
failedLookupLocation.push(packageJsonPath);
|
||||
}
|
||||
|
||||
return loadModuleFromFile(combinePaths(candidate, "index"), extensions, failedLookupLocation, !directoryExists, state);
|
||||
return loadModuleFromFile(extensions, combinePaths(candidate, "index"), failedLookupLocation, !directoryExists, state);
|
||||
}
|
||||
|
||||
function pathToPackageJson(directory: string): string {
|
||||
return combinePaths(directory, "package.json");
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesFolder(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
|
||||
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
|
||||
const nodeModulesFolder = combinePaths(directory, "node_modules");
|
||||
const nodeModulesFolderExists = directoryProbablyExists(nodeModulesFolder, state.host);
|
||||
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName));
|
||||
const supportedExtensions = getSupportedExtensions(state.compilerOptions);
|
||||
|
||||
let result = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = loadNodeModuleFromDirectory(supportedExtensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
return loadModuleFromFile(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state) ||
|
||||
loadNodeModuleFromDirectory(extensions, candidate, failedLookupLocations, !nodeModulesFolderExists, state);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function loadModuleFromNodeModules(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): string {
|
||||
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
|
||||
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean): Resolved | undefined {
|
||||
return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, checkOneLevel, /*typesOnly*/ false);
|
||||
}
|
||||
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
|
||||
return loadModuleFromNodeModulesWorker(Extensions.TypeScript, moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesAtTypes(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState): string {
|
||||
return loadModuleFromNodeModulesWorker(moduleName, directory, failedLookupLocations, state, /*checkOneLevel*/ false, /*typesOnly*/ true);
|
||||
}
|
||||
|
||||
function loadModuleFromNodeModulesWorker(moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): string {
|
||||
function loadModuleFromNodeModulesWorker(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: string[], state: ModuleResolutionState, checkOneLevel: boolean, typesOnly: boolean): Resolved | undefined {
|
||||
directory = normalizeSlashes(directory);
|
||||
while (true) {
|
||||
const baseName = getBaseFileName(directory);
|
||||
if (baseName !== "node_modules") {
|
||||
let packageResult: string | undefined;
|
||||
if (!typesOnly) {
|
||||
// Try to load source from the package
|
||||
packageResult = loadModuleFromNodeModulesFolder(moduleName, directory, failedLookupLocations, state);
|
||||
if (packageResult && hasTypeScriptFileExtension(packageResult)) {
|
||||
// Always prefer a TypeScript (.ts, .tsx, .d.ts) file shipped with the package
|
||||
return packageResult;
|
||||
}
|
||||
}
|
||||
|
||||
// Else prefer a types package over non-TypeScript results (e.g. JavaScript files)
|
||||
const typesResult = loadModuleFromNodeModulesFolder(combinePaths("@types", moduleName), directory, failedLookupLocations, state);
|
||||
if (typesResult || packageResult) {
|
||||
return typesResult || packageResult;
|
||||
if (getBaseFileName(directory) !== "node_modules") {
|
||||
const resolved = tryInDirectory();
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
const parentPath = getDirectoryPath(directory);
|
||||
if (parentPath === directory || checkOneLevel) {
|
||||
break;
|
||||
return undefined;
|
||||
}
|
||||
|
||||
directory = parentPath;
|
||||
}
|
||||
return undefined;
|
||||
|
||||
function tryInDirectory(): Resolved | undefined {
|
||||
const packageResult = typesOnly ? undefined : loadModuleFromNodeModulesFolder(extensions, moduleName, directory, failedLookupLocations, state);
|
||||
return packageResult || loadModuleFromNodeModulesFolder(extensions, combinePaths("@types", moduleName), directory, failedLookupLocations, state);
|
||||
}
|
||||
}
|
||||
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
const state = { compilerOptions, host, traceEnabled, skipTsx: !compilerOptions.jsx };
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
|
||||
const failedLookupLocations: string[] = [];
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions);
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
|
||||
const resolvedFileName = tryLoadModuleUsingOptionalResolutionSettings(moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, supportedExtensions, state);
|
||||
if (resolvedFileName) {
|
||||
return createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/false, failedLookupLocations);
|
||||
}
|
||||
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ false, failedLookupLocations);
|
||||
|
||||
let referencedSourceFile: string;
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
referencedSourceFile = referencedSourceFile = loadModuleFromAncestorDirectories(moduleName, containingDirectory, supportedExtensions, failedLookupLocations, state) ||
|
||||
// If we didn't find the file normally, look it up in @types.
|
||||
loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
referencedSourceFile = loadModuleFromFile(candidate, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
}
|
||||
function tryResolve(extensions: Extensions): Resolved | undefined {
|
||||
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFile, failedLookupLocations, state);
|
||||
if (resolvedUsingSettings) {
|
||||
return resolvedUsingSettings;
|
||||
}
|
||||
|
||||
|
||||
return referencedSourceFile
|
||||
? { resolvedModule: { resolvedFileName: referencedSourceFile }, failedLookupLocations }
|
||||
: { resolvedModule: undefined, failedLookupLocations };
|
||||
if (moduleHasNonRelativeName(moduleName)) {
|
||||
const resolved = loadModuleFromAncestorDirectories(extensions, moduleName, containingDirectory, failedLookupLocations, state);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
if (extensions === Extensions.TypeScript) {
|
||||
// If we didn't find the file normally, look it up in @types.
|
||||
return loadModuleFromNodeModulesAtTypes(moduleName, containingDirectory, failedLookupLocations, state);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const candidate = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
return loadModuleFromFile(extensions, candidate, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Climb up parent directories looking for a module. */
|
||||
function loadModuleFromAncestorDirectories(moduleName: string, containingDirectory: string, supportedExtensions: string[], failedLookupLocations: string[], state: ModuleResolutionState): string | undefined {
|
||||
function loadModuleFromAncestorDirectories(extensions: Extensions, moduleName: string, containingDirectory: string, failedLookupLocations: string[], state: ModuleResolutionState): Resolved | undefined {
|
||||
while (true) {
|
||||
const searchName = normalizePath(combinePaths(containingDirectory, moduleName));
|
||||
const referencedSourceFile = loadModuleFromFile(searchName, supportedExtensions, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
const referencedSourceFile = loadModuleFromFile(extensions, searchName, failedLookupLocations, /*onlyRecordFailures*/ false, state);
|
||||
if (referencedSourceFile) {
|
||||
return referencedSourceFile;
|
||||
}
|
||||
@@ -758,4 +795,21 @@ namespace ts {
|
||||
containingDirectory = parentPath;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* LSHost may load a module from a global cache of typings.
|
||||
* This is the minumum code needed to expose that functionality; the rest is in LSHost.
|
||||
*/
|
||||
/* @internal */
|
||||
export function loadModuleFromGlobalCache(moduleName: string, projectName: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, globalCache: string): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, projectName, moduleName, globalCache);
|
||||
}
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
|
||||
const failedLookupLocations: string[] = [];
|
||||
const resolved = loadModuleFromNodeModules(Extensions.TypeScript, moduleName, globalCache, failedLookupLocations, state, /*checkOneLevel*/ true) ||
|
||||
loadModuleFromNodeModules(Extensions.JavaScript, moduleName, globalCache, failedLookupLocations, state, /*checkOneLevel*/ true);
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
|
||||
}
|
||||
}
|
||||
+81
-21
@@ -134,7 +134,11 @@ namespace ts {
|
||||
case SyntaxKind.IntersectionType:
|
||||
return visitNodes(cbNodes, (<UnionOrIntersectionTypeNode>node).types);
|
||||
case SyntaxKind.ParenthesizedType:
|
||||
return visitNode(cbNode, (<ParenthesizedTypeNode>node).type);
|
||||
case SyntaxKind.TypeOperator:
|
||||
return visitNode(cbNode, (<ParenthesizedTypeNode | TypeOperatorNode>node).type);
|
||||
case SyntaxKind.IndexedAccessType:
|
||||
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
|
||||
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
|
||||
case SyntaxKind.LiteralType:
|
||||
return visitNode(cbNode, (<LiteralTypeNode>node).literal);
|
||||
case SyntaxKind.ObjectBindingPattern:
|
||||
@@ -411,6 +415,7 @@ namespace ts {
|
||||
return visitNodes(cbNodes, (<JSDocTemplateTag>node).typeParameters);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return visitNode(cbNode, (<JSDocTypedefTag>node).typeExpression) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).fullName) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).name) ||
|
||||
visitNode(cbNode, (<JSDocTypedefTag>node).jsDocTypeLiteral);
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
@@ -572,10 +577,10 @@ namespace ts {
|
||||
// attached to the EOF token.
|
||||
let parseErrorBeforeNextFinishedNode = false;
|
||||
|
||||
export function parseSourceFile(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
|
||||
export function parseSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, syntaxCursor: IncrementalParser.SyntaxCursor, setParentNodes?: boolean, scriptKind?: ScriptKind): SourceFile {
|
||||
scriptKind = ensureScriptKind(fileName, scriptKind);
|
||||
|
||||
initializeState(fileName, _sourceText, languageVersion, _syntaxCursor, scriptKind);
|
||||
initializeState(sourceText, languageVersion, syntaxCursor, scriptKind);
|
||||
|
||||
const result = parseSourceFileWorker(fileName, languageVersion, setParentNodes, scriptKind);
|
||||
|
||||
@@ -589,7 +594,7 @@ namespace ts {
|
||||
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS ? LanguageVariant.JSX : LanguageVariant.Standard;
|
||||
}
|
||||
|
||||
function initializeState(fileName: string, _sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
|
||||
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
|
||||
NodeConstructor = objectAllocator.getNodeConstructor();
|
||||
TokenConstructor = objectAllocator.getTokenConstructor();
|
||||
IdentifierConstructor = objectAllocator.getIdentifierConstructor();
|
||||
@@ -2518,14 +2523,39 @@ namespace ts {
|
||||
function parseArrayTypeOrHigher(): TypeNode {
|
||||
let type = parseNonArrayType();
|
||||
while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
const node = <ArrayTypeNode>createNode(SyntaxKind.ArrayType, type.pos);
|
||||
node.elementType = type;
|
||||
type = finishNode(node);
|
||||
if (isStartOfType()) {
|
||||
const node = <IndexedAccessTypeNode>createNode(SyntaxKind.IndexedAccessType, type.pos);
|
||||
node.objectType = type;
|
||||
node.indexType = parseType();
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
type = finishNode(node);
|
||||
}
|
||||
else {
|
||||
const node = <ArrayTypeNode>createNode(SyntaxKind.ArrayType, type.pos);
|
||||
node.elementType = type;
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
type = finishNode(node);
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword) {
|
||||
const node = <TypeOperatorNode>createNode(SyntaxKind.TypeOperator);
|
||||
parseExpected(operator);
|
||||
node.operator = operator;
|
||||
node.type = parseTypeOperatorOrHigher();
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function parseTypeOperatorOrHigher(): TypeNode {
|
||||
switch (token()) {
|
||||
case SyntaxKind.KeyOfKeyword:
|
||||
return parseTypeOperator(SyntaxKind.KeyOfKeyword);
|
||||
}
|
||||
return parseArrayTypeOrHigher();
|
||||
}
|
||||
|
||||
function parseUnionOrIntersectionType(kind: SyntaxKind, parseConstituentType: () => TypeNode, operator: SyntaxKind): TypeNode {
|
||||
let type = parseConstituentType();
|
||||
if (token() === operator) {
|
||||
@@ -2542,7 +2572,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseIntersectionTypeOrHigher(): TypeNode {
|
||||
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseArrayTypeOrHigher, SyntaxKind.AmpersandToken);
|
||||
return parseUnionOrIntersectionType(SyntaxKind.IntersectionType, parseTypeOperatorOrHigher, SyntaxKind.AmpersandToken);
|
||||
}
|
||||
|
||||
function parseUnionTypeOrHigher(): TypeNode {
|
||||
@@ -5259,7 +5289,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.ClassKeyword);
|
||||
node.name = parseNameOfClassDeclarationOrExpression();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
|
||||
node.heritageClauses = parseHeritageClauses();
|
||||
|
||||
if (parseExpected(SyntaxKind.OpenBraceToken)) {
|
||||
// ClassTail[Yield,Await] : (Modified) See 14.5
|
||||
@@ -5289,7 +5319,7 @@ namespace ts {
|
||||
return token() === SyntaxKind.ImplementsKeyword && lookAhead(nextTokenIsIdentifierOrKeyword);
|
||||
}
|
||||
|
||||
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
|
||||
function parseHeritageClauses(): NodeArray<HeritageClause> {
|
||||
// ClassTail[Yield,Await] : (Modified) See 14.5
|
||||
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
|
||||
|
||||
@@ -5337,7 +5367,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.InterfaceKeyword);
|
||||
node.name = parseIdentifier();
|
||||
node.typeParameters = parseTypeParameters();
|
||||
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ false);
|
||||
node.heritageClauses = parseHeritageClauses();
|
||||
node.members = parseObjectTypeMembers();
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
@@ -5472,7 +5502,7 @@ namespace ts {
|
||||
|
||||
exportDeclaration.name = parseIdentifier();
|
||||
|
||||
parseExpected(SyntaxKind.SemicolonToken);
|
||||
parseSemicolon();
|
||||
|
||||
return finishNode(exportDeclaration);
|
||||
}
|
||||
@@ -5817,7 +5847,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function parseJSDocTypeExpressionForTests(content: string, start: number, length: number) {
|
||||
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
sourceFile = createSourceFile("file.js", ScriptTarget.Latest, ScriptKind.JS);
|
||||
scanner.setText(content, start, length);
|
||||
currentToken = scanner.scan();
|
||||
@@ -6134,7 +6164,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function parseIsolatedJSDocComment(content: string, start: number, length: number) {
|
||||
initializeState("file.js", content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
initializeState(content, ScriptTarget.Latest, /*_syntaxCursor:*/ undefined, ScriptKind.JS);
|
||||
sourceFile = <SourceFile>{ languageVariant: LanguageVariant.Standard, text: content };
|
||||
const jsDoc = parseJSDocCommentWorker(start, length);
|
||||
const diagnostics = parseDiagnostics;
|
||||
@@ -6552,7 +6582,14 @@ namespace ts {
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
|
||||
typedefTag.atToken = atToken;
|
||||
typedefTag.tagName = tagName;
|
||||
typedefTag.name = parseJSDocIdentifierName();
|
||||
typedefTag.fullName = parseJSDocTypeNameWithNamespace(/*flags*/ 0);
|
||||
if (typedefTag.fullName) {
|
||||
let rightNode = typedefTag.fullName;
|
||||
while (rightNode.kind !== SyntaxKind.Identifier) {
|
||||
rightNode = rightNode.body;
|
||||
}
|
||||
typedefTag.name = rightNode;
|
||||
}
|
||||
typedefTag.typeExpression = typeExpression;
|
||||
skipWhitespace();
|
||||
|
||||
@@ -6615,8 +6652,27 @@ namespace ts {
|
||||
scanner.setTextPos(resumePos);
|
||||
return finishNode(jsDocTypeLiteral);
|
||||
}
|
||||
|
||||
function parseJSDocTypeNameWithNamespace(flags: NodeFlags) {
|
||||
const pos = scanner.getTokenPos();
|
||||
const typeNameOrNamespaceName = parseJSDocIdentifierName();
|
||||
|
||||
if (typeNameOrNamespaceName && parseOptional(SyntaxKind.DotToken)) {
|
||||
const jsDocNamespaceNode = <JSDocNamespaceDeclaration>createNode(SyntaxKind.ModuleDeclaration, pos);
|
||||
jsDocNamespaceNode.flags |= flags;
|
||||
jsDocNamespaceNode.name = typeNameOrNamespaceName;
|
||||
jsDocNamespaceNode.body = parseJSDocTypeNameWithNamespace(NodeFlags.NestedNamespace);
|
||||
return jsDocNamespaceNode;
|
||||
}
|
||||
|
||||
if (typeNameOrNamespaceName && flags & NodeFlags.NestedNamespace) {
|
||||
typeNameOrNamespaceName.isInJSDocNamespace = true;
|
||||
}
|
||||
return typeNameOrNamespaceName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function tryParseChildTag(parentTag: JSDocTypeLiteral): boolean {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getStartPos());
|
||||
@@ -6639,12 +6695,16 @@ namespace ts {
|
||||
return true;
|
||||
case "prop":
|
||||
case "property":
|
||||
if (!parentTag.jsDocPropertyTags) {
|
||||
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
|
||||
}
|
||||
const propertyTag = parsePropertyTag(atToken, tagName);
|
||||
parentTag.jsDocPropertyTags.push(propertyTag);
|
||||
return true;
|
||||
if (propertyTag) {
|
||||
if (!parentTag.jsDocPropertyTags) {
|
||||
parentTag.jsDocPropertyTags = <NodeArray<JSDocPropertyTag>>[];
|
||||
}
|
||||
parentTag.jsDocPropertyTags.push(propertyTag);
|
||||
return true;
|
||||
}
|
||||
// Error parsing property tag
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace ts.performance {
|
||||
|
||||
const profilerEvent = typeof onProfilerEvent === "function" && onProfilerEvent.profiler === true
|
||||
? onProfilerEvent
|
||||
: (markName: string) => { };
|
||||
: (_markName: string) => { };
|
||||
|
||||
let enabled = false;
|
||||
let profilerStart = 0;
|
||||
|
||||
+277
-104
@@ -239,11 +239,11 @@ namespace ts {
|
||||
const { line, character } = getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start);
|
||||
const fileName = diagnostic.file.fileName;
|
||||
const relativeFileName = convertToRelativePath(fileName, host.getCurrentDirectory(), fileName => host.getCanonicalFileName(fileName));
|
||||
output += `${ relativeFileName }(${ line + 1 },${ character + 1 }): `;
|
||||
output += `${relativeFileName}(${line + 1},${character + 1}): `;
|
||||
}
|
||||
|
||||
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
|
||||
output += `${ category } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }${ host.getNewLine() }`;
|
||||
output += `${category} TS${diagnostic.code}: ${flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine())}${host.getNewLine()}`;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
@@ -307,7 +307,7 @@ namespace ts {
|
||||
// - This calls resolveModuleNames, and then calls findSourceFile for each resolved module.
|
||||
// As all these operations happen - and are nested - within the createProgram call, they close over the below variables.
|
||||
// The current resolution depth is tracked by incrementing/decrementing as the depth first search progresses.
|
||||
const maxNodeModulesJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
|
||||
const maxNodeModuleJsDepth = typeof options.maxNodeModuleJsDepth === "number" ? options.maxNodeModuleJsDepth : 0;
|
||||
let currentNodeModulesDepth = 0;
|
||||
|
||||
// If a module has some of its imports skipped due to being at the depth limit under node_modules, then track
|
||||
@@ -329,9 +329,17 @@ namespace ts {
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createFileMap<boolean>(getCanonicalFileName);
|
||||
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModule[];
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string) => ResolvedModuleFull[];
|
||||
if (host.resolveModuleNames) {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile);
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => host.resolveModuleNames(moduleNames, containingFile).map(resolved => {
|
||||
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
|
||||
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
|
||||
return resolved as ResolvedModuleFull;
|
||||
}
|
||||
const withExtension = clone(resolved) as ResolvedModuleFull;
|
||||
withExtension.extension = extensionFromPath(resolved.resolvedFileName);
|
||||
return withExtension;
|
||||
});
|
||||
}
|
||||
else {
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host).resolvedModule;
|
||||
@@ -454,6 +462,130 @@ namespace ts {
|
||||
return classifiableNames;
|
||||
}
|
||||
|
||||
interface OldProgramState {
|
||||
program: Program;
|
||||
file: SourceFile;
|
||||
modifiedFilePaths: Path[];
|
||||
}
|
||||
|
||||
function resolveModuleNamesReusingOldState(moduleNames: string[], containingFile: string, file: SourceFile, oldProgramState?: OldProgramState) {
|
||||
if (!oldProgramState && !file.ambientModuleNames.length) {
|
||||
// if old program state is not supplied and file does not contain locally defined ambient modules
|
||||
// then the best we can do is fallback to the default logic
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
}
|
||||
|
||||
// at this point we know that either
|
||||
// - file has local declarations for ambient modules
|
||||
// OR
|
||||
// - old program state is available
|
||||
// OR
|
||||
// - both of items above
|
||||
// With this it is possible that we can tell how some module names from the initial list will be resolved
|
||||
// without doing actual resolution (in particular if some name was resolved to ambient module).
|
||||
// Such names should be excluded from the list of module names that will be provided to `resolveModuleNamesWorker`
|
||||
// since we don't want to resolve them again.
|
||||
|
||||
// this is a list of modules for which we cannot predict resolution so they should be actually resolved
|
||||
let unknownModuleNames: string[];
|
||||
// this is a list of combined results assembles from predicted and resolved results.
|
||||
// Order in this list matches the order in the original list of module names `moduleNames` which is important
|
||||
// so later we can split results to resolutions of modules and resolutions of module augmentations.
|
||||
let result: ResolvedModuleFull[];
|
||||
// a transient placeholder that is used to mark predicted resolution in the result list
|
||||
const predictedToResolveToAmbientModuleMarker: ResolvedModuleFull = <any>{};
|
||||
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const moduleName = moduleNames[i];
|
||||
// module name is known to be resolved to ambient module if
|
||||
// - module name is contained in the list of ambient modules that are locally declared in the file
|
||||
// - in the old program module name was resolved to ambient module whose declaration is in non-modified file
|
||||
// (so the same module declaration will land in the new program)
|
||||
let isKnownToResolveToAmbientModule = false;
|
||||
if (contains(file.ambientModuleNames, moduleName)) {
|
||||
isKnownToResolveToAmbientModule = true;
|
||||
if (isTraceEnabled(options, host)) {
|
||||
trace(host, Diagnostics.Module_0_was_resolved_as_locally_declared_ambient_module_in_file_1, moduleName, containingFile);
|
||||
}
|
||||
}
|
||||
else {
|
||||
isKnownToResolveToAmbientModule = checkModuleNameResolvedToAmbientModuleInNonModifiedFile(moduleName, oldProgramState);
|
||||
}
|
||||
|
||||
if (isKnownToResolveToAmbientModule) {
|
||||
if (!unknownModuleNames) {
|
||||
// found a first module name for which result can be prediced
|
||||
// this means that this module name should not be passed to `resolveModuleNamesWorker`.
|
||||
// We'll use a separate list for module names that are definitely unknown.
|
||||
result = new Array(moduleNames.length);
|
||||
// copy all module names that appear before the current one in the list
|
||||
// since they are known to be unknown
|
||||
unknownModuleNames = moduleNames.slice(0, i);
|
||||
}
|
||||
// mark prediced resolution in the result list
|
||||
result[i] = predictedToResolveToAmbientModuleMarker;
|
||||
}
|
||||
else if (unknownModuleNames) {
|
||||
// found unknown module name and we are already using separate list for those - add it to the list
|
||||
unknownModuleNames.push(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
if (!unknownModuleNames) {
|
||||
// we've looked throught the list but have not seen any predicted resolution
|
||||
// use default logic
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
}
|
||||
|
||||
const resolutions = unknownModuleNames.length
|
||||
? resolveModuleNamesWorker(unknownModuleNames, containingFile)
|
||||
: emptyArray;
|
||||
|
||||
// combine results of resolutions and predicted results
|
||||
let j = 0;
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
if (result[i] == predictedToResolveToAmbientModuleMarker) {
|
||||
result[i] = undefined;
|
||||
}
|
||||
else {
|
||||
result[i] = resolutions[j];
|
||||
j++;
|
||||
}
|
||||
}
|
||||
Debug.assert(j === resolutions.length);
|
||||
return result;
|
||||
|
||||
function checkModuleNameResolvedToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState?: OldProgramState): boolean {
|
||||
if (!oldProgramState) {
|
||||
return false;
|
||||
}
|
||||
const resolutionToFile = getResolvedModule(oldProgramState.file, moduleName);
|
||||
if (resolutionToFile) {
|
||||
// module used to be resolved to file - ignore it
|
||||
return false;
|
||||
}
|
||||
const ambientModule = oldProgram.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
|
||||
if (!(ambientModule && ambientModule.declarations)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// at least one of declarations should come from non-modified source file
|
||||
const firstUnmodifiedFile = forEach(ambientModule.declarations, d => {
|
||||
const f = getSourceFileOfNode(d);
|
||||
return !contains(oldProgramState.modifiedFilePaths, f.path) && f;
|
||||
});
|
||||
|
||||
if (!firstUnmodifiedFile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(options, host)) {
|
||||
trace(host, Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, firstUnmodifiedFile.fileName);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function tryReuseStructureFromOldProgram(): boolean {
|
||||
if (!oldProgram) {
|
||||
return false;
|
||||
@@ -462,21 +594,7 @@ namespace ts {
|
||||
// check properties that can affect structure of the program or module resolution strategy
|
||||
// if any of these properties has changed - structure cannot be reused
|
||||
const oldOptions = oldProgram.getCompilerOptions();
|
||||
if ((oldOptions.module !== options.module) ||
|
||||
(oldOptions.moduleResolution !== options.moduleResolution) ||
|
||||
(oldOptions.noResolve !== options.noResolve) ||
|
||||
(oldOptions.target !== options.target) ||
|
||||
(oldOptions.noLib !== options.noLib) ||
|
||||
(oldOptions.jsx !== options.jsx) ||
|
||||
(oldOptions.allowJs !== options.allowJs) ||
|
||||
(oldOptions.rootDir !== options.rootDir) ||
|
||||
(oldOptions.configFilePath !== options.configFilePath) ||
|
||||
(oldOptions.baseUrl !== options.baseUrl) ||
|
||||
(oldOptions.maxNodeModuleJsDepth !== options.maxNodeModuleJsDepth) ||
|
||||
!arrayIsEqualTo(oldOptions.lib, options.lib) ||
|
||||
!arrayIsEqualTo(oldOptions.typeRoots, oldOptions.typeRoots) ||
|
||||
!arrayIsEqualTo(oldOptions.rootDirs, options.rootDirs) ||
|
||||
!equalOwnProperties(oldOptions.paths, options.paths)) {
|
||||
if (changesAffectModuleResolution(oldOptions, options)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -495,7 +613,7 @@ namespace ts {
|
||||
// check if program source files has changed in the way that can affect structure of the program
|
||||
const newSourceFiles: SourceFile[] = [];
|
||||
const filePaths: Path[] = [];
|
||||
const modifiedSourceFiles: SourceFile[] = [];
|
||||
const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = [];
|
||||
|
||||
for (const oldSourceFile of oldProgram.getSourceFiles()) {
|
||||
let newSourceFile = host.getSourceFileByPath
|
||||
@@ -538,29 +656,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesWorker(moduleNames, newSourceFilePath);
|
||||
// ensure that module resolution results are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (resolveTypeReferenceDirectiveNamesWorker) {
|
||||
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
|
||||
// ensure that types resolutions are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// pass the cache of module/types resolutions from the old source file
|
||||
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
|
||||
newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
|
||||
modifiedSourceFiles.push(newSourceFile);
|
||||
// tentatively approve the file
|
||||
modifiedSourceFiles.push({ oldFile: oldSourceFile, newFile: newSourceFile });
|
||||
}
|
||||
else {
|
||||
// file has no changes - use it as is
|
||||
@@ -571,6 +668,33 @@ namespace ts {
|
||||
newSourceFiles.push(newSourceFile);
|
||||
}
|
||||
|
||||
const modifiedFilePaths = modifiedSourceFiles.map(f => f.newFile.path);
|
||||
// try to verify results of module resolution
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = map(concatenate(newSourceFile.imports, newSourceFile.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, { file: oldSourceFile, program: oldProgram, modifiedFilePaths });
|
||||
// ensure that module resolution results are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (resolveTypeReferenceDirectiveNamesWorker) {
|
||||
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
|
||||
// ensure that types resolutions are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// pass the cache of module/types resolutions from the old source file
|
||||
newSourceFile.resolvedModules = oldSourceFile.resolvedModules;
|
||||
newSourceFile.resolvedTypeReferenceDirectiveNames = oldSourceFile.resolvedTypeReferenceDirectiveNames;
|
||||
}
|
||||
|
||||
// update fileName -> file mapping
|
||||
for (let i = 0, len = newSourceFiles.length; i < len; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
@@ -580,7 +704,7 @@ namespace ts {
|
||||
fileProcessingDiagnostics = oldProgram.getFileProcessingDiagnostics();
|
||||
|
||||
for (const modifiedFile of modifiedSourceFiles) {
|
||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile);
|
||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
|
||||
}
|
||||
resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
|
||||
oldProgram.structureIsReused = true;
|
||||
@@ -724,7 +848,15 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
// For JavaScript files, we report semantic errors for using TypeScript-only
|
||||
// constructs from within a JavaScript file as syntactic errors.
|
||||
if (isSourceFileJavaScript(sourceFile)) {
|
||||
if (!sourceFile.additionalSyntacticDiagnostics) {
|
||||
sourceFile.additionalSyntacticDiagnostics = getJavaScriptSyntacticDiagnosticsForFile(sourceFile);
|
||||
}
|
||||
return concatenate(sourceFile.additionalSyntacticDiagnostics, sourceFile.parseDiagnostics);
|
||||
}
|
||||
return sourceFile.parseDiagnostics;
|
||||
}
|
||||
|
||||
@@ -757,20 +889,18 @@ namespace ts {
|
||||
|
||||
Debug.assert(!!sourceFile.bindDiagnostics);
|
||||
const bindDiagnostics = sourceFile.bindDiagnostics;
|
||||
// For JavaScript files, we don't want to report the normal typescript semantic errors.
|
||||
// Instead, we just report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file.
|
||||
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ?
|
||||
getJavaScriptSemanticDiagnosticsForFile(sourceFile, cancellationToken) :
|
||||
typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
// For JavaScript files, we don't want to report semantic errors.
|
||||
// Instead, we'll report errors for using TypeScript-only constructs from within a
|
||||
// JavaScript file when we get syntactic diagnostics for the file.
|
||||
const checkDiagnostics = isSourceFileJavaScript(sourceFile) ? [] : typeChecker.getDiagnostics(sourceFile, cancellationToken);
|
||||
const fileProcessingDiagnosticsInFile = fileProcessingDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
const programDiagnosticsInFile = programDiagnostics.getDiagnostics(sourceFile.fileName);
|
||||
|
||||
return bindDiagnostics.concat(checkDiagnostics).concat(fileProcessingDiagnosticsInFile).concat(programDiagnosticsInFile);
|
||||
return bindDiagnostics.concat(checkDiagnostics, fileProcessingDiagnosticsInFile, programDiagnosticsInFile);
|
||||
});
|
||||
}
|
||||
|
||||
function getJavaScriptSemanticDiagnosticsForFile(sourceFile: SourceFile, cancellationToken: CancellationToken): Diagnostic[] {
|
||||
function getJavaScriptSyntacticDiagnosticsForFile(sourceFile: SourceFile): Diagnostic[] {
|
||||
return runWithCancellationToken(() => {
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
walk(sourceFile);
|
||||
@@ -950,8 +1080,7 @@ namespace ts {
|
||||
return runWithCancellationToken(() => {
|
||||
const resolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile, cancellationToken);
|
||||
// Don't actually write any files since we're just getting diagnostics.
|
||||
const writeFile: WriteFileCallback = () => { };
|
||||
return ts.getDeclarationDiagnostics(getEmitHost(writeFile), resolver, sourceFile);
|
||||
return ts.getDeclarationDiagnostics(getEmitHost(noop), resolver, sourceFile);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -972,12 +1101,8 @@ namespace ts {
|
||||
return sortAndDeduplicateDiagnostics(allDiagnostics);
|
||||
}
|
||||
|
||||
function hasExtension(fileName: string): boolean {
|
||||
return getBaseFileName(fileName).indexOf(".") >= 0;
|
||||
}
|
||||
|
||||
function processRootFile(fileName: string, isDefaultLib: boolean) {
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib, /*isReference*/ true);
|
||||
processSourceFile(normalizePath(fileName), isDefaultLib);
|
||||
}
|
||||
|
||||
function fileReferenceIsEqualTo(a: FileReference, b: FileReference): boolean {
|
||||
@@ -999,9 +1124,11 @@ namespace ts {
|
||||
|
||||
const isJavaScriptFile = isSourceFileJavaScript(file);
|
||||
const isExternalModuleFile = isExternalModule(file);
|
||||
const isDtsFile = isDeclarationFile(file);
|
||||
|
||||
let imports: LiteralExpression[];
|
||||
let moduleAugmentations: LiteralExpression[];
|
||||
let ambientModules: string[];
|
||||
|
||||
// If we are importing helpers, we need to add a synthetic reference to resolve the
|
||||
// helpers library.
|
||||
@@ -1023,6 +1150,7 @@ namespace ts {
|
||||
|
||||
file.imports = imports || emptyArray;
|
||||
file.moduleAugmentations = moduleAugmentations || emptyArray;
|
||||
file.ambientModuleNames = ambientModules || emptyArray;
|
||||
|
||||
return;
|
||||
|
||||
@@ -1058,6 +1186,10 @@ namespace ts {
|
||||
(moduleAugmentations || (moduleAugmentations = [])).push(moduleName);
|
||||
}
|
||||
else if (!inAmbientModule) {
|
||||
if (isDtsFile) {
|
||||
// for global .d.ts files record name of ambient module
|
||||
(ambientModules || (ambientModules = [])).push(moduleName.text);
|
||||
}
|
||||
// An AmbientExternalModuleDeclaration declares an external module.
|
||||
// This type of declaration is permitted only in the global module.
|
||||
// The StringLiteral must specify a top - level external module name.
|
||||
@@ -1085,10 +1217,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 'isReference' indicates whether the file was brought in via a reference directive (rather than an import declaration)
|
||||
*/
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
|
||||
function processSourceFile(fileName: string, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number) {
|
||||
let diagnosticArgument: string[];
|
||||
let diagnostic: DiagnosticMessage;
|
||||
if (hasExtension(fileName)) {
|
||||
@@ -1096,7 +1225,7 @@ namespace ts {
|
||||
diagnostic = Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1;
|
||||
diagnosticArgument = [fileName, "'" + supportedExtensions.join("', '") + "'"];
|
||||
}
|
||||
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd)) {
|
||||
else if (!findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd)) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
@@ -1106,13 +1235,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd);
|
||||
const nonTsFile: SourceFile = options.allowNonTsExtensions && findSourceFile(fileName, toPath(fileName, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd);
|
||||
if (!nonTsFile) {
|
||||
if (options.allowNonTsExtensions) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
diagnosticArgument = [fileName];
|
||||
}
|
||||
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, isReference, refFile, refPos, refEnd))) {
|
||||
else if (!forEach(supportedExtensions, extension => findSourceFile(fileName + extension, toPath(fileName + extension, currentDirectory, getCanonicalFileName), isDefaultLib, refFile, refPos, refEnd))) {
|
||||
diagnostic = Diagnostics.File_0_not_found;
|
||||
fileName += ".ts";
|
||||
diagnosticArgument = [fileName];
|
||||
@@ -1141,7 +1270,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get source file from normalized fileName
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, isReference: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, refFile?: SourceFile, refPos?: number, refEnd?: number): SourceFile {
|
||||
if (filesByName.contains(path)) {
|
||||
const file = filesByName.get(path);
|
||||
// try to check if we've already seen this file but with a different casing in path
|
||||
@@ -1155,18 +1284,18 @@ namespace ts {
|
||||
if (file && sourceFilesFoundSearchingNodeModules[file.path] && currentNodeModulesDepth == 0) {
|
||||
sourceFilesFoundSearchingNodeModules[file.path] = false;
|
||||
if (!options.noResolve) {
|
||||
processReferencedFiles(file, getDirectoryPath(fileName), isDefaultLib);
|
||||
processReferencedFiles(file, isDefaultLib);
|
||||
processTypeReferenceDirectives(file);
|
||||
}
|
||||
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
processImportedModules(file, getDirectoryPath(fileName));
|
||||
processImportedModules(file);
|
||||
}
|
||||
// See if we need to reprocess the imports due to prior skipped imports
|
||||
else if (file && modulesWithElidedImports[file.path]) {
|
||||
if (currentNodeModulesDepth < maxNodeModulesJsDepth) {
|
||||
if (currentNodeModulesDepth < maxNodeModuleJsDepth) {
|
||||
modulesWithElidedImports[file.path] = false;
|
||||
processImportedModules(file, getDirectoryPath(fileName));
|
||||
processImportedModules(file);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1202,14 +1331,13 @@ namespace ts {
|
||||
|
||||
skipDefaultLib = skipDefaultLib || file.hasNoDefaultLib;
|
||||
|
||||
const basePath = getDirectoryPath(fileName);
|
||||
if (!options.noResolve) {
|
||||
processReferencedFiles(file, basePath, isDefaultLib);
|
||||
processReferencedFiles(file, isDefaultLib);
|
||||
processTypeReferenceDirectives(file);
|
||||
}
|
||||
|
||||
// always process imported modules to record module name resolutions
|
||||
processImportedModules(file, basePath);
|
||||
processImportedModules(file);
|
||||
|
||||
if (isDefaultLib) {
|
||||
files.unshift(file);
|
||||
@@ -1222,10 +1350,10 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, basePath: string, isDefaultLib: boolean) {
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
|
||||
processSourceFile(referencedFileName, isDefaultLib, /*isReference*/ true, file, ref.pos, ref.end);
|
||||
processSourceFile(referencedFileName, isDefaultLib, file, ref.pos, ref.end);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1256,7 +1384,7 @@ namespace ts {
|
||||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
}
|
||||
else {
|
||||
// If we already resolved to this file, it must have been a secondary reference. Check file contents
|
||||
@@ -1276,7 +1404,7 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
// First resolution of this library
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, /*isReference*/ true, refFile, refPos, refEnd);
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName, /*isDefaultLib*/ false, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1302,41 +1430,46 @@ namespace ts {
|
||||
return host.getCanonicalFileName(fileName);
|
||||
}
|
||||
|
||||
function processImportedModules(file: SourceFile, basePath: string) {
|
||||
function processImportedModules(file: SourceFile) {
|
||||
collectExternalModuleReferences(file);
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
file.resolvedModules = createMap<ResolvedModule>();
|
||||
file.resolvedModules = createMap<ResolvedModuleFull>();
|
||||
const moduleNames = map(concatenate(file.imports, file.moduleAugmentations), getTextOfLiteral);
|
||||
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const resolution = resolutions[i];
|
||||
setResolvedModule(file, moduleNames[i], resolution);
|
||||
|
||||
if (!resolution) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const isFromNodeModulesSearch = resolution.isExternalLibraryImport;
|
||||
const isJsFileFromNodeModules = isFromNodeModulesSearch && !extensionIsTypeScript(resolution.extension);
|
||||
const resolvedFileName = resolution.resolvedFileName;
|
||||
|
||||
if (isFromNodeModulesSearch) {
|
||||
currentNodeModulesDepth++;
|
||||
}
|
||||
|
||||
// add file to program only if:
|
||||
// - resolution was successful
|
||||
// - noResolve is falsy
|
||||
// - module name comes from the list of imports
|
||||
// - it's not a top level JavaScript module that exceeded the search max
|
||||
const isFromNodeModulesSearch = resolution && resolution.isExternalLibraryImport;
|
||||
const isJsFileFromNodeModules = isFromNodeModulesSearch && hasJavaScriptFileExtension(resolution.resolvedFileName);
|
||||
|
||||
if (isFromNodeModulesSearch) {
|
||||
currentNodeModulesDepth++;
|
||||
}
|
||||
|
||||
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModulesJsDepth;
|
||||
const shouldAddFile = resolution && !options.noResolve && i < file.imports.length && !elideImport;
|
||||
const elideImport = isJsFileFromNodeModules && currentNodeModulesDepth > maxNodeModuleJsDepth;
|
||||
// Don't add the file if it has a bad extension (e.g. 'tsx' if we don't have '--allowJs')
|
||||
// This may still end up being an untyped module -- the file won't be included but imports will be allowed.
|
||||
const shouldAddFile = resolvedFileName && !getResolutionDiagnostic(options, resolution) && !options.noResolve && i < file.imports.length && !elideImport;
|
||||
|
||||
if (elideImport) {
|
||||
modulesWithElidedImports[file.path] = true;
|
||||
}
|
||||
else if (shouldAddFile) {
|
||||
findSourceFile(resolution.resolvedFileName,
|
||||
toPath(resolution.resolvedFileName, currentDirectory, getCanonicalFileName),
|
||||
/*isDefaultLib*/ false, /*isReference*/ false,
|
||||
file,
|
||||
skipTrivia(file.text, file.imports[i].pos),
|
||||
file.imports[i].end);
|
||||
const path = toPath(resolvedFileName, currentDirectory, getCanonicalFileName);
|
||||
const pos = skipTrivia(file.text, file.imports[i].pos);
|
||||
findSourceFile(resolvedFileName, path, /*isDefaultLib*/ false, file, pos, file.imports[i].end);
|
||||
}
|
||||
|
||||
if (isFromNodeModulesSearch) {
|
||||
@@ -1348,7 +1481,6 @@ namespace ts {
|
||||
// no imports - drop cached module resolutions
|
||||
file.resolvedModules = undefined;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
function computeCommonSourceDirectory(sourceFiles: SourceFile[]): string {
|
||||
@@ -1541,7 +1673,7 @@ namespace ts {
|
||||
if (!options.noEmit && !options.suppressOutputPathCheck) {
|
||||
const emitHost = getEmitHost();
|
||||
const emitFilesSeen = createFileMap<boolean>(!host.useCaseSensitiveFileNames() ? key => key.toLocaleLowerCase() : undefined);
|
||||
forEachExpectedEmitFile(emitHost, (emitFileNames, sourceFiles, isBundledEmit) => {
|
||||
forEachExpectedEmitFile(emitHost, (emitFileNames) => {
|
||||
verifyEmitFilePath(emitFileNames.jsFilePath, emitFilesSeen);
|
||||
verifyEmitFilePath(emitFileNames.declarationFilePath, emitFilesSeen);
|
||||
});
|
||||
@@ -1553,13 +1685,24 @@ namespace ts {
|
||||
const emitFilePath = toPath(emitFileName, currentDirectory, getCanonicalFileName);
|
||||
// Report error if the output overwrites input file
|
||||
if (filesByName.contains(emitFilePath)) {
|
||||
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file);
|
||||
if (options.noEmitOverwritenFiles && !options.out && !options.outDir && !options.outFile) {
|
||||
blockEmittingOfFile(emitFileName);
|
||||
}
|
||||
else {
|
||||
let chain: DiagnosticMessageChain;
|
||||
if (!options.configFilePath) {
|
||||
// The program is from either an inferred project or an external project
|
||||
chain = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Adding_a_tsconfig_json_file_will_help_organize_projects_that_contain_both_TypeScript_and_JavaScript_files_Learn_more_at_https_Colon_Slash_Slashaka_ms_Slashtsconfig);
|
||||
}
|
||||
chain = chainDiagnosticMessages(chain, Diagnostics.Cannot_write_file_0_because_it_would_overwrite_input_file, emitFileName);
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnosticFromMessageChain(chain));
|
||||
}
|
||||
}
|
||||
|
||||
// Report error if multiple files write into same file
|
||||
if (emitFilesSeen.contains(emitFilePath)) {
|
||||
// Already seen the same emit file - report error
|
||||
createEmitBlockingDiagnostics(emitFileName, emitFilePath, Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files);
|
||||
blockEmittingOfFile(emitFileName, createCompilerDiagnostic(Diagnostics.Cannot_write_file_0_because_it_would_be_overwritten_by_multiple_input_files, emitFileName));
|
||||
}
|
||||
else {
|
||||
emitFilesSeen.set(emitFilePath, true);
|
||||
@@ -1568,9 +1711,39 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function createEmitBlockingDiagnostics(emitFileName: string, emitFilePath: Path, message: DiagnosticMessage) {
|
||||
function blockEmittingOfFile(emitFileName: string, diag?: Diagnostic) {
|
||||
hasEmitBlockingDiagnostics.set(toPath(emitFileName, currentDirectory, getCanonicalFileName), true);
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, emitFileName));
|
||||
if (diag) {
|
||||
programDiagnostics.add(diag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
/**
|
||||
* Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
|
||||
* The DiagnosticMessage's parameters are the imported module name, and the filename it resolved to.
|
||||
* This returns a diagnostic even if the module will be an untyped module.
|
||||
*/
|
||||
export function getResolutionDiagnostic(options: CompilerOptions, { extension }: ResolvedModuleFull): DiagnosticMessage | undefined {
|
||||
switch (extension) {
|
||||
case Extension.Ts:
|
||||
case Extension.Dts:
|
||||
// These are always allowed.
|
||||
return undefined;
|
||||
case Extension.Tsx:
|
||||
return needJsx();
|
||||
case Extension.Jsx:
|
||||
return needJsx() || needAllowJs();
|
||||
case Extension.Js:
|
||||
return needAllowJs();
|
||||
}
|
||||
|
||||
function needJsx() {
|
||||
return options.jsx ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_jsx_is_not_set;
|
||||
}
|
||||
function needAllowJs() {
|
||||
return options.allowJs ? undefined : Diagnostics.Module_0_was_resolved_to_1_but_allowJs_is_not_set;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ namespace ts {
|
||||
"instanceof": SyntaxKind.InstanceOfKeyword,
|
||||
"interface": SyntaxKind.InterfaceKeyword,
|
||||
"is": SyntaxKind.IsKeyword,
|
||||
"keyof": SyntaxKind.KeyOfKeyword,
|
||||
"let": SyntaxKind.LetKeyword,
|
||||
"module": SyntaxKind.ModuleKeyword,
|
||||
"namespace": SyntaxKind.NamespaceKeyword,
|
||||
@@ -723,7 +724,7 @@ namespace ts {
|
||||
return iterateCommentRanges(/*reduce*/ true, text, pos, /*trailing*/ true, cb, state, initial);
|
||||
}
|
||||
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, state: any, comments: CommentRange[]) {
|
||||
function appendCommentRange(pos: number, end: number, kind: SyntaxKind, hasTrailingNewLine: boolean, _state: any, comments: CommentRange[]) {
|
||||
if (!comments) {
|
||||
comments = [];
|
||||
}
|
||||
@@ -1799,6 +1800,9 @@ namespace ts {
|
||||
case CharacterCodes.comma:
|
||||
pos++;
|
||||
return token = SyntaxKind.CommaToken;
|
||||
case CharacterCodes.dot:
|
||||
pos++;
|
||||
return token = SyntaxKind.DotToken;
|
||||
}
|
||||
|
||||
if (isIdentifierStart(ch, ScriptTarget.Latest)) {
|
||||
|
||||
+9
-9
@@ -34,6 +34,8 @@ namespace ts {
|
||||
realpath?(path: string): string;
|
||||
/*@internal*/ getEnvironmentVariable(name: string): string;
|
||||
/*@internal*/ tryEnableSourceMapsForHost?(): void;
|
||||
setTimeout?(callback: (...args: any[]) => void, ms: number, ...args: any[]): any;
|
||||
clearTimeout?(timeoutId: any): void;
|
||||
}
|
||||
|
||||
export interface FileWatcher {
|
||||
@@ -46,13 +48,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
declare var require: any;
|
||||
declare var module: any;
|
||||
declare var process: any;
|
||||
declare var global: any;
|
||||
declare var __filename: string;
|
||||
declare var Buffer: {
|
||||
new (str: string, encoding?: string): any;
|
||||
};
|
||||
|
||||
declare class Enumerator {
|
||||
public atEnd(): boolean;
|
||||
@@ -324,7 +322,7 @@ namespace ts {
|
||||
const platform: string = _os.platform();
|
||||
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
|
||||
|
||||
function readFile(fileName: string, encoding?: string): string {
|
||||
function readFile(fileName: string, _encoding?: string): string {
|
||||
if (!fileExists(fileName)) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -564,7 +562,9 @@ namespace ts {
|
||||
catch (e) {
|
||||
// Could not enable source maps.
|
||||
}
|
||||
}
|
||||
},
|
||||
setTimeout,
|
||||
clearTimeout
|
||||
};
|
||||
return nodeSystem;
|
||||
}
|
||||
@@ -576,7 +576,7 @@ namespace ts {
|
||||
args: ChakraHost.args,
|
||||
useCaseSensitiveFileNames: !!ChakraHost.useCaseSensitiveFileNames,
|
||||
write: ChakraHost.echo,
|
||||
readFile(path: string, encoding?: string) {
|
||||
readFile(path: string, _encoding?: string) {
|
||||
// encoding is automatically handled by the implementation in ChakraHost
|
||||
return ChakraHost.readFile(path);
|
||||
},
|
||||
@@ -595,9 +595,9 @@ namespace ts {
|
||||
getExecutingFilePath: () => ChakraHost.executingFile,
|
||||
getCurrentDirectory: () => ChakraHost.currentDirectory,
|
||||
getDirectories: ChakraHost.getDirectories,
|
||||
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || ((name: string) => ""),
|
||||
getEnvironmentVariable: ChakraHost.getEnvironmentVariable || (() => ""),
|
||||
readDirectory: (path: string, extensions?: string[], excludes?: string[], includes?: string[]) => {
|
||||
const pattern = getFileMatcherPatterns(path, extensions, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
|
||||
const pattern = getFileMatcherPatterns(path, excludes, includes, !!ChakraHost.useCaseSensitiveFileNames, ChakraHost.currentDirectory);
|
||||
return ChakraHost.readDirectory(path, extensions, pattern.basePaths, pattern.excludePattern, pattern.includeFilePattern, pattern.includeDirectoryPattern);
|
||||
},
|
||||
exit: ChakraHost.quit,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
/// <reference path="transformers/es2016.ts" />
|
||||
/// <reference path="transformers/es2015.ts" />
|
||||
/// <reference path="transformers/generators.ts" />
|
||||
/// <reference path="transformers/es5.ts" />
|
||||
/// <reference path="transformers/module/module.ts" />
|
||||
/// <reference path="transformers/module/system.ts" />
|
||||
/// <reference path="transformers/module/es2015.ts" />
|
||||
@@ -110,7 +111,6 @@ namespace ts {
|
||||
const transformers: Transformer[] = [];
|
||||
|
||||
transformers.push(transformTypeScript);
|
||||
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
|
||||
|
||||
if (jsx === JsxEmit.React) {
|
||||
transformers.push(transformJsx);
|
||||
@@ -129,6 +129,14 @@ namespace ts {
|
||||
transformers.push(transformGenerators);
|
||||
}
|
||||
|
||||
transformers.push(moduleTransformerMap[moduleKind] || moduleTransformerMap[ModuleKind.None]);
|
||||
|
||||
// The ES5 transformer is last so that it can substitute expressions like `exports.default`
|
||||
// for ES3.
|
||||
if (languageVersion < ScriptTarget.ES5) {
|
||||
transformers.push(transformES5);
|
||||
}
|
||||
|
||||
return transformers;
|
||||
}
|
||||
|
||||
@@ -160,7 +168,7 @@ namespace ts {
|
||||
hoistFunctionDeclaration,
|
||||
startLexicalEnvironment,
|
||||
endLexicalEnvironment,
|
||||
onSubstituteNode: (emitContext, node) => node,
|
||||
onSubstituteNode: (_emitContext, node) => node,
|
||||
enableSubstitution,
|
||||
isSubstitutionEnabled,
|
||||
onEmitNode: (node, emitContext, emitCallback) => emitCallback(node, emitContext),
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace ts {
|
||||
location = value;
|
||||
}
|
||||
|
||||
flattenDestructuring(context, node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, location, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
if (needsValue) {
|
||||
expressions.push(value);
|
||||
@@ -87,13 +87,12 @@ namespace ts {
|
||||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenParameterDestructuring(
|
||||
context: TransformationContext,
|
||||
node: ParameterDeclaration,
|
||||
value: Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
return declarations;
|
||||
|
||||
@@ -123,7 +122,6 @@ namespace ts {
|
||||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenVariableDestructuring(
|
||||
context: TransformationContext,
|
||||
node: VariableDeclaration,
|
||||
value?: Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>,
|
||||
@@ -131,7 +129,7 @@ namespace ts {
|
||||
const declarations: VariableDeclaration[] = [];
|
||||
|
||||
let pendingAssignments: Expression[];
|
||||
flattenDestructuring(context, node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, value, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
return declarations;
|
||||
|
||||
@@ -176,37 +174,39 @@ namespace ts {
|
||||
*
|
||||
* @param node The VariableDeclaration to flatten.
|
||||
* @param recordTempVariable A callback used to record new temporary variables.
|
||||
* @param nameSubstitution An optional callback used to substitute binding names.
|
||||
* @param createAssignmentCallback An optional callback used to create assignment expressions
|
||||
* for non-temporary variables.
|
||||
* @param visitor An optional visitor to use to visit expressions.
|
||||
*/
|
||||
export function flattenVariableDestructuringToExpression(
|
||||
context: TransformationContext,
|
||||
node: VariableDeclaration,
|
||||
recordTempVariable: (name: Identifier) => void,
|
||||
nameSubstitution?: (name: Identifier) => Expression,
|
||||
createAssignmentCallback?: (name: Identifier, value: Expression, location?: TextRange) => Expression,
|
||||
visitor?: (node: Node) => VisitResult<Node>) {
|
||||
|
||||
const pendingAssignments: Expression[] = [];
|
||||
|
||||
flattenDestructuring(context, node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
flattenDestructuring(node, /*value*/ undefined, node, emitAssignment, emitTempVariableAssignment, visitor);
|
||||
|
||||
const expression = inlineExpressions(pendingAssignments);
|
||||
aggregateTransformFlags(expression);
|
||||
return expression;
|
||||
|
||||
function emitAssignment(name: Identifier, value: Expression, location: TextRange, original: Node) {
|
||||
const left = nameSubstitution && nameSubstitution(name) || name;
|
||||
emitPendingAssignment(left, value, location, original);
|
||||
const expression = createAssignmentCallback
|
||||
? createAssignmentCallback(name, value, location)
|
||||
: createAssignment(name, value, location);
|
||||
|
||||
emitPendingAssignment(expression, original);
|
||||
}
|
||||
|
||||
function emitTempVariableAssignment(value: Expression, location: TextRange) {
|
||||
const name = createTempVariable(recordTempVariable);
|
||||
emitPendingAssignment(name, value, location, /*original*/ undefined);
|
||||
emitPendingAssignment(createAssignment(name, value, location), /*original*/ undefined);
|
||||
return name;
|
||||
}
|
||||
|
||||
function emitPendingAssignment(name: Expression, value: Expression, location: TextRange, original: Node) {
|
||||
const expression = createAssignment(name, value, location);
|
||||
function emitPendingAssignment(expression: Expression, original: Node) {
|
||||
expression.original = original;
|
||||
|
||||
// NOTE: this completely disables source maps, but aligns with the behavior of
|
||||
@@ -214,12 +214,10 @@ namespace ts {
|
||||
setEmitFlags(expression, EmitFlags.NoNestedSourceMaps);
|
||||
|
||||
pendingAssignments.push(expression);
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
function flattenDestructuring(
|
||||
context: TransformationContext,
|
||||
root: VariableDeclaration | ParameterDeclaration | BindingElement | BinaryExpression,
|
||||
value: Expression,
|
||||
location: TextRange,
|
||||
|
||||
+138
-125
@@ -186,6 +186,7 @@ namespace ts {
|
||||
let enclosingFunction: FunctionLikeDeclaration;
|
||||
let enclosingNonArrowFunction: FunctionLikeDeclaration;
|
||||
let enclosingNonAsyncFunctionBody: FunctionLikeDeclaration | ClassElement;
|
||||
let isInConstructorWithCapturedSuper: boolean;
|
||||
|
||||
/**
|
||||
* Used to track if we are emitting body of the converted loop
|
||||
@@ -231,14 +232,17 @@ namespace ts {
|
||||
const savedCurrentParent = currentParent;
|
||||
const savedCurrentNode = currentNode;
|
||||
const savedConvertedLoopState = convertedLoopState;
|
||||
const savedIsInConstructorWithCapturedSuper = isInConstructorWithCapturedSuper;
|
||||
if (nodeStartsNewLexicalEnvironment(node)) {
|
||||
// don't treat content of nodes that start new lexical environment as part of converted loop copy
|
||||
// don't treat content of nodes that start new lexical environment as part of converted loop copy or constructor body
|
||||
isInConstructorWithCapturedSuper = false;
|
||||
convertedLoopState = undefined;
|
||||
}
|
||||
|
||||
onBeforeVisitNode(node);
|
||||
const visited = f(node);
|
||||
|
||||
isInConstructorWithCapturedSuper = savedIsInConstructorWithCapturedSuper;
|
||||
convertedLoopState = savedConvertedLoopState;
|
||||
enclosingFunction = savedEnclosingFunction;
|
||||
enclosingNonArrowFunction = savedEnclosingNonArrowFunction;
|
||||
@@ -251,6 +255,14 @@ namespace ts {
|
||||
return visited;
|
||||
}
|
||||
|
||||
function returnCapturedThis(node: Node): Node {
|
||||
return setOriginalNode(createReturn(createIdentifier("_this")), node);
|
||||
}
|
||||
|
||||
function isReturnVoidStatementInConstructorWithCapturedSuper(node: Node): boolean {
|
||||
return isInConstructorWithCapturedSuper && node.kind === SyntaxKind.ReturnStatement && !(<ReturnStatement>node).expression;
|
||||
}
|
||||
|
||||
function shouldCheckNode(node: Node): boolean {
|
||||
return (node.transformFlags & TransformFlags.ES2015) !== 0 ||
|
||||
node.kind === SyntaxKind.LabeledStatement ||
|
||||
@@ -258,10 +270,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function visitorWorker(node: Node): VisitResult<Node> {
|
||||
if (shouldCheckNode(node)) {
|
||||
if (isReturnVoidStatementInConstructorWithCapturedSuper(node)) {
|
||||
return returnCapturedThis(<ReturnStatement>node);
|
||||
}
|
||||
else if (shouldCheckNode(node)) {
|
||||
return visitJavaScript(node);
|
||||
}
|
||||
else if (node.transformFlags & TransformFlags.ContainsES2015) {
|
||||
else if (node.transformFlags & TransformFlags.ContainsES2015 || (isInConstructorWithCapturedSuper && !isExpression(node))) {
|
||||
// we want to dive in this branch either if node has children with ES2015 specific syntax
|
||||
// or we are inside constructor that captures result of the super call so all returns without expression should be
|
||||
// rewritten. Note: we skip expressions since returns should never appear there
|
||||
return visitEachChild(node, visitor, context);
|
||||
}
|
||||
else {
|
||||
@@ -283,6 +301,7 @@ namespace ts {
|
||||
function visitNodesInConvertedLoop(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ReturnStatement:
|
||||
node = isReturnVoidStatementInConstructorWithCapturedSuper(node) ? returnCapturedThis(node) : node;
|
||||
return visitReturnStatement(<ReturnStatement>node);
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
@@ -308,8 +327,8 @@ namespace ts {
|
||||
|
||||
function visitJavaScript(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ExportKeyword:
|
||||
return node;
|
||||
case SyntaxKind.StaticKeyword:
|
||||
return undefined; // elide static keyword
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
return visitClassDeclaration(<ClassDeclaration>node);
|
||||
@@ -362,6 +381,9 @@ namespace ts {
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
return visitObjectLiteralExpression(<ObjectLiteralExpression>node);
|
||||
|
||||
case SyntaxKind.CatchClause:
|
||||
return visitCatchClause(<CatchClause>node);
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
return visitShorthandPropertyAssignment(<ShorthandPropertyAssignment>node);
|
||||
|
||||
@@ -396,7 +418,7 @@ namespace ts {
|
||||
return visitYieldExpression(<YieldExpression>node);
|
||||
|
||||
case SyntaxKind.SuperKeyword:
|
||||
return visitSuperKeyword(<PrimaryExpression>node);
|
||||
return visitSuperKeyword();
|
||||
|
||||
case SyntaxKind.YieldExpression:
|
||||
// `yield` will be handled by a generators transform.
|
||||
@@ -584,47 +606,39 @@ namespace ts {
|
||||
// return C;
|
||||
// }());
|
||||
|
||||
const modifierFlags = getModifierFlags(node);
|
||||
const isExported = modifierFlags & ModifierFlags.Export;
|
||||
const isDefault = modifierFlags & ModifierFlags.Default;
|
||||
|
||||
// Add an `export` modifier to the statement if needed (for `--target es5 --module es6`)
|
||||
const modifiers = isExported && !isDefault
|
||||
? filter(node.modifiers, isExportModifier)
|
||||
: undefined;
|
||||
|
||||
const statement = createVariableStatement(
|
||||
modifiers,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
getDeclarationName(node, /*allowComments*/ true),
|
||||
/*type*/ undefined,
|
||||
transformClassLikeDeclarationToExpression(node)
|
||||
)
|
||||
]),
|
||||
/*location*/ node
|
||||
const variable = createVariableDeclaration(
|
||||
getLocalName(node, /*allowComments*/ true),
|
||||
/*type*/ undefined,
|
||||
transformClassLikeDeclarationToExpression(node)
|
||||
);
|
||||
|
||||
setOriginalNode(variable, node);
|
||||
|
||||
const statements: Statement[] = [];
|
||||
const statement = createVariableStatement(/*modifiers*/ undefined, createVariableDeclarationList([variable]), /*location*/ node);
|
||||
|
||||
setOriginalNode(statement, node);
|
||||
startOnNewLine(statement);
|
||||
statements.push(statement);
|
||||
|
||||
// Add an `export default` statement for default exports (for `--target es5 --module es6`)
|
||||
if (isExported && isDefault) {
|
||||
const statements: Statement[] = [statement];
|
||||
statements.push(createExportAssignment(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*isExportEquals*/ false,
|
||||
getDeclarationName(node, /*allowComments*/ false)
|
||||
));
|
||||
return statements;
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
const exportStatement = hasModifier(node, ModifierFlags.Default)
|
||||
? createExportDefault(getLocalName(node))
|
||||
: createExternalModuleExport(getLocalName(node));
|
||||
|
||||
setOriginalNode(exportStatement, statement);
|
||||
statements.push(exportStatement);
|
||||
}
|
||||
|
||||
return statement;
|
||||
}
|
||||
const emitFlags = getEmitFlags(node);
|
||||
if ((emitFlags & EmitFlags.HasEndOfDeclarationMarker) === 0) {
|
||||
// Add a DeclarationMarker as a marker for the end of the declaration
|
||||
statements.push(createEndOfDeclarationMarker(node));
|
||||
setEmitFlags(statement, emitFlags | EmitFlags.HasEndOfDeclarationMarker);
|
||||
}
|
||||
|
||||
function isExportModifier(node: Modifier) {
|
||||
return node.kind === SyntaxKind.ExportKeyword;
|
||||
return singleOrMany(statements);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -685,7 +699,7 @@ namespace ts {
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
extendsClauseElement ? [createParameter("_super")] : [],
|
||||
extendsClauseElement ? [createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, "_super")] : [],
|
||||
/*type*/ undefined,
|
||||
transformClassBody(node, extendsClauseElement)
|
||||
);
|
||||
@@ -764,7 +778,7 @@ namespace ts {
|
||||
if (extendsClauseElement) {
|
||||
statements.push(
|
||||
createStatement(
|
||||
createExtendsHelper(currentSourceFile.externalHelpersModuleName, getDeclarationName(node)),
|
||||
createExtendsHelper(currentSourceFile.externalHelpersModuleName, getLocalName(node)),
|
||||
/*location*/ extendsClauseElement
|
||||
)
|
||||
);
|
||||
@@ -861,7 +875,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (constructor) {
|
||||
const body = saveStateAndInvoke(constructor, constructor => visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset));
|
||||
const body = saveStateAndInvoke(constructor, constructor => {
|
||||
isInConstructorWithCapturedSuper = superCaptureStatus === SuperCaptureResult.ReplaceSuperCapture;
|
||||
return visitNodes(constructor.body.statements, visitor, isStatement, /*start*/ statementOffset);
|
||||
});
|
||||
addRange(statements, body);
|
||||
}
|
||||
|
||||
@@ -1035,7 +1052,12 @@ namespace ts {
|
||||
// evaluated inside the function body.
|
||||
return setOriginalNode(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
getGeneratedNameForNode(node),
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined,
|
||||
/*location*/ node
|
||||
),
|
||||
@@ -1046,7 +1068,12 @@ namespace ts {
|
||||
// Initializers are elided
|
||||
return setOriginalNode(
|
||||
createParameter(
|
||||
/*decorators*/ undefined,
|
||||
/*modifiers*/ undefined,
|
||||
/*dotDotDotToken*/ undefined,
|
||||
node.name,
|
||||
/*questionToken*/ undefined,
|
||||
/*type*/ undefined,
|
||||
/*initializer*/ undefined,
|
||||
/*location*/ node
|
||||
),
|
||||
@@ -1118,7 +1145,7 @@ namespace ts {
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
flattenParameterDestructuring(context, parameter, temp, visitor)
|
||||
flattenParameterDestructuring(parameter, temp, visitor)
|
||||
)
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
@@ -1690,7 +1717,7 @@ namespace ts {
|
||||
if (decl.initializer) {
|
||||
let assignment: Expression;
|
||||
if (isBindingPattern(decl.name)) {
|
||||
assignment = flattenVariableDestructuringToExpression(context, decl, hoistVariableDeclaration, /*nameSubstitution*/ undefined, visitor);
|
||||
assignment = flattenVariableDestructuringToExpression(decl, hoistVariableDeclaration, /*createAssignmentCallback*/ undefined, visitor);
|
||||
}
|
||||
else {
|
||||
assignment = createBinary(<Identifier>decl.name, SyntaxKind.EqualsToken, visitNode(decl.initializer, visitor, isExpression));
|
||||
@@ -1843,7 +1870,7 @@ namespace ts {
|
||||
if (isBindingPattern(node.name)) {
|
||||
const recordTempVariablesInLine = !enclosingVariableStatement
|
||||
|| !hasModifier(enclosingVariableStatement, ModifierFlags.Export);
|
||||
return flattenVariableDestructuring(context, node, /*value*/ undefined, visitor,
|
||||
return flattenVariableDestructuring(node, /*value*/ undefined, visitor,
|
||||
recordTempVariablesInLine ? undefined : hoistVariableDeclaration);
|
||||
}
|
||||
|
||||
@@ -1946,7 +1973,6 @@ namespace ts {
|
||||
// This works whether the declaration is a var, let, or const.
|
||||
// It will use rhsIterationValue _a[_i] as the initializer.
|
||||
const declarations = flattenVariableDestructuring(
|
||||
context,
|
||||
firstOriginalDeclaration,
|
||||
createElementAccess(rhsReference, counter),
|
||||
visitor
|
||||
@@ -1974,13 +2000,16 @@ namespace ts {
|
||||
statements.push(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
|
||||
/*type*/ undefined,
|
||||
createElementAccess(rhsReference, counter)
|
||||
)
|
||||
], /*location*/ moveRangePos(initializer, -1)),
|
||||
setOriginalNode(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(
|
||||
firstOriginalDeclaration ? firstOriginalDeclaration.name : createTempVariable(/*recordTempVariable*/ undefined),
|
||||
/*type*/ undefined,
|
||||
createElementAccess(rhsReference, counter)
|
||||
)
|
||||
], /*location*/ moveRangePos(initializer, -1)),
|
||||
initializer
|
||||
),
|
||||
/*location*/ moveRangeEnd(initializer, -1)
|
||||
)
|
||||
);
|
||||
@@ -2042,10 +2071,13 @@ namespace ts {
|
||||
setEmitFlags(body, EmitFlags.NoSourceMap | EmitFlags.NoTokenSourceMaps);
|
||||
|
||||
const forStatement = createFor(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
|
||||
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
|
||||
], /*location*/ node.expression),
|
||||
setEmitFlags(
|
||||
createVariableDeclarationList([
|
||||
createVariableDeclaration(counter, /*type*/ undefined, createLiteral(0), /*location*/ moveRangePos(node.expression, -1)),
|
||||
createVariableDeclaration(rhsReference, /*type*/ undefined, expression, /*location*/ node.expression)
|
||||
], /*location*/ node.expression),
|
||||
EmitFlags.NoHoisting
|
||||
),
|
||||
createLessThan(
|
||||
counter,
|
||||
createPropertyAccess(rhsReference, "length"),
|
||||
@@ -2237,25 +2269,28 @@ namespace ts {
|
||||
const convertedLoopVariable =
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
functionName,
|
||||
/*type*/ undefined,
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
loopParameters,
|
||||
/*type*/ undefined,
|
||||
<Block>loopBody
|
||||
),
|
||||
loopBodyFlags
|
||||
setEmitFlags(
|
||||
createVariableDeclarationList(
|
||||
[
|
||||
createVariableDeclaration(
|
||||
functionName,
|
||||
/*type*/ undefined,
|
||||
setEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*modifiers*/ undefined,
|
||||
isAsyncBlockContainingAwait ? createToken(SyntaxKind.AsteriskToken) : undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
loopParameters,
|
||||
/*type*/ undefined,
|
||||
<Block>loopBody
|
||||
),
|
||||
loopBodyFlags
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
]
|
||||
),
|
||||
EmitFlags.NoHoisting
|
||||
)
|
||||
);
|
||||
|
||||
@@ -2506,7 +2541,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
loopParameters.push(createParameter(name));
|
||||
loopParameters.push(createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, name));
|
||||
if (resolver.getNodeCheckFlags(decl) & NodeCheckFlags.NeedsLoopOutParameter) {
|
||||
const outParamName = createUniqueName("out_" + name.text);
|
||||
loopOutParameters.push({ originalName: name, outParamName });
|
||||
@@ -2539,15 +2574,15 @@ namespace ts {
|
||||
break;
|
||||
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
expressions.push(transformPropertyAssignmentToExpression(node, <PropertyAssignment>property, receiver, node.multiLine));
|
||||
expressions.push(transformPropertyAssignmentToExpression(<PropertyAssignment>property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(node, <ShorthandPropertyAssignment>property, receiver, node.multiLine));
|
||||
expressions.push(transformShorthandPropertyAssignmentToExpression(<ShorthandPropertyAssignment>property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
case SyntaxKind.MethodDeclaration:
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(node, <MethodDeclaration>property, receiver, node.multiLine));
|
||||
expressions.push(transformObjectLiteralMethodDeclarationToExpression(<MethodDeclaration>property, receiver, node.multiLine));
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -2564,7 +2599,7 @@ namespace ts {
|
||||
* @param property The PropertyAssignment node.
|
||||
* @param receiver The receiver for the assignment.
|
||||
*/
|
||||
function transformPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
function transformPropertyAssignmentToExpression(property: PropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
const expression = createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
@@ -2586,7 +2621,7 @@ namespace ts {
|
||||
* @param property The ShorthandPropertyAssignment node.
|
||||
* @param receiver The receiver for the assignment.
|
||||
*/
|
||||
function transformShorthandPropertyAssignmentToExpression(node: ObjectLiteralExpression, property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
function transformShorthandPropertyAssignmentToExpression(property: ShorthandPropertyAssignment, receiver: Expression, startsOnNewLine: boolean) {
|
||||
const expression = createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
@@ -2608,7 +2643,7 @@ namespace ts {
|
||||
* @param method The MethodDeclaration node.
|
||||
* @param receiver The receiver for the assignment.
|
||||
*/
|
||||
function transformObjectLiteralMethodDeclarationToExpression(node: ObjectLiteralExpression, method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
|
||||
function transformObjectLiteralMethodDeclarationToExpression(method: MethodDeclaration, receiver: Expression, startsOnNewLine: boolean) {
|
||||
const expression = createAssignment(
|
||||
createMemberAccessForPropertyName(
|
||||
receiver,
|
||||
@@ -2623,6 +2658,24 @@ namespace ts {
|
||||
return expression;
|
||||
}
|
||||
|
||||
function visitCatchClause(node: CatchClause): CatchClause {
|
||||
Debug.assert(isBindingPattern(node.variableDeclaration.name));
|
||||
|
||||
const temp = createTempVariable(undefined);
|
||||
const newVariableDeclaration = createVariableDeclaration(temp, undefined, undefined, node.variableDeclaration);
|
||||
|
||||
const vars = flattenVariableDestructuring(node.variableDeclaration, temp, visitor);
|
||||
const list = createVariableDeclarationList(vars, /*location*/node.variableDeclaration, /*flags*/node.variableDeclaration.flags);
|
||||
const destructure = createVariableStatement(undefined, list);
|
||||
|
||||
return updateCatchClause(node, newVariableDeclaration, addStatementToStartOfBlock(node.block, destructure));
|
||||
}
|
||||
|
||||
function addStatementToStartOfBlock(block: Block, statement: Statement): Block {
|
||||
const transformedStatements = visitNodes(block.statements, visitor, isStatement);
|
||||
return updateBlock(block, [statement].concat(transformedStatements));
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a MethodDeclaration of an ObjectLiteralExpression and transforms it into a
|
||||
* PropertyAssignment.
|
||||
@@ -2798,7 +2851,7 @@ namespace ts {
|
||||
// expressions into an array literal.
|
||||
const numElements = elements.length;
|
||||
const segments = flatten(
|
||||
spanMap(elements, partitionSpreadElement, (partition, visitPartition, start, end) =>
|
||||
spanMap(elements, partitionSpreadElement, (partition, visitPartition, _start, end) =>
|
||||
visitPartition(partition, multiLine, hasTrailingComma && end === numElements)
|
||||
)
|
||||
);
|
||||
@@ -2820,7 +2873,7 @@ namespace ts {
|
||||
: visitSpanOfNonSpreadElements;
|
||||
}
|
||||
|
||||
function visitSpanOfSpreadElements(chunk: Expression[], multiLine: boolean, hasTrailingComma: boolean): VisitResult<Expression> {
|
||||
function visitSpanOfSpreadElements(chunk: Expression[]): VisitResult<Expression> {
|
||||
return map(chunk, visitExpressionOfSpreadElement);
|
||||
}
|
||||
|
||||
@@ -3009,7 +3062,7 @@ namespace ts {
|
||||
/**
|
||||
* Visits the `super` keyword
|
||||
*/
|
||||
function visitSuperKeyword(node: PrimaryExpression): LeftHandSideExpression {
|
||||
function visitSuperKeyword(): LeftHandSideExpression {
|
||||
return enclosingNonAsyncFunctionBody
|
||||
&& isClassElement(enclosingNonAsyncFunctionBody)
|
||||
&& !hasModifier(enclosingNonAsyncFunctionBody, ModifierFlags.Static)
|
||||
@@ -3081,9 +3134,8 @@ namespace ts {
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
* @param isExpression A value indicating whether the node is to be used in an expression
|
||||
* position.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
@@ -3183,45 +3235,6 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the local name for a declaration for use in expressions.
|
||||
*
|
||||
* A local name will *never* be prefixed with an module or namespace export modifier like
|
||||
* "exports.".
|
||||
*
|
||||
* @param node The declaration.
|
||||
* @param allowComments A value indicating whether comments may be emitted for the name.
|
||||
* @param allowSourceMaps A value indicating whether source maps may be emitted for the name.
|
||||
*/
|
||||
function getLocalName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean) {
|
||||
return getDeclarationName(node, allowComments, allowSourceMaps, EmitFlags.LocalName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of a declaration, without source map or comments.
|
||||
*
|
||||
* @param node The declaration.
|
||||
* @param allowComments Allow comments for the name.
|
||||
*/
|
||||
function getDeclarationName(node: ClassDeclaration | ClassExpression | FunctionDeclaration, allowComments?: boolean, allowSourceMaps?: boolean, emitFlags?: EmitFlags) {
|
||||
if (node.name && !isGeneratedIdentifier(node.name)) {
|
||||
const name = getMutableClone(node.name);
|
||||
emitFlags |= getEmitFlags(node.name);
|
||||
if (!allowSourceMaps) {
|
||||
emitFlags |= EmitFlags.NoSourceMap;
|
||||
}
|
||||
if (!allowComments) {
|
||||
emitFlags |= EmitFlags.NoComments;
|
||||
}
|
||||
if (emitFlags) {
|
||||
setEmitFlags(name, emitFlags);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
return getGeneratedNameForNode(node);
|
||||
}
|
||||
|
||||
function getClassMemberPrefix(node: ClassExpression | ClassDeclaration, member: ClassElement) {
|
||||
const expression = getLocalName(node);
|
||||
return hasModifier(member, ModifierFlags.Static) ? expression : createPropertyAccess(expression, "prototype");
|
||||
|
||||
@@ -262,7 +262,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody {
|
||||
const nodeType = node.original ? (<FunctionLikeDeclaration>node.original).type : node.type;
|
||||
const original = getOriginalNode(node, isFunctionLike);
|
||||
const nodeType = original.type;
|
||||
const promiseConstructor = languageVersion < ScriptTarget.ES2015 ? getPromiseConstructor(nodeType) : undefined;
|
||||
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
|
||||
const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
|
||||
@@ -336,15 +337,16 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getPromiseConstructor(type: TypeNode) {
|
||||
const typeName = getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
if (type) {
|
||||
const typeName = getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/// <reference path="../factory.ts" />
|
||||
/// <reference path="../visitor.ts" />
|
||||
|
||||
/*@internal*/
|
||||
namespace ts {
|
||||
/**
|
||||
* Transforms ES5 syntax into ES3 syntax.
|
||||
*
|
||||
* @param context Context and state information for the transformation.
|
||||
*/
|
||||
export function transformES5(context: TransformationContext) {
|
||||
const previousOnSubstituteNode = context.onSubstituteNode;
|
||||
context.onSubstituteNode = onSubstituteNode;
|
||||
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
|
||||
context.enableSubstitution(SyntaxKind.PropertyAssignment);
|
||||
return transformSourceFile;
|
||||
|
||||
/**
|
||||
* Transforms an ES5 source file to ES3.
|
||||
*
|
||||
* @param node A SourceFile
|
||||
*/
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hooks node substitutions.
|
||||
*
|
||||
* @param emitContext The context for the emitter.
|
||||
* @param node The node to substitute.
|
||||
*/
|
||||
function onSubstituteNode(emitContext: EmitContext, node: Node) {
|
||||
node = previousOnSubstituteNode(emitContext, node);
|
||||
if (isPropertyAccessExpression(node)) {
|
||||
return substitutePropertyAccessExpression(node);
|
||||
}
|
||||
else if (isPropertyAssignment(node)) {
|
||||
return substitutePropertyAssignment(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes a PropertyAccessExpression whose name is a reserved word.
|
||||
*
|
||||
* @param node A PropertyAccessExpression
|
||||
*/
|
||||
function substitutePropertyAccessExpression(node: PropertyAccessExpression): Expression {
|
||||
const literalName = trySubstituteReservedName(node.name);
|
||||
if (literalName) {
|
||||
return createElementAccess(node.expression, literalName, /*location*/ node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes a PropertyAssignment whose name is a reserved word.
|
||||
*
|
||||
* @param node A PropertyAssignment
|
||||
*/
|
||||
function substitutePropertyAssignment(node: PropertyAssignment): PropertyAssignment {
|
||||
const literalName = isIdentifier(node.name) && trySubstituteReservedName(node.name);
|
||||
if (literalName) {
|
||||
return updatePropertyAssignment(node, literalName, node.initializer);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* If an identifier name is a reserved word, returns a string literal for the name.
|
||||
*
|
||||
* @param name An Identifier
|
||||
*/
|
||||
function trySubstituteReservedName(name: Identifier) {
|
||||
const token = name.originalKeywordKind || (nodeIsSynthesized(name) ? stringToToken(name.text) : undefined);
|
||||
if (token >= SyntaxKind.FirstReservedWord && token <= SyntaxKind.LastReservedWord) {
|
||||
return createLiteral(name, /*location*/ name);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -956,7 +956,7 @@ namespace ts {
|
||||
* @param elements The elements to visit.
|
||||
* @param multiLine Whether array literals created should be emitted on multiple lines.
|
||||
*/
|
||||
function visitElements(elements: NodeArray<Expression>, multiLine: boolean) {
|
||||
function visitElements(elements: NodeArray<Expression>, _multiLine?: boolean) {
|
||||
// [source]
|
||||
// ar = [1, yield, 2];
|
||||
//
|
||||
@@ -1102,7 +1102,7 @@ namespace ts {
|
||||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isLeftHandSideExpression)),
|
||||
thisArg,
|
||||
visitElements(node.arguments, /*multiLine*/ false),
|
||||
visitElements(node.arguments),
|
||||
/*location*/ node
|
||||
),
|
||||
node
|
||||
@@ -1131,7 +1131,7 @@ namespace ts {
|
||||
createFunctionApply(
|
||||
cacheExpression(visitNode(target, visitor, isExpression)),
|
||||
thisArg,
|
||||
visitElements(node.arguments, /*multiLine*/ false)
|
||||
visitElements(node.arguments)
|
||||
),
|
||||
/*typeArguments*/ undefined,
|
||||
[],
|
||||
@@ -2369,7 +2369,7 @@ namespace ts {
|
||||
labelExpressions = [];
|
||||
}
|
||||
|
||||
const expression = <LiteralExpression>createSynthesizedNode(SyntaxKind.NumericLiteral);
|
||||
const expression = createLiteral(-1);
|
||||
if (labelExpressions[label] === undefined) {
|
||||
labelExpressions[label] = [expression];
|
||||
}
|
||||
@@ -2380,7 +2380,7 @@ namespace ts {
|
||||
return expression;
|
||||
}
|
||||
|
||||
return <OmittedExpression>createNode(SyntaxKind.OmittedExpression);
|
||||
return createOmittedExpression();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2596,7 +2596,7 @@ namespace ts {
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(state)],
|
||||
[createParameter(/*decorators*/ undefined, /*modifiers*/ undefined, /*dotDotDotToken*/ undefined, state)],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
buildResult,
|
||||
|
||||
@@ -22,7 +22,8 @@ namespace ts {
|
||||
function visitor(node: Node): VisitResult<Node> {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.ImportEqualsDeclaration:
|
||||
return visitImportEqualsDeclaration(<ImportEqualsDeclaration>node);
|
||||
// Elide `import=` as it is not legal with --module ES6
|
||||
return undefined;
|
||||
case SyntaxKind.ExportAssignment:
|
||||
return visitExportAssignment(<ExportAssignment>node);
|
||||
}
|
||||
@@ -30,11 +31,6 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function visitImportEqualsDeclaration(node: ImportEqualsDeclaration): VisitResult<ImportEqualsDeclaration> {
|
||||
// Elide `import=` as it is not legal with --module ES6
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function visitExportAssignment(node: ExportAssignment): VisitResult<ExportAssignment> {
|
||||
// Elide `export=` as it is not legal with --module ES6
|
||||
return node.isExportEquals ? undefined : node;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+254
-388
File diff suppressed because it is too large
Load Diff
+20
-12
@@ -29,7 +29,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function reportEmittedFiles(files: string[], host: CompilerHost): void {
|
||||
function reportEmittedFiles(files: string[]): void {
|
||||
if (!files || files.length == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -111,7 +111,7 @@ namespace ts {
|
||||
return count;
|
||||
}
|
||||
|
||||
function getDiagnosticText(message: DiagnosticMessage, ...args: any[]): string {
|
||||
function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string {
|
||||
const diagnostic = createCompilerDiagnostic.apply(undefined, arguments);
|
||||
return <string>diagnostic.messageText;
|
||||
}
|
||||
@@ -250,8 +250,8 @@ namespace ts {
|
||||
let compilerOptions: CompilerOptions; // Compiler options for compilation
|
||||
let compilerHost: CompilerHost; // Compiler host
|
||||
let hostGetSourceFile: typeof compilerHost.getSourceFile; // getSourceFile method from default host
|
||||
let timerHandleForRecompilation: number; // Handle for 0.25s wait timer to trigger recompilation
|
||||
let timerHandleForDirectoryChanges: number; // Handle for 0.25s wait timer to trigger directory change handler
|
||||
let timerHandleForRecompilation: any; // Handle for 0.25s wait timer to trigger recompilation
|
||||
let timerHandleForDirectoryChanges: any; // Handle for 0.25s wait timer to trigger directory change handler
|
||||
|
||||
// This map stores and reuses results of fileExists check that happen inside 'createProgram'
|
||||
// This allows to save time in module resolution heavy scenarios when existence of the same file might be checked multiple times.
|
||||
@@ -456,7 +456,7 @@ namespace ts {
|
||||
const sourceFile = hostGetSourceFile(fileName, languageVersion, onError);
|
||||
if (sourceFile && isWatchSet(compilerOptions) && sys.watchFile) {
|
||||
// Attach a file watcher
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
sourceFile.fileWatcher = sys.watchFile(sourceFile.fileName, (_fileName: string, removed?: boolean) => sourceFileChanged(sourceFile, removed));
|
||||
}
|
||||
return sourceFile;
|
||||
}
|
||||
@@ -503,10 +503,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
function startTimerForHandlingDirectoryChanges() {
|
||||
if (timerHandleForDirectoryChanges) {
|
||||
clearTimeout(timerHandleForDirectoryChanges);
|
||||
if (!sys.setTimeout || !sys.clearTimeout) {
|
||||
return;
|
||||
}
|
||||
timerHandleForDirectoryChanges = setTimeout(directoryChangeHandler, 250);
|
||||
|
||||
if (timerHandleForDirectoryChanges) {
|
||||
sys.clearTimeout(timerHandleForDirectoryChanges);
|
||||
}
|
||||
timerHandleForDirectoryChanges = sys.setTimeout(directoryChangeHandler, 250);
|
||||
}
|
||||
|
||||
function directoryChangeHandler() {
|
||||
@@ -525,10 +529,14 @@ namespace ts {
|
||||
// operations (such as saving all modified files in an editor) a chance to complete before we kick
|
||||
// off a new compilation.
|
||||
function startTimerForRecompilation() {
|
||||
if (timerHandleForRecompilation) {
|
||||
clearTimeout(timerHandleForRecompilation);
|
||||
if (!sys.setTimeout || !sys.clearTimeout) {
|
||||
return;
|
||||
}
|
||||
timerHandleForRecompilation = setTimeout(recompile, 250);
|
||||
|
||||
if (timerHandleForRecompilation) {
|
||||
sys.clearTimeout(timerHandleForRecompilation);
|
||||
}
|
||||
timerHandleForRecompilation = sys.setTimeout(recompile, 250);
|
||||
}
|
||||
|
||||
function recompile() {
|
||||
@@ -617,7 +625,7 @@ namespace ts {
|
||||
|
||||
reportDiagnostics(sortAndDeduplicateDiagnostics(diagnostics), compilerHost);
|
||||
|
||||
reportEmittedFiles(emitOutput.emittedFiles, compilerHost);
|
||||
reportEmittedFiles(emitOutput.emittedFiles);
|
||||
|
||||
if (emitOutput.emitSkipped && diagnostics.length > 0) {
|
||||
// If the emitter didn't emit anything, then pass that value along.
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
"outFile": "../../built/local/tsc.js",
|
||||
"sourceMap": true,
|
||||
"declaration": true,
|
||||
"stripInternal": true
|
||||
"stripInternal": true,
|
||||
"target": "es5",
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
},
|
||||
"files": [
|
||||
"core.ts",
|
||||
@@ -27,7 +30,9 @@
|
||||
"transformers/es2017.ts",
|
||||
"transformers/es2016.ts",
|
||||
"transformers/es2015.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/generators.ts",
|
||||
"transformers/es5.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/module/module.ts",
|
||||
"transformers/module/system.ts",
|
||||
|
||||
+176
-49
@@ -45,6 +45,7 @@ namespace ts {
|
||||
// Literals
|
||||
NumericLiteral,
|
||||
StringLiteral,
|
||||
JsxText,
|
||||
RegularExpressionLiteral,
|
||||
NoSubstitutionTemplateLiteral,
|
||||
// Pseudo-literals
|
||||
@@ -167,6 +168,7 @@ namespace ts {
|
||||
DeclareKeyword,
|
||||
GetKeyword,
|
||||
IsKeyword,
|
||||
KeyOfKeyword,
|
||||
ModuleKeyword,
|
||||
NamespaceKeyword,
|
||||
NeverKeyword,
|
||||
@@ -215,6 +217,8 @@ namespace ts {
|
||||
IntersectionType,
|
||||
ParenthesizedType,
|
||||
ThisType,
|
||||
TypeOperator,
|
||||
IndexedAccessType,
|
||||
LiteralType,
|
||||
// Binding patterns
|
||||
ObjectBindingPattern,
|
||||
@@ -302,7 +306,6 @@ namespace ts {
|
||||
JsxElement,
|
||||
JsxSelfClosingElement,
|
||||
JsxOpeningElement,
|
||||
JsxText,
|
||||
JsxClosingElement,
|
||||
JsxAttribute,
|
||||
JsxSpreadAttribute,
|
||||
@@ -362,6 +365,8 @@ namespace ts {
|
||||
// Transformation nodes
|
||||
NotEmittedStatement,
|
||||
PartiallyEmittedExpression,
|
||||
MergeDeclarationMarker,
|
||||
EndOfDeclarationMarker,
|
||||
|
||||
// Enum value count
|
||||
Count,
|
||||
@@ -457,7 +462,8 @@ namespace ts {
|
||||
ParameterPropertyModifier = AccessibilityModifier | Readonly,
|
||||
NonPublicAccessibilityModifier = Private | Protected,
|
||||
|
||||
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const
|
||||
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const,
|
||||
ExportDefault = Export | Default,
|
||||
}
|
||||
|
||||
export const enum JsxFlags {
|
||||
@@ -545,6 +551,7 @@ namespace ts {
|
||||
originalKeywordKind?: SyntaxKind; // Original syntaxKind which get set so that we can report an error later
|
||||
/*@internal*/ autoGenerateKind?: GeneratedIdentifierKind; // Specifies whether to auto-generate the text for an identifier.
|
||||
/*@internal*/ autoGenerateId?: number; // Ensures unique generated identifiers get unique names, but clones get the same name.
|
||||
isInJSDocNamespace?: boolean; // if the node is a member in a JSDoc namespace
|
||||
}
|
||||
|
||||
// Transient identifier node (marked by id === -1)
|
||||
@@ -552,6 +559,14 @@ namespace ts {
|
||||
resolvedSymbol: Symbol;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface GeneratedIdentifier extends Identifier {
|
||||
autoGenerateKind: GeneratedIdentifierKind.Auto
|
||||
| GeneratedIdentifierKind.Loop
|
||||
| GeneratedIdentifierKind.Unique
|
||||
| GeneratedIdentifierKind.Node;
|
||||
}
|
||||
|
||||
export interface QualifiedName extends Node {
|
||||
kind: SyntaxKind.QualifiedName;
|
||||
left: EntityName;
|
||||
@@ -870,6 +885,18 @@ namespace ts {
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface TypeOperatorNode extends TypeNode {
|
||||
kind: SyntaxKind.TypeOperator;
|
||||
operator: SyntaxKind.KeyOfKeyword;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface IndexedAccessTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.IndexedAccessType;
|
||||
objectType: TypeNode;
|
||||
indexType: TypeNode;
|
||||
}
|
||||
|
||||
export interface LiteralTypeNode extends TypeNode {
|
||||
kind: SyntaxKind.LiteralType;
|
||||
literal: Expression;
|
||||
@@ -941,10 +968,6 @@ namespace ts {
|
||||
operator: PostfixUnaryOperator;
|
||||
}
|
||||
|
||||
export interface PostfixExpression extends UnaryExpression {
|
||||
_postfixExpressionBrand: any;
|
||||
}
|
||||
|
||||
export interface LeftHandSideExpression extends IncrementExpression {
|
||||
_leftHandSideExpressionBrand: any;
|
||||
}
|
||||
@@ -1146,6 +1169,21 @@ namespace ts {
|
||||
right: Expression;
|
||||
}
|
||||
|
||||
export interface AssignmentExpression extends BinaryExpression {
|
||||
left: LeftHandSideExpression;
|
||||
operatorToken: Token<SyntaxKind.EqualsToken>;
|
||||
}
|
||||
|
||||
export interface ObjectDestructuringAssignment extends AssignmentExpression {
|
||||
left: ObjectLiteralExpression;
|
||||
}
|
||||
|
||||
export interface ArrayDestructuringAssignment extends AssignmentExpression {
|
||||
left: ArrayLiteralExpression;
|
||||
}
|
||||
|
||||
export type DestructuringAssignment = ObjectDestructuringAssignment | ArrayDestructuringAssignment;
|
||||
|
||||
export interface ConditionalExpression extends Expression {
|
||||
kind: SyntaxKind.ConditionalExpression;
|
||||
condition: Expression;
|
||||
@@ -1418,6 +1456,22 @@ namespace ts {
|
||||
kind: SyntaxKind.NotEmittedStatement;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the end of transformed declaration to properly emit exports.
|
||||
*/
|
||||
/* @internal */
|
||||
export interface EndOfDeclarationMarker extends Statement {
|
||||
kind: SyntaxKind.EndOfDeclarationMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the beginning of a merged transformed declaration.
|
||||
*/
|
||||
/* @internal */
|
||||
export interface MergeDeclarationMarker extends Statement {
|
||||
kind: SyntaxKind.MergeDeclarationMarker;
|
||||
}
|
||||
|
||||
export interface EmptyStatement extends Statement {
|
||||
kind: SyntaxKind.EmptyStatement;
|
||||
}
|
||||
@@ -1634,7 +1688,7 @@ namespace ts {
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
name: Identifier | LiteralExpression;
|
||||
body?: ModuleBlock | NamespaceDeclaration;
|
||||
body?: ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | Identifier;
|
||||
}
|
||||
|
||||
export interface NamespaceDeclaration extends ModuleDeclaration {
|
||||
@@ -1642,6 +1696,11 @@ namespace ts {
|
||||
body: ModuleBlock | NamespaceDeclaration;
|
||||
}
|
||||
|
||||
export interface JSDocNamespaceDeclaration extends ModuleDeclaration {
|
||||
name: Identifier;
|
||||
body: JSDocNamespaceDeclaration | Identifier;
|
||||
}
|
||||
|
||||
export interface ModuleBlock extends Node, Statement {
|
||||
kind: SyntaxKind.ModuleBlock;
|
||||
statements: NodeArray<Statement>;
|
||||
@@ -1871,6 +1930,7 @@ namespace ts {
|
||||
|
||||
export interface JSDocTypedefTag extends JSDocTag, Declaration {
|
||||
kind: SyntaxKind.JSDocTypedefTag;
|
||||
fullName?: JSDocNamespaceDeclaration | Identifier;
|
||||
name?: Identifier;
|
||||
typeExpression?: JSDocTypeExpression;
|
||||
jsDocTypeLiteral?: JSDocTypeLiteral;
|
||||
@@ -2024,6 +2084,9 @@ namespace ts {
|
||||
// as well as code diagnostics).
|
||||
/* @internal */ parseDiagnostics: Diagnostic[];
|
||||
|
||||
// Stores additional file level diagnostics reported by the program
|
||||
/* @internal */ additionalSyntacticDiagnostics?: Diagnostic[];
|
||||
|
||||
// File level diagnostics reported by the binder.
|
||||
/* @internal */ bindDiagnostics: Diagnostic[];
|
||||
|
||||
@@ -2034,11 +2097,12 @@ namespace ts {
|
||||
// Stores a mapping 'external module reference text' -> 'resolved file name' | undefined
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules: Map<ResolvedModule>;
|
||||
/* @internal */ resolvedModules: Map<ResolvedModuleFull>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ imports: LiteralExpression[];
|
||||
/* @internal */ moduleAugmentations: LiteralExpression[];
|
||||
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
|
||||
/* @internal */ ambientModuleNames: string[];
|
||||
// The synthesized identifier for an imported external helpers module.
|
||||
/* @internal */ externalHelpersModuleName?: Identifier;
|
||||
}
|
||||
@@ -2233,6 +2297,8 @@ namespace ts {
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
|
||||
/* @internal */ tryFindAmbientModuleWithoutAugmentations(moduleName: string): Symbol;
|
||||
|
||||
// Should not be called directly. Should only be accessed through the Program instance.
|
||||
/* @internal */ getDiagnostics(sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[];
|
||||
/* @internal */ getGlobalDiagnostics(): Diagnostic[];
|
||||
@@ -2612,24 +2678,19 @@ namespace ts {
|
||||
Null = 1 << 12,
|
||||
Never = 1 << 13, // Never type
|
||||
TypeParameter = 1 << 14, // Type parameter
|
||||
Class = 1 << 15, // Class
|
||||
Interface = 1 << 16, // Interface
|
||||
Reference = 1 << 17, // Generic type reference
|
||||
Tuple = 1 << 18, // Synthesized generic tuple type
|
||||
Union = 1 << 19, // Union (T | U)
|
||||
Intersection = 1 << 20, // Intersection (T & U)
|
||||
Anonymous = 1 << 21, // Anonymous
|
||||
Instantiated = 1 << 22, // Instantiated anonymous type
|
||||
Object = 1 << 15, // Object type
|
||||
Union = 1 << 16, // Union (T | U)
|
||||
Intersection = 1 << 17, // Intersection (T & U)
|
||||
Index = 1 << 18, // keyof T
|
||||
IndexedAccess = 1 << 19, // T[K]
|
||||
/* @internal */
|
||||
ObjectLiteral = 1 << 23, // Originates in an object literal
|
||||
FreshLiteral = 1 << 20, // Fresh literal type
|
||||
/* @internal */
|
||||
FreshLiteral = 1 << 24, // Fresh literal type
|
||||
ContainsWideningType = 1 << 21, // Type is or contains undefined or null widening type
|
||||
/* @internal */
|
||||
ContainsWideningType = 1 << 25, // Type is or contains undefined or null widening type
|
||||
ContainsObjectLiteral = 1 << 22, // Type is or contains object literal type
|
||||
/* @internal */
|
||||
ContainsObjectLiteral = 1 << 26, // Type is or contains object literal type
|
||||
/* @internal */
|
||||
ContainsAnyFunctionType = 1 << 27, // Type is or contains object literal type
|
||||
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
|
||||
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
@@ -2646,15 +2707,14 @@ namespace ts {
|
||||
NumberLike = Number | NumberLiteral | Enum | EnumLiteral,
|
||||
BooleanLike = Boolean | BooleanLiteral,
|
||||
EnumLike = Enum | EnumLiteral,
|
||||
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = ObjectType | Union | Intersection,
|
||||
StructuredOrTypeParameter = StructuredType | TypeParameter,
|
||||
StructuredType = Object | Union | Intersection,
|
||||
StructuredOrTypeParameter = StructuredType | TypeParameter | Index,
|
||||
|
||||
// 'Narrowable' types are types where narrowing actually narrows.
|
||||
// This *should* be every type other than null, undefined, void, and never
|
||||
Narrowable = Any | StructuredType | TypeParameter | StringLike | NumberLike | BooleanLike | ESSymbol,
|
||||
NotUnionOrUnit = Any | ESSymbol | ObjectType,
|
||||
Narrowable = Any | StructuredType | TypeParameter | Index | IndexedAccess | StringLike | NumberLike | BooleanLike | ESSymbol,
|
||||
NotUnionOrUnit = Any | ESSymbol | Object,
|
||||
/* @internal */
|
||||
RequiresWidening = ContainsWideningType | ContainsObjectLiteral,
|
||||
/* @internal */
|
||||
@@ -2697,9 +2757,22 @@ namespace ts {
|
||||
baseType: EnumType & UnionType; // Base enum type
|
||||
}
|
||||
|
||||
export const enum ObjectFlags {
|
||||
Class = 1 << 0, // Class
|
||||
Interface = 1 << 1, // Interface
|
||||
Reference = 1 << 2, // Generic type reference
|
||||
Tuple = 1 << 3, // Synthesized generic tuple type
|
||||
Anonymous = 1 << 4, // Anonymous
|
||||
Instantiated = 1 << 5, // Instantiated anonymous type
|
||||
ObjectLiteral = 1 << 6, // Originates in an object literal
|
||||
EvolvingArray = 1 << 7, // Evolving array type
|
||||
ObjectLiteralPatternWithComputedProperties = 1 << 8, // Object literal pattern with computed properties
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
// Object types (TypeFlags.ObjectType)
|
||||
export interface ObjectType extends Type {
|
||||
isObjectLiteralPatternWithComputedProperties?: boolean;
|
||||
objectFlags: ObjectFlags;
|
||||
}
|
||||
|
||||
// Class and interface types (TypeFlags.Class and TypeFlags.Interface)
|
||||
@@ -2753,13 +2826,18 @@ namespace ts {
|
||||
|
||||
export interface IntersectionType extends UnionOrIntersectionType { }
|
||||
|
||||
export type StructuredType = ObjectType | UnionType | IntersectionType;
|
||||
|
||||
/* @internal */
|
||||
// An instantiated anonymous type has a target and a mapper
|
||||
export interface AnonymousType extends ObjectType {
|
||||
target?: AnonymousType; // Instantiation target
|
||||
mapper?: TypeMapper; // Instantiation mapper
|
||||
elementType?: Type; // Element expressions of evolving array type
|
||||
finalArrayType?: Type; // Final array type of evolving array type
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
elementType: Type; // Element expressions of evolving array type
|
||||
finalArrayType?: Type; // Final array type of evolving array type
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2798,9 +2876,22 @@ namespace ts {
|
||||
/* @internal */
|
||||
resolvedApparentType: Type;
|
||||
/* @internal */
|
||||
resolvedIndexType: IndexType;
|
||||
/* @internal */
|
||||
resolvedIndexedAccessTypes: IndexedAccessType[];
|
||||
/* @internal */
|
||||
isThisType?: boolean;
|
||||
}
|
||||
|
||||
export interface IndexType extends Type {
|
||||
type: TypeParameter;
|
||||
}
|
||||
|
||||
export interface IndexedAccessType extends Type {
|
||||
objectType: Type;
|
||||
indexType: TypeParameter;
|
||||
}
|
||||
|
||||
export const enum SignatureKind {
|
||||
Call,
|
||||
Construct,
|
||||
@@ -2967,6 +3058,7 @@ namespace ts {
|
||||
moduleResolution?: ModuleResolutionKind;
|
||||
newLine?: NewLineKind;
|
||||
noEmit?: boolean;
|
||||
/*@internal*/noEmitOverwritenFiles?: boolean;
|
||||
noEmitHelpers?: boolean;
|
||||
noEmitOnError?: boolean;
|
||||
noErrorTruncation?: boolean;
|
||||
@@ -3024,6 +3116,7 @@ namespace ts {
|
||||
packageNameToTypingLocation: Map<string>; // The map of package names to their cached typing locations
|
||||
typingOptions: TypingOptions; // Used to customize the typing inference process
|
||||
compilerOptions: CompilerOptions; // Used as a source for typing inference
|
||||
unresolvedImports: ReadonlyArray<string>; // List of unresolved module ids from imports
|
||||
}
|
||||
|
||||
export enum ModuleKind {
|
||||
@@ -3082,6 +3175,7 @@ namespace ts {
|
||||
Pretty,
|
||||
}
|
||||
|
||||
/** Either a parsed command line or a parsed tsconfig.json */
|
||||
export interface ParsedCommandLine {
|
||||
options: CompilerOptions;
|
||||
typingOptions?: TypingOptions;
|
||||
@@ -3287,10 +3381,18 @@ namespace ts {
|
||||
getDirectories?(path: string): string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the result of module resolution.
|
||||
* Module resolution will pick up tsx/jsx/js files even if '--jsx' and '--allowJs' are turned off.
|
||||
* The Program will then filter results based on these flags.
|
||||
*
|
||||
* Prefer to return a `ResolvedModuleFull` so that the file type does not have to be inferred.
|
||||
*/
|
||||
export interface ResolvedModule {
|
||||
/** Path of the file the module was resolved to. */
|
||||
resolvedFileName: string;
|
||||
/*
|
||||
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be proper external module:
|
||||
/**
|
||||
* Denotes if 'resolvedFileName' is isExternalLibraryImport and thus should be a proper external module:
|
||||
* - be a .d.ts file
|
||||
* - use top level imports\exports
|
||||
* - don't use tripleslash references
|
||||
@@ -3298,8 +3400,29 @@ namespace ts {
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* ResolvedModule with an explicitly provided `extension` property.
|
||||
* Prefer this over `ResolvedModule`.
|
||||
*/
|
||||
export interface ResolvedModuleFull extends ResolvedModule {
|
||||
/**
|
||||
* Extension of resolvedFileName. This must match what's at the end of resolvedFileName.
|
||||
* This is optional for backwards-compatibility, but will be added if not provided.
|
||||
*/
|
||||
extension: Extension;
|
||||
}
|
||||
|
||||
export enum Extension {
|
||||
Ts,
|
||||
Tsx,
|
||||
Dts,
|
||||
Js,
|
||||
Jsx,
|
||||
LastTypeScriptExtension = Dts
|
||||
}
|
||||
|
||||
export interface ResolvedModuleWithFailedLookupLocations {
|
||||
resolvedModule: ResolvedModule;
|
||||
resolvedModule: ResolvedModuleFull | undefined;
|
||||
failedLookupLocations: string[];
|
||||
}
|
||||
|
||||
@@ -3359,25 +3482,26 @@ namespace ts {
|
||||
ContainsES2016 = 1 << 7,
|
||||
ES2015 = 1 << 8,
|
||||
ContainsES2015 = 1 << 9,
|
||||
DestructuringAssignment = 1 << 10,
|
||||
Generator = 1 << 11,
|
||||
ContainsGenerator = 1 << 12,
|
||||
Generator = 1 << 10,
|
||||
ContainsGenerator = 1 << 11,
|
||||
DestructuringAssignment = 1 << 12,
|
||||
ContainsDestructuringAssignment = 1 << 13,
|
||||
|
||||
// Markers
|
||||
// - Flags used to indicate that a subtree contains a specific transformation.
|
||||
ContainsDecorators = 1 << 13,
|
||||
ContainsPropertyInitializer = 1 << 14,
|
||||
ContainsLexicalThis = 1 << 15,
|
||||
ContainsCapturedLexicalThis = 1 << 16,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 17,
|
||||
ContainsDefaultValueAssignments = 1 << 18,
|
||||
ContainsParameterPropertyAssignments = 1 << 19,
|
||||
ContainsSpreadElementExpression = 1 << 20,
|
||||
ContainsComputedPropertyName = 1 << 21,
|
||||
ContainsBlockScopedBinding = 1 << 22,
|
||||
ContainsBindingPattern = 1 << 23,
|
||||
ContainsYield = 1 << 24,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 25,
|
||||
ContainsDecorators = 1 << 14,
|
||||
ContainsPropertyInitializer = 1 << 15,
|
||||
ContainsLexicalThis = 1 << 16,
|
||||
ContainsCapturedLexicalThis = 1 << 17,
|
||||
ContainsLexicalThisInComputedPropertyName = 1 << 18,
|
||||
ContainsDefaultValueAssignments = 1 << 19,
|
||||
ContainsParameterPropertyAssignments = 1 << 20,
|
||||
ContainsSpreadElementExpression = 1 << 21,
|
||||
ContainsComputedPropertyName = 1 << 22,
|
||||
ContainsBlockScopedBinding = 1 << 23,
|
||||
ContainsBindingPattern = 1 << 24,
|
||||
ContainsYield = 1 << 25,
|
||||
ContainsHoistedDeclarationOrCompletion = 1 << 26,
|
||||
|
||||
HasComputedFlags = 1 << 29, // Transform flags have been computed.
|
||||
|
||||
@@ -3389,6 +3513,7 @@ namespace ts {
|
||||
AssertES2016 = ES2016 | ContainsES2016,
|
||||
AssertES2015 = ES2015 | ContainsES2015,
|
||||
AssertGenerator = Generator | ContainsGenerator,
|
||||
AssertDestructuringAssignment = DestructuringAssignment | ContainsDestructuringAssignment,
|
||||
|
||||
// Scope Exclusions
|
||||
// - Bitmasks that exclude flags from propagating out of a specific context
|
||||
@@ -3451,6 +3576,8 @@ namespace ts {
|
||||
AsyncFunctionBody = 1 << 21,
|
||||
ReuseTempVariableScope = 1 << 22, // Reuse the existing temp variable scope during emit.
|
||||
CustomPrologue = 1 << 23, // Treat the statement as if it were a prologue directive (NOTE: Prologue directives are *not* transformed).
|
||||
NoHoisting = 1 << 24, // Do not hoist this declaration in --module system
|
||||
HasEndOfDeclarationMarker = 1 << 25, // Declaration has an associated NotEmittedStatement to mark the end of the declaration
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
+223
-80
@@ -63,11 +63,11 @@ namespace ts {
|
||||
// Completely ignore indentation for string writers. And map newlines to
|
||||
// a single space.
|
||||
writeLine: () => str += " ",
|
||||
increaseIndent: () => { },
|
||||
decreaseIndent: () => { },
|
||||
increaseIndent: noop,
|
||||
decreaseIndent: noop,
|
||||
clear: () => str = "",
|
||||
trackSymbol: () => { },
|
||||
reportInaccessibleThisError: () => { }
|
||||
trackSymbol: noop,
|
||||
reportInaccessibleThisError: noop
|
||||
};
|
||||
}
|
||||
|
||||
@@ -83,36 +83,17 @@ namespace ts {
|
||||
return node.end - node.pos;
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T>, array2: ReadonlyArray<T>, equaler?: (a: T, b: T) => boolean): boolean {
|
||||
if (!array1 || !array2) {
|
||||
return array1 === array2;
|
||||
}
|
||||
|
||||
if (array1.length !== array2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.length; i++) {
|
||||
const equals = equaler ? equaler(array1[i], array2[i]) : array1[i] === array2[i];
|
||||
if (!equals) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export function hasResolvedModule(sourceFile: SourceFile, moduleNameText: string): boolean {
|
||||
return !!(sourceFile && sourceFile.resolvedModules && sourceFile.resolvedModules[moduleNameText]);
|
||||
}
|
||||
|
||||
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModule {
|
||||
export function getResolvedModule(sourceFile: SourceFile, moduleNameText: string): ResolvedModuleFull {
|
||||
return hasResolvedModule(sourceFile, moduleNameText) ? sourceFile.resolvedModules[moduleNameText] : undefined;
|
||||
}
|
||||
|
||||
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModule): void {
|
||||
export function setResolvedModule(sourceFile: SourceFile, moduleNameText: string, resolvedModule: ResolvedModuleFull): void {
|
||||
if (!sourceFile.resolvedModules) {
|
||||
sourceFile.resolvedModules = createMap<ResolvedModule>();
|
||||
sourceFile.resolvedModules = createMap<ResolvedModuleFull>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedModules[moduleNameText] = resolvedModule;
|
||||
@@ -127,8 +108,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function moduleResolutionIsEqualTo(oldResolution: ResolvedModule, newResolution: ResolvedModule): boolean {
|
||||
return oldResolution.resolvedFileName === newResolution.resolvedFileName && oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport;
|
||||
export function moduleResolutionIsEqualTo(oldResolution: ResolvedModuleFull, newResolution: ResolvedModuleFull): boolean {
|
||||
return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
|
||||
oldResolution.extension === newResolution.extension &&
|
||||
oldResolution.resolvedFileName === newResolution.resolvedFileName;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -406,7 +389,12 @@ namespace ts {
|
||||
|
||||
export function isBlockOrCatchScoped(declaration: Declaration) {
|
||||
return (getCombinedNodeFlags(declaration) & NodeFlags.BlockScoped) !== 0 ||
|
||||
isCatchClauseVariableDeclaration(declaration);
|
||||
isCatchClauseVariableDeclarationOrBindingElement(declaration);
|
||||
}
|
||||
|
||||
export function isCatchClauseVariableDeclarationOrBindingElement(declaration: Declaration) {
|
||||
const node = getRootDeclaration(declaration);
|
||||
return node.kind === SyntaxKind.VariableDeclaration && node.parent.kind === SyntaxKind.CatchClause;
|
||||
}
|
||||
|
||||
export function isAmbientModule(node: Node): boolean {
|
||||
@@ -414,6 +402,7 @@ namespace ts {
|
||||
((<ModuleDeclaration>node).name.kind === SyntaxKind.StringLiteral || isGlobalScopeAugmentation(<ModuleDeclaration>node));
|
||||
}
|
||||
|
||||
/** Given a symbol for a module, checks that it is either an untyped import or a shorthand ambient module. */
|
||||
export function isShorthandAmbientModuleSymbol(moduleSymbol: Symbol): boolean {
|
||||
return isShorthandAmbientModule(moduleSymbol.valueDeclaration);
|
||||
}
|
||||
@@ -489,13 +478,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isCatchClauseVariableDeclaration(declaration: Declaration) {
|
||||
return declaration &&
|
||||
declaration.kind === SyntaxKind.VariableDeclaration &&
|
||||
declaration.parent &&
|
||||
declaration.parent.kind === SyntaxKind.CatchClause;
|
||||
}
|
||||
|
||||
// Return display name of an identifier
|
||||
// Computed property names will just be emitted as "[<expr>]", where <expr> is the source
|
||||
// text of the expression in the computed property.
|
||||
@@ -503,7 +485,18 @@ namespace ts {
|
||||
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
|
||||
}
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic {
|
||||
export function entityNameToString(name: EntityNameOrEntityNameExpression): string {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return getFullWidth(name) === 0 ? unescapeIdentifier((<Identifier>name).text) : getTextOfNode(name);
|
||||
case SyntaxKind.QualifiedName:
|
||||
return entityNameToString((<QualifiedName>name).left) + "." + entityNameToString((<QualifiedName>name).right);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return entityNameToString((<PropertyAccessEntityNameExpression>name).expression) + "." + entityNameToString((<PropertyAccessEntityNameExpression>name).name);
|
||||
}
|
||||
}
|
||||
|
||||
export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): Diagnostic {
|
||||
const sourceFile = getSourceFileOfNode(node);
|
||||
const span = getErrorSpanForNode(sourceFile, node);
|
||||
return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2);
|
||||
@@ -1060,17 +1053,19 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getEntityNameFromTypeNode(node: TypeNode): EntityNameOrEntityNameExpression {
|
||||
if (node) {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
return (<TypeReferenceNode>node).typeName;
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
Debug.assert(isEntityNameExpression((<ExpressionWithTypeArguments>node).expression));
|
||||
return <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression;
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.QualifiedName:
|
||||
return (<EntityName><Node>node);
|
||||
}
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.TypeReference:
|
||||
case SyntaxKind.JSDocTypeReference:
|
||||
return (<TypeReferenceNode>node).typeName;
|
||||
|
||||
case SyntaxKind.ExpressionWithTypeArguments:
|
||||
return isEntityNameExpression((<ExpressionWithTypeArguments>node).expression)
|
||||
? <EntityNameExpression>(<ExpressionWithTypeArguments>node).expression
|
||||
: undefined;
|
||||
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.QualifiedName:
|
||||
return (<EntityName><Node>node);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
@@ -1624,29 +1619,51 @@ namespace ts {
|
||||
return node && node.dotDotDotToken !== undefined;
|
||||
}
|
||||
|
||||
export const enum AssignmentKind {
|
||||
None, Definite, Compound
|
||||
}
|
||||
|
||||
export function getAssignmentTargetKind(node: Node): AssignmentKind {
|
||||
let parent = node.parent;
|
||||
while (true) {
|
||||
switch (parent.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
const binaryOperator = (<BinaryExpression>parent).operatorToken.kind;
|
||||
return isAssignmentOperator(binaryOperator) && (<BinaryExpression>parent).left === node ?
|
||||
binaryOperator === SyntaxKind.EqualsToken ? AssignmentKind.Definite : AssignmentKind.Compound :
|
||||
AssignmentKind.None;
|
||||
case SyntaxKind.PrefixUnaryExpression:
|
||||
case SyntaxKind.PostfixUnaryExpression:
|
||||
const unaryOperator = (<PrefixUnaryExpression | PostfixUnaryExpression>parent).operator;
|
||||
return unaryOperator === SyntaxKind.PlusPlusToken || unaryOperator === SyntaxKind.MinusMinusToken ? AssignmentKind.Compound : AssignmentKind.None;
|
||||
case SyntaxKind.ForInStatement:
|
||||
case SyntaxKind.ForOfStatement:
|
||||
return (<ForInStatement | ForOfStatement>parent).initializer === node ? AssignmentKind.Definite : AssignmentKind.None;
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.SpreadElementExpression:
|
||||
node = parent;
|
||||
break;
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
if ((<ShorthandPropertyAssignment>parent).name !== node) {
|
||||
return AssignmentKind.None;
|
||||
}
|
||||
// Fall through
|
||||
case SyntaxKind.PropertyAssignment:
|
||||
node = parent.parent;
|
||||
break;
|
||||
default:
|
||||
return AssignmentKind.None;
|
||||
}
|
||||
parent = node.parent;
|
||||
}
|
||||
}
|
||||
|
||||
// A node is an assignment target if it is on the left hand side of an '=' token, if it is parented by a property
|
||||
// assignment in an object literal that is an assignment target, or if it is parented by an array literal that is
|
||||
// an assignment target. Examples include 'a = xxx', '{ p: a } = xxx', '[{ p: a}] = xxx'.
|
||||
export function isAssignmentTarget(node: Node): boolean {
|
||||
while (node.parent.kind === SyntaxKind.ParenthesizedExpression) {
|
||||
node = node.parent;
|
||||
}
|
||||
while (true) {
|
||||
const parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.ArrayLiteralExpression || parent.kind === SyntaxKind.SpreadElementExpression) {
|
||||
node = parent;
|
||||
continue;
|
||||
}
|
||||
if (parent.kind === SyntaxKind.PropertyAssignment || parent.kind === SyntaxKind.ShorthandPropertyAssignment) {
|
||||
node = parent.parent;
|
||||
continue;
|
||||
}
|
||||
return parent.kind === SyntaxKind.BinaryExpression &&
|
||||
isAssignmentOperator((<BinaryExpression>parent).operatorToken.kind) &&
|
||||
(<BinaryExpression>parent).left === node ||
|
||||
(parent.kind === SyntaxKind.ForInStatement || parent.kind === SyntaxKind.ForOfStatement) &&
|
||||
(<ForInStatement | ForOfStatement>parent).initializer === node;
|
||||
}
|
||||
return getAssignmentTargetKind(node) !== AssignmentKind.None;
|
||||
}
|
||||
|
||||
export function isNodeDescendantOf(node: Node, ancestor: Node): boolean {
|
||||
@@ -1953,14 +1970,16 @@ namespace ts {
|
||||
|| positionIsSynthesized(node.end);
|
||||
}
|
||||
|
||||
export function getOriginalNode(node: Node): Node {
|
||||
export function getOriginalNode(node: Node): Node;
|
||||
export function getOriginalNode<T extends Node>(node: Node, nodeTest: (node: Node) => node is T): T;
|
||||
export function getOriginalNode(node: Node, nodeTest?: (node: Node) => boolean): Node {
|
||||
if (node) {
|
||||
while (node.original !== undefined) {
|
||||
node = node.original;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
return !nodeTest || nodeTest(node) ? node : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2566,7 +2585,7 @@ namespace ts {
|
||||
const options = host.getCompilerOptions();
|
||||
// Emit on each source file
|
||||
if (options.outFile || options.out) {
|
||||
onBundledEmit(host, sourceFiles);
|
||||
onBundledEmit(sourceFiles);
|
||||
}
|
||||
else {
|
||||
for (const sourceFile of sourceFiles) {
|
||||
@@ -2599,7 +2618,7 @@ namespace ts {
|
||||
action(jsFilePath, sourceMapFilePath, declarationFilePath, [sourceFile], /*isBundledEmit*/ false);
|
||||
}
|
||||
|
||||
function onBundledEmit(host: EmitHost, sourceFiles: SourceFile[]) {
|
||||
function onBundledEmit(sourceFiles: SourceFile[]) {
|
||||
if (sourceFiles.length) {
|
||||
const jsFilePath = options.outFile || options.out;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
@@ -3038,7 +3057,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
if (node.flags & NodeFlags.NestedNamespace) {
|
||||
if (node.flags & NodeFlags.NestedNamespace || (node.kind === SyntaxKind.Identifier && (<Identifier>node).isInJSDocNamespace)) {
|
||||
flags |= ModifierFlags.Export;
|
||||
}
|
||||
|
||||
@@ -3082,7 +3101,13 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function isDestructuringAssignment(node: Node): node is BinaryExpression {
|
||||
export function isAssignmentExpression(node: Node): node is AssignmentExpression {
|
||||
return isBinaryExpression(node)
|
||||
&& isAssignmentOperator(node.operatorToken.kind)
|
||||
&& isLeftHandSideExpression(node.left);
|
||||
}
|
||||
|
||||
export function isDestructuringAssignment(node: Node): node is DestructuringAssignment {
|
||||
if (isBinaryExpression(node)) {
|
||||
if (node.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const kind = node.left.kind;
|
||||
@@ -3506,9 +3531,21 @@ namespace ts {
|
||||
return positionIsSynthesized(range.pos) ? -1 : skipTrivia(sourceFile.text, range.pos);
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile) {
|
||||
export interface ExternalModuleInfo {
|
||||
externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[]; // imports of other external modules
|
||||
exportSpecifiers: Map<ExportSpecifier[]>; // export specifiers by name
|
||||
exportedBindings: Map<Identifier[]>; // exported names of local declarations
|
||||
exportedNames: Identifier[]; // all exported names local to module
|
||||
exportEquals: ExportAssignment | undefined; // an export= declaration if one was present
|
||||
hasExportStarsToExportValues: boolean; // whether this module contains export*
|
||||
}
|
||||
|
||||
export function collectExternalModuleInfo(sourceFile: SourceFile, resolver: EmitResolver): ExternalModuleInfo {
|
||||
const externalImports: (ImportDeclaration | ImportEqualsDeclaration | ExportDeclaration)[] = [];
|
||||
const exportSpecifiers = createMap<ExportSpecifier[]>();
|
||||
const exportedBindings = createMap<Identifier[]>();
|
||||
const uniqueExports = createMap<Identifier>();
|
||||
let hasExportDefault = false;
|
||||
let exportEquals: ExportAssignment = undefined;
|
||||
let hasExportStarsToExportValues = false;
|
||||
for (const node of sourceFile.statements) {
|
||||
@@ -3526,6 +3563,7 @@ namespace ts {
|
||||
// import x = require("mod")
|
||||
externalImports.push(<ImportEqualsDeclaration>node);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case SyntaxKind.ExportDeclaration:
|
||||
@@ -3543,8 +3581,19 @@ namespace ts {
|
||||
else {
|
||||
// export { x, y }
|
||||
for (const specifier of (<ExportDeclaration>node).exportClause.elements) {
|
||||
const name = (specifier.propertyName || specifier.name).text;
|
||||
(exportSpecifiers[name] || (exportSpecifiers[name] = [])).push(specifier);
|
||||
if (!uniqueExports[specifier.name.text]) {
|
||||
const name = specifier.propertyName || specifier.name;
|
||||
multiMapAdd(exportSpecifiers, name.text, specifier);
|
||||
|
||||
const decl = resolver.getReferencedImportDeclaration(name)
|
||||
|| resolver.getReferencedValueDeclaration(name);
|
||||
|
||||
if (decl) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(decl), specifier.name);
|
||||
}
|
||||
|
||||
uniqueExports[specifier.name.text] = specifier.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3555,10 +3604,94 @@ namespace ts {
|
||||
exportEquals = <ExportAssignment>node;
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.VariableStatement:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
for (const decl of (<VariableStatement>node).declarationList.declarations) {
|
||||
collectExportedVariableInfo(decl, uniqueExports);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default function() { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<FunctionDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export function x() { }
|
||||
const name = (<FunctionDeclaration>node).name;
|
||||
if (!uniqueExports[name.text]) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports[name.text] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.ClassDeclaration:
|
||||
if (hasModifier(node, ModifierFlags.Export)) {
|
||||
if (hasModifier(node, ModifierFlags.Default)) {
|
||||
// export default class { }
|
||||
if (!hasExportDefault) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), getDeclarationName(<ClassDeclaration>node));
|
||||
hasExportDefault = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// export class x { }
|
||||
const name = (<ClassDeclaration>node).name;
|
||||
if (!uniqueExports[name.text]) {
|
||||
multiMapAdd(exportedBindings, getOriginalNodeId(node), name);
|
||||
uniqueExports[name.text] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues };
|
||||
let exportedNames: Identifier[];
|
||||
for (const key in uniqueExports) {
|
||||
exportedNames = ts.append(exportedNames, uniqueExports[key]);
|
||||
}
|
||||
|
||||
return { externalImports, exportSpecifiers, exportEquals, hasExportStarsToExportValues, exportedBindings, exportedNames };
|
||||
}
|
||||
|
||||
function collectExportedVariableInfo(decl: VariableDeclaration | BindingElement, uniqueExports: Map<Identifier>) {
|
||||
if (isBindingPattern(decl.name)) {
|
||||
for (const element of decl.name.elements) {
|
||||
if (!isOmittedExpression(element)) {
|
||||
collectExportedVariableInfo(element, uniqueExports);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!isGeneratedIdentifier(decl.name)) {
|
||||
if (!uniqueExports[decl.name.text]) {
|
||||
uniqueExports[decl.name.text] = decl.name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a name was originally the declaration name of an enum or namespace
|
||||
* declaration.
|
||||
*/
|
||||
export function isDeclarationNameOfEnumOrNamespace(node: Identifier) {
|
||||
const parseNode = getParseTreeNode(node);
|
||||
if (parseNode) {
|
||||
switch (parseNode.parent.kind) {
|
||||
case SyntaxKind.EnumDeclaration:
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return parseNode === (<EnumDeclaration | ModuleDeclaration>parseNode.parent).name;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getInitializedVariables(node: VariableDeclarationList) {
|
||||
@@ -3646,7 +3779,7 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
export function isGeneratedIdentifier(node: Node): boolean {
|
||||
export function isGeneratedIdentifier(node: Node): node is GeneratedIdentifier {
|
||||
// Using `>` here catches both `GeneratedIdentifierKind.None` and `undefined`.
|
||||
return isIdentifier(node) && node.autoGenerateKind > GeneratedIdentifierKind.None;
|
||||
}
|
||||
@@ -3782,6 +3915,14 @@ namespace ts {
|
||||
|
||||
// Expression
|
||||
|
||||
export function isArrayLiteralExpression(node: Node): node is ArrayLiteralExpression {
|
||||
return node.kind === SyntaxKind.ArrayLiteralExpression;
|
||||
}
|
||||
|
||||
export function isObjectLiteralExpression(node: Node): node is ObjectLiteralExpression {
|
||||
return node.kind === SyntaxKind.ObjectLiteralExpression;
|
||||
}
|
||||
|
||||
export function isPropertyAccessExpression(node: Node): node is PropertyAccessExpression {
|
||||
return node.kind === SyntaxKind.PropertyAccessExpression;
|
||||
}
|
||||
@@ -4041,7 +4182,9 @@ namespace ts {
|
||||
|| kind === SyntaxKind.VariableStatement
|
||||
|| kind === SyntaxKind.WhileStatement
|
||||
|| kind === SyntaxKind.WithStatement
|
||||
|| kind === SyntaxKind.NotEmittedStatement;
|
||||
|| kind === SyntaxKind.NotEmittedStatement
|
||||
|| kind === SyntaxKind.EndOfDeclarationMarker
|
||||
|| kind === SyntaxKind.MergeDeclarationMarker;
|
||||
}
|
||||
|
||||
export function isDeclaration(node: Node): node is Declaration {
|
||||
@@ -4172,7 +4315,7 @@ namespace ts {
|
||||
case ScriptTarget.ES2016:
|
||||
return "lib.es2016.d.ts";
|
||||
case ScriptTarget.ES2015:
|
||||
return "lib.es2015.d.ts";
|
||||
return "lib.es6.d.ts";
|
||||
|
||||
default:
|
||||
return "lib.d.ts";
|
||||
|
||||
@@ -553,6 +553,7 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
aggregateTransformFlags(node);
|
||||
const visited = visitor(node);
|
||||
if (visited === node) {
|
||||
return node;
|
||||
@@ -621,6 +622,7 @@ namespace ts {
|
||||
// Visit each original node.
|
||||
for (let i = 0; i < count; i++) {
|
||||
const node = nodes[i + start];
|
||||
aggregateTransformFlags(node);
|
||||
const visited = node !== undefined ? visitor(node) : undefined;
|
||||
if (updated !== undefined || visited === undefined || visited !== node) {
|
||||
if (updated === undefined) {
|
||||
@@ -692,7 +694,7 @@ namespace ts {
|
||||
|
||||
// Signature elements
|
||||
case SyntaxKind.Parameter:
|
||||
return updateParameterDeclaration(<ParameterDeclaration>node,
|
||||
return updateParameter(<ParameterDeclaration>node,
|
||||
visitNodes((<ParameterDeclaration>node).decorators, visitor, isDecorator),
|
||||
visitNodes((<ParameterDeclaration>node).modifiers, visitor, isModifier),
|
||||
visitNode((<ParameterDeclaration>node).name, visitor, isBindingName),
|
||||
@@ -1331,18 +1333,18 @@ namespace ts {
|
||||
export namespace Debug {
|
||||
export const failNotOptional = shouldAssert(AssertionLevel.Normal)
|
||||
? (message?: string) => assert(false, message || "Node not optional.")
|
||||
: (message?: string) => {};
|
||||
: noop;
|
||||
|
||||
export const failBadSyntaxKind = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, message?: string) => assert(false, message || "Unexpected node.", () => `Node ${formatSyntaxKind(node.kind)} was unexpected.`)
|
||||
: (node: Node, message?: string) => {};
|
||||
: noop;
|
||||
|
||||
export const assertNode = shouldAssert(AssertionLevel.Normal)
|
||||
? (node: Node, test: (node: Node) => boolean, message?: string) => assert(
|
||||
test === undefined || test(node),
|
||||
message || "Unexpected node.",
|
||||
() => `Node ${formatSyntaxKind(node.kind)} did not pass test '${getFunctionName(test)}'.`)
|
||||
: (node: Node, test: (node: Node) => boolean, message?: string) => {};
|
||||
: noop;
|
||||
|
||||
function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
|
||||
+75
-131
@@ -47,19 +47,6 @@ namespace FourSlash {
|
||||
ranges: Range[];
|
||||
}
|
||||
|
||||
interface MemberListData {
|
||||
result: {
|
||||
maybeInaccurate: boolean;
|
||||
isMemberCompletion: boolean;
|
||||
entries: {
|
||||
name: string;
|
||||
type: string;
|
||||
kind: string;
|
||||
kindModifiers: string;
|
||||
}[];
|
||||
};
|
||||
}
|
||||
|
||||
export interface Marker {
|
||||
fileName: string;
|
||||
position: number;
|
||||
@@ -178,15 +165,9 @@ namespace FourSlash {
|
||||
// Return object may lack some functionalities for other purposes.
|
||||
function createScriptSnapShot(sourceText: string): ts.IScriptSnapshot {
|
||||
return {
|
||||
getText: (start: number, end: number) => {
|
||||
return sourceText.substr(start, end - start);
|
||||
},
|
||||
getLength: () => {
|
||||
return sourceText.length;
|
||||
},
|
||||
getChangeRange: (oldSnapshot: ts.IScriptSnapshot) => {
|
||||
return <ts.TextChangeRange>undefined;
|
||||
}
|
||||
getText: (start: number, end: number) => sourceText.substr(start, end - start),
|
||||
getLength: () => sourceText.length,
|
||||
getChangeRange: () => undefined
|
||||
};
|
||||
}
|
||||
|
||||
@@ -419,9 +400,8 @@ namespace FourSlash {
|
||||
public verifyErrorExistsBetweenMarkers(startMarkerName: string, endMarkerName: string, negative: boolean) {
|
||||
const startMarker = this.getMarkerByName(startMarkerName);
|
||||
const endMarker = this.getMarkerByName(endMarkerName);
|
||||
const predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
|
||||
return ((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false;
|
||||
};
|
||||
const predicate = (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) =>
|
||||
((errorMinChar === startPos) && (errorLimChar === endPos)) ? true : false;
|
||||
|
||||
const exists = this.anyErrorInRange(predicate, startMarker, endMarker);
|
||||
|
||||
@@ -458,9 +438,8 @@ namespace FourSlash {
|
||||
private getAllDiagnostics(): ts.Diagnostic[] {
|
||||
const diagnostics: ts.Diagnostic[] = [];
|
||||
|
||||
const fileNames = this.languageServiceAdapterHost.getFilenames();
|
||||
for (let i = 0, n = fileNames.length; i < n; i++) {
|
||||
diagnostics.push.apply(this.getDiagnostics(fileNames[i]));
|
||||
for (const fileName of this.languageServiceAdapterHost.getFilenames()) {
|
||||
diagnostics.push.apply(this.getDiagnostics(fileName));
|
||||
}
|
||||
|
||||
return diagnostics;
|
||||
@@ -471,14 +450,12 @@ namespace FourSlash {
|
||||
let predicate: (errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) => boolean;
|
||||
|
||||
if (after) {
|
||||
predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
|
||||
return ((errorMinChar >= startPos) && (errorLimChar >= startPos)) ? true : false;
|
||||
};
|
||||
predicate = (errorMinChar: number, errorLimChar: number, startPos: number) =>
|
||||
((errorMinChar >= startPos) && (errorLimChar >= startPos)) ? true : false;
|
||||
}
|
||||
else {
|
||||
predicate = function(errorMinChar: number, errorLimChar: number, startPos: number, endPos: number) {
|
||||
return ((errorMinChar <= startPos) && (errorLimChar <= startPos)) ? true : false;
|
||||
};
|
||||
predicate = (errorMinChar: number, errorLimChar: number, startPos: number) =>
|
||||
((errorMinChar <= startPos) && (errorLimChar <= startPos)) ? true : false;
|
||||
}
|
||||
|
||||
const exists = this.anyErrorInRange(predicate, marker);
|
||||
@@ -602,12 +579,12 @@ namespace FourSlash {
|
||||
this.raiseError(`goToDefinitions failed - expected to find ${endMarkers.length} definitions but got ${definitions.length}`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < endMarkers.length; i++) {
|
||||
const marker = this.getMarkerByName(endMarkers[i]), definition = definitions[i];
|
||||
ts.zipWith(endMarkers, definitions, (endMarker, definition, i) => {
|
||||
const marker = this.getMarkerByName(endMarker);
|
||||
if (marker.fileName !== definition.fileName || marker.position !== definition.textSpan.start) {
|
||||
this.raiseError(`goToDefinition failed for definition ${i}: expected ${marker.fileName} at ${marker.position}, got ${definition.fileName} at ${definition.textSpan.start}`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public verifyGetEmitOutputForCurrentFile(expected: string): void {
|
||||
@@ -624,10 +601,10 @@ namespace FourSlash {
|
||||
public verifyGetEmitOutputContentsForCurrentFile(expected: ts.OutputFile[]): void {
|
||||
const emit = this.languageService.getEmitOutput(this.activeFile.fileName);
|
||||
assert.equal(emit.outputFiles.length, expected.length, "Number of emit output files");
|
||||
for (let i = 0; i < emit.outputFiles.length; i++) {
|
||||
assert.equal(emit.outputFiles[i].name, expected[i].name, "FileName");
|
||||
assert.equal(emit.outputFiles[i].text, expected[i].text, "Content");
|
||||
}
|
||||
ts.zipWith(emit.outputFiles, expected, (outputFile, expected) => {
|
||||
assert.equal(outputFile.name, expected.name, "FileName");
|
||||
assert.equal(outputFile.text, expected.text, "Content");
|
||||
});
|
||||
}
|
||||
|
||||
public verifyMemberListContains(symbol: string, text?: string, documentation?: string, kind?: string) {
|
||||
@@ -690,9 +667,9 @@ namespace FourSlash {
|
||||
|
||||
const entries = this.getCompletionListAtCaret().entries;
|
||||
assert.isTrue(items.length <= entries.length, `Amount of expected items in completion list [ ${items.length} ] is greater than actual number of items in list [ ${entries.length} ]`);
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
assert.equal(entries[i].name, items[i], `Unexpected item in completion list`);
|
||||
}
|
||||
ts.zipWith(entries, items, (entry, item) => {
|
||||
assert.equal(entry.name, item, `Unexpected item in completion list`);
|
||||
});
|
||||
}
|
||||
|
||||
public noItemsWithSameNameButDifferentKind(): void {
|
||||
@@ -714,15 +691,7 @@ namespace FourSlash {
|
||||
this.raiseError("Member list is empty at Caret");
|
||||
}
|
||||
else if ((members && members.entries.length !== 0) && !negative) {
|
||||
|
||||
let errorMsg = "\n" + "Member List contains: [" + members.entries[0].name;
|
||||
for (let i = 1; i < members.entries.length; i++) {
|
||||
errorMsg += ", " + members.entries[i].name;
|
||||
}
|
||||
errorMsg += "]\n";
|
||||
|
||||
this.raiseError("Member list is not empty at Caret: " + errorMsg);
|
||||
|
||||
this.raiseError(`Member list is not empty at Caret:\nMember List contains: ${stringify(members.entries.map(e => e.name))}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -732,13 +701,8 @@ namespace FourSlash {
|
||||
this.raiseError("Completion list is empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition);
|
||||
}
|
||||
else if (completions && completions.entries.length !== 0 && !negative) {
|
||||
let errorMsg = "\n" + "Completion List contains: [" + completions.entries[0].name;
|
||||
for (let i = 1; i < completions.entries.length; i++) {
|
||||
errorMsg += ", " + completions.entries[i].name;
|
||||
}
|
||||
errorMsg += "]\n";
|
||||
|
||||
this.raiseError("Completion list is not empty at caret at position " + this.activeFile.fileName + " " + this.currentCaretPosition + errorMsg);
|
||||
this.raiseError(`Completion list is not empty at caret at position ${this.activeFile.fileName} ${this.currentCaretPosition}\n` +
|
||||
`Completion List contains: ${stringify(completions.entries.map(e => e.name))}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -912,8 +876,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
|
||||
for (let i = 0; i < references.length; i++) {
|
||||
const reference = references[i];
|
||||
for (const reference of references) {
|
||||
if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) {
|
||||
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
|
||||
this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`);
|
||||
@@ -1030,16 +993,11 @@ namespace FourSlash {
|
||||
ranges = ranges.sort((r1, r2) => r1.start - r2.start);
|
||||
references = references.sort((r1, r2) => r1.textSpan.start - r2.textSpan.start);
|
||||
|
||||
for (let i = 0, n = ranges.length; i < n; i++) {
|
||||
const reference = references[i];
|
||||
const range = ranges[i];
|
||||
|
||||
if (reference.textSpan.start !== range.start ||
|
||||
ts.textSpanEnd(reference.textSpan) !== range.end) {
|
||||
|
||||
ts.zipWith(references, ranges, (reference, range) => {
|
||||
if (reference.textSpan.start !== range.start || ts.textSpanEnd(reference.textSpan) !== range.end) {
|
||||
this.raiseError("Rename location results do not match.\n\nExpected: " + stringify(ranges) + "\n\nActual:" + JSON.stringify(references));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.raiseError("Expected rename to succeed, but it actually failed.");
|
||||
@@ -1179,7 +1137,7 @@ namespace FourSlash {
|
||||
|
||||
private alignmentForExtraInfo = 50;
|
||||
|
||||
private spanInfoToString(pos: number, spanInfo: ts.TextSpan, prefixString: string) {
|
||||
private spanInfoToString(spanInfo: ts.TextSpan, prefixString: string) {
|
||||
let resultString = "SpanInfo: " + JSON.stringify(spanInfo);
|
||||
if (spanInfo) {
|
||||
const spanString = this.activeFile.content.substr(spanInfo.start, spanInfo.length);
|
||||
@@ -1230,7 +1188,7 @@ namespace FourSlash {
|
||||
startColumn = 0;
|
||||
length = 0;
|
||||
}
|
||||
const spanInfo = this.spanInfoToString(pos, getSpanAtPos(pos), prefixString);
|
||||
const spanInfo = this.spanInfoToString(getSpanAtPos(pos), prefixString);
|
||||
if (previousSpanInfo && previousSpanInfo !== spanInfo) {
|
||||
addSpanInfoString();
|
||||
previousSpanInfo = spanInfo;
|
||||
@@ -1269,8 +1227,7 @@ namespace FourSlash {
|
||||
const emitFiles: FourSlashFile[] = []; // List of FourSlashFile that has emitThisFile flag on
|
||||
|
||||
const allFourSlashFiles = this.testData.files;
|
||||
for (let idx = 0; idx < allFourSlashFiles.length; idx++) {
|
||||
const file = allFourSlashFiles[idx];
|
||||
for (const file of allFourSlashFiles) {
|
||||
if (file.fileOptions[metadataOptionNames.emitThisFile] === "true") {
|
||||
// Find a file with the flag emitThisFile turned on
|
||||
emitFiles.push(file);
|
||||
@@ -1295,15 +1252,26 @@ namespace FourSlash {
|
||||
if (emitOutput.emitSkipped) {
|
||||
resultString += "Diagnostics:" + Harness.IO.newLine();
|
||||
const diagnostics = ts.getPreEmitDiagnostics(this.languageService.getProgram());
|
||||
for (let i = 0, n = diagnostics.length; i < n; i++) {
|
||||
resultString += " " + diagnostics[0].messageText + Harness.IO.newLine();
|
||||
for (const diagnostic of diagnostics) {
|
||||
if (typeof diagnostic.messageText !== "string") {
|
||||
let chainedMessage = <ts.DiagnosticMessageChain>diagnostic.messageText;
|
||||
let indentation = " ";
|
||||
while (chainedMessage) {
|
||||
resultString += indentation + chainedMessage.messageText + Harness.IO.newLine();
|
||||
chainedMessage = chainedMessage.next;
|
||||
indentation = indentation + " ";
|
||||
}
|
||||
}
|
||||
else {
|
||||
resultString += " " + diagnostic.messageText + Harness.IO.newLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emitOutput.outputFiles.forEach((outputFile, idx, array) => {
|
||||
for (const outputFile of emitOutput.outputFiles) {
|
||||
const fileName = "FileName : " + outputFile.name + Harness.IO.newLine();
|
||||
resultString = resultString + fileName + outputFile.text;
|
||||
});
|
||||
}
|
||||
resultString += Harness.IO.newLine();
|
||||
});
|
||||
|
||||
@@ -1328,7 +1296,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public printBreakpointLocation(pos: number) {
|
||||
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(pos, this.getBreakpointStatementLocation(pos), " "));
|
||||
Harness.IO.log("\n**Pos: " + pos + " " + this.spanInfoToString(this.getBreakpointStatementLocation(pos), " "));
|
||||
}
|
||||
|
||||
public printBreakpointAtCurrentLocation() {
|
||||
@@ -1362,8 +1330,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public printCurrentFileState(makeWhitespaceVisible = false, makeCaretVisible = true) {
|
||||
for (let i = 0; i < this.testData.files.length; i++) {
|
||||
const file = this.testData.files[i];
|
||||
for (const file of this.testData.files) {
|
||||
const active = (this.activeFile === file);
|
||||
Harness.IO.log(`=== Script (${file.fileName}) ${(active ? "(active, cursor at |)" : "")} ===`);
|
||||
let content = this.getFileContent(file.fileName);
|
||||
@@ -1598,10 +1565,10 @@ namespace FourSlash {
|
||||
edits = edits.sort((a, b) => a.span.start - b.span.start);
|
||||
// Get a snapshot of the content of the file so we can make sure any formatting edits didn't destroy non-whitespace characters
|
||||
const oldContent = this.getFileContent(this.activeFile.fileName);
|
||||
for (let j = 0; j < edits.length; j++) {
|
||||
this.languageServiceAdapterHost.editScript(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText);
|
||||
this.updateMarkersForEdit(fileName, edits[j].span.start + runningOffset, ts.textSpanEnd(edits[j].span) + runningOffset, edits[j].newText);
|
||||
const change = (edits[j].span.start - ts.textSpanEnd(edits[j].span)) + edits[j].newText.length;
|
||||
for (const edit of edits) {
|
||||
this.languageServiceAdapterHost.editScript(fileName, edit.span.start + runningOffset, ts.textSpanEnd(edit.span) + runningOffset, edit.newText);
|
||||
this.updateMarkersForEdit(fileName, edit.span.start + runningOffset, ts.textSpanEnd(edit.span) + runningOffset, edit.newText);
|
||||
const change = (edit.span.start - ts.textSpanEnd(edit.span)) + edit.newText.length;
|
||||
runningOffset += change;
|
||||
// TODO: Consider doing this at least some of the time for higher fidelity. Currently causes a failure (bug 707150)
|
||||
// this.languageService.getScriptLexicalStructure(fileName);
|
||||
@@ -1830,7 +1797,7 @@ namespace FourSlash {
|
||||
return result;
|
||||
}
|
||||
|
||||
private rangeText({fileName, start, end}: Range, more = false): string {
|
||||
private rangeText({fileName, start, end}: Range): string {
|
||||
return this.getFileContent(fileName).slice(start, end);
|
||||
}
|
||||
|
||||
@@ -1925,7 +1892,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
public printNameOrDottedNameSpans(pos: number) {
|
||||
Harness.IO.log(this.spanInfoToString(pos, this.getNameOrDottedNameSpan(pos), "**"));
|
||||
Harness.IO.log(this.spanInfoToString(this.getNameOrDottedNameSpan(pos), "**"));
|
||||
}
|
||||
|
||||
private verifyClassifications(expected: { classificationType: string; text: string; textSpan?: TextSpan }[], actual: ts.ClassifiedSpan[]) {
|
||||
@@ -1935,10 +1902,7 @@ namespace FourSlash {
|
||||
jsonMismatchString());
|
||||
}
|
||||
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
const expectedClassification = expected[i];
|
||||
const actualClassification = actual[i];
|
||||
|
||||
ts.zipWith(expected, actual, (expectedClassification, actualClassification) => {
|
||||
const expectedType: string = (<any>ts.ClassificationTypeNames)[expectedClassification.classificationType];
|
||||
if (expectedType !== actualClassification.classificationType) {
|
||||
this.raiseError("verifyClassifications failed - expected classifications type to be " +
|
||||
@@ -1968,7 +1932,7 @@ namespace FourSlash {
|
||||
actualText +
|
||||
jsonMismatchString());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function jsonMismatchString() {
|
||||
return Harness.IO.newLine() +
|
||||
@@ -2013,13 +1977,11 @@ namespace FourSlash {
|
||||
this.raiseError(`verifyOutliningSpans failed - expected total spans to be ${spans.length}, but was ${actual.length}`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < spans.length; i++) {
|
||||
const expectedSpan = spans[i];
|
||||
const actualSpan = actual[i];
|
||||
ts.zipWith(spans, actual, (expectedSpan, actualSpan, i) => {
|
||||
if (expectedSpan.start !== actualSpan.textSpan.start || expectedSpan.end !== ts.textSpanEnd(actualSpan.textSpan)) {
|
||||
this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.start},${expectedSpan.end}), actual: (${actualSpan.textSpan.start},${ts.textSpanEnd(actualSpan.textSpan)})`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public verifyTodoComments(descriptors: string[], spans: TextSpan[]) {
|
||||
@@ -2030,15 +1992,13 @@ namespace FourSlash {
|
||||
this.raiseError(`verifyTodoComments failed - expected total spans to be ${spans.length}, but was ${actual.length}`);
|
||||
}
|
||||
|
||||
for (let i = 0; i < spans.length; i++) {
|
||||
const expectedSpan = spans[i];
|
||||
const actualComment = actual[i];
|
||||
ts.zipWith(spans, actual, (expectedSpan, actualComment, i) => {
|
||||
const actualCommentSpan = ts.createTextSpan(actualComment.position, actualComment.message.length);
|
||||
|
||||
if (expectedSpan.start !== actualCommentSpan.start || expectedSpan.end !== ts.textSpanEnd(actualCommentSpan)) {
|
||||
this.raiseError(`verifyOutliningSpans failed - span ${(i + 1)} expected: (${expectedSpan.start},${expectedSpan.end}), actual: (${actualCommentSpan.start},${ts.textSpanEnd(actualCommentSpan)})`);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private getCodeFixes(errorCode?: number) {
|
||||
@@ -2185,11 +2145,9 @@ namespace FourSlash {
|
||||
public verifyNavigationItemsCount(expected: number, searchValue: string, matchKind?: string, fileName?: string) {
|
||||
const items = this.languageService.getNavigateToItems(searchValue, /*maxResultCount*/ undefined, fileName);
|
||||
let actual = 0;
|
||||
let item: ts.NavigateToItem;
|
||||
|
||||
// Count only the match that match the same MatchKind
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
item = items[i];
|
||||
for (const item of items) {
|
||||
if (!matchKind || item.matchKind === matchKind) {
|
||||
actual++;
|
||||
}
|
||||
@@ -2217,8 +2175,7 @@ namespace FourSlash {
|
||||
this.raiseError("verifyNavigationItemsListContains failed - found 0 navigation items, expected at least one.");
|
||||
}
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
for (const item of items) {
|
||||
if (item && item.name === name && item.kind === kind &&
|
||||
(matchKind === undefined || item.matchKind === matchKind) &&
|
||||
(fileName === undefined || item.fileName === fileName) &&
|
||||
@@ -2269,24 +2226,16 @@ namespace FourSlash {
|
||||
|
||||
public printNavigationItems(searchValue: string) {
|
||||
const items = this.languageService.getNavigateToItems(searchValue);
|
||||
const length = items && items.length;
|
||||
|
||||
Harness.IO.log(`NavigationItems list (${length} items)`);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
const item = items[i];
|
||||
Harness.IO.log(`NavigationItems list (${items.length} items)`);
|
||||
for (const item of items) {
|
||||
Harness.IO.log(`name: ${item.name}, kind: ${item.kind}, parentName: ${item.containerName}, fileName: ${item.fileName}`);
|
||||
}
|
||||
}
|
||||
|
||||
public printNavigationBar() {
|
||||
const items = this.languageService.getNavigationBarItems(this.activeFile.fileName);
|
||||
const length = items && items.length;
|
||||
|
||||
Harness.IO.log(`Navigation bar (${length} items)`);
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
const item = items[i];
|
||||
Harness.IO.log(`Navigation bar (${items.length} items)`);
|
||||
for (const item of items) {
|
||||
Harness.IO.log(`${repeatString(item.indent, " ")}name: ${item.text}, kind: ${item.kind}, childItems: ${item.childItems.map(child => child.text)}`);
|
||||
}
|
||||
}
|
||||
@@ -2407,8 +2356,7 @@ namespace FourSlash {
|
||||
}
|
||||
|
||||
private assertItemInCompletionList(items: ts.CompletionEntry[], name: string, text?: string, documentation?: string, kind?: string, spanIndex?: number) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
for (const item of items) {
|
||||
if (item.name === name) {
|
||||
if (documentation != undefined || text !== undefined) {
|
||||
const details = this.getCompletionEntryDetails(item.name);
|
||||
@@ -2457,20 +2405,17 @@ namespace FourSlash {
|
||||
name = name.indexOf("/") === -1 ? (this.basePath + "/" + name) : name;
|
||||
|
||||
const availableNames: string[] = [];
|
||||
let foundIt = false;
|
||||
for (let i = 0; i < this.testData.files.length; i++) {
|
||||
const fn = this.testData.files[i].fileName;
|
||||
result = ts.forEach(this.testData.files, file => {
|
||||
const fn = file.fileName;
|
||||
if (fn) {
|
||||
if (fn === name) {
|
||||
result = this.testData.files[i];
|
||||
foundIt = true;
|
||||
break;
|
||||
return file;
|
||||
}
|
||||
availableNames.push(fn);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!foundIt) {
|
||||
if (!result) {
|
||||
throw new Error(`No test file named "${name}" exists. Available file names are: ${availableNames.join(", ")}`);
|
||||
}
|
||||
}
|
||||
@@ -2571,8 +2516,8 @@ ${code}
|
||||
|
||||
function chompLeadingSpace(content: string) {
|
||||
const lines = content.split("\n");
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
if ((lines[i].length !== 0) && (lines[i].charAt(0) !== " ")) {
|
||||
for (const line of lines) {
|
||||
if ((line.length !== 0) && (line.charAt(0) !== " ")) {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -2610,8 +2555,7 @@ ${code}
|
||||
currentFileName = fileName;
|
||||
}
|
||||
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let line = lines[i];
|
||||
for (let line of lines) {
|
||||
const lineLength = line.length;
|
||||
|
||||
if (lineLength > 0 && line.charAt(lineLength - 1) === "\r") {
|
||||
|
||||
+50
-40
@@ -220,9 +220,7 @@ namespace Utils {
|
||||
}
|
||||
|
||||
export function sourceFileToJSON(file: ts.Node): string {
|
||||
return JSON.stringify(file, (k, v) => {
|
||||
return isNodeOrArray(v) ? serializeNode(v) : v;
|
||||
}, " ");
|
||||
return JSON.stringify(file, (_, v) => isNodeOrArray(v) ? serializeNode(v) : v, " ");
|
||||
|
||||
function getKindName(k: number | string): string {
|
||||
if (typeof k === "string") {
|
||||
@@ -692,7 +690,7 @@ namespace Harness {
|
||||
export const getCurrentDirectory = () => "";
|
||||
export const args = () => <string[]>[];
|
||||
export const getExecutingFilePath = () => "";
|
||||
export const exit = (exitCode: number) => { };
|
||||
export const exit = ts.noop;
|
||||
export const getDirectories = () => <string[]>[];
|
||||
|
||||
export let log = (s: string) => console.log(s);
|
||||
@@ -742,7 +740,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
export function createDirectory(path: string) {
|
||||
export function createDirectory() {
|
||||
// Do nothing (?)
|
||||
}
|
||||
|
||||
@@ -750,7 +748,7 @@ namespace Harness {
|
||||
Http.writeToServerSync(serverRoot + path, "DELETE");
|
||||
}
|
||||
|
||||
export function directoryExists(path: string): boolean {
|
||||
export function directoryExists(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -792,7 +790,7 @@ namespace Harness {
|
||||
return response.status === 200;
|
||||
}
|
||||
|
||||
export function _listFilesImpl(path: string, spec?: RegExp, options?: any) {
|
||||
export let listFiles = Utils.memoize((path: string, spec?: RegExp): string[] => {
|
||||
const response = Http.getFileFromServerSync(serverRoot + path);
|
||||
if (response.status === 200) {
|
||||
const results = response.responseText.split(",");
|
||||
@@ -806,8 +804,7 @@ namespace Harness {
|
||||
else {
|
||||
return [""];
|
||||
}
|
||||
};
|
||||
export let listFiles = Utils.memoize(_listFilesImpl);
|
||||
});
|
||||
|
||||
export function readFile(file: string) {
|
||||
const response = Http.getFileFromServerSync(serverRoot + file);
|
||||
@@ -991,7 +988,7 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceFile(fileName: string, languageVersion: ts.ScriptTarget) {
|
||||
function getSourceFile(fileName: string) {
|
||||
fileName = ts.normalizePath(fileName);
|
||||
const path = ts.toPath(fileName, currentDirectory, getCanonicalFileName);
|
||||
if (fileMap.contains(path)) {
|
||||
@@ -1032,7 +1029,7 @@ namespace Harness {
|
||||
},
|
||||
realpath: realPathMap && ((f: string) => {
|
||||
const path = ts.toPath(f, currentDirectory, getCanonicalFileName);
|
||||
return realPathMap.contains(path) ? realPathMap.get(path) : path;
|
||||
return realPathMap.get(path) || path;
|
||||
}),
|
||||
directoryExists: dir => {
|
||||
let path = ts.toPath(dir, currentDirectory, getCanonicalFileName);
|
||||
@@ -1040,18 +1037,12 @@ namespace Harness {
|
||||
if (path[path.length - 1] === "/") {
|
||||
path = <ts.Path>path.substr(0, path.length - 1);
|
||||
}
|
||||
let exists = false;
|
||||
fileMap.forEachValue(key => {
|
||||
if (key.indexOf(path) === 0 && key[path.length] === "/") {
|
||||
exists = true;
|
||||
}
|
||||
});
|
||||
return exists;
|
||||
return mapHasFileInDirectory(path, fileMap) || mapHasFileInDirectory(path, realPathMap);
|
||||
},
|
||||
getDirectories: d => {
|
||||
const path = ts.toPath(d, currentDirectory, getCanonicalFileName);
|
||||
const result: string[] = [];
|
||||
fileMap.forEachValue((key, value) => {
|
||||
fileMap.forEachValue(key => {
|
||||
if (key.indexOf(path) === 0 && key.lastIndexOf("/") > path.length) {
|
||||
let dirName = key.substr(path.length, key.indexOf("/", path.length + 1) - path.length);
|
||||
if (dirName[0] === "/") {
|
||||
@@ -1067,6 +1058,19 @@ namespace Harness {
|
||||
};
|
||||
}
|
||||
|
||||
function mapHasFileInDirectory(directoryPath: ts.Path, map: ts.FileMap<any>): boolean {
|
||||
if (!map) {
|
||||
return false;
|
||||
}
|
||||
let exists = false;
|
||||
map.forEachValue(fileName => {
|
||||
if (!exists && ts.startsWith(fileName, directoryPath) && fileName[directoryPath.length] === "/") {
|
||||
exists = true;
|
||||
}
|
||||
});
|
||||
return exists;
|
||||
}
|
||||
|
||||
interface HarnessOptions {
|
||||
useCaseSensitiveFileNames?: boolean;
|
||||
includeBuiltFile?: string;
|
||||
@@ -1111,22 +1115,7 @@ namespace Harness {
|
||||
const option = getCommandLineOption(name);
|
||||
if (option) {
|
||||
const errors: ts.Diagnostic[] = [];
|
||||
switch (option.type) {
|
||||
case "boolean":
|
||||
options[option.name] = value.toLowerCase() === "true";
|
||||
break;
|
||||
case "string":
|
||||
options[option.name] = value;
|
||||
break;
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
case "list":
|
||||
options[option.name] = ts.parseListTypeOption(<ts.CommandLineOptionOfListType>option, value, errors);
|
||||
break;
|
||||
default:
|
||||
options[option.name] = ts.parseCustomTypeOption(<ts.CommandLineOptionOfCustomType>option, value, errors);
|
||||
break;
|
||||
}
|
||||
|
||||
options[option.name] = optionValue(option, value, errors);
|
||||
if (errors.length > 0) {
|
||||
throw new Error(`Unknown value '${value}' for compiler option '${name}'.`);
|
||||
}
|
||||
@@ -1138,6 +1127,27 @@ namespace Harness {
|
||||
}
|
||||
}
|
||||
|
||||
function optionValue(option: ts.CommandLineOption, value: string, errors: ts.Diagnostic[]): any {
|
||||
switch (option.type) {
|
||||
case "boolean":
|
||||
return value.toLowerCase() === "true";
|
||||
case "string":
|
||||
return value;
|
||||
case "number": {
|
||||
const number = parseInt(value, 10);
|
||||
if (isNaN(number)) {
|
||||
throw new Error(`Value must be a number, got: ${JSON.stringify(value)}`);
|
||||
}
|
||||
return number;
|
||||
}
|
||||
// If not a primitive, the possible types are specified in what is effectively a map of options.
|
||||
case "list":
|
||||
return ts.parseListTypeOption(<ts.CommandLineOptionOfListType>option, value, errors);
|
||||
default:
|
||||
return ts.parseCustomTypeOption(<ts.CommandLineOptionOfCustomType>option, value, errors);
|
||||
}
|
||||
}
|
||||
|
||||
export interface TestFile {
|
||||
unitName: string;
|
||||
content: string;
|
||||
@@ -1241,7 +1251,7 @@ namespace Harness {
|
||||
if (options.declaration && result.errors.length === 0 && result.declFilesCode.length > 0) {
|
||||
ts.forEach(inputFiles, file => addDtsFile(file, declInputFiles));
|
||||
ts.forEach(otherFiles, file => addDtsFile(file, declOtherFiles));
|
||||
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory);
|
||||
const output = compileFiles(declInputFiles, declOtherFiles, harnessSettings, options, currentDirectory || harnessSettings["currentDirectory"]);
|
||||
return { declInputFiles, declOtherFiles, declResult: output.result };
|
||||
}
|
||||
|
||||
@@ -1669,9 +1679,9 @@ namespace Harness {
|
||||
}
|
||||
|
||||
// This does not need to exist strictly speaking, but many tests will need to be updated if it's removed
|
||||
export function compileString(code: string, unitName: string, callback: (result: CompilerResult) => void) {
|
||||
export function compileString(_code: string, _unitName: string, _callback: (result: CompilerResult) => void) {
|
||||
// NEWTODO: Re-implement 'compileString'
|
||||
throw new Error("compileString NYI");
|
||||
return ts.notImplemented();
|
||||
}
|
||||
|
||||
export interface GeneratedFile {
|
||||
@@ -1853,8 +1863,8 @@ namespace Harness {
|
||||
// unit tests always list files explicitly
|
||||
const parseConfigHost: ts.ParseConfigHost = {
|
||||
useCaseSensitiveFileNames: false,
|
||||
readDirectory: (name) => [],
|
||||
fileExists: (name) => true,
|
||||
readDirectory: () => [],
|
||||
fileExists: () => true,
|
||||
readFile: (name) => ts.forEach(testUnitData, data => data.name.toLowerCase() === name.toLowerCase() ? data.content : undefined)
|
||||
};
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace Harness.LanguageService {
|
||||
throw new Error("No script with name '" + fileName + "'");
|
||||
}
|
||||
|
||||
public openFile(fileName: string, content?: string, scriptKindName?: string): void {
|
||||
public openFile(_fileName: string, _content?: string, _scriptKindName?: string): void {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +198,7 @@ namespace Harness.LanguageService {
|
||||
const script = this.getScriptInfo(fileName);
|
||||
return script ? new ScriptSnapshot(script) : undefined;
|
||||
}
|
||||
getScriptKind(fileName: string): ts.ScriptKind { return ts.ScriptKind.Unknown; }
|
||||
getScriptKind(): ts.ScriptKind { return ts.ScriptKind.Unknown; }
|
||||
getScriptVersion(fileName: string): string {
|
||||
const script = this.getScriptInfo(fileName);
|
||||
return script ? script.version.toString() : undefined;
|
||||
@@ -214,7 +214,7 @@ namespace Harness.LanguageService {
|
||||
this.getCurrentDirectory(),
|
||||
(p) => this.virtualFileSystem.getAccessibleFileSystemEntries(p));
|
||||
}
|
||||
readFile(path: string, encoding?: string): string {
|
||||
readFile(path: string): string {
|
||||
const snapshot = this.getScriptSnapshot(path);
|
||||
return snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
@@ -223,9 +223,9 @@ namespace Harness.LanguageService {
|
||||
}
|
||||
|
||||
|
||||
log(s: string): void { }
|
||||
trace(s: string): void { }
|
||||
error(s: string): void { }
|
||||
log(_: string): void { }
|
||||
trace(_: string): void { }
|
||||
error(_: string): void { }
|
||||
}
|
||||
|
||||
export class NativeLanguageServiceAdapter implements LanguageServiceAdapter {
|
||||
@@ -308,19 +308,15 @@ namespace Harness.LanguageService {
|
||||
const nativeScriptSnapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||
return nativeScriptSnapshot && new ScriptSnapshotProxy(nativeScriptSnapshot);
|
||||
}
|
||||
getScriptKind(fileName: string): ts.ScriptKind { return this.nativeHost.getScriptKind(fileName); }
|
||||
getScriptKind(): ts.ScriptKind { return this.nativeHost.getScriptKind(); }
|
||||
getScriptVersion(fileName: string): string { return this.nativeHost.getScriptVersion(fileName); }
|
||||
getLocalizedDiagnosticMessages(): string { return JSON.stringify({}); }
|
||||
|
||||
readDirectory(rootDir: string, extension: string): string {
|
||||
throw new Error("NYI");
|
||||
}
|
||||
readDirectoryNames(path: string): string {
|
||||
throw new Error("Not implemented.");
|
||||
}
|
||||
readFileNames(path: string): string {
|
||||
throw new Error("Not implemented.");
|
||||
readDirectory(_rootDir: string, _extension: string): string {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
readDirectoryNames = ts.notImplemented;
|
||||
readFileNames = ts.notImplemented;
|
||||
fileExists(fileName: string) { return this.getScriptInfo(fileName) !== undefined; }
|
||||
readFile(fileName: string) {
|
||||
const snapshot = this.nativeHost.getScriptSnapshot(fileName);
|
||||
@@ -329,7 +325,7 @@ namespace Harness.LanguageService {
|
||||
log(s: string): void { this.nativeHost.log(s); }
|
||||
trace(s: string): void { this.nativeHost.trace(s); }
|
||||
error(s: string): void { this.nativeHost.error(s); }
|
||||
directoryExists(directoryName: string): boolean {
|
||||
directoryExists(): boolean {
|
||||
// for tests pessimistically assume that directory always exists
|
||||
return true;
|
||||
}
|
||||
@@ -338,8 +334,8 @@ namespace Harness.LanguageService {
|
||||
class ClassifierShimProxy implements ts.Classifier {
|
||||
constructor(private shim: ts.ClassifierShim) {
|
||||
}
|
||||
getEncodedLexicalClassifications(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.Classifications {
|
||||
throw new Error("NYI");
|
||||
getEncodedLexicalClassifications(_text: string, _lexState: ts.EndOfLineState, _classifyKeywordsInGenerics?: boolean): ts.Classifications {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
getClassificationsForLine(text: string, lexState: ts.EndOfLineState, classifyKeywordsInGenerics?: boolean): ts.ClassificationResult {
|
||||
const result = this.shim.getClassificationsForLine(text, lexState, classifyKeywordsInGenerics).split("\n");
|
||||
@@ -411,7 +407,7 @@ namespace Harness.LanguageService {
|
||||
getCompletionEntryDetails(fileName: string, position: number, entryName: string): ts.CompletionEntryDetails {
|
||||
return unwrapJSONCallResult(this.shim.getCompletionEntryDetails(fileName, position, entryName));
|
||||
}
|
||||
getCompletionEntrySymbol(fileName: string, position: number, entryName: string): ts.Symbol {
|
||||
getCompletionEntrySymbol(): ts.Symbol {
|
||||
throw new Error("getCompletionEntrySymbol not implemented across the shim layer.");
|
||||
}
|
||||
getQuickInfoAtPosition(fileName: string, position: number): ts.QuickInfo {
|
||||
@@ -490,7 +486,7 @@ namespace Harness.LanguageService {
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
return unwrapJSONCallResult(this.shim.isValidBraceCompletionAtPosition(fileName, position, openingBrace));
|
||||
}
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): ts.CodeAction[] {
|
||||
getCodeFixesAtPosition(): ts.CodeAction[] {
|
||||
throw new Error("Not supported on the shim.");
|
||||
}
|
||||
getEmitOutput(fileName: string): ts.EmitOutput {
|
||||
@@ -499,10 +495,10 @@ namespace Harness.LanguageService {
|
||||
getProgram(): ts.Program {
|
||||
throw new Error("Program can not be marshaled across the shim layer.");
|
||||
}
|
||||
getNonBoundSourceFile(fileName: string): ts.SourceFile {
|
||||
getNonBoundSourceFile(): ts.SourceFile {
|
||||
throw new Error("SourceFile can not be marshaled across the shim layer.");
|
||||
}
|
||||
getSourceFile(fileName: string): ts.SourceFile {
|
||||
getSourceFile(): ts.SourceFile {
|
||||
throw new Error("SourceFile can not be marshaled across the shim layer.");
|
||||
}
|
||||
dispose(): void { this.shim.dispose({}); }
|
||||
@@ -572,11 +568,11 @@ namespace Harness.LanguageService {
|
||||
super(cancellationToken, settings);
|
||||
}
|
||||
|
||||
onMessage(message: string): void {
|
||||
onMessage(): void {
|
||||
|
||||
}
|
||||
|
||||
writeMessage(message: string): void {
|
||||
writeMessage(): void {
|
||||
|
||||
}
|
||||
|
||||
@@ -604,11 +600,11 @@ namespace Harness.LanguageService {
|
||||
this.newLine = this.host.getNewLine();
|
||||
}
|
||||
|
||||
onMessage(message: string): void {
|
||||
onMessage(): void {
|
||||
|
||||
}
|
||||
|
||||
writeMessage(message: string): void {
|
||||
writeMessage(_message: string): void {
|
||||
}
|
||||
|
||||
write(message: string): void {
|
||||
@@ -624,7 +620,7 @@ namespace Harness.LanguageService {
|
||||
return snapshot && snapshot.getText(0, snapshot.getLength());
|
||||
}
|
||||
|
||||
writeFile(name: string, text: string, writeByteOrderMark: boolean): void {
|
||||
writeFile(): void {
|
||||
}
|
||||
|
||||
resolvePath(path: string): string {
|
||||
@@ -635,7 +631,7 @@ namespace Harness.LanguageService {
|
||||
return !!this.host.getScriptSnapshot(path);
|
||||
}
|
||||
|
||||
directoryExists(path: string): boolean {
|
||||
directoryExists(): boolean {
|
||||
// for tests assume that directory exists
|
||||
return true;
|
||||
}
|
||||
@@ -644,18 +640,18 @@ namespace Harness.LanguageService {
|
||||
return "";
|
||||
}
|
||||
|
||||
exit(exitCode: number): void {
|
||||
exit(): void {
|
||||
}
|
||||
|
||||
createDirectory(directoryName: string): void {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
createDirectory(_directoryName: string): void {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
|
||||
getCurrentDirectory(): string {
|
||||
return this.host.getCurrentDirectory();
|
||||
}
|
||||
|
||||
getDirectories(path: string): string[] {
|
||||
getDirectories(): string[] {
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -663,16 +659,16 @@ namespace Harness.LanguageService {
|
||||
return ts.sys.getEnvironmentVariable(name);
|
||||
}
|
||||
|
||||
readDirectory(path: string, extension?: string[], exclude?: string[], include?: string[]): string[] {
|
||||
throw new Error("Not implemented Yet.");
|
||||
readDirectory(_path: string, _extension?: string[], _exclude?: string[], _include?: string[]): string[] {
|
||||
return ts.notImplemented();
|
||||
}
|
||||
|
||||
watchFile(fileName: string, callback: (fileName: string) => void): ts.FileWatcher {
|
||||
return { close() { } };
|
||||
watchFile(): ts.FileWatcher {
|
||||
return { close: ts.noop };
|
||||
}
|
||||
|
||||
watchDirectory(path: string, callback: (path: string) => void, recursive?: boolean): ts.FileWatcher {
|
||||
return { close() { } };
|
||||
watchDirectory(): ts.FileWatcher {
|
||||
return { close: ts.noop };
|
||||
}
|
||||
|
||||
close(): void {
|
||||
@@ -717,7 +713,7 @@ namespace Harness.LanguageService {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
|
||||
setImmediate(callback: (...args: any[]) => void, ms: number, ...args: any[]): any {
|
||||
setImmediate(callback: (...args: any[]) => void, _ms: number, ...args: any[]): any {
|
||||
return setImmediate(callback, args);
|
||||
}
|
||||
|
||||
@@ -760,6 +756,6 @@ namespace Harness.LanguageService {
|
||||
getHost() { return this.host; }
|
||||
getLanguageService(): ts.LanguageService { return this.client; }
|
||||
getClassifier(): ts.Classifier { throw new Error("getClassifier is not available using the server interface."); }
|
||||
getPreProcessedFileInfo(fileName: string, fileContents: string): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
|
||||
getPreProcessedFileInfo(): ts.PreProcessedFileInfo { throw new Error("getPreProcessedFileInfo is not available using the server interface."); }
|
||||
}
|
||||
}
|
||||
|
||||
+15
-11
@@ -173,7 +173,7 @@ namespace Playback {
|
||||
path => callAndRecord(underlying.fileExists(path), recordLog.fileExists, { path }),
|
||||
memoize(path => {
|
||||
// If we read from the file, it must exist
|
||||
if (findFileByPath(wrapper, replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
|
||||
if (findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ false)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -217,7 +217,7 @@ namespace Playback {
|
||||
recordLog.filesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
memoize(path => findFileByPath(wrapper, replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
|
||||
memoize(path => findFileByPath(replayLog.filesRead, path, /*throwFileNotFoundError*/ true).contents));
|
||||
|
||||
wrapper.readDirectory = recordReplay(wrapper.readDirectory, underlying)(
|
||||
(path, extensions, exclude, include) => {
|
||||
@@ -226,7 +226,7 @@ namespace Playback {
|
||||
recordLog.directoriesRead.push(logEntry);
|
||||
return result;
|
||||
},
|
||||
(path, extensions, exclude) => {
|
||||
path => {
|
||||
// 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).
|
||||
@@ -244,7 +244,7 @@ namespace Playback {
|
||||
|
||||
wrapper.writeFile = recordReplay(wrapper.writeFile, underlying)(
|
||||
(path: string, contents: string) => callAndRecord(underlying.writeFile(path, contents), recordLog.filesWritten, { path, contents, bom: false }),
|
||||
(path: string, contents: string) => noOpReplay("writeFile"));
|
||||
() => noOpReplay("writeFile"));
|
||||
|
||||
wrapper.exit = (exitCode) => {
|
||||
if (recordLog !== undefined) {
|
||||
@@ -295,7 +295,7 @@ namespace Playback {
|
||||
return results[0].result;
|
||||
}
|
||||
|
||||
function findFileByPath(wrapper: { resolvePath(s: string): string }, logArray: IOLogFile[],
|
||||
function findFileByPath(logArray: IOLogFile[],
|
||||
expectedPath: string, throwFileNotFoundError: boolean): FileInformation {
|
||||
const normalizedName = ts.normalizePath(expectedPath).toLowerCase();
|
||||
// Try to find the result through normal fileName
|
||||
@@ -314,7 +314,7 @@ namespace Playback {
|
||||
}
|
||||
}
|
||||
|
||||
function noOpReplay(name: string) {
|
||||
function noOpReplay(_name: string) {
|
||||
// console.log("Swallowed write operation during replay: " + name);
|
||||
}
|
||||
|
||||
@@ -322,13 +322,17 @@ namespace Playback {
|
||||
const wrapper: PlaybackIO = <any>{};
|
||||
initWrapper(wrapper, underlying);
|
||||
|
||||
wrapper.directoryName = (path): string => { throw new Error("NotSupported"); };
|
||||
wrapper.createDirectory = (path): void => { throw new Error("NotSupported"); };
|
||||
wrapper.directoryExists = (path): boolean => { throw new Error("NotSupported"); };
|
||||
wrapper.deleteFile = (path): void => { throw new Error("NotSupported"); };
|
||||
wrapper.listFiles = (path, filter, options): string[] => { throw new Error("NotSupported"); };
|
||||
wrapper.directoryName = notSupported;
|
||||
wrapper.createDirectory = notSupported;
|
||||
wrapper.directoryExists = notSupported;
|
||||
wrapper.deleteFile = notSupported;
|
||||
wrapper.listFiles = notSupported;
|
||||
|
||||
return wrapper;
|
||||
|
||||
function notSupported(): never {
|
||||
throw new Error("NotSupported");
|
||||
}
|
||||
}
|
||||
|
||||
export function wrapSystem(underlying: ts.System): PlaybackSystem {
|
||||
|
||||
@@ -178,7 +178,7 @@ class ProjectRunner extends RunnerBase {
|
||||
function createCompilerHost(): ts.CompilerHost {
|
||||
return {
|
||||
getSourceFile,
|
||||
getDefaultLibFileName: options => Harness.Compiler.defaultLibFileName,
|
||||
getDefaultLibFileName: () => Harness.Compiler.defaultLibFileName,
|
||||
writeFile,
|
||||
getCurrentDirectory,
|
||||
getCanonicalFileName: Harness.Compiler.getCanonicalFileName,
|
||||
@@ -421,7 +421,7 @@ class ProjectRunner extends RunnerBase {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function writeFile(fileName: string, data: string, writeByteOrderMark: boolean) {
|
||||
function writeFile() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,5 +222,5 @@ else {
|
||||
}
|
||||
if (!runUnitTests) {
|
||||
// patch `describe` to skip unit tests
|
||||
describe = <any>(function () { });
|
||||
describe = ts.noop as any;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
"stripInternal": true,
|
||||
"types": [
|
||||
"node", "mocha", "chai"
|
||||
]
|
||||
],
|
||||
"target": "es5",
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
},
|
||||
"files": [
|
||||
"../compiler/core.ts",
|
||||
@@ -29,7 +32,9 @@
|
||||
"../compiler/transformers/es2017.ts",
|
||||
"../compiler/transformers/es2016.ts",
|
||||
"../compiler/transformers/es2015.ts",
|
||||
"../compiler/transformers/es5.ts",
|
||||
"../compiler/transformers/generators.ts",
|
||||
"../compiler/transformers/es5.ts",
|
||||
"../compiler/transformers/destructuring.ts",
|
||||
"../compiler/transformers/module/module.ts",
|
||||
"../compiler/transformers/module/system.ts",
|
||||
|
||||
@@ -21,65 +21,42 @@ namespace ts {
|
||||
args: <string[]>[],
|
||||
newLine: "\r\n",
|
||||
useCaseSensitiveFileNames: false,
|
||||
write: (s: string) => {
|
||||
},
|
||||
readFile: (path: string, encoding?: string): string => {
|
||||
return path in fileMap ? fileMap[path].content : undefined;
|
||||
},
|
||||
writeFile: (path: string, data: string, writeByteOrderMark?: boolean) => {
|
||||
throw new Error("NYI");
|
||||
},
|
||||
resolvePath: (path: string): string => {
|
||||
throw new Error("NYI");
|
||||
},
|
||||
fileExists: (path: string): boolean => {
|
||||
return path in fileMap;
|
||||
},
|
||||
directoryExists: (path: string): boolean => {
|
||||
return existingDirectories[path] || false;
|
||||
},
|
||||
createDirectory: (path: string) => {
|
||||
},
|
||||
getExecutingFilePath: (): string => {
|
||||
return "";
|
||||
},
|
||||
getCurrentDirectory: (): string => {
|
||||
return "";
|
||||
},
|
||||
getDirectories: (path: string) => [],
|
||||
getEnvironmentVariable: (name: string) => "",
|
||||
readDirectory: (path: string, extension?: string[], exclude?: string[], include?: string[]): string[] => {
|
||||
throw new Error("NYI");
|
||||
},
|
||||
exit: (exitCode?: number) => {
|
||||
},
|
||||
watchFile: (path, callback) => {
|
||||
return {
|
||||
close: () => { }
|
||||
};
|
||||
},
|
||||
watchDirectory: (path, callback, recursive?) => {
|
||||
return {
|
||||
close: () => { }
|
||||
};
|
||||
},
|
||||
write: noop,
|
||||
readFile: path => path in fileMap ? fileMap[path].content : undefined,
|
||||
writeFile: notImplemented,
|
||||
resolvePath: notImplemented,
|
||||
fileExists: path => path in fileMap,
|
||||
directoryExists: path => existingDirectories[path] || false,
|
||||
createDirectory: noop,
|
||||
getExecutingFilePath: () => "",
|
||||
getCurrentDirectory: () => "",
|
||||
getDirectories: () => [],
|
||||
getEnvironmentVariable: () => "",
|
||||
readDirectory: notImplemented,
|
||||
exit: noop,
|
||||
watchFile: () => ({
|
||||
close: noop
|
||||
}),
|
||||
watchDirectory: () => ({
|
||||
close: noop
|
||||
}),
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
setImmediate,
|
||||
clearImmediate
|
||||
setImmediate: typeof setImmediate !== "undefined" ? setImmediate : action => setTimeout(action, 0),
|
||||
clearImmediate: typeof clearImmediate !== "undefined" ? clearImmediate : clearTimeout
|
||||
};
|
||||
}
|
||||
|
||||
function createProject(rootFile: string, serverHost: server.ServerHost): { project: server.Project, rootScriptInfo: server.ScriptInfo } {
|
||||
const logger: server.Logger = {
|
||||
close() { },
|
||||
close: noop,
|
||||
hasLevel: () => false,
|
||||
loggingEnabled: () => false,
|
||||
perftrc: (s: string) => { },
|
||||
info: (s: string) => { },
|
||||
startGroup: () => { },
|
||||
endGroup: () => { },
|
||||
msg: (s: string, type?: string) => { },
|
||||
perftrc: noop,
|
||||
info: noop,
|
||||
startGroup: noop,
|
||||
endGroup: noop,
|
||||
msg: noop,
|
||||
getLogFileName: (): string => undefined
|
||||
};
|
||||
|
||||
@@ -116,10 +93,7 @@ namespace ts {
|
||||
const originalFileExists = serverHost.fileExists;
|
||||
{
|
||||
// patch fileExists to make sure that disk is not touched
|
||||
serverHost.fileExists = (fileName): boolean => {
|
||||
assert.isTrue(false, "fileExists should not be called");
|
||||
return false;
|
||||
};
|
||||
serverHost.fileExists = notImplemented;
|
||||
|
||||
const newContent = `import {x} from "f1"
|
||||
var x: string = 1;`;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\harness.ts" />
|
||||
/// <reference path="..\..\compiler\commandLineParser.ts" />
|
||||
|
||||
namespace ts {
|
||||
@@ -60,7 +60,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5,invalidOption", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -165,7 +165,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -191,7 +191,7 @@ namespace ts {
|
||||
start: undefined,
|
||||
length: undefined,
|
||||
}, {
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5,", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -283,7 +283,7 @@ namespace ts {
|
||||
assertParseResult(["--lib", "es5, ", "es7", "0.ts"],
|
||||
{
|
||||
errors: [{
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
category: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.category,
|
||||
code: ts.Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
|
||||
@@ -338,5 +338,38 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse explicit boolean flag value", () => {
|
||||
assertParseResult(["--strictNullChecks", "false", "0.ts"],
|
||||
{
|
||||
errors: [],
|
||||
fileNames: ["0.ts"],
|
||||
options: {
|
||||
strictNullChecks: false,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse non boolean argument after boolean flag", () => {
|
||||
assertParseResult(["--noImplicitAny", "t", "0.ts"],
|
||||
{
|
||||
errors: [],
|
||||
fileNames: ["t", "0.ts"],
|
||||
options: {
|
||||
noImplicitAny: true,
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it("Parse implicit boolean flag value", () => {
|
||||
assertParseResult(["--strictNullChecks"],
|
||||
{
|
||||
errors: [],
|
||||
fileNames: [],
|
||||
options: {
|
||||
strictNullChecks: true,
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
messageText: "Argument for '--jsx' option must be: 'preserve', 'react'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -122,7 +122,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
messageText: "Argument for '--module' option must be: 'none', 'commonjs', 'amd', 'system', 'umd', 'es6', 'es2015'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -150,7 +150,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
messageText: "Argument for '--newLine' option must be: 'crlf', 'lf'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -176,7 +176,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
messageText: "Argument for '--target' option must be: 'es3', 'es5', 'es6', 'es2015', 'es2016', 'es2017'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -202,7 +202,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
messageText: "Argument for '--moduleResolution' option must be: 'node', 'classic'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -233,7 +233,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -264,7 +264,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -295,7 +295,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
@@ -326,7 +326,7 @@ namespace ts {
|
||||
file: undefined,
|
||||
start: 0,
|
||||
length: 0,
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
messageText: "Argument for '--lib' option must be: 'es5', 'es6', 'es2015', 'es7', 'es2016', 'es2017', 'dom', 'dom.iterable', 'webworker', 'scripthost', 'es2015.core', 'es2015.collection', 'es2015.generator', 'es2015.iterable', 'es2015.promise', 'es2015.proxy', 'es2015.reflect', 'es2015.symbol', 'es2015.symbol.wellknown', 'es2016.array.include', 'es2017.object', 'es2017.sharedmemory'",
|
||||
code: Diagnostics.Argument_for_0_option_must_be_Colon_1.code,
|
||||
category: Diagnostics.Argument_for_0_option_must_be_Colon_1.category
|
||||
}]
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace ts {
|
||||
|
||||
Harness.Baseline.runBaseline("JSDocParsing/DocComments.parsesCorrectly." + name + ".json",
|
||||
() => JSON.stringify(comment.jsDoc,
|
||||
(k, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4));
|
||||
(_, v) => v && v.pos !== undefined ? JSON.parse(Utils.sourceFileToJSON(v)) : v, 4));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+131
-177
@@ -3,6 +3,7 @@
|
||||
|
||||
namespace ts {
|
||||
const caseInsensitiveBasePath = "c:/dev/";
|
||||
const caseInsensitiveTsconfigPath = "c:/dev/tsconfig.json";
|
||||
const caseInsensitiveHost = new Utils.MockParseConfigHost(caseInsensitiveBasePath, /*useCaseSensitiveFileNames*/ false, [
|
||||
"c:/dev/a.ts",
|
||||
"c:/dev/a.d.ts",
|
||||
@@ -88,6 +89,14 @@ namespace ts {
|
||||
"c:/dev/g.min.js/.g/g.ts"
|
||||
]);
|
||||
|
||||
const defaultExcludes = ["node_modules", "bower_components", "jspm_packages"];
|
||||
|
||||
function assertParsed(actual: ts.ParsedCommandLine, expected: ts.ParsedCommandLine): void {
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
}
|
||||
|
||||
describe("matchFiles", () => {
|
||||
describe("with literal file list", () => {
|
||||
it("without exclusions", () => {
|
||||
@@ -107,9 +116,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("missing files are still present", () => {
|
||||
const json = {
|
||||
@@ -128,9 +135,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("are not removed due to excludes", () => {
|
||||
const json = {
|
||||
@@ -152,9 +157,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -176,9 +179,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with non .ts file extensions are excluded", () => {
|
||||
const json = {
|
||||
@@ -189,14 +190,15 @@ namespace ts {
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -207,14 +209,15 @@ namespace ts {
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with literal excludes", () => {
|
||||
const json = {
|
||||
@@ -235,9 +238,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with wildcard excludes", () => {
|
||||
const json = {
|
||||
@@ -265,9 +266,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with recursive excludes", () => {
|
||||
const json = {
|
||||
@@ -294,9 +293,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with case sensitive exclude", () => {
|
||||
const json = {
|
||||
@@ -316,9 +313,7 @@ namespace ts {
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
@@ -340,9 +335,7 @@ namespace ts {
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -369,9 +362,7 @@ namespace ts {
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -397,9 +388,7 @@ namespace ts {
|
||||
wildcardDirectories: {},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -423,9 +412,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("`*` matches only ts files", () => {
|
||||
const json = {
|
||||
@@ -446,9 +433,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("`?` matches only a single character", () => {
|
||||
const json = {
|
||||
@@ -468,9 +453,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with recursive directory", () => {
|
||||
const json = {
|
||||
@@ -492,9 +475,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with multiple recursive directories", () => {
|
||||
const json = {
|
||||
@@ -518,9 +499,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("case sensitive", () => {
|
||||
const json = {
|
||||
@@ -539,9 +518,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseSensitiveHost, caseSensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with missing files are excluded", () => {
|
||||
const json = {
|
||||
@@ -551,16 +528,17 @@ namespace ts {
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
fileNames: [],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("always include literal files", () => {
|
||||
const json = {
|
||||
@@ -585,9 +563,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("exclude folders", () => {
|
||||
const json = {
|
||||
@@ -612,14 +588,12 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with common package folders and no exclusions", () => {
|
||||
const json = {
|
||||
include: [
|
||||
"**/a.ts"
|
||||
"**/a.ts"
|
||||
]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
@@ -633,9 +607,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with common package folders and exclusions", () => {
|
||||
const json = {
|
||||
@@ -659,9 +631,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with common package folders and empty exclude", () => {
|
||||
const json = {
|
||||
@@ -684,9 +654,7 @@ namespace ts {
|
||||
},
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveCommonFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("exclude .js files when allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -701,16 +669,17 @@ namespace ts {
|
||||
options: {
|
||||
allowJs: false
|
||||
},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {
|
||||
"c:/dev/js": 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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include .js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -735,9 +704,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include explicitly listed .min.js files when allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -762,9 +729,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include paths outside of the project", () => {
|
||||
const json = {
|
||||
@@ -788,9 +753,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -813,9 +776,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("exclude paths outside of the project using relative paths", () => {
|
||||
const json = {
|
||||
@@ -828,14 +789,15 @@ namespace ts {
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))]
|
||||
,
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("include files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -855,9 +817,7 @@ namespace 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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("exclude files with .. in their name", () => {
|
||||
const json = {
|
||||
@@ -879,9 +839,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with jsx=none, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -904,9 +862,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=false", () => {
|
||||
const json = {
|
||||
@@ -931,9 +887,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with jsx=none, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -958,9 +912,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with jsx=preserve, allowJs=true", () => {
|
||||
const json = {
|
||||
@@ -987,9 +939,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveMixedExtensionHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("exclude .min.js files using wildcards", () => {
|
||||
const json = {
|
||||
@@ -1016,9 +966,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
describe("with trailing recursive directory", () => {
|
||||
it("in includes", () => {
|
||||
@@ -1030,15 +978,15 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**")
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1051,14 +999,15 @@ namespace ts {
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
describe("with multiple recursive directory patterns", () => {
|
||||
@@ -1071,15 +1020,15 @@ namespace ts {
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*")
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0, "**/x/**/*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("in excludes", () => {
|
||||
const json = {
|
||||
@@ -1106,9 +1055,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1122,15 +1069,15 @@ namespace ts {
|
||||
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, "**/../*")
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/../*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
|
||||
it("in includes after a subdirectory", () => {
|
||||
@@ -1142,15 +1089,15 @@ namespace ts {
|
||||
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/../*")
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0, "**/y/../*"),
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(defaultExcludes))
|
||||
],
|
||||
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);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
|
||||
it("in excludes immediately after", () => {
|
||||
@@ -1178,9 +1125,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
|
||||
it("in excludes after a subdirectory", () => {
|
||||
@@ -1195,7 +1140,7 @@ namespace ts {
|
||||
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/..")
|
||||
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",
|
||||
@@ -1208,9 +1153,25 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
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);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe("with implicit globbification", () => {
|
||||
it("Expands 'z' to 'z/**/*'", () => {
|
||||
const json = {
|
||||
include: ["z"]
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
fileNames: [ "a.ts", "aba.ts", "abz.ts", "b.ts", "bba.ts", "bbz.ts" ].map(x => `c:/dev/z/${x}`),
|
||||
wildcardDirectories: {
|
||||
"c:/dev/z": ts.WatchDirectoryFlags.Recursive
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveHost, caseInsensitiveBasePath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1235,9 +1196,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
describe("that are explicitly included", () => {
|
||||
it("without wildcards", () => {
|
||||
@@ -1257,9 +1216,7 @@ namespace ts {
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with recursive wildcards that match directories", () => {
|
||||
const json = {
|
||||
@@ -1281,9 +1238,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with recursive wildcards that match nothing", () => {
|
||||
const json = {
|
||||
@@ -1305,9 +1260,7 @@ namespace ts {
|
||||
}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
it("with wildcard excludes that implicitly exclude dotted files", () => {
|
||||
const json = {
|
||||
@@ -1320,14 +1273,15 @@ namespace ts {
|
||||
};
|
||||
const expected: ts.ParsedCommandLine = {
|
||||
options: {},
|
||||
errors: [],
|
||||
errors: [
|
||||
ts.createCompilerDiagnostic(ts.Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2,
|
||||
caseInsensitiveTsconfigPath, JSON.stringify(json.include), JSON.stringify(json.exclude))
|
||||
],
|
||||
fileNames: [],
|
||||
wildcardDirectories: {}
|
||||
};
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath);
|
||||
assert.deepEqual(actual.fileNames, expected.fileNames);
|
||||
assert.deepEqual(actual.wildcardDirectories, expected.wildcardDirectories);
|
||||
assert.deepEqual(actual.errors, expected.errors);
|
||||
const actual = ts.parseJsonConfigFileContent(json, caseInsensitiveDottedFoldersHost, caseInsensitiveBasePath, undefined, caseInsensitiveTsconfigPath);
|
||||
assertParsed(actual, expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,28 @@
|
||||
/// <reference path="..\harness.ts" />
|
||||
|
||||
namespace ts {
|
||||
export function checkResolvedModule(expected: ResolvedModuleFull, actual: ResolvedModuleFull): boolean {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${Extension[expected.extension]}' to be equal to '${Extension[actual.extension]}'`);
|
||||
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void {
|
||||
assert.isTrue(actual.resolvedModule !== undefined, "module should be resolved");
|
||||
checkResolvedModule(actual.resolvedModule, expectedResolvedModule);
|
||||
assert.deepEqual(actual.failedLookupLocations, expectedFailedLookupLocations);
|
||||
}
|
||||
|
||||
export function createResolvedModule(resolvedFileName: string, isExternalLibraryImport = false): ResolvedModuleFull {
|
||||
return { resolvedFileName, extension: extensionFromPath(resolvedFileName), isExternalLibraryImport };
|
||||
}
|
||||
|
||||
interface File {
|
||||
name: string;
|
||||
content?: string;
|
||||
@@ -53,8 +75,7 @@ namespace ts {
|
||||
const containingFile = { name: containingFileName };
|
||||
const moduleFile = { name: moduleFileNameNoExt + ext };
|
||||
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name));
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
const dir = getDirectoryPath(containingFileName);
|
||||
@@ -97,8 +118,7 @@ namespace ts {
|
||||
const packageJson = { name: packageJsonFileName, content: JSON.stringify({ "typings": fieldRef }) };
|
||||
const moduleFile = { name: moduleFileName };
|
||||
const resolution = nodeModuleNameResolver(moduleName, containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name));
|
||||
// expect three failed lookup location - attempt to load module as file with all supported extensions
|
||||
assert.equal(resolution.failedLookupLocations.length, supportedTypeScriptExtensions.length);
|
||||
}
|
||||
@@ -125,7 +145,7 @@ namespace ts {
|
||||
|
||||
const resolution = nodeModuleNameResolver("b", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, moduleFile, indexFile));
|
||||
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexPath);
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(indexPath, /*isExternalLibraryImport*/true));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,7 +158,6 @@ namespace ts {
|
||||
/* tslint:enable no-null-keyword */
|
||||
testTypingsIgnored(undefined);
|
||||
});
|
||||
|
||||
it("module name as directory - load index.d.ts", () => {
|
||||
test(/*hasDirectoryExists*/ false);
|
||||
test(/*hasDirectoryExists*/ true);
|
||||
@@ -148,9 +167,7 @@ namespace ts {
|
||||
const packageJson = { name: "/a/b/foo/package.json", content: JSON.stringify({ main: "/c/d" }) };
|
||||
const indexFile = { name: "/a/b/foo/index.d.ts" };
|
||||
const resolution = nodeModuleNameResolver("./foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, packageJson, indexFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, indexFile.name);
|
||||
assert.equal(!!resolution.resolvedModule.isExternalLibraryImport, false);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(indexFile.name), [
|
||||
"/a/b/foo.ts",
|
||||
"/a/b/foo.tsx",
|
||||
"/a/b/foo.d.ts",
|
||||
@@ -170,33 +187,39 @@ namespace ts {
|
||||
const containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
const moduleFile = { name: "/a/b/node_modules/foo.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
|
||||
"/a/b/c/d/node_modules/foo.ts",
|
||||
"/a/b/c/d/node_modules/foo.tsx",
|
||||
"/a/b/c/d/node_modules/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/foo/package.json",
|
||||
|
||||
"/a/b/c/d/node_modules/foo/index.ts",
|
||||
"/a/b/c/d/node_modules/foo/index.tsx",
|
||||
"/a/b/c/d/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/d/node_modules/@types/foo.ts",
|
||||
"/a/b/c/d/node_modules/@types/foo.tsx",
|
||||
"/a/b/c/d/node_modules/@types/foo.d.ts",
|
||||
"/a/b/c/d/node_modules/@types/foo/package.json",
|
||||
|
||||
"/a/b/c/d/node_modules/@types/foo/index.ts",
|
||||
"/a/b/c/d/node_modules/@types/foo/index.tsx",
|
||||
"/a/b/c/d/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/foo.ts",
|
||||
"/a/b/c/node_modules/foo.tsx",
|
||||
"/a/b/c/node_modules/foo.d.ts",
|
||||
"/a/b/c/node_modules/foo/package.json",
|
||||
|
||||
"/a/b/c/node_modules/foo/index.ts",
|
||||
"/a/b/c/node_modules/foo/index.tsx",
|
||||
"/a/b/c/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/b/c/node_modules/@types/foo.ts",
|
||||
"/a/b/c/node_modules/@types/foo.tsx",
|
||||
"/a/b/c/node_modules/@types/foo.d.ts",
|
||||
"/a/b/c/node_modules/@types/foo/package.json",
|
||||
|
||||
"/a/b/c/node_modules/@types/foo/index.ts",
|
||||
"/a/b/c/node_modules/@types/foo/index.tsx",
|
||||
"/a/b/c/node_modules/@types/foo/index.d.ts",
|
||||
@@ -212,8 +235,7 @@ namespace ts {
|
||||
const containingFile = { name: "/a/b/c/d/e.ts" };
|
||||
const moduleFile = { name: "/a/b/node_modules/foo.d.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
checkResolvedModule(resolution.resolvedModule, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -225,55 +247,66 @@ namespace ts {
|
||||
const containingFile = { name: "/a/node_modules/b/c/node_modules/d/e.ts" };
|
||||
const moduleFile = { name: "/a/node_modules/foo/index.d.ts" };
|
||||
const resolution = nodeModuleNameResolver("foo", containingFile.name, {}, createModuleResolutionHost(hasDirectoryExists, containingFile, moduleFile));
|
||||
assert.equal(resolution.resolvedModule.resolvedFileName, moduleFile.name);
|
||||
assert.equal(resolution.resolvedModule.isExternalLibraryImport, true);
|
||||
assert.deepEqual(resolution.failedLookupLocations, [
|
||||
checkResolvedModuleWithFailedLookupLocations(resolution, createResolvedModule(moduleFile.name, /*isExternalLibraryImport*/ true), [
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/d/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.ts",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.tsx",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/index.ts",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/index.tsx",
|
||||
"/a/node_modules/b/c/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/foo.ts",
|
||||
"/a/node_modules/b/node_modules/foo.tsx",
|
||||
"/a/node_modules/b/node_modules/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/node_modules/foo/index.ts",
|
||||
"/a/node_modules/b/node_modules/foo/index.tsx",
|
||||
"/a/node_modules/b/node_modules/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/b/node_modules/@types/foo.ts",
|
||||
"/a/node_modules/b/node_modules/@types/foo.tsx",
|
||||
"/a/node_modules/b/node_modules/@types/foo.d.ts",
|
||||
"/a/node_modules/b/node_modules/@types/foo/package.json",
|
||||
|
||||
"/a/node_modules/b/node_modules/@types/foo/index.ts",
|
||||
"/a/node_modules/b/node_modules/@types/foo/index.tsx",
|
||||
"/a/node_modules/b/node_modules/@types/foo/index.d.ts",
|
||||
|
||||
"/a/node_modules/foo.ts",
|
||||
"/a/node_modules/foo.tsx",
|
||||
"/a/node_modules/foo.d.ts",
|
||||
"/a/node_modules/foo/package.json",
|
||||
|
||||
"/a/node_modules/foo/index.ts",
|
||||
"/a/node_modules/foo/index.tsx"
|
||||
]);
|
||||
@@ -290,7 +323,7 @@ namespace ts {
|
||||
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: (fileName, content): void => { throw new Error("NotImplemented"); },
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: fileName => fileName.toLowerCase(),
|
||||
@@ -300,7 +333,7 @@ namespace ts {
|
||||
const path = normalizePath(combinePaths(currentDirectory, fileName));
|
||||
return path in files;
|
||||
},
|
||||
readFile: (fileName): string => { throw new Error("NotImplemented"); }
|
||||
readFile: notImplemented
|
||||
};
|
||||
|
||||
const program = createProgram(rootFiles, options, host);
|
||||
@@ -370,7 +403,7 @@ export = C;
|
||||
return path in files ? createSourceFile(fileName, files[path], languageVersion) : undefined;
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: (fileName, content): void => { throw new Error("NotImplemented"); },
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory: () => currentDirectory,
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName,
|
||||
@@ -380,7 +413,7 @@ export = C;
|
||||
const path = getCanonicalFileName(normalizePath(combinePaths(currentDirectory, fileName)));
|
||||
return path in files;
|
||||
},
|
||||
readFile: (fileName): string => { throw new Error("NotImplemented"); }
|
||||
readFile: notImplemented
|
||||
};
|
||||
const program = createProgram(rootFiles, options, host);
|
||||
const diagnostics = sortAndDeduplicateDiagnostics(program.getSemanticDiagnostics().concat(program.getOptionsDiagnostics()));
|
||||
@@ -481,21 +514,15 @@ import b = require("./moduleB");
|
||||
const options: CompilerOptions = { moduleResolution, baseUrl: "/root" };
|
||||
{
|
||||
const result = resolveModuleName("folder2/file2", file1.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, file2.name);
|
||||
assert.deepEqual(result.failedLookupLocations, []);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file2.name), []);
|
||||
}
|
||||
{
|
||||
const result = resolveModuleName("./file3", file2.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, file3.name);
|
||||
assert.deepEqual(result.failedLookupLocations, []);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file3.name), []);
|
||||
}
|
||||
{
|
||||
const result = resolveModuleName("/root/folder1/file1", file2.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, file1.name);
|
||||
assert.deepEqual(result.failedLookupLocations, []);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(file1.name), []);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -520,12 +547,11 @@ import b = require("./moduleB");
|
||||
check("m1", main, m1);
|
||||
check("m2", main, m2);
|
||||
check("m3", main, m3Typings);
|
||||
check("m4", main, m4);
|
||||
check("m4", main, m4, /*isExternalLibraryImport*/true);
|
||||
|
||||
function check(name: string, caller: File, expected: File) {
|
||||
function check(name: string, caller: File, expected: File, isExternalLibraryImport = false) {
|
||||
const result = resolveModuleName(name, caller.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined);
|
||||
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
|
||||
checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name, isExternalLibraryImport));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -547,8 +573,7 @@ import b = require("./moduleB");
|
||||
|
||||
function check(name: string, caller: File, expected: File) {
|
||||
const result = resolveModuleName(name, caller.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined);
|
||||
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
|
||||
checkResolvedModule(result.resolvedModule, createResolvedModule(expected.name));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -590,9 +615,10 @@ import b = require("./moduleB");
|
||||
"/root/folder1/file2.tsx",
|
||||
"/root/folder1/file2.d.ts",
|
||||
"/root/folder1/file2/package.json",
|
||||
|
||||
"/root/folder1/file2/index.ts",
|
||||
"/root/folder1/file2/index.tsx",
|
||||
"/root/folder1/file2/index.d.ts"
|
||||
"/root/folder1/file2/index.d.ts",
|
||||
// then first attempt on 'generated/*' was successful
|
||||
]);
|
||||
check("folder2/file3", file3, [
|
||||
@@ -601,14 +627,17 @@ import b = require("./moduleB");
|
||||
"/root/folder2/file3.tsx",
|
||||
"/root/folder2/file3.d.ts",
|
||||
"/root/folder2/file3/package.json",
|
||||
|
||||
"/root/folder2/file3/index.ts",
|
||||
"/root/folder2/file3/index.tsx",
|
||||
"/root/folder2/file3/index.d.ts",
|
||||
|
||||
// then use remapped location
|
||||
"/root/generated/folder2/file3.ts",
|
||||
"/root/generated/folder2/file3.tsx",
|
||||
"/root/generated/folder2/file3.d.ts",
|
||||
"/root/generated/folder2/file3/package.json",
|
||||
|
||||
"/root/generated/folder2/file3/index.ts",
|
||||
"/root/generated/folder2/file3/index.tsx",
|
||||
// success on index.d.ts
|
||||
@@ -619,13 +648,15 @@ import b = require("./moduleB");
|
||||
"/root/folder2/file4.tsx",
|
||||
"/root/folder2/file4.d.ts",
|
||||
"/root/folder2/file4/package.json",
|
||||
|
||||
"/root/folder2/file4/index.ts",
|
||||
"/root/folder2/file4/index.tsx",
|
||||
"/root/folder2/file4/index.d.ts",
|
||||
|
||||
// try to load from file from remapped location
|
||||
"/root/generated/folder2/file4.ts",
|
||||
"/root/generated/folder2/file4.tsx",
|
||||
"/root/generated/folder2/file4.d.ts"
|
||||
"/root/generated/folder2/file4.d.ts",
|
||||
// success on loading as from folder
|
||||
]);
|
||||
check("somefolder/file5", file5, [
|
||||
@@ -634,6 +665,7 @@ import b = require("./moduleB");
|
||||
"/root/someanotherfolder/file5.ts",
|
||||
"/root/someanotherfolder/file5.tsx",
|
||||
"/root/someanotherfolder/file5.d.ts",
|
||||
|
||||
// load from folder
|
||||
"/root/someanotherfolder/file5/package.json",
|
||||
"/root/someanotherfolder/file5/index.ts",
|
||||
@@ -646,46 +678,51 @@ import b = require("./moduleB");
|
||||
"/root/file6.ts",
|
||||
"/root/file6.tsx",
|
||||
"/root/file6.d.ts",
|
||||
|
||||
// load from folder
|
||||
"/root/file6/package.json",
|
||||
"/root/file6/index.ts",
|
||||
"/root/file6/index.tsx",
|
||||
"/root/file6/index.d.ts",
|
||||
|
||||
// then try 'generated/*'
|
||||
// load from file
|
||||
"/root/generated/file6.ts",
|
||||
"/root/generated/file6.tsx",
|
||||
"/root/generated/file6.d.ts",
|
||||
|
||||
// load from folder
|
||||
"/root/generated/file6/package.json",
|
||||
"/root/generated/file6/index.ts",
|
||||
"/root/generated/file6/index.tsx",
|
||||
"/root/generated/file6/index.d.ts",
|
||||
|
||||
// fallback to standard node behavior
|
||||
// load from file
|
||||
"/root/folder1/node_modules/file6.ts",
|
||||
"/root/folder1/node_modules/file6.tsx",
|
||||
"/root/folder1/node_modules/file6.d.ts",
|
||||
|
||||
// load from folder
|
||||
"/root/folder1/node_modules/file6/package.json",
|
||||
"/root/folder1/node_modules/file6/index.ts",
|
||||
"/root/folder1/node_modules/file6/index.tsx",
|
||||
"/root/folder1/node_modules/file6/index.d.ts",
|
||||
|
||||
"/root/folder1/node_modules/@types/file6.ts",
|
||||
"/root/folder1/node_modules/@types/file6.tsx",
|
||||
"/root/folder1/node_modules/@types/file6.d.ts",
|
||||
|
||||
"/root/folder1/node_modules/@types/file6/package.json",
|
||||
"/root/folder1/node_modules/@types/file6/index.ts",
|
||||
"/root/folder1/node_modules/@types/file6/index.tsx",
|
||||
"/root/folder1/node_modules/@types/file6/index.d.ts"
|
||||
"/root/folder1/node_modules/@types/file6/index.d.ts",
|
||||
// success on /root/node_modules/file6.ts
|
||||
]);
|
||||
], /*isExternalLibraryImport*/ true);
|
||||
|
||||
function check(name: string, expected: File, expectedFailedLookups: string[]) {
|
||||
function check(name: string, expected: File, expectedFailedLookups: string[], isExternalLibraryImport = false) {
|
||||
const result = resolveModuleName(name, main.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
|
||||
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name, isExternalLibraryImport), expectedFailedLookups);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -744,9 +781,7 @@ import b = require("./moduleB");
|
||||
|
||||
function check(name: string, expected: File, expectedFailedLookups: string[]) {
|
||||
const result = resolveModuleName(name, main.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
|
||||
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -819,9 +854,7 @@ import b = require("./moduleB");
|
||||
|
||||
function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) {
|
||||
const result = resolveModuleName(name, container.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
|
||||
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -875,9 +908,7 @@ import b = require("./moduleB");
|
||||
|
||||
function check(name: string, container: File, expected: File, expectedFailedLookups: string[]) {
|
||||
const result = resolveModuleName(name, container.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, expected.name);
|
||||
assert.deepEqual(result.failedLookupLocations, expectedFailedLookups);
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(expected.name), expectedFailedLookups);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -899,9 +930,7 @@ import b = require("./moduleB");
|
||||
}
|
||||
};
|
||||
const result = resolveModuleName("libs/guid", app.name, options, host);
|
||||
assert.isTrue(result.resolvedModule !== undefined, "module should be resolved");
|
||||
assert.equal(result.resolvedModule.resolvedFileName, libsTypings.name);
|
||||
assert.deepEqual(result.failedLookupLocations, [
|
||||
checkResolvedModuleWithFailedLookupLocations(result, createResolvedModule(libsTypings.name), [
|
||||
// first try to load module as file
|
||||
"/root/src/libs/guid.ts",
|
||||
"/root/src/libs/guid.tsx",
|
||||
@@ -911,15 +940,11 @@ import b = require("./moduleB");
|
||||
});
|
||||
});
|
||||
|
||||
function notImplemented(name: string): () => any {
|
||||
return () => assert(`${name} is not implemented and should not be called`);
|
||||
}
|
||||
|
||||
describe("ModuleResolutionHost.directoryExists", () => {
|
||||
it("No 'fileExists' calls if containing directory is missing", () => {
|
||||
const host: ModuleResolutionHost = {
|
||||
readFile: notImplemented("readFile"),
|
||||
fileExists: notImplemented("fileExists"),
|
||||
readFile: notImplemented,
|
||||
fileExists: notImplemented,
|
||||
directoryExists: _ => false
|
||||
};
|
||||
|
||||
@@ -1022,9 +1047,7 @@ import b = require("./moduleB");
|
||||
fileExists : fileName => fileName in sourceFiles,
|
||||
getSourceFile: fileName => sourceFiles[fileName],
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile(file, text) {
|
||||
throw new Error("NYI");
|
||||
},
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory: () => "/",
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: f => f.toLowerCase(),
|
||||
@@ -1042,5 +1065,69 @@ import b = require("./moduleB");
|
||||
assert.equal(diagnostics2.length, 1, "expected one diagnostic");
|
||||
assert.equal(diagnostics1[0].messageText, diagnostics2[0].messageText, "expected one diagnostic");
|
||||
});
|
||||
|
||||
it ("Modules in the same .d.ts file are preferred to external files", () => {
|
||||
const f = {
|
||||
name: "/a/b/c/c/app.d.ts",
|
||||
content: `
|
||||
declare module "fs" {
|
||||
export interface Stat { id: number }
|
||||
}
|
||||
declare module "fs-client" {
|
||||
import { Stat } from "fs";
|
||||
export function foo(): Stat;
|
||||
}`
|
||||
};
|
||||
const file = createSourceFile(f.name, f.content, ScriptTarget.ES2015);
|
||||
const compilerHost: CompilerHost = {
|
||||
fileExists : fileName => fileName === file.fileName,
|
||||
getSourceFile: fileName => fileName === file.fileName ? file : undefined,
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory: () => "/",
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: f => f.toLowerCase(),
|
||||
getNewLine: () => "\r\n",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
readFile: fileName => fileName === file.fileName ? file.text : undefined,
|
||||
resolveModuleNames() {
|
||||
assert(false, "resolveModuleNames should not be called");
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
createProgram([f.name], {}, compilerHost);
|
||||
});
|
||||
|
||||
it ("Modules in .ts file are not checked in the same file", () => {
|
||||
const f = {
|
||||
name: "/a/b/c/c/app.ts",
|
||||
content: `
|
||||
declare module "fs" {
|
||||
export interface Stat { id: number }
|
||||
}
|
||||
declare module "fs-client" {
|
||||
import { Stat } from "fs";
|
||||
export function foo(): Stat;
|
||||
}`
|
||||
};
|
||||
const file = createSourceFile(f.name, f.content, ScriptTarget.ES2015);
|
||||
const compilerHost: CompilerHost = {
|
||||
fileExists : fileName => fileName === file.fileName,
|
||||
getSourceFile: fileName => fileName === file.fileName ? file : undefined,
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory: () => "/",
|
||||
getDirectories: () => [],
|
||||
getCanonicalFileName: f => f.toLowerCase(),
|
||||
getNewLine: () => "\r\n",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
readFile: fileName => fileName === file.fileName ? file.text : undefined,
|
||||
resolveModuleNames(moduleNames: string[], _containingFile: string) {
|
||||
assert.deepEqual(moduleNames, ["fs"]);
|
||||
return [undefined];
|
||||
}
|
||||
};
|
||||
createProgram([f.name], {}, compilerHost);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -22,6 +22,11 @@ namespace ts {
|
||||
|
||||
interface ProgramWithSourceTexts extends Program {
|
||||
sourceTexts?: NamedSourceText[];
|
||||
host: TestCompilerHost;
|
||||
}
|
||||
|
||||
interface TestCompilerHost extends CompilerHost {
|
||||
getTrace(): string[];
|
||||
}
|
||||
|
||||
class SourceText implements IScriptSnapshot {
|
||||
@@ -101,23 +106,32 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget): CompilerHost {
|
||||
const files = arrayToMap(texts, t => t.name, t => createSourceFileWithText(t.name, t.text, target));
|
||||
function createTestCompilerHost(texts: NamedSourceText[], target: ScriptTarget, oldProgram?: ProgramWithSourceTexts): TestCompilerHost {
|
||||
const files = arrayToMap(texts, t => t.name, t => {
|
||||
if (oldProgram) {
|
||||
const oldFile = <SourceFileWithText>oldProgram.getSourceFile(t.name);
|
||||
if (oldFile && oldFile.sourceText.getVersion() === t.text.getVersion()) {
|
||||
return oldFile;
|
||||
}
|
||||
}
|
||||
return createSourceFileWithText(t.name, t.text, target);
|
||||
});
|
||||
const trace: string[] = [];
|
||||
|
||||
return {
|
||||
trace: s => trace.push(s),
|
||||
getTrace: () => trace,
|
||||
getSourceFile(fileName): SourceFile {
|
||||
return files[fileName];
|
||||
},
|
||||
getDefaultLibFileName(): string {
|
||||
return "lib.d.ts";
|
||||
},
|
||||
writeFile(file, text) {
|
||||
throw new Error("NYI");
|
||||
},
|
||||
writeFile: notImplemented,
|
||||
getCurrentDirectory(): string {
|
||||
return "";
|
||||
},
|
||||
getDirectories(path: string): string[] {
|
||||
getDirectories(): string[] {
|
||||
return [];
|
||||
},
|
||||
getCanonicalFileName(fileName): string {
|
||||
@@ -132,37 +146,28 @@ namespace ts {
|
||||
fileExists: fileName => fileName in files,
|
||||
readFile: fileName => {
|
||||
return fileName in files ? files[fileName].text : undefined;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function newProgram(texts: NamedSourceText[], rootNames: string[], options: CompilerOptions): Program {
|
||||
function newProgram(texts: NamedSourceText[], rootNames: string[], options: CompilerOptions): ProgramWithSourceTexts {
|
||||
const host = createTestCompilerHost(texts, options.target);
|
||||
const program = <ProgramWithSourceTexts>createProgram(rootNames, options, host);
|
||||
program.sourceTexts = texts;
|
||||
program.host = host;
|
||||
return program;
|
||||
}
|
||||
|
||||
function updateProgram(oldProgram: Program, rootNames: string[], options: CompilerOptions, updater: (files: NamedSourceText[]) => void) {
|
||||
function updateProgram(oldProgram: ProgramWithSourceTexts, rootNames: string[], options: CompilerOptions, updater: (files: NamedSourceText[]) => void) {
|
||||
const texts: NamedSourceText[] = (<ProgramWithSourceTexts>oldProgram).sourceTexts.slice(0);
|
||||
updater(texts);
|
||||
const host = createTestCompilerHost(texts, options.target);
|
||||
const host = createTestCompilerHost(texts, options.target, oldProgram);
|
||||
const program = <ProgramWithSourceTexts>createProgram(rootNames, options, host, oldProgram);
|
||||
program.sourceTexts = texts;
|
||||
program.host = host;
|
||||
return program;
|
||||
}
|
||||
|
||||
function checkResolvedModule(expected: ResolvedModule, actual: ResolvedModule): boolean {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
|
||||
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): boolean {
|
||||
if (!expected === !actual) {
|
||||
if (expected) {
|
||||
@@ -244,17 +249,13 @@ namespace ts {
|
||||
|
||||
it("fails if change affects type references", () => {
|
||||
const program_1 = newProgram(files, ["a.ts"], { types: ["a"] });
|
||||
updateProgram(program_1, ["a.ts"], { types: ["b"] }, files => {
|
||||
|
||||
});
|
||||
updateProgram(program_1, ["a.ts"], { types: ["b"] }, noop);
|
||||
assert.isTrue(!program_1.structureIsReused);
|
||||
});
|
||||
|
||||
it("succeeds if change doesn't affect type references", () => {
|
||||
const program_1 = newProgram(files, ["a.ts"], { types: ["a"] });
|
||||
updateProgram(program_1, ["a.ts"], { types: ["a"] }, files => {
|
||||
|
||||
});
|
||||
updateProgram(program_1, ["a.ts"], { types: ["a"] }, noop);
|
||||
assert.isTrue(program_1.structureIsReused);
|
||||
});
|
||||
|
||||
@@ -280,19 +281,19 @@ namespace ts {
|
||||
|
||||
it("fails if module kind changes", () => {
|
||||
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS });
|
||||
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, files => void 0);
|
||||
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.AMD }, noop);
|
||||
assert.isTrue(!program_1.structureIsReused);
|
||||
});
|
||||
|
||||
it("fails if rootdir changes", () => {
|
||||
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" });
|
||||
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, files => void 0);
|
||||
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, noop);
|
||||
assert.isTrue(!program_1.structureIsReused);
|
||||
});
|
||||
|
||||
it("fails if config path changes", () => {
|
||||
const program_1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/b/tsconfig.json" });
|
||||
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, files => void 0);
|
||||
updateProgram(program_1, ["a.ts"], { target, module: ModuleKind.CommonJS, configFilePath: "/a/c/tsconfig.json" }, noop);
|
||||
assert.isTrue(!program_1.structureIsReused);
|
||||
});
|
||||
|
||||
@@ -306,7 +307,7 @@ namespace ts {
|
||||
const options: CompilerOptions = { target };
|
||||
|
||||
const program_1 = newProgram(files, ["a.ts"], options);
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") }));
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
|
||||
const program_2 = updateProgram(program_1, ["a.ts"], options, files => {
|
||||
@@ -315,7 +316,7 @@ namespace ts {
|
||||
assert.isTrue(program_1.structureIsReused);
|
||||
|
||||
// content of resolution cache should not change
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" } }));
|
||||
checkResolvedModulesCache(program_1, "a.ts", createMap({ "b": createResolvedModule("b.ts") }));
|
||||
checkResolvedModulesCache(program_1, "b.ts", undefined);
|
||||
|
||||
// imports has changed - program is not reused
|
||||
@@ -332,7 +333,7 @@ namespace ts {
|
||||
files[0].text = files[0].text.updateImportsAndExports(newImports);
|
||||
});
|
||||
assert.isTrue(!program_3.structureIsReused);
|
||||
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": { resolvedFileName: "b.ts" }, "c": undefined }));
|
||||
checkResolvedModulesCache(program_4, "a.ts", createMap({ "b": createResolvedModule("b.ts"), "c": undefined }));
|
||||
});
|
||||
|
||||
it("resolved type directives cache follows type directives", () => {
|
||||
@@ -372,6 +373,112 @@ namespace ts {
|
||||
assert.isTrue(!program_3.structureIsReused);
|
||||
checkResolvedTypeDirectivesCache(program_1, "/a.ts", createMap({ "typedefs": { resolvedFileName: "/types/typedefs/index.d.ts", primary: true } }));
|
||||
});
|
||||
|
||||
it("can reuse ambient module declarations from non-modified files", () => {
|
||||
const files = [
|
||||
{ name: "/a/b/app.ts", text: SourceText.New("", "import * as fs from 'fs'", "") },
|
||||
{ name: "/a/b/node.d.ts", text: SourceText.New("", "", "declare module 'fs' {}") }
|
||||
];
|
||||
const options = { target: ScriptTarget.ES2015, traceResolution: true };
|
||||
const program = newProgram(files, files.map(f => f.name), options);
|
||||
assert.deepEqual(program.host.getTrace(),
|
||||
[
|
||||
"======== Resolving module 'fs' from '/a/b/app.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'Classic'.",
|
||||
"File '/a/b/fs.ts' does not exist.",
|
||||
"File '/a/b/fs.tsx' does not exist.",
|
||||
"File '/a/b/fs.d.ts' does not exist.",
|
||||
"File '/a/fs.ts' does not exist.",
|
||||
"File '/a/fs.tsx' does not exist.",
|
||||
"File '/a/fs.d.ts' does not exist.",
|
||||
"File '/fs.ts' does not exist.",
|
||||
"File '/fs.tsx' does not exist.",
|
||||
"File '/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.tsx' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.tsx' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/b/fs.js' does not exist.",
|
||||
"File '/a/b/fs.jsx' does not exist.",
|
||||
"File '/a/fs.js' does not exist.",
|
||||
"File '/a/fs.jsx' does not exist.",
|
||||
"File '/fs.js' does not exist.",
|
||||
"File '/fs.jsx' does not exist.",
|
||||
"======== Module name 'fs' was not resolved. ========",
|
||||
], "should look for 'fs'");
|
||||
|
||||
const program_2 = updateProgram(program, program.getRootFileNames(), options, f => {
|
||||
f[0].text = f[0].text.updateProgram("var x = 1;");
|
||||
});
|
||||
assert.deepEqual(program_2.host.getTrace(), [
|
||||
"Module 'fs' was resolved as ambient module declared in '/a/b/node.d.ts' since this file was not modified."
|
||||
], "should reuse 'fs' since node.d.ts was not changed");
|
||||
|
||||
const program_3 = updateProgram(program_2, program_2.getRootFileNames(), options, f => {
|
||||
f[0].text = f[0].text.updateProgram("var y = 1;");
|
||||
f[1].text = f[1].text.updateProgram("declare var process: any");
|
||||
});
|
||||
assert.deepEqual(program_3.host.getTrace(),
|
||||
[
|
||||
"======== Resolving module 'fs' from '/a/b/app.ts'. ========",
|
||||
"Module resolution kind is not specified, using 'Classic'.",
|
||||
"File '/a/b/fs.ts' does not exist.",
|
||||
"File '/a/b/fs.tsx' does not exist.",
|
||||
"File '/a/b/fs.d.ts' does not exist.",
|
||||
"File '/a/fs.ts' does not exist.",
|
||||
"File '/a/fs.tsx' does not exist.",
|
||||
"File '/a/fs.d.ts' does not exist.",
|
||||
"File '/fs.ts' does not exist.",
|
||||
"File '/fs.tsx' does not exist.",
|
||||
"File '/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs.tsx' does not exist.",
|
||||
"File '/node_modules/@types/fs.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/package.json' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.ts' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.tsx' does not exist.",
|
||||
"File '/node_modules/@types/fs/index.d.ts' does not exist.",
|
||||
"File '/a/b/fs.js' does not exist.",
|
||||
"File '/a/b/fs.jsx' does not exist.",
|
||||
"File '/a/fs.js' does not exist.",
|
||||
"File '/a/fs.jsx' does not exist.",
|
||||
"File '/fs.js' does not exist.",
|
||||
"File '/fs.jsx' does not exist.",
|
||||
"======== Module name 'fs' was not resolved. ========",
|
||||
], "should look for 'fs' again since node.d.ts was changed");
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("host is optional", () => {
|
||||
|
||||
@@ -62,7 +62,7 @@ describe("DocumentRegistry", () => {
|
||||
const snapshot = ts.ScriptSnapshot.fromString(contents);
|
||||
|
||||
// Always treat any change as a full change.
|
||||
snapshot.getChangeRange = old => ts.createTextChangeRange(ts.createTextSpan(0, contents.length), contents.length);
|
||||
snapshot.getChangeRange = () => ts.createTextChangeRange(ts.createTextSpan(0, contents.length), contents.length);
|
||||
|
||||
// Simulate one LS getting the document.
|
||||
documentRegistry.acquireDocument("file1.ts", defaultCompilerOptions, snapshot, /* version */ "1");
|
||||
|
||||
@@ -10,41 +10,47 @@ namespace ts.server {
|
||||
useCaseSensitiveFileNames: true,
|
||||
write(s): void { lastWrittenToHost = s; },
|
||||
readFile(): string { return void 0; },
|
||||
writeFile(): void {},
|
||||
writeFile: noop,
|
||||
resolvePath(): string { return void 0; },
|
||||
fileExists: () => false,
|
||||
directoryExists: () => false,
|
||||
getDirectories: () => [],
|
||||
createDirectory(): void {},
|
||||
createDirectory: noop,
|
||||
getExecutingFilePath(): string { return void 0; },
|
||||
getCurrentDirectory(): string { return void 0; },
|
||||
getEnvironmentVariable(name: string): string { return ""; },
|
||||
getEnvironmentVariable(): string { return ""; },
|
||||
readDirectory(): string[] { return []; },
|
||||
exit(): void { },
|
||||
setTimeout(callback, ms, ...args) { return 0; },
|
||||
clearTimeout(timeoutId) { },
|
||||
exit: noop,
|
||||
setTimeout() { return 0; },
|
||||
clearTimeout: noop,
|
||||
setImmediate: () => 0,
|
||||
clearImmediate() {}
|
||||
clearImmediate: noop
|
||||
};
|
||||
const nullCancellationToken: HostCancellationToken = { isCancellationRequested: () => false };
|
||||
const mockLogger: Logger = {
|
||||
close(): void {},
|
||||
close: noop,
|
||||
hasLevel(): boolean { return false; },
|
||||
loggingEnabled(): boolean { return false; },
|
||||
perftrc(s: string): void {},
|
||||
info(s: string): void {},
|
||||
startGroup(): void {},
|
||||
endGroup(): void {},
|
||||
msg(s: string, type?: string): void {},
|
||||
perftrc: noop,
|
||||
info: noop,
|
||||
startGroup: noop,
|
||||
endGroup: noop,
|
||||
msg: noop,
|
||||
getLogFileName: (): string => undefined
|
||||
};
|
||||
|
||||
class TestSession extends Session {
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
}
|
||||
|
||||
describe("the Session class", () => {
|
||||
let session: Session;
|
||||
let session: TestSession;
|
||||
let lastSent: protocol.Message;
|
||||
|
||||
beforeEach(() => {
|
||||
session = new Session(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
|
||||
session = new TestSession(mockHost, nullCancellationToken, /*useOneInferredProject*/ false, /*typingsInstaller*/ undefined, Utils.byteLength, process.hrtime, mockLogger, /*canUseEvents*/ true);
|
||||
session.send = (msg: protocol.Message) => {
|
||||
lastSent = msg;
|
||||
};
|
||||
@@ -55,7 +61,7 @@ namespace ts.server {
|
||||
const req: protocol.FileRequest = {
|
||||
command: CommandNames.Open,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
arguments: {
|
||||
file: undefined
|
||||
}
|
||||
@@ -67,7 +73,7 @@ namespace ts.server {
|
||||
const req: protocol.Request = {
|
||||
command: "foobar",
|
||||
seq: 0,
|
||||
type: "command"
|
||||
type: "request"
|
||||
};
|
||||
|
||||
session.executeCommand(req);
|
||||
@@ -85,7 +91,7 @@ namespace ts.server {
|
||||
const req: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
arguments: {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
@@ -106,6 +112,48 @@ namespace ts.server {
|
||||
body: undefined
|
||||
});
|
||||
});
|
||||
it ("should handle literal types in request", () => {
|
||||
const configureRequest: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "request",
|
||||
arguments: {
|
||||
formatOptions: {
|
||||
indentStyle: "Block"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
session.onMessage(JSON.stringify(configureRequest));
|
||||
|
||||
assert.equal(session.getProjectService().getFormatCodeOptions().indentStyle, IndentStyle.Block);
|
||||
|
||||
const setOptionsRequest: protocol.SetCompilerOptionsForInferredProjectsRequest = {
|
||||
command: CommandNames.CompilerOptionsForInferredProjects,
|
||||
seq: 1,
|
||||
type: "request",
|
||||
arguments: {
|
||||
options: {
|
||||
module: "System",
|
||||
target: "ES5",
|
||||
jsx: "React",
|
||||
newLine: "Lf",
|
||||
moduleResolution: "Node"
|
||||
}
|
||||
}
|
||||
};
|
||||
session.onMessage(JSON.stringify(setOptionsRequest));
|
||||
assert.deepEqual(
|
||||
session.getProjectService().getCompilerOptionsForInferredProjects(),
|
||||
<CompilerOptions>{
|
||||
module: ModuleKind.System,
|
||||
target: ScriptTarget.ES5,
|
||||
jsx: JsxEmit.React,
|
||||
newLine: NewLineKind.LineFeed,
|
||||
moduleResolution: ModuleResolutionKind.NodeJs,
|
||||
allowNonTsExtensions: true // injected by tsserver
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("onMessage", () => {
|
||||
@@ -118,7 +166,7 @@ namespace ts.server {
|
||||
const req: protocol.Request = {
|
||||
command: name,
|
||||
seq: i,
|
||||
type: "command"
|
||||
type: "request"
|
||||
};
|
||||
i++;
|
||||
session.onMessage(JSON.stringify(req));
|
||||
@@ -151,7 +199,7 @@ namespace ts.server {
|
||||
const req: protocol.ConfigureRequest = {
|
||||
command: CommandNames.Configure,
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
arguments: {
|
||||
hostInfo: "unit test",
|
||||
formatOptions: {
|
||||
@@ -175,7 +223,7 @@ namespace ts.server {
|
||||
|
||||
describe("send", () => {
|
||||
it("is an overrideable handle which sends protocol messages over the wire", () => {
|
||||
const msg = { seq: 0, type: "none" };
|
||||
const msg: server.protocol.Request = { seq: 0, type: "request", command: "" };
|
||||
const strmsg = JSON.stringify(msg);
|
||||
const len = 1 + Utils.byteLength(strmsg, "utf8");
|
||||
const resultMsg = `Content-Length: ${len}\r\n\r\n${strmsg}\n`;
|
||||
@@ -198,12 +246,12 @@ namespace ts.server {
|
||||
responseRequired: true
|
||||
};
|
||||
|
||||
session.addProtocolHandler(command, (req) => result);
|
||||
session.addProtocolHandler(command, () => result);
|
||||
|
||||
expect(session.executeCommand({
|
||||
command,
|
||||
seq: 0,
|
||||
type: "command"
|
||||
type: "request"
|
||||
})).to.deep.equal(result);
|
||||
});
|
||||
it("throws when a duplicate handler is passed", () => {
|
||||
@@ -216,9 +264,9 @@ namespace ts.server {
|
||||
};
|
||||
const command = "newhandle";
|
||||
|
||||
session.addProtocolHandler(command, (req) => resp);
|
||||
session.addProtocolHandler(command, () => resp);
|
||||
|
||||
expect(() => session.addProtocolHandler(command, (req) => resp))
|
||||
expect(() => session.addProtocolHandler(command, () => resp))
|
||||
.to.throw(`Protocol handler already exists for command "${command}"`);
|
||||
});
|
||||
});
|
||||
@@ -304,7 +352,7 @@ namespace ts.server {
|
||||
|
||||
expect(session.executeCommand({
|
||||
seq: 0,
|
||||
type: "command",
|
||||
type: "request",
|
||||
command: session.customHandler
|
||||
})).to.deep.equal({
|
||||
response: undefined,
|
||||
@@ -405,7 +453,7 @@ namespace ts.server {
|
||||
this.seq++;
|
||||
this.server.enqueue({
|
||||
seq: this.seq,
|
||||
type: "command",
|
||||
type: "request",
|
||||
command,
|
||||
arguments: args
|
||||
});
|
||||
|
||||
@@ -28,6 +28,14 @@ namespace ts {
|
||||
assert.isTrue(arrayIsEqualTo(parsed.fileNames.sort(), expectedFileList.sort()));
|
||||
}
|
||||
|
||||
function assertParseFileDiagnostics(jsonText: string, configFileName: string, basePath: string, allFileList: string[], expectedDiagnosticCode: number) {
|
||||
const json = JSON.parse(jsonText);
|
||||
const host: ParseConfigHost = new Utils.MockParseConfigHost(basePath, true, allFileList);
|
||||
const parsed = ts.parseJsonConfigFileContent(json, host, basePath, /*existingOptions*/ undefined, configFileName);
|
||||
assert.isTrue(parsed.errors.length >= 0);
|
||||
assert.isTrue(parsed.errors.filter(e => e.code === expectedDiagnosticCode).length > 0, `Expected error code ${expectedDiagnosticCode} to be in ${JSON.stringify(parsed.errors)}`);
|
||||
}
|
||||
|
||||
it("returns empty config for file with only whitespaces", () => {
|
||||
assertParseResult("", { config : {} });
|
||||
assertParseResult(" ", { config : {} });
|
||||
@@ -202,5 +210,64 @@ namespace ts {
|
||||
assert.isTrue(diagnostics.length === 2);
|
||||
assert.equal(JSON.stringify(configJsonObject), JSON.stringify(expectedResult));
|
||||
});
|
||||
|
||||
it("generates errors for empty files list", () => {
|
||||
const content = `{
|
||||
"files": []
|
||||
}`;
|
||||
assertParseFileDiagnostics(content,
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.ts"],
|
||||
Diagnostics.The_files_list_in_config_file_0_is_empty.code);
|
||||
});
|
||||
|
||||
it("generates errors for directory with no .ts files", () => {
|
||||
const content = `{
|
||||
}`;
|
||||
assertParseFileDiagnostics(content,
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.js"],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
});
|
||||
|
||||
it("generates errors for empty directory", () => {
|
||||
const content = `{
|
||||
"compilerOptions": {
|
||||
"allowJs": true
|
||||
}
|
||||
}`;
|
||||
assertParseFileDiagnostics(content,
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
[],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
});
|
||||
|
||||
it("generates errors for empty include", () => {
|
||||
const content = `{
|
||||
"include": []
|
||||
}`;
|
||||
assertParseFileDiagnostics(content,
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.ts"],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
});
|
||||
|
||||
it("generates errors for includes with outDir", () => {
|
||||
const content = `{
|
||||
"compilerOptions": {
|
||||
"outDir": "./"
|
||||
},
|
||||
"include": ["**/*"]
|
||||
}`;
|
||||
assertParseFileDiagnostics(content,
|
||||
"/apath/tsconfig.json",
|
||||
"tests/cases/unittests",
|
||||
["/apath/a.ts"],
|
||||
Diagnostics.No_inputs_were_found_in_config_file_0_Specified_include_paths_were_1_and_exclude_paths_were_2.code);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -23,10 +23,6 @@ namespace ts.projectSystem {
|
||||
readonly callback: TI.RequestCompletedAction;
|
||||
}
|
||||
|
||||
export function notImplemented(): any {
|
||||
throw new Error("Not yet implemented");
|
||||
}
|
||||
|
||||
export const nullLogger: server.Logger = {
|
||||
close: () => void 0,
|
||||
hasLevel: () => void 0,
|
||||
@@ -72,7 +68,7 @@ namespace ts.projectSystem {
|
||||
this.postExecActions.forEach((act, i) => assert.equal(act.requestKind, expected[i], "Unexpected post install action"));
|
||||
}
|
||||
|
||||
onProjectClosed(p: server.Project) {
|
||||
onProjectClosed() {
|
||||
}
|
||||
|
||||
attach(projectService: server.ProjectService) {
|
||||
@@ -83,7 +79,7 @@ namespace ts.projectSystem {
|
||||
return this.installTypingHost;
|
||||
}
|
||||
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
switch (requestKind) {
|
||||
case TI.NpmViewRequest:
|
||||
case TI.NpmInstallRequest:
|
||||
@@ -98,8 +94,8 @@ namespace ts.projectSystem {
|
||||
this.projectService.updateTypingsForProject(response);
|
||||
}
|
||||
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
|
||||
const request = server.createInstallTypingsRequest(project, typingOptions, this.globalTypingsCacheLocation);
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
|
||||
const request = server.createInstallTypingsRequest(project, typingOptions, unresolvedImports, this.globalTypingsCacheLocation);
|
||||
this.install(request);
|
||||
}
|
||||
|
||||
@@ -122,7 +118,7 @@ namespace ts.projectSystem {
|
||||
return JSON.stringify({ dependencies: dependencies });
|
||||
}
|
||||
|
||||
export function getExecutingFilePathFromLibFile(libFilePath: string): string {
|
||||
export function getExecutingFilePathFromLibFile(): string {
|
||||
return combinePaths(getDirectoryPath(libFile.path), "tsc.js");
|
||||
}
|
||||
|
||||
@@ -154,27 +150,31 @@ namespace ts.projectSystem {
|
||||
currentDirectory?: string;
|
||||
}
|
||||
|
||||
export function createServerHost(fileOrFolderList: FileOrFolder[],
|
||||
params?: TestServerHostCreationParameters,
|
||||
libFilePath: string = libFile.path): TestServerHost {
|
||||
|
||||
export function createServerHost(fileOrFolderList: FileOrFolder[], params?: TestServerHostCreationParameters): TestServerHost {
|
||||
if (!params) {
|
||||
params = {};
|
||||
}
|
||||
const host = new TestServerHost(
|
||||
params.useCaseSensitiveFileNames !== undefined ? params.useCaseSensitiveFileNames : false,
|
||||
params.executingFilePath || getExecutingFilePathFromLibFile(libFilePath),
|
||||
params.executingFilePath || getExecutingFilePathFromLibFile(),
|
||||
params.currentDirectory || "/",
|
||||
fileOrFolderList);
|
||||
host.createFileOrFolder(safeList, /*createParentDirectory*/ true);
|
||||
return host;
|
||||
}
|
||||
|
||||
class TestSession extends server.Session {
|
||||
getProjectService() {
|
||||
return this.projectService;
|
||||
}
|
||||
};
|
||||
|
||||
export function createSession(host: server.ServerHost, typingsInstaller?: server.ITypingsInstaller, projectServiceEventHandler?: server.ProjectServiceEventHandler) {
|
||||
if (typingsInstaller === undefined) {
|
||||
typingsInstaller = new TestTypingsInstaller("/a/data/", /*throttleLimit*/5, host);
|
||||
}
|
||||
return new server.Session(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
|
||||
return new TestSession(host, nullCancellationToken, /*useSingleInferredProject*/ false, typingsInstaller, Utils.byteLength, process.hrtime, nullLogger, /*canUseEvents*/ projectServiceEventHandler !== undefined, projectServiceEventHandler);
|
||||
}
|
||||
|
||||
export interface CreateProjectServiceParameters {
|
||||
@@ -315,9 +315,9 @@ namespace ts.projectSystem {
|
||||
|
||||
count() {
|
||||
let n = 0;
|
||||
/* tslint:disable:no-unused-variable */
|
||||
for (const _ in this.map) {
|
||||
/* tslint:enable:no-unused-variable */
|
||||
// TODO: GH#11734
|
||||
_;
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
@@ -466,7 +466,7 @@ namespace ts.projectSystem {
|
||||
}
|
||||
|
||||
// TOOD: record and invoke callbacks to simulate timer events
|
||||
setTimeout(callback: TimeOutCallback, time: number, ...args: any[]) {
|
||||
setTimeout(callback: TimeOutCallback, _time: number, ...args: any[]) {
|
||||
return this.timeoutCallbacks.register(callback, args);
|
||||
};
|
||||
|
||||
@@ -483,7 +483,7 @@ namespace ts.projectSystem {
|
||||
this.timeoutCallbacks.invoke();
|
||||
}
|
||||
|
||||
setImmediate(callback: TimeOutCallback, time: number, ...args: any[]) {
|
||||
setImmediate(callback: TimeOutCallback, _time: number, ...args: any[]) {
|
||||
return this.immediateCallbacks.register(callback, args);
|
||||
}
|
||||
|
||||
@@ -515,13 +515,14 @@ namespace ts.projectSystem {
|
||||
this.reloadFS(filesOrFolders);
|
||||
}
|
||||
|
||||
write() { }
|
||||
|
||||
readonly readFile = (s: string) => (<File>this.fs.get(this.toPath(s))).content;
|
||||
readonly resolvePath = (s: string) => s;
|
||||
readonly getExecutingFilePath = () => this.executingFilePath;
|
||||
readonly getCurrentDirectory = () => this.currentDirectory;
|
||||
readonly write = (s: string) => notImplemented();
|
||||
readonly exit = () => notImplemented();
|
||||
readonly getEnvironmentVariable = (v: string) => notImplemented();
|
||||
readonly exit = notImplemented;
|
||||
readonly getEnvironmentVariable = notImplemented;
|
||||
}
|
||||
|
||||
export function makeSessionRequest<T>(command: string, args: T) {
|
||||
@@ -1658,67 +1659,74 @@ namespace ts.projectSystem {
|
||||
"File '/a/b/node_modules/lib.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib.js' does not exist.",
|
||||
"File '/a/b/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.d.ts' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"File '/a/node_modules/lib.ts' does not exist.",
|
||||
"File '/a/node_modules/lib.tsx' does not exist.",
|
||||
"File '/a/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/node_modules/lib.js' does not exist.",
|
||||
"File '/a/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/a/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/a/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.d.ts' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"File '/node_modules/lib.ts' does not exist.",
|
||||
"File '/node_modules/lib.tsx' does not exist.",
|
||||
"File '/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/node_modules/lib.js' does not exist.",
|
||||
"File '/node_modules/lib.jsx' does not exist.",
|
||||
"File '/node_modules/lib/package.json' does not exist.",
|
||||
"File '/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/node_modules/lib/index.js' does not exist.",
|
||||
"File '/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.d.ts' does not exist.",
|
||||
"Loading module 'lib' from 'node_modules' folder.",
|
||||
"File '/a/b/node_modules/lib.js' does not exist.",
|
||||
"File '/a/b/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/b/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/a/b/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"File '/a/node_modules/lib.js' does not exist.",
|
||||
"File '/a/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/a/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"File '/node_modules/lib.js' does not exist.",
|
||||
"File '/node_modules/lib.jsx' does not exist.",
|
||||
"File '/node_modules/lib/package.json' does not exist.",
|
||||
"File '/node_modules/lib/index.js' does not exist.",
|
||||
"File '/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.js' does not exist.",
|
||||
"File '/node_modules/@types/lib/index.jsx' does not exist.",
|
||||
"======== Module name 'lib' was not resolved. ========",
|
||||
@@ -1726,19 +1734,13 @@ namespace ts.projectSystem {
|
||||
"File '/a/cache/node_modules/lib.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.js' does not exist.",
|
||||
"File '/a/cache/node_modules/lib.jsx' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/package.json' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.js' does not exist.",
|
||||
"File '/a/cache/node_modules/lib/index.jsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.tsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.d.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.js' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib.jsx' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/package.json' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.ts' does not exist.",
|
||||
"File '/a/cache/node_modules/@types/lib/index.tsx' does not exist.",
|
||||
@@ -2420,4 +2422,111 @@ namespace ts.projectSystem {
|
||||
assert.isTrue(inferredProject.containsFile(<server.NormalizedPath>file1.path));
|
||||
});
|
||||
});
|
||||
|
||||
describe("reload", () => {
|
||||
it("should work with temp file", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.ts",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const tmp = {
|
||||
path: "/a/b/app.tmp",
|
||||
content: "const y = 42"
|
||||
};
|
||||
const host = createServerHost([f1, tmp]);
|
||||
const session = createSession(host);
|
||||
|
||||
// send open request
|
||||
session.executeCommand(<server.protocol.OpenRequest>{
|
||||
type: "request",
|
||||
command: "open",
|
||||
seq: 1,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
|
||||
// reload from tmp file
|
||||
session.executeCommand(<server.protocol.ReloadRequest>{
|
||||
type: "request",
|
||||
command: "reload",
|
||||
seq: 2,
|
||||
arguments: { file: f1.path, tmpfile: tmp.path }
|
||||
});
|
||||
|
||||
// verify content
|
||||
const projectServiice = session.getProjectService();
|
||||
const snap1 = projectServiice.getScriptInfo(f1.path).snap();
|
||||
assert.equal(snap1.getText(0, snap1.getLength()), tmp.content, "content should be equal to the content of temp file");
|
||||
|
||||
// reload from original file file
|
||||
session.executeCommand(<server.protocol.ReloadRequest>{
|
||||
type: "request",
|
||||
command: "reload",
|
||||
seq: 2,
|
||||
arguments: { file: f1.path }
|
||||
});
|
||||
|
||||
// verify content
|
||||
const snap2 = projectServiice.getScriptInfo(f1.path).snap();
|
||||
assert.equal(snap2.getText(0, snap2.getLength()), f1.content, "content should be equal to the content of original file");
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe("Inferred projects", () => {
|
||||
it("should support files without extensions", () => {
|
||||
const f = {
|
||||
path: "/a/compile",
|
||||
content: "let x = 1"
|
||||
};
|
||||
const host = createServerHost([f]);
|
||||
const session = createSession(host);
|
||||
session.executeCommand(<server.protocol.SetCompilerOptionsForInferredProjectsRequest>{
|
||||
seq: 1,
|
||||
type: "request",
|
||||
command: "compilerOptionsForInferredProjects",
|
||||
arguments: {
|
||||
options: {
|
||||
allowJs: true
|
||||
}
|
||||
}
|
||||
});
|
||||
session.executeCommand(<server.protocol.OpenRequest>{
|
||||
seq: 2,
|
||||
type: "request",
|
||||
command: "open",
|
||||
arguments: {
|
||||
file: f.path,
|
||||
fileContent: f.content,
|
||||
scriptKindName: "JS"
|
||||
}
|
||||
});
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
checkProjectActualFiles(projectService.inferredProjects[0], [f.path]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("No overwrite emit error", () => {
|
||||
it("for inferred project", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/f1.js",
|
||||
content: "function test1() { }"
|
||||
};
|
||||
const host = createServerHost([f1, libFile]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([f1], session);
|
||||
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
const projectName = projectService.inferredProjects[0].getProjectName();
|
||||
|
||||
const diags = session.executeCommand(<server.protocol.CompilerOptionsDiagnosticsRequest>{
|
||||
type: "request",
|
||||
command: server.CommandNames.CompilerOptionsDiagnosticsFull,
|
||||
seq: 2,
|
||||
arguments: { projectFileName: projectName }
|
||||
}).response;
|
||||
assert.isTrue(diags.length === 0);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -81,7 +81,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jquery];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -125,7 +125,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jquery];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -217,11 +217,11 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host);
|
||||
}
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
|
||||
enqueueIsCalled = true;
|
||||
super.enqueueInstallTypingsRequest(project, typingOptions);
|
||||
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jquery];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -275,7 +275,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/lodash", "@types/react"];
|
||||
const typingFiles = [lodash, react];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -319,11 +319,11 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host);
|
||||
}
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions) {
|
||||
enqueueInstallTypingsRequest(project: server.Project, typingOptions: TypingOptions, unresolvedImports: server.SortedReadonlyArray<string>) {
|
||||
enqueueIsCalled = true;
|
||||
super.enqueueInstallTypingsRequest(project, typingOptions);
|
||||
super.enqueueInstallTypingsRequest(project, typingOptions, unresolvedImports);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings: string[] = [];
|
||||
const typingFiles: FileOrFolder[] = [];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -398,7 +398,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host);
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/commander", "@types/express", "@types/jquery", "@types/moment"];
|
||||
const typingFiles = [commander, express, jquery, moment];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -477,7 +477,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host, { throttleLimit: 3 });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
const installedTypings = ["@types/commander", "@types/express", "@types/jquery", "@types/moment", "@types/lodash"];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
}
|
||||
@@ -567,9 +567,9 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host, { throttleLimit: 3 });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
|
||||
if (requestKind === TI.NpmInstallRequest) {
|
||||
let typingFiles: (FileOrFolder & { typings: string}) [] = [];
|
||||
let typingFiles: (FileOrFolder & { typings: string })[] = [];
|
||||
if (args.indexOf("@types/commander") >= 0) {
|
||||
typingFiles = [commander, jquery, lodash, cordova];
|
||||
}
|
||||
@@ -591,7 +591,7 @@ namespace ts.projectSystem {
|
||||
projectFileName: projectFileName1,
|
||||
options: { allowJS: true, moduleResolution: ModuleResolutionKind.NodeJs },
|
||||
rootFiles: [toExternalFile(lodashJs.path), toExternalFile(commanderJs.path), toExternalFile(file3.path)],
|
||||
typingOptions: { include: ["jquery", "cordova" ] }
|
||||
typingOptions: { include: ["jquery", "cordova"] }
|
||||
});
|
||||
|
||||
installer.checkPendingCommands([TI.NpmViewRequest, TI.NpmViewRequest, TI.NpmViewRequest]);
|
||||
@@ -626,7 +626,7 @@ namespace ts.projectSystem {
|
||||
installer.executePendingCommands();
|
||||
|
||||
checkProjectActualFiles(p1, [lodashJs.path, commanderJs.path, file3.path, commander.path, jquery.path, lodash.path, cordova.path]);
|
||||
checkProjectActualFiles(p2, [file3.path, grunt.path, gulp.path ]);
|
||||
checkProjectActualFiles(p2, [file3.path, grunt.path, gulp.path]);
|
||||
});
|
||||
|
||||
it("configured projects discover from node_modules", () => {
|
||||
@@ -655,7 +655,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jqueryDTS];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -687,10 +687,10 @@ namespace ts.projectSystem {
|
||||
const bowerJson = {
|
||||
path: "/bower.json",
|
||||
content: JSON.stringify({
|
||||
"dependencies": {
|
||||
"jquery": "^3.1.0"
|
||||
}
|
||||
})
|
||||
"dependencies": {
|
||||
"jquery": "^3.1.0"
|
||||
}
|
||||
})
|
||||
};
|
||||
const jqueryDTS = {
|
||||
path: "/tmp/node_modules/@types/jquery/index.d.ts",
|
||||
@@ -701,7 +701,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/jquery"];
|
||||
const typingFiles = [jqueryDTS];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
@@ -720,26 +720,196 @@ namespace ts.projectSystem {
|
||||
checkNumberOfProjects(projectService, { configuredProjects: 1 });
|
||||
checkProjectActualFiles(p, [app.path, jqueryDTS.path]);
|
||||
});
|
||||
|
||||
it("Malformed package.json should be watched", () => {
|
||||
const f = {
|
||||
path: "/a/b/app.js",
|
||||
content: "var x = 1"
|
||||
};
|
||||
const brokenPackageJson = {
|
||||
path: "/a/b/package.json",
|
||||
content: `{ "dependencies": { "co } }`
|
||||
};
|
||||
const fixedPackageJson = {
|
||||
path: brokenPackageJson.path,
|
||||
content: `{ "dependencies": { "commander": "0.0.2" } }`
|
||||
};
|
||||
const cachePath = "/a/cache/";
|
||||
const commander = {
|
||||
path: cachePath + "node_modules/@types/commander/index.d.ts",
|
||||
content: "export let x: number"
|
||||
};
|
||||
const host = createServerHost([f, brokenPackageJson]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/commander"];
|
||||
const typingFiles = [commander];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
}
|
||||
})();
|
||||
const service = createProjectService(host, { typingsInstaller: installer });
|
||||
service.openClientFile(f.path);
|
||||
|
||||
installer.checkPendingCommands([]);
|
||||
|
||||
host.reloadFS([f, fixedPackageJson]);
|
||||
host.triggerFileWatcherCallback(fixedPackageJson.path, /*removed*/ false);
|
||||
// expected one view and one install request
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
|
||||
service.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
checkProjectActualFiles(service.inferredProjects[0], [f.path, commander.path]);
|
||||
});
|
||||
|
||||
it("should install typings for unresolved imports", () => {
|
||||
const file = {
|
||||
path: "/a/b/app.js",
|
||||
content: `
|
||||
import * as fs from "fs";
|
||||
import * as commander from "commander";`
|
||||
};
|
||||
const cachePath = "/a/cache";
|
||||
const node = {
|
||||
path: cachePath + "/node_modules/@types/node/index.d.ts",
|
||||
content: "export let x: number"
|
||||
};
|
||||
const commander = {
|
||||
path: cachePath + "/node_modules/@types/commander/index.d.ts",
|
||||
content: "export let y: string"
|
||||
};
|
||||
const host = createServerHost([file]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: cachePath });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, _args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
const installedTypings = ["@types/node", "@types/commander"];
|
||||
const typingFiles = [node, commander];
|
||||
executeCommand(this, host, installedTypings, typingFiles, requestKind, cb);
|
||||
}
|
||||
})();
|
||||
const service = createProjectService(host, { typingsInstaller: installer });
|
||||
service.openClientFile(file.path);
|
||||
|
||||
service.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
checkProjectActualFiles(service.inferredProjects[0], [file.path]);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest, TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
|
||||
assert.isTrue(host.fileExists(node.path), "typings for 'node' should be created");
|
||||
assert.isTrue(host.fileExists(commander.path), "typings for 'commander' should be created");
|
||||
|
||||
checkProjectActualFiles(service.inferredProjects[0], [file.path, node.path, commander.path]);
|
||||
});
|
||||
|
||||
it("should pick typing names from non-relative unresolved imports", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.js",
|
||||
content: `
|
||||
import * as a from "foo/a/a";
|
||||
import * as b from "foo/a/b";
|
||||
import * as c from "foo/a/c";
|
||||
import * as d from "@bar/router/";
|
||||
import * as e from "@bar/common/shared";
|
||||
import * as e from "@bar/common/apps";
|
||||
import * as f from "./lib"
|
||||
`
|
||||
};
|
||||
|
||||
const host = createServerHost([f1]);
|
||||
const installer = new (class extends Installer {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, _requestId: number, args: string[], _cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
if (requestKind === TI.NpmViewRequest) {
|
||||
// args should have only non-scoped packages - scoped packages are not yet supported
|
||||
assert.deepEqual(args, ["foo"]);
|
||||
}
|
||||
executeCommand(this, host, ["foo"], [], requestKind, cb);
|
||||
}
|
||||
})();
|
||||
const projectService = createProjectService(host, { typingsInstaller: installer });
|
||||
projectService.openClientFile(f1.path);
|
||||
projectService.checkNumberOfProjects({ inferredProjects: 1 });
|
||||
|
||||
const proj = projectService.inferredProjects[0];
|
||||
proj.updateGraph();
|
||||
|
||||
assert.deepEqual(
|
||||
proj.getCachedUnresolvedImportsPerFile_TestOnly().get(<Path>f1.path),
|
||||
["foo", "foo", "foo", "@bar/router", "@bar/common", "@bar/common"]
|
||||
);
|
||||
|
||||
installer.installAll([TI.NpmViewRequest], [TI.NpmInstallRequest]);
|
||||
});
|
||||
|
||||
it("cached unresolved typings are not recomputed if program structure did not change", () => {
|
||||
const host = createServerHost([]);
|
||||
const session = createSession(host);
|
||||
const f = {
|
||||
path: "/a/app.js",
|
||||
content: `
|
||||
import * as fs from "fs";
|
||||
import * as cmd from "commander
|
||||
`
|
||||
};
|
||||
session.executeCommand(<server.protocol.OpenRequest>{
|
||||
seq: 1,
|
||||
type: "request",
|
||||
command: "open",
|
||||
arguments: {
|
||||
file: f.path,
|
||||
fileContent: f.content
|
||||
}
|
||||
});
|
||||
const projectService = session.getProjectService();
|
||||
checkNumberOfProjects(projectService, { inferredProjects: 1 });
|
||||
const proj = projectService.inferredProjects[0];
|
||||
const version1 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
|
||||
|
||||
// make a change that should not affect the structure of the program
|
||||
session.executeCommand(<server.protocol.ChangeRequest>{
|
||||
seq: 2,
|
||||
type: "request",
|
||||
command: "change",
|
||||
arguments: {
|
||||
file: f.path,
|
||||
insertString: "\nlet x = 1;",
|
||||
line: 2,
|
||||
offset: 0,
|
||||
endLine: 2,
|
||||
endOffset: 0
|
||||
}
|
||||
});
|
||||
host.checkTimeoutQueueLength(1);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
const version2 = proj.getCachedUnresolvedImportsPerFile_TestOnly().getVersion();
|
||||
assert.equal(version1, version2, "set of unresolved imports should not change");
|
||||
});
|
||||
});
|
||||
|
||||
describe("Validate package name:", () => {
|
||||
it ("name cannot be too long", () => {
|
||||
it("name cannot be too long", () => {
|
||||
let packageName = "a";
|
||||
for (let i = 0; i < 8; i++) {
|
||||
packageName += packageName;
|
||||
}
|
||||
assert.equal(TI.validatePackageName(packageName), TI.PackageNameValidationResult.NameTooLong);
|
||||
});
|
||||
it ("name cannot start with dot", () => {
|
||||
it("name cannot start with dot", () => {
|
||||
assert.equal(TI.validatePackageName(".foo"), TI.PackageNameValidationResult.NameStartsWithDot);
|
||||
});
|
||||
it ("name cannot start with underscore", () => {
|
||||
it("name cannot start with underscore", () => {
|
||||
assert.equal(TI.validatePackageName("_foo"), TI.PackageNameValidationResult.NameStartsWithUnderscore);
|
||||
});
|
||||
it ("scoped packages not supported", () => {
|
||||
it("scoped packages not supported", () => {
|
||||
assert.equal(TI.validatePackageName("@scope/bar"), TI.PackageNameValidationResult.ScopedPackagesNotSupported);
|
||||
});
|
||||
it ("non URI safe characters are not supported", () => {
|
||||
it("non URI safe characters are not supported", () => {
|
||||
assert.equal(TI.validatePackageName(" scope "), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(TI.validatePackageName("; say ‘Hello from TypeScript!’ #"), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
assert.equal(TI.validatePackageName("a/b/c"), TI.PackageNameValidationResult.NameContainsNonURISafeCharacters);
|
||||
@@ -747,7 +917,7 @@ namespace ts.projectSystem {
|
||||
});
|
||||
|
||||
describe("Invalid package names", () => {
|
||||
it ("should not be installed", () => {
|
||||
it("should not be installed", () => {
|
||||
const f1 = {
|
||||
path: "/a/b/app.js",
|
||||
content: "let x = 1"
|
||||
@@ -766,7 +936,7 @@ namespace ts.projectSystem {
|
||||
constructor() {
|
||||
super(host, { globalTypingsCacheLocation: "/tmp" }, { isEnabled: () => true, writeLine: msg => messages.push(msg) });
|
||||
}
|
||||
executeRequest(requestKind: TI.RequestKind, requestId: number, args: string[], cwd: string, cb: server.typingsInstaller.RequestCompletedAction) {
|
||||
executeRequest() {
|
||||
assert(false, "runCommand should not be invoked");
|
||||
}
|
||||
})();
|
||||
@@ -777,4 +947,35 @@ namespace ts.projectSystem {
|
||||
assert.isTrue(messages.indexOf("Package name '; say ‘Hello from TypeScript!’ #' contains non URI safe characters") > 0, "should find package with invalid name");
|
||||
});
|
||||
});
|
||||
|
||||
describe("discover typings", () => {
|
||||
it("should return node for core modules", () => {
|
||||
const f = {
|
||||
path: "/a/b/app.js",
|
||||
content: ""
|
||||
};
|
||||
const host = createServerHost([f]);
|
||||
const cache = createMap<string>();
|
||||
for (const name of JsTyping.nodeCoreModuleList) {
|
||||
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, [name, "somename"]);
|
||||
assert.deepEqual(result.newTypingNames.sort(), ["node", "somename"]);
|
||||
}
|
||||
});
|
||||
|
||||
it("should use cached locaitons", () => {
|
||||
const f = {
|
||||
path: "/a/b/app.js",
|
||||
content: ""
|
||||
};
|
||||
const node = {
|
||||
path: "/a/b/node.d.ts",
|
||||
content: ""
|
||||
};
|
||||
const host = createServerHost([f, node]);
|
||||
const cache = createMap<string>({ "node": node.path });
|
||||
const result = JsTyping.discoverTypings(host, [f.path], getDirectoryPath(<Path>f.path), /*safeListPath*/ undefined, cache, { enableAutoDiscovery: true }, ["fs", "bar"]);
|
||||
assert.deepEqual(result.cachedTypingPaths, [node.path]);
|
||||
assert.deepEqual(result.newTypingNames, ["bar"]);
|
||||
});
|
||||
});
|
||||
}
|
||||
Vendored
+16
-12
@@ -1679,6 +1679,7 @@ interface CSSStyleDeclaration {
|
||||
writingMode: string | null;
|
||||
zIndex: string | null;
|
||||
zoom: string | null;
|
||||
resize: string | null;
|
||||
getPropertyPriority(propertyName: string): string;
|
||||
getPropertyValue(propertyName: string): string;
|
||||
item(index: number): string;
|
||||
@@ -1748,6 +1749,7 @@ declare var CanvasGradient: {
|
||||
}
|
||||
|
||||
interface CanvasPattern {
|
||||
setTransform(matrix: SVGMatrix): void;
|
||||
}
|
||||
|
||||
declare var CanvasPattern: {
|
||||
@@ -2173,7 +2175,7 @@ interface DataTransfer {
|
||||
effectAllowed: string;
|
||||
readonly files: FileList;
|
||||
readonly items: DataTransferItemList;
|
||||
readonly types: DOMStringList;
|
||||
readonly types: string[];
|
||||
clearData(format?: string): boolean;
|
||||
getData(format: string): string;
|
||||
setData(format: string, data: string): boolean;
|
||||
@@ -7584,7 +7586,7 @@ declare var IDBCursorWithValue: {
|
||||
|
||||
interface IDBDatabase extends EventTarget {
|
||||
readonly name: string;
|
||||
readonly objectStoreNames: DOMStringList;
|
||||
readonly objectStoreNames: string[];
|
||||
onabort: (this: this, ev: Event) => any;
|
||||
onerror: (this: this, ev: ErrorEvent) => any;
|
||||
version: number;
|
||||
@@ -7650,7 +7652,7 @@ declare var IDBKeyRange: {
|
||||
}
|
||||
|
||||
interface IDBObjectStore {
|
||||
readonly indexNames: DOMStringList;
|
||||
readonly indexNames: string[];
|
||||
keyPath: string | string[];
|
||||
readonly name: string;
|
||||
readonly transaction: IDBTransaction;
|
||||
@@ -8602,7 +8604,7 @@ interface MouseEvent extends UIEvent {
|
||||
readonly x: number;
|
||||
readonly y: number;
|
||||
getModifierState(keyArg: string): boolean;
|
||||
initMouseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget): void;
|
||||
initMouseEvent(typeArg: string, canBubbleArg: boolean, cancelableArg: boolean, viewArg: Window, detailArg: number, screenXArg: number, screenYArg: number, clientXArg: number, clientYArg: number, ctrlKeyArg: boolean, altKeyArg: boolean, shiftKeyArg: boolean, metaKeyArg: boolean, buttonArg: number, relatedTargetArg: EventTarget | null): void;
|
||||
}
|
||||
|
||||
declare var MouseEvent: {
|
||||
@@ -8715,6 +8717,7 @@ interface Navigator extends Object, NavigatorID, NavigatorOnLine, NavigatorConte
|
||||
readonly plugins: PluginArray;
|
||||
readonly pointerEnabled: boolean;
|
||||
readonly webdriver: boolean;
|
||||
readonly hardwareConcurrency: number;
|
||||
getGamepads(): Gamepad[];
|
||||
javaEnabled(): boolean;
|
||||
msLaunchUri(uri: string, successCallback?: MSLaunchUriCallback, noHandlerCallback?: MSLaunchUriCallback): void;
|
||||
@@ -8732,18 +8735,18 @@ interface Node extends EventTarget {
|
||||
readonly attributes: NamedNodeMap;
|
||||
readonly baseURI: string | null;
|
||||
readonly childNodes: NodeList;
|
||||
readonly firstChild: Node;
|
||||
readonly lastChild: Node;
|
||||
readonly firstChild: Node | null;
|
||||
readonly lastChild: Node | null;
|
||||
readonly localName: string | null;
|
||||
readonly namespaceURI: string | null;
|
||||
readonly nextSibling: Node;
|
||||
readonly nextSibling: Node | null;
|
||||
readonly nodeName: string;
|
||||
readonly nodeType: number;
|
||||
nodeValue: string | null;
|
||||
readonly ownerDocument: Document;
|
||||
readonly parentElement: HTMLElement;
|
||||
readonly parentNode: Node;
|
||||
readonly previousSibling: Node;
|
||||
readonly parentElement: HTMLElement | null;
|
||||
readonly parentNode: Node | null;
|
||||
readonly previousSibling: Node | null;
|
||||
textContent: string | null;
|
||||
appendChild(newChild: Node): Node;
|
||||
cloneNode(deep?: boolean): Node;
|
||||
@@ -12853,7 +12856,7 @@ interface Window extends EventTarget, WindowTimers, WindowSessionStorage, Window
|
||||
readonly devicePixelRatio: number;
|
||||
readonly doNotTrack: string;
|
||||
readonly document: Document;
|
||||
event: Event;
|
||||
event: Event | undefined;
|
||||
readonly external: External;
|
||||
readonly frameElement: Element;
|
||||
readonly frames: Window;
|
||||
@@ -13155,6 +13158,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
|
||||
readonly upload: XMLHttpRequestUpload;
|
||||
withCredentials: boolean;
|
||||
msCaching?: string;
|
||||
readonly responseURL: string;
|
||||
abort(): void;
|
||||
getAllResponseHeaders(): string;
|
||||
getResponseHeader(header: string): string | null;
|
||||
@@ -14301,7 +14305,7 @@ declare var defaultStatus: string;
|
||||
declare var devicePixelRatio: number;
|
||||
declare var doNotTrack: string;
|
||||
declare var document: Document;
|
||||
declare var event: Event;
|
||||
declare var event: Event | undefined;
|
||||
declare var external: External;
|
||||
declare var frameElement: Element;
|
||||
declare var frames: Window;
|
||||
|
||||
Vendored
+4
-4
@@ -205,13 +205,13 @@ interface NumberConstructor {
|
||||
* number. Only finite values of the type number, result in true.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isFinite(number: number): boolean;
|
||||
isFinite(value: any): value is number;
|
||||
|
||||
/**
|
||||
* Returns true if the value passed is an integer, false otherwise.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isInteger(number: number): boolean;
|
||||
isInteger(value: any): value is number;
|
||||
|
||||
/**
|
||||
* Returns a Boolean value that indicates whether a value is the reserved value NaN (not a
|
||||
@@ -219,13 +219,13 @@ interface NumberConstructor {
|
||||
* to a number. Only values of the type number, that are also NaN, result in true.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isNaN(number: number): boolean;
|
||||
isNaN(value: any): value is number;
|
||||
|
||||
/**
|
||||
* Returns true if the value passed is a safe integer.
|
||||
* @param number A numeric value.
|
||||
*/
|
||||
isSafeInteger(number: number): boolean;
|
||||
isSafeInteger(value: any): value is number;
|
||||
|
||||
/**
|
||||
* The value of the largest integer n such that n and n + 1 are both exactly representable as
|
||||
|
||||
Vendored
+4
-2
@@ -341,7 +341,7 @@ declare var IDBCursorWithValue: {
|
||||
|
||||
interface IDBDatabase extends EventTarget {
|
||||
readonly name: string;
|
||||
readonly objectStoreNames: DOMStringList;
|
||||
readonly objectStoreNames: string[];
|
||||
onabort: (this: this, ev: Event) => any;
|
||||
onerror: (this: this, ev: ErrorEvent) => any;
|
||||
version: number;
|
||||
@@ -407,7 +407,7 @@ declare var IDBKeyRange: {
|
||||
}
|
||||
|
||||
interface IDBObjectStore {
|
||||
readonly indexNames: DOMStringList;
|
||||
readonly indexNames: string[];
|
||||
keyPath: string | string[];
|
||||
readonly name: string;
|
||||
readonly transaction: IDBTransaction;
|
||||
@@ -740,6 +740,7 @@ interface XMLHttpRequest extends EventTarget, XMLHttpRequestEventTarget {
|
||||
readonly upload: XMLHttpRequestUpload;
|
||||
withCredentials: boolean;
|
||||
msCaching?: string;
|
||||
readonly responseURL: string;
|
||||
abort(): void;
|
||||
getAllResponseHeaders(): string;
|
||||
getResponseHeader(header: string): string | null;
|
||||
@@ -902,6 +903,7 @@ declare var WorkerLocation: {
|
||||
}
|
||||
|
||||
interface WorkerNavigator extends Object, NavigatorID, NavigatorOnLine {
|
||||
readonly hardwareConcurrency: number;
|
||||
addEventListener(type: string, listener: EventListenerOrEventListenerObject, useCapture?: boolean): void;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
protected forEachFileInfo(action: (fileInfo: T) => any) {
|
||||
this.fileInfos.forEachValue((path: Path, value: T) => action(value));
|
||||
this.fileInfos.forEachValue((_path, value) => action(value));
|
||||
}
|
||||
|
||||
abstract getFilesAffectedBy(scriptInfo: ScriptInfo): string[];
|
||||
|
||||
@@ -10,7 +10,10 @@
|
||||
"stripInternal": true,
|
||||
"types": [
|
||||
"node"
|
||||
]
|
||||
],
|
||||
"target": "es5",
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true
|
||||
},
|
||||
"files": [
|
||||
"cancellationToken.ts"
|
||||
|
||||
+49
-48
@@ -5,11 +5,6 @@ namespace ts.server {
|
||||
writeMessage(message: string): void;
|
||||
}
|
||||
|
||||
interface CompletionEntry extends CompletionInfo {
|
||||
fileName: string;
|
||||
position: number;
|
||||
}
|
||||
|
||||
interface RenameEntry extends RenameInfo {
|
||||
fileName: string;
|
||||
position: number;
|
||||
@@ -246,8 +241,8 @@ namespace ts.server {
|
||||
return response.body[0];
|
||||
}
|
||||
|
||||
getCompletionEntrySymbol(fileName: string, position: number, entryName: string): Symbol {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getCompletionEntrySymbol(_fileName: string, _position: number, _entryName: string): Symbol {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getNavigateToItems(searchValue: string): NavigateToItem[] {
|
||||
@@ -278,7 +273,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getFormattingEditsForRange(fileName: string, start: number, end: number, options: ts.FormatCodeOptions): ts.TextChange[] {
|
||||
getFormattingEditsForRange(fileName: string, start: number, end: number, _options: ts.FormatCodeOptions): ts.TextChange[] {
|
||||
const startLineOffset = this.positionToOneBasedLineOffset(fileName, start);
|
||||
const endLineOffset = this.positionToOneBasedLineOffset(fileName, end);
|
||||
const args: protocol.FormatRequestArgs = {
|
||||
@@ -300,7 +295,7 @@ namespace ts.server {
|
||||
return this.getFormattingEditsForRange(fileName, 0, this.host.getScriptSnapshot(fileName).getLength(), options);
|
||||
}
|
||||
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, options: FormatCodeOptions): ts.TextChange[] {
|
||||
getFormattingEditsAfterKeystroke(fileName: string, position: number, key: string, _options: FormatCodeOptions): ts.TextChange[] {
|
||||
const lineOffset = this.positionToOneBasedLineOffset(fileName, position);
|
||||
const args: protocol.FormatOnKeyRequestArgs = {
|
||||
file: fileName,
|
||||
@@ -390,7 +385,7 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
findReferences(fileName: string, position: number): ReferencedSymbol[] {
|
||||
findReferences(_fileName: string, _position: number): ReferencedSymbol[] {
|
||||
// Not yet implemented.
|
||||
return [];
|
||||
}
|
||||
@@ -419,44 +414,50 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getEmitOutput(fileName: string): EmitOutput {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getEmitOutput(_fileName: string): EmitOutput {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getSyntacticDiagnostics(fileName: string): Diagnostic[] {
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName };
|
||||
const args: protocol.SyntacticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true };
|
||||
|
||||
const request = this.processRequest<protocol.SyntacticDiagnosticsSyncRequest>(CommandNames.SyntacticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SyntacticDiagnosticsSyncResponse>(request);
|
||||
|
||||
return (<protocol.Diagnostic[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
return (<protocol.DiagnosticWithLinePosition[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
}
|
||||
|
||||
getSemanticDiagnostics(fileName: string): Diagnostic[] {
|
||||
const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName };
|
||||
const args: protocol.SemanticDiagnosticsSyncRequestArgs = { file: fileName, includeLinePosition: true };
|
||||
|
||||
const request = this.processRequest<protocol.SemanticDiagnosticsSyncRequest>(CommandNames.SemanticDiagnosticsSync, args);
|
||||
const response = this.processResponse<protocol.SemanticDiagnosticsSyncResponse>(request);
|
||||
|
||||
return (<protocol.Diagnostic[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
return (<protocol.DiagnosticWithLinePosition[]>response.body).map(entry => this.convertDiagnostic(entry, fileName));
|
||||
}
|
||||
|
||||
convertDiagnostic(entry: protocol.Diagnostic, fileName: string): Diagnostic {
|
||||
const start = this.lineOffsetToPosition(fileName, entry.start);
|
||||
const end = this.lineOffsetToPosition(fileName, entry.end);
|
||||
convertDiagnostic(entry: protocol.DiagnosticWithLinePosition, _fileName: string): Diagnostic {
|
||||
let category: DiagnosticCategory;
|
||||
for (const id in DiagnosticCategory) {
|
||||
if (typeof id === "string" && entry.category === id.toLowerCase()) {
|
||||
category = (<any>DiagnosticCategory)[id];
|
||||
}
|
||||
}
|
||||
|
||||
Debug.assert(category !== undefined, "convertDiagnostic: category should not be undefined");
|
||||
|
||||
return {
|
||||
file: undefined,
|
||||
start: start,
|
||||
length: end - start,
|
||||
messageText: entry.text,
|
||||
category: undefined,
|
||||
start: entry.start,
|
||||
length: entry.length,
|
||||
messageText: entry.message,
|
||||
category: category,
|
||||
code: entry.code
|
||||
};
|
||||
}
|
||||
|
||||
getCompilerOptionsDiagnostics(): Diagnostic[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getRenameInfo(fileName: string, position: number, findInStrings?: boolean, findInComments?: boolean): RenameInfo {
|
||||
@@ -560,12 +561,12 @@ namespace ts.server {
|
||||
this.lineOffsetToPosition(fileName, span.end, lineMap));
|
||||
}
|
||||
|
||||
getNameOrDottedNameSpan(fileName: string, startPos: number, endPos: number): TextSpan {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getNameOrDottedNameSpan(_fileName: string, _startPos: number, _endPos: number): TextSpan {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getBreakpointStatementAtPosition(fileName: string, position: number): TextSpan {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getBreakpointStatementAtPosition(_fileName: string, _position: number): TextSpan {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getSignatureHelpItems(fileName: string, position: number): SignatureHelpItems {
|
||||
@@ -654,20 +655,20 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
getOutliningSpans(fileName: string): OutliningSpan[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getOutliningSpans(_fileName: string): OutliningSpan[] {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getTodoComments(fileName: string, descriptors: TodoCommentDescriptor[]): TodoComment[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getTodoComments(_fileName: string, _descriptors: TodoCommentDescriptor[]): TodoComment[] {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getDocCommentTemplateAtPosition(_fileName: string, _position: number): TextInsertion {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
isValidBraceCompletionAtPosition(_fileName: string, _position: number, _openingBrace: number): boolean {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: number[]): CodeAction[] {
|
||||
@@ -733,35 +734,35 @@ namespace ts.server {
|
||||
});
|
||||
}
|
||||
|
||||
getIndentationAtPosition(fileName: string, position: number, options: EditorOptions): number {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getIndentationAtPosition(_fileName: string, _position: number, _options: EditorOptions): number {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getSyntacticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getSyntacticClassifications(_fileName: string, _span: TextSpan): ClassifiedSpan[] {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getSemanticClassifications(fileName: string, span: TextSpan): ClassifiedSpan[] {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getSemanticClassifications(_fileName: string, _span: TextSpan): ClassifiedSpan[] {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getEncodedSyntacticClassifications(fileName: string, span: TextSpan): Classifications {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getEncodedSyntacticClassifications(_fileName: string, _span: TextSpan): Classifications {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getEncodedSemanticClassifications(fileName: string, span: TextSpan): Classifications {
|
||||
throw new Error("Not Implemented Yet.");
|
||||
getEncodedSemanticClassifications(_fileName: string, _span: TextSpan): Classifications {
|
||||
return notImplemented();
|
||||
}
|
||||
|
||||
getProgram(): Program {
|
||||
throw new Error("SourceFile objects are not serializable through the server protocol.");
|
||||
}
|
||||
|
||||
getNonBoundSourceFile(fileName: string): SourceFile {
|
||||
getNonBoundSourceFile(_fileName: string): SourceFile {
|
||||
throw new Error("SourceFile objects are not serializable through the server protocol.");
|
||||
}
|
||||
|
||||
getSourceFile(fileName: string): SourceFile {
|
||||
getSourceFile(_fileName: string): SourceFile {
|
||||
throw new Error("SourceFile objects are not serializable through the server protocol.");
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,68 @@ namespace ts.server {
|
||||
(event: ProjectServiceEvent): void;
|
||||
}
|
||||
|
||||
function prepareConvertersForEnumLikeCompilerOptions(commandLineOptions: CommandLineOption[]): Map<Map<number>> {
|
||||
const map: Map<Map<number>> = createMap<Map<number>>();
|
||||
for (const option of commandLineOptions) {
|
||||
if (typeof option.type === "object") {
|
||||
const optionMap = <Map<number>>option.type;
|
||||
// verify that map contains only numbers
|
||||
for (const id in optionMap) {
|
||||
Debug.assert(typeof optionMap[id] === "number");
|
||||
}
|
||||
map[option.name] = optionMap;
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
const compilerOptionConverters = prepareConvertersForEnumLikeCompilerOptions(optionDeclarations);
|
||||
const indentStyle = createMap({
|
||||
"none": IndentStyle.None,
|
||||
"block": IndentStyle.Block,
|
||||
"smart": IndentStyle.Smart
|
||||
});
|
||||
|
||||
export function convertFormatOptions(protocolOptions: protocol.FormatCodeSettings): FormatCodeSettings {
|
||||
if (typeof protocolOptions.indentStyle === "string") {
|
||||
protocolOptions.indentStyle = indentStyle[protocolOptions.indentStyle.toLowerCase()];
|
||||
Debug.assert(protocolOptions.indentStyle !== undefined);
|
||||
}
|
||||
return <any>protocolOptions;
|
||||
}
|
||||
|
||||
export function convertCompilerOptions(protocolOptions: protocol.ExternalProjectCompilerOptions): CompilerOptions & protocol.CompileOnSaveMixin {
|
||||
for (const id in compilerOptionConverters) {
|
||||
const propertyValue = protocolOptions[id];
|
||||
if (typeof propertyValue === "string") {
|
||||
const mappedValues = compilerOptionConverters[id];
|
||||
protocolOptions[id] = mappedValues[propertyValue.toLowerCase()];
|
||||
}
|
||||
}
|
||||
return <any>protocolOptions;
|
||||
}
|
||||
|
||||
export function tryConvertScriptKindName(scriptKindName: protocol.ScriptKindName | ScriptKind): ScriptKind {
|
||||
return typeof scriptKindName === "string"
|
||||
? convertScriptKindName(scriptKindName)
|
||||
: scriptKindName;
|
||||
}
|
||||
|
||||
export function convertScriptKindName(scriptKindName: protocol.ScriptKindName) {
|
||||
switch (scriptKindName) {
|
||||
case "JS":
|
||||
return ScriptKind.JS;
|
||||
case "JSX":
|
||||
return ScriptKind.JSX;
|
||||
case "TS":
|
||||
return ScriptKind.TS;
|
||||
case "TSX":
|
||||
return ScriptKind.TSX;
|
||||
default:
|
||||
return ScriptKind.Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This helper function processes a list of projects and return the concatenated, sortd and deduplicated output of processing each project.
|
||||
*/
|
||||
@@ -63,7 +125,7 @@ namespace ts.server {
|
||||
|
||||
const externalFilePropertyReader: FilePropertyReader<protocol.ExternalFile> = {
|
||||
getFileName: x => x.fileName,
|
||||
getScriptKind: x => x.scriptKind,
|
||||
getScriptKind: x => tryConvertScriptKindName(x.scriptKind),
|
||||
hasMixedContent: x => x.hasMixedContent
|
||||
};
|
||||
|
||||
@@ -214,6 +276,10 @@ namespace ts.server {
|
||||
this.ensureInferredProjectsUpToDate();
|
||||
}
|
||||
|
||||
getCompilerOptionsForInferredProjects() {
|
||||
return this.compilerOptionsForInferredProjects;
|
||||
}
|
||||
|
||||
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings): void {
|
||||
const project = this.findProject(response.projectName);
|
||||
if (!project) {
|
||||
@@ -221,20 +287,23 @@ namespace ts.server {
|
||||
}
|
||||
switch (response.kind) {
|
||||
case "set":
|
||||
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.typings);
|
||||
project.updateGraph();
|
||||
this.typingsCache.updateTypingsForProject(response.projectName, response.compilerOptions, response.typingOptions, response.unresolvedImports, response.typings);
|
||||
break;
|
||||
case "invalidate":
|
||||
this.typingsCache.invalidateCachedTypingsForProject(project);
|
||||
this.typingsCache.deleteTypingsForProject(response.projectName);
|
||||
break;
|
||||
}
|
||||
project.updateGraph();
|
||||
}
|
||||
|
||||
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions): void {
|
||||
this.compilerOptionsForInferredProjects = projectCompilerOptions;
|
||||
this.compilerOptionsForInferredProjects = convertCompilerOptions(projectCompilerOptions);
|
||||
// always set 'allowNonTsExtensions' for inferred projects since user cannot configure it from the outside
|
||||
// previously we did not expose a way for user to change these settings and this option was enabled by default
|
||||
this.compilerOptionsForInferredProjects.allowNonTsExtensions = true;
|
||||
this.compileOnSaveForInferredProjects = projectCompilerOptions.compileOnSave;
|
||||
for (const proj of this.inferredProjects) {
|
||||
proj.setCompilerOptions(projectCompilerOptions);
|
||||
proj.setCompilerOptions(this.compilerOptionsForInferredProjects);
|
||||
proj.compileOnSaveEnabled = projectCompilerOptions.compileOnSave;
|
||||
}
|
||||
this.updateProjectGraphs(this.inferredProjects);
|
||||
@@ -744,12 +813,13 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
private createAndAddExternalProject(projectFileName: string, files: protocol.ExternalFile[], options: protocol.ExternalProjectCompilerOptions, typingOptions: TypingOptions) {
|
||||
const compilerOptions = convertCompilerOptions(options);
|
||||
const project = new ExternalProject(
|
||||
projectFileName,
|
||||
this,
|
||||
this.documentRegistry,
|
||||
options,
|
||||
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(options, files, externalFilePropertyReader),
|
||||
compilerOptions,
|
||||
/*languageServiceEnabled*/ !this.exceededTotalSizeLimitForNonTsFiles(compilerOptions, files, externalFilePropertyReader),
|
||||
options.compileOnSave === undefined ? true : options.compileOnSave);
|
||||
|
||||
this.addFilesToProjectAndUpdateGraph(project, files, externalFilePropertyReader, /*clientFileName*/ undefined, typingOptions, /*configFileErrors*/ undefined);
|
||||
@@ -941,7 +1011,7 @@ namespace ts.server {
|
||||
const useExistingProject = this.useSingleInferredProject && this.inferredProjects.length;
|
||||
const project = useExistingProject
|
||||
? this.inferredProjects[0]
|
||||
: new InferredProject(this, this.documentRegistry, /*languageServiceEnabled*/ true, this.compilerOptionsForInferredProjects, /*compileOnSaveEnabled*/ this.compileOnSaveForInferredProjects);
|
||||
: new InferredProject(this, this.documentRegistry, /*languageServiceEnabled*/ true, this.compilerOptionsForInferredProjects);
|
||||
|
||||
project.addRoot(root);
|
||||
|
||||
@@ -1018,7 +1088,7 @@ namespace ts.server {
|
||||
if (args.file) {
|
||||
const info = this.getScriptInfoForNormalizedPath(toNormalizedPath(args.file));
|
||||
if (info) {
|
||||
info.setFormatOptions(args.formatOptions);
|
||||
info.setFormatOptions(convertFormatOptions(args.formatOptions));
|
||||
this.logger.info(`Host configuration update for file ${args.file}`);
|
||||
}
|
||||
}
|
||||
@@ -1028,7 +1098,7 @@ namespace ts.server {
|
||||
this.logger.info(`Host information ${args.hostInfo}`);
|
||||
}
|
||||
if (args.formatOptions) {
|
||||
mergeMaps(this.hostConfiguration.formatCodeOptions, args.formatOptions);
|
||||
mergeMaps(this.hostConfiguration.formatCodeOptions, convertFormatOptions(args.formatOptions));
|
||||
this.logger.info("Format host information updated");
|
||||
}
|
||||
}
|
||||
@@ -1142,7 +1212,7 @@ namespace ts.server {
|
||||
const scriptInfo = this.getScriptInfo(file.fileName);
|
||||
Debug.assert(!scriptInfo || !scriptInfo.isOpen);
|
||||
const normalizedPath = scriptInfo ? scriptInfo.fileName : toNormalizedPath(file.fileName);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, file.scriptKind, file.hasMixedContent);
|
||||
this.openClientFileWithNormalizedPath(normalizedPath, file.content, tryConvertScriptKindName(file.scriptKind), file.hasMixedContent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1235,7 +1305,7 @@ namespace ts.server {
|
||||
if (externalProject) {
|
||||
if (!tsConfigFiles) {
|
||||
// external project already exists and not config files were added - update the project and return;
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, proj.options, proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
|
||||
this.updateNonInferredProject(externalProject, proj.rootFiles, externalFilePropertyReader, convertCompilerOptions(proj.options), proj.typingOptions, proj.options.compileOnSave, /*configFileErrors*/ undefined);
|
||||
return;
|
||||
}
|
||||
// some config files were added to external project (that previously were not there)
|
||||
|
||||
+62
-38
@@ -5,59 +5,60 @@
|
||||
namespace ts.server {
|
||||
export class LSHost implements ts.LanguageServiceHost, ModuleResolutionHost, ServerLanguageServiceHost {
|
||||
private compilationSettings: ts.CompilerOptions;
|
||||
private readonly resolvedModuleNames: ts.FileMap<Map<ResolvedModuleWithFailedLookupLocations>>;
|
||||
private readonly resolvedTypeReferenceDirectives: ts.FileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>;
|
||||
private readonly resolvedModuleNames= createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
private readonly resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
private readonly getCanonicalFileName: (fileName: string) => string;
|
||||
|
||||
private filesWithChangedSetOfUnresolvedImports: Path[];
|
||||
|
||||
private readonly resolveModuleName: typeof resolveModuleName;
|
||||
readonly trace: (s: string) => void;
|
||||
|
||||
constructor(private readonly host: ServerHost, private readonly project: Project, private readonly cancellationToken: HostCancellationToken) {
|
||||
this.getCanonicalFileName = ts.createGetCanonicalFileName(this.host.useCaseSensitiveFileNames);
|
||||
this.resolvedModuleNames = createFileMap<Map<ResolvedModuleWithFailedLookupLocations>>();
|
||||
this.resolvedTypeReferenceDirectives = createFileMap<Map<ResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
|
||||
if (host.trace) {
|
||||
this.trace = s => host.trace(s);
|
||||
}
|
||||
|
||||
this.resolveModuleName = (moduleName, containingFile, compilerOptions, host) => {
|
||||
const globalCache = this.project.getTypingOptions().enableAutoDiscovery
|
||||
? this.project.projectService.typingsInstaller.globalTypingsCacheLocation
|
||||
: undefined;
|
||||
const primaryResult = resolveModuleName(moduleName, containingFile, compilerOptions, host);
|
||||
if (primaryResult.resolvedModule) {
|
||||
// return result immediately only if it is .ts, .tsx or .d.ts
|
||||
// return result immediately only if it is .ts, .tsx or .d.ts
|
||||
if (!(primaryResult.resolvedModule && extensionIsTypeScript(primaryResult.resolvedModule.extension)) && globalCache !== undefined) {
|
||||
// otherwise try to load typings from @types
|
||||
if (fileExtensionIsAny(primaryResult.resolvedModule.resolvedFileName, supportedTypeScriptExtensions)) {
|
||||
return primaryResult;
|
||||
|
||||
// create different collection of failed lookup locations for second pass
|
||||
// if it will fail and we've already found something during the first pass - we don't want to pollute its results
|
||||
const { resolvedModule, failedLookupLocations } = loadModuleFromGlobalCache(moduleName, this.project.getProjectName(), compilerOptions, host, globalCache);
|
||||
if (resolvedModule) {
|
||||
return { resolvedModule, failedLookupLocations: primaryResult.failedLookupLocations.concat(failedLookupLocations) };
|
||||
}
|
||||
}
|
||||
// create different collection of failed lookup locations for second pass
|
||||
// if it will fail and we've already found something during the first pass - we don't want to pollute its results
|
||||
const secondaryLookupFailedLookupLocations: string[] = [];
|
||||
const globalCache = this.project.projectService.typingsInstaller.globalTypingsCacheLocation;
|
||||
if (this.project.getTypingOptions().enableAutoDiscovery && globalCache) {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Auto_discovery_for_typings_is_enabled_in_project_0_Running_extra_resolution_pass_for_module_1_using_cache_location_2, this.project.getProjectName(), moduleName, globalCache);
|
||||
}
|
||||
const state: ModuleResolutionState = { compilerOptions, host, skipTsx: false, traceEnabled };
|
||||
const resolvedName = loadModuleFromNodeModules(moduleName, globalCache, secondaryLookupFailedLookupLocations, state, /*checkOneLevel*/ true);
|
||||
if (resolvedName) {
|
||||
return createResolvedModule(resolvedName, /*isExternalLibraryImport*/ true, primaryResult.failedLookupLocations.concat(secondaryLookupFailedLookupLocations));
|
||||
}
|
||||
}
|
||||
if (!primaryResult.resolvedModule && secondaryLookupFailedLookupLocations.length) {
|
||||
primaryResult.failedLookupLocations = primaryResult.failedLookupLocations.concat(secondaryLookupFailedLookupLocations);
|
||||
}
|
||||
return primaryResult;
|
||||
};
|
||||
}
|
||||
|
||||
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R extends { resolvedFileName?: string }>(
|
||||
public startRecordingFilesWithChangedResolutions() {
|
||||
this.filesWithChangedSetOfUnresolvedImports = [];
|
||||
}
|
||||
|
||||
public finishRecordingFilesWithChangedResolutions() {
|
||||
const collected = this.filesWithChangedSetOfUnresolvedImports;
|
||||
this.filesWithChangedSetOfUnresolvedImports = undefined;
|
||||
return collected;
|
||||
}
|
||||
|
||||
private resolveNamesWithLocalCache<T extends { failedLookupLocations: string[] }, R>(
|
||||
names: string[],
|
||||
containingFile: string,
|
||||
cache: ts.FileMap<Map<T>>,
|
||||
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => T,
|
||||
getResult: (s: T) => R): R[] {
|
||||
getResult: (s: T) => R,
|
||||
getResultFileName: (result: R) => string | undefined,
|
||||
logChanges: boolean): R[] {
|
||||
|
||||
const path = toPath(containingFile, this.host.getCurrentDirectory(), this.getCanonicalFileName);
|
||||
const currentResolutionsInFile = cache.get(path);
|
||||
@@ -79,6 +80,11 @@ namespace ts.server {
|
||||
else {
|
||||
newResolutions[name] = resolution = loader(name, containingFile, compilerOptions, this);
|
||||
}
|
||||
if (logChanges && this.filesWithChangedSetOfUnresolvedImports && !resolutionIsEqualTo(existingResolution, resolution)) {
|
||||
this.filesWithChangedSetOfUnresolvedImports.push(path);
|
||||
// reset log changes to avoid recording the same file multiple times
|
||||
logChanges = false;
|
||||
}
|
||||
}
|
||||
|
||||
ts.Debug.assert(resolution !== undefined);
|
||||
@@ -90,6 +96,24 @@ namespace ts.server {
|
||||
cache.set(path, newResolutions);
|
||||
return resolvedModules;
|
||||
|
||||
function resolutionIsEqualTo(oldResolution: T, newResolution: T): boolean {
|
||||
if (oldResolution === newResolution) {
|
||||
return true;
|
||||
}
|
||||
if (!oldResolution || !newResolution) {
|
||||
return false;
|
||||
}
|
||||
const oldResult = getResult(oldResolution);
|
||||
const newResult = getResult(newResolution);
|
||||
if (oldResult === newResult) {
|
||||
return true;
|
||||
}
|
||||
if (!oldResult || !newResult) {
|
||||
return false;
|
||||
}
|
||||
return getResultFileName(oldResult) === getResultFileName(newResult);
|
||||
}
|
||||
|
||||
function moduleResolutionIsValid(resolution: T): boolean {
|
||||
if (!resolution) {
|
||||
return false;
|
||||
@@ -97,10 +121,7 @@ namespace ts.server {
|
||||
|
||||
const result = getResult(resolution);
|
||||
if (result) {
|
||||
if (result.resolvedFileName && result.resolvedFileName === lastDeletedFileName) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return getResultFileName(result) !== lastDeletedFileName;
|
||||
}
|
||||
|
||||
// consider situation if we have no candidate locations as valid resolution.
|
||||
@@ -126,11 +147,13 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
return this.resolveNamesWithLocalCache(typeDirectiveNames, containingFile, this.resolvedTypeReferenceDirectives, resolveTypeReferenceDirective, m => m.resolvedTypeReferenceDirective);
|
||||
return this.resolveNamesWithLocalCache(typeDirectiveNames, containingFile, this.resolvedTypeReferenceDirectives, resolveTypeReferenceDirective,
|
||||
m => m.resolvedTypeReferenceDirective, r => r.resolvedFileName, /*logChanges*/ false);
|
||||
}
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModule[] {
|
||||
return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, this.resolveModuleName, m => m.resolvedModule);
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string): ResolvedModuleFull[] {
|
||||
return this.resolveNamesWithLocalCache(moduleNames, containingFile, this.resolvedModuleNames, this.resolveModuleName,
|
||||
m => m.resolvedModule, r => r.resolvedFileName, /*logChanges*/ true);
|
||||
}
|
||||
|
||||
getDefaultLibFileName() {
|
||||
@@ -197,10 +220,11 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
setCompilationSettings(opt: ts.CompilerOptions) {
|
||||
if (changesAffectModuleResolution(this.compilationSettings, opt)) {
|
||||
this.resolvedModuleNames.clear();
|
||||
this.resolvedTypeReferenceDirectives.clear();
|
||||
}
|
||||
this.compilationSettings = opt;
|
||||
// conservatively assume that changing compiler options might affect module resolution strategy
|
||||
this.resolvedModuleNames.clear();
|
||||
this.resolvedTypeReferenceDirectives.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
+111
-7
@@ -62,12 +62,43 @@ namespace ts.server {
|
||||
projectErrors: Diagnostic[];
|
||||
}
|
||||
|
||||
export class UnresolvedImportsMap {
|
||||
readonly perFileMap = createFileMap<ReadonlyArray<string>>();
|
||||
private version = 0;
|
||||
|
||||
public clear() {
|
||||
this.perFileMap.clear();
|
||||
this.version = 0;
|
||||
}
|
||||
|
||||
public getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public remove(path: Path) {
|
||||
this.perFileMap.remove(path);
|
||||
this.version++;
|
||||
}
|
||||
|
||||
public get(path: Path) {
|
||||
return this.perFileMap.get(path);
|
||||
}
|
||||
|
||||
public set(path: Path, value: ReadonlyArray<string>) {
|
||||
this.perFileMap.set(path, value);
|
||||
this.version++;
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Project {
|
||||
private rootFiles: ScriptInfo[] = [];
|
||||
private rootFilesMap: FileMap<ScriptInfo> = createFileMap<ScriptInfo>();
|
||||
private lsHost: ServerLanguageServiceHost;
|
||||
private program: ts.Program;
|
||||
|
||||
private cachedUnresolvedImportsPerFile = new UnresolvedImportsMap();
|
||||
private lastCachedUnresolvedImportsList: SortedReadonlyArray<string>;
|
||||
|
||||
private languageService: LanguageService;
|
||||
builder: Builder;
|
||||
/**
|
||||
@@ -91,7 +122,7 @@ namespace ts.server {
|
||||
*/
|
||||
private projectStateVersion = 0;
|
||||
|
||||
private typingFiles: TypingsArray;
|
||||
private typingFiles: SortedReadonlyArray<string>;
|
||||
|
||||
protected projectErrors: Diagnostic[];
|
||||
|
||||
@@ -107,6 +138,10 @@ namespace ts.server {
|
||||
return hasOneOrMoreJsAndNoTsFiles(this);
|
||||
}
|
||||
|
||||
public getCachedUnresolvedImportsPerFile_TestOnly() {
|
||||
return this.cachedUnresolvedImportsPerFile;
|
||||
}
|
||||
|
||||
constructor(
|
||||
readonly projectKind: ProjectKind,
|
||||
readonly projectService: ProjectService,
|
||||
@@ -126,6 +161,10 @@ namespace ts.server {
|
||||
this.compilerOptions.allowNonTsExtensions = true;
|
||||
}
|
||||
|
||||
if (this.projectKind === ProjectKind.Inferred) {
|
||||
this.compilerOptions.noEmitOverwritenFiles = true;
|
||||
}
|
||||
|
||||
if (languageServiceEnabled) {
|
||||
this.enableLanguageService();
|
||||
}
|
||||
@@ -326,6 +365,7 @@ namespace ts.server {
|
||||
removeFile(info: ScriptInfo, detachFromProject = true) {
|
||||
this.removeRootFileIfNecessary(info);
|
||||
this.lsHost.notifyFileRemoved(info);
|
||||
this.cachedUnresolvedImportsPerFile.remove(info.path);
|
||||
|
||||
if (detachFromProject) {
|
||||
info.detachFromProject(this);
|
||||
@@ -338,6 +378,38 @@ namespace ts.server {
|
||||
this.projectStateVersion++;
|
||||
}
|
||||
|
||||
private extractUnresolvedImportsFromSourceFile(file: SourceFile, result: string[]) {
|
||||
const cached = this.cachedUnresolvedImportsPerFile.get(file.path);
|
||||
if (cached) {
|
||||
// found cached result - use it and return
|
||||
for (const f of cached) {
|
||||
result.push(f);
|
||||
}
|
||||
return;
|
||||
}
|
||||
let unresolvedImports: string[];
|
||||
if (file.resolvedModules) {
|
||||
for (const name in file.resolvedModules) {
|
||||
// pick unresolved non-relative names
|
||||
if (!file.resolvedModules[name] && !isExternalModuleNameRelative(name)) {
|
||||
// for non-scoped names extract part up-to the first slash
|
||||
// for scoped names - extract up to the second slash
|
||||
let trimmed = name.trim();
|
||||
let i = trimmed.indexOf("/");
|
||||
if (i !== -1 && trimmed.charCodeAt(0) === CharacterCodes.at) {
|
||||
i = trimmed.indexOf("/", i + 1);
|
||||
}
|
||||
if (i !== -1) {
|
||||
trimmed = trimmed.substr(0, i);
|
||||
}
|
||||
(unresolvedImports || (unresolvedImports = [])).push(trimmed);
|
||||
result.push(trimmed);
|
||||
}
|
||||
}
|
||||
}
|
||||
this.cachedUnresolvedImportsPerFile.set(file.path, unresolvedImports || emptyArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates set of files that contribute to this project
|
||||
* @returns: true if set of files in the project stays the same and false - otherwise.
|
||||
@@ -346,8 +418,35 @@ namespace ts.server {
|
||||
if (!this.languageServiceEnabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
this.lsHost.startRecordingFilesWithChangedResolutions();
|
||||
|
||||
let hasChanges = this.updateGraphWorker();
|
||||
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, hasChanges);
|
||||
|
||||
const changedFiles: ReadonlyArray<Path> = this.lsHost.finishRecordingFilesWithChangedResolutions() || emptyArray;
|
||||
|
||||
for (const file of changedFiles) {
|
||||
// delete cached information for changed files
|
||||
this.cachedUnresolvedImportsPerFile.remove(file);
|
||||
}
|
||||
|
||||
// 1. no changes in structure, no changes in unresolved imports - do nothing
|
||||
// 2. no changes in structure, unresolved imports were changed - collect unresolved imports for all files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 3. new files were added/removed, but compilation settings stays the same - collect unresolved imports for all new/modified files
|
||||
// (can reuse cached imports for files that were not changed)
|
||||
// 4. compilation settings were changed in the way that might affect module resolution - drop all caches and collect all data from the scratch
|
||||
let unresolvedImports: SortedReadonlyArray<string>;
|
||||
if (hasChanges || changedFiles.length) {
|
||||
const result: string[] = [];
|
||||
for (const sourceFile of this.program.getSourceFiles()) {
|
||||
this.extractUnresolvedImportsFromSourceFile(sourceFile, result);
|
||||
}
|
||||
this.lastCachedUnresolvedImportsList = toSortedReadonlyArray(result);
|
||||
}
|
||||
unresolvedImports = this.lastCachedUnresolvedImportsList;
|
||||
|
||||
const cachedTypings = this.projectService.typingsCache.getTypingsForProject(this, unresolvedImports, hasChanges);
|
||||
if (this.setTypings(cachedTypings)) {
|
||||
hasChanges = this.updateGraphWorker() || hasChanges;
|
||||
}
|
||||
@@ -357,7 +456,7 @@ namespace ts.server {
|
||||
return !hasChanges;
|
||||
}
|
||||
|
||||
private setTypings(typings: TypingsArray): boolean {
|
||||
private setTypings(typings: SortedReadonlyArray<string>): boolean {
|
||||
if (arrayIsEqualTo(this.typingFiles, typings)) {
|
||||
return false;
|
||||
}
|
||||
@@ -430,6 +529,11 @@ namespace ts.server {
|
||||
compilerOptions.allowJs = true;
|
||||
}
|
||||
compilerOptions.allowNonTsExtensions = true;
|
||||
if (changesAffectModuleResolution(this.compilerOptions, compilerOptions)) {
|
||||
// reset cached unresolved imports if changes in compiler options affected module resolution
|
||||
this.cachedUnresolvedImportsPerFile.clear();
|
||||
this.lastCachedUnresolvedImportsList = undefined;
|
||||
}
|
||||
this.compilerOptions = compilerOptions;
|
||||
this.lsHost.setCompilationSettings(compilerOptions);
|
||||
|
||||
@@ -437,11 +541,11 @@ namespace ts.server {
|
||||
}
|
||||
}
|
||||
|
||||
reloadScript(filename: NormalizedPath): boolean {
|
||||
reloadScript(filename: NormalizedPath, tempFileName?: NormalizedPath): boolean {
|
||||
const script = this.projectService.getScriptInfoForNormalizedPath(filename);
|
||||
if (script) {
|
||||
Debug.assert(script.isAttached(this));
|
||||
script.reloadFromFile();
|
||||
script.reloadFromFile(tempFileName);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -566,14 +670,14 @@ namespace ts.server {
|
||||
// Used to keep track of what directories are watched for this project
|
||||
directoriesWatchedForTsconfig: string[] = [];
|
||||
|
||||
constructor(projectService: ProjectService, documentRegistry: ts.DocumentRegistry, languageServiceEnabled: boolean, compilerOptions: CompilerOptions, public compileOnSaveEnabled: boolean) {
|
||||
constructor(projectService: ProjectService, documentRegistry: ts.DocumentRegistry, languageServiceEnabled: boolean, compilerOptions: CompilerOptions) {
|
||||
super(ProjectKind.Inferred,
|
||||
projectService,
|
||||
documentRegistry,
|
||||
/*files*/ undefined,
|
||||
languageServiceEnabled,
|
||||
compilerOptions,
|
||||
compileOnSaveEnabled);
|
||||
/*compileOnSaveEnabled*/ false);
|
||||
|
||||
this.inferredProjectName = makeInferredProjectName(InferredProject.NextId);
|
||||
InferredProject.NextId++;
|
||||
|
||||
+154
-9
@@ -109,7 +109,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* One of "request", "response", or "event"
|
||||
*/
|
||||
type: string;
|
||||
type: "request" | "response" | "event";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -833,7 +833,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Script kind of the file
|
||||
*/
|
||||
scriptKind?: ScriptKind;
|
||||
scriptKind?: ScriptKindName | ts.ScriptKind;
|
||||
/**
|
||||
* Whether file has mixed content (i.e. .cshtml file that combines html markup with C#/JavaScript)
|
||||
*/
|
||||
@@ -866,20 +866,23 @@ namespace ts.server.protocol {
|
||||
typingOptions?: TypingOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* For external projects, some of the project settings are sent together with
|
||||
* compiler settings.
|
||||
*/
|
||||
export interface ExternalProjectCompilerOptions extends CompilerOptions {
|
||||
export interface CompileOnSaveMixin {
|
||||
/**
|
||||
* If compile on save is enabled for the project
|
||||
*/
|
||||
compileOnSave?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* For external projects, some of the project settings are sent together with
|
||||
* compiler settings.
|
||||
*/
|
||||
export type ExternalProjectCompilerOptions = CompilerOptions & CompileOnSaveMixin;
|
||||
|
||||
/**
|
||||
* Contains information about current project version
|
||||
*/
|
||||
/* @internal */
|
||||
export interface ProjectVersionInfo {
|
||||
/**
|
||||
* Project name
|
||||
@@ -896,7 +899,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Current set of compiler options for project
|
||||
*/
|
||||
options: CompilerOptions;
|
||||
options: ts.CompilerOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -920,6 +923,7 @@ namespace ts.server.protocol {
|
||||
* if changes is set - then this is the set of changes that should be applied to existing project
|
||||
* otherwise - assume that nothing is changed
|
||||
*/
|
||||
/* @internal */
|
||||
export interface ProjectFiles {
|
||||
/**
|
||||
* Information abount project verison
|
||||
@@ -938,6 +942,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Combines project information with project level errors.
|
||||
*/
|
||||
/* @internal */
|
||||
export interface ProjectFilesWithDiagnostics extends ProjectFiles {
|
||||
/**
|
||||
* List of errors in project
|
||||
@@ -1012,9 +1017,11 @@ namespace ts.server.protocol {
|
||||
* Used to specify the script kind of the file explicitly. It could be one of the following:
|
||||
* "TS", "JS", "TSX", "JSX"
|
||||
*/
|
||||
scriptKindName?: "TS" | "JS" | "TSX" | "JSX";
|
||||
scriptKindName?: ScriptKindName;
|
||||
}
|
||||
|
||||
export type ScriptKindName = "TS" | "JS" | "TSX" | "JSX";
|
||||
|
||||
/**
|
||||
* Open request; value of command field is "open". Notify the
|
||||
* server that the client has file open. The server will not
|
||||
@@ -1109,6 +1116,7 @@ namespace ts.server.protocol {
|
||||
/**
|
||||
* Arguments to SynchronizeProjectListRequest
|
||||
*/
|
||||
/* @internal */
|
||||
export interface SynchronizeProjectListRequestArgs {
|
||||
/**
|
||||
* List of last known projects
|
||||
@@ -2056,4 +2064,141 @@ namespace ts.server.protocol {
|
||||
export interface NavTreeResponse extends Response {
|
||||
body?: NavigationTree;
|
||||
}
|
||||
|
||||
export namespace IndentStyle {
|
||||
export type None = "None";
|
||||
export type Block = "Block";
|
||||
export type Smart = "Smart";
|
||||
}
|
||||
|
||||
export type IndentStyle = IndentStyle.None | IndentStyle.Block | IndentStyle.Smart;
|
||||
|
||||
export interface EditorSettings {
|
||||
baseIndentSize?: number;
|
||||
indentSize?: number;
|
||||
tabSize?: number;
|
||||
newLineCharacter?: string;
|
||||
convertTabsToSpaces?: boolean;
|
||||
indentStyle?: IndentStyle | ts.IndentStyle;
|
||||
}
|
||||
|
||||
export interface FormatCodeSettings extends EditorSettings {
|
||||
insertSpaceAfterCommaDelimiter?: boolean;
|
||||
insertSpaceAfterSemicolonInForStatements?: boolean;
|
||||
insertSpaceBeforeAndAfterBinaryOperators?: boolean;
|
||||
insertSpaceAfterKeywordsInControlFlowStatements?: boolean;
|
||||
insertSpaceAfterFunctionKeywordForAnonymousFunctions?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces?: boolean;
|
||||
insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces?: boolean;
|
||||
placeOpenBraceOnNewLineForFunctions?: boolean;
|
||||
placeOpenBraceOnNewLineForControlBlocks?: boolean;
|
||||
}
|
||||
|
||||
export interface CompilerOptions {
|
||||
allowJs?: boolean;
|
||||
allowSyntheticDefaultImports?: boolean;
|
||||
allowUnreachableCode?: boolean;
|
||||
allowUnusedLabels?: boolean;
|
||||
baseUrl?: string;
|
||||
charset?: string;
|
||||
declaration?: boolean;
|
||||
declarationDir?: string;
|
||||
disableSizeLimit?: boolean;
|
||||
emitBOM?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
experimentalDecorators?: boolean;
|
||||
forceConsistentCasingInFileNames?: boolean;
|
||||
inlineSourceMap?: boolean;
|
||||
inlineSources?: boolean;
|
||||
isolatedModules?: boolean;
|
||||
jsx?: JsxEmit | ts.JsxEmit;
|
||||
lib?: string[];
|
||||
locale?: string;
|
||||
mapRoot?: string;
|
||||
maxNodeModuleJsDepth?: number;
|
||||
module?: ModuleKind | ts.ModuleKind;
|
||||
moduleResolution?: ModuleResolutionKind | ts.ModuleResolutionKind;
|
||||
newLine?: NewLineKind | ts.NewLineKind;
|
||||
noEmit?: boolean;
|
||||
noEmitHelpers?: boolean;
|
||||
noEmitOnError?: boolean;
|
||||
noErrorTruncation?: boolean;
|
||||
noFallthroughCasesInSwitch?: boolean;
|
||||
noImplicitAny?: boolean;
|
||||
noImplicitReturns?: boolean;
|
||||
noImplicitThis?: boolean;
|
||||
noUnusedLocals?: boolean;
|
||||
noUnusedParameters?: boolean;
|
||||
noImplicitUseStrict?: boolean;
|
||||
noLib?: boolean;
|
||||
noResolve?: boolean;
|
||||
out?: string;
|
||||
outDir?: string;
|
||||
outFile?: string;
|
||||
paths?: MapLike<string[]>;
|
||||
preserveConstEnums?: boolean;
|
||||
project?: string;
|
||||
reactNamespace?: string;
|
||||
removeComments?: boolean;
|
||||
rootDir?: string;
|
||||
rootDirs?: string[];
|
||||
skipLibCheck?: boolean;
|
||||
skipDefaultLibCheck?: boolean;
|
||||
sourceMap?: boolean;
|
||||
sourceRoot?: string;
|
||||
strictNullChecks?: boolean;
|
||||
suppressExcessPropertyErrors?: boolean;
|
||||
suppressImplicitAnyIndexErrors?: boolean;
|
||||
target?: ScriptTarget | ts.ScriptTarget;
|
||||
traceResolution?: boolean;
|
||||
types?: string[];
|
||||
/** Paths used to used to compute primary types search locations */
|
||||
typeRoots?: string[];
|
||||
[option: string]: CompilerOptionsValue | undefined;
|
||||
}
|
||||
|
||||
export namespace JsxEmit {
|
||||
export type None = "None";
|
||||
export type Preserve = "Preserve";
|
||||
export type React = "React";
|
||||
}
|
||||
|
||||
export type JsxEmit = JsxEmit.None | JsxEmit.Preserve | JsxEmit.React;
|
||||
|
||||
export namespace ModuleKind {
|
||||
export type None = "None";
|
||||
export type CommonJS = "CommonJS";
|
||||
export type AMD = "AMD";
|
||||
export type UMD = "UMD";
|
||||
export type System = "System";
|
||||
export type ES6 = "ES6";
|
||||
export type ES2015 = "ES2015";
|
||||
}
|
||||
|
||||
export type ModuleKind = ModuleKind.None | ModuleKind.CommonJS | ModuleKind.AMD | ModuleKind.UMD | ModuleKind.System | ModuleKind.ES6 | ModuleKind.ES2015;
|
||||
|
||||
export namespace ModuleResolutionKind {
|
||||
export type Classic = "Classic";
|
||||
export type Node = "Node";
|
||||
}
|
||||
|
||||
export type ModuleResolutionKind = ModuleResolutionKind.Classic | ModuleResolutionKind.Node;
|
||||
|
||||
export namespace NewLineKind {
|
||||
export type Crlf = "Crlf";
|
||||
export type Lf = "Lf";
|
||||
}
|
||||
|
||||
export type NewLineKind = NewLineKind.Crlf | NewLineKind.Lf;
|
||||
|
||||
export namespace ScriptTarget {
|
||||
export type ES3 = "ES3";
|
||||
export type ES5 = "ES5";
|
||||
export type ES6 = "ES6";
|
||||
export type ES2015 = "ES2015";
|
||||
}
|
||||
|
||||
export type ScriptTarget = ScriptTarget.ES3 | ScriptTarget.ES5 | ScriptTarget.ES6 | ScriptTarget.ES2015;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,6 @@ namespace ts.server {
|
||||
if (this.containingProjects.length === 0) {
|
||||
return Errors.ThrowNoProject();
|
||||
}
|
||||
Debug.assert(this.containingProjects.length !== 0);
|
||||
return this.containingProjects[0];
|
||||
}
|
||||
|
||||
@@ -126,12 +125,12 @@ namespace ts.server {
|
||||
this.host.writeFile(fileName, snap.getText(0, snap.getLength()));
|
||||
}
|
||||
|
||||
reloadFromFile() {
|
||||
reloadFromFile(tempFileName?: NormalizedPath) {
|
||||
if (this.hasMixedContent) {
|
||||
this.reload("");
|
||||
}
|
||||
else {
|
||||
this.svc.reloadFromFile(this.fileName);
|
||||
this.svc.reloadFromFile(tempFileName || this.fileName);
|
||||
this.markContainingProjectsAsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace ts.server {
|
||||
class BaseLineIndexWalker implements ILineIndexWalker {
|
||||
goSubtree = true;
|
||||
done = false;
|
||||
leaf(rangeStart: number, rangeLength: number, ll: LineLeaf) {
|
||||
leaf(_rangeStart: number, _rangeLength: number, _ll: LineLeaf) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ namespace ts.server {
|
||||
return this.lineIndex;
|
||||
}
|
||||
|
||||
post(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineCollection, nodeType: CharRangeSection): LineCollection {
|
||||
post(_relativeStart: number, _relativeLength: number, lineCollection: LineCollection): LineCollection {
|
||||
// have visited the path for start of range, now looking for end
|
||||
// if range is on single line, we will never make this state transition
|
||||
if (lineCollection === this.lineCollectionAtBranch) {
|
||||
@@ -161,7 +161,7 @@ namespace ts.server {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
pre(relativeStart: number, relativeLength: number, lineCollection: LineCollection, parent: LineCollection, nodeType: CharRangeSection) {
|
||||
pre(_relativeStart: number, _relativeLength: number, lineCollection: LineCollection, _parent: LineCollection, nodeType: CharRangeSection) {
|
||||
// currentNode corresponds to parent, but in the new tree
|
||||
const currentNode = this.stack[this.stack.length - 1];
|
||||
|
||||
@@ -414,7 +414,7 @@ namespace ts.server {
|
||||
const starts: number[] = [-1];
|
||||
let count = 1;
|
||||
let pos = 0;
|
||||
this.index.every((ll, s, len) => {
|
||||
this.index.every(ll => {
|
||||
starts[count] = pos;
|
||||
count++;
|
||||
pos += ll.text.length;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user