Merge branch 'master' into fix2-getConstraintOfIndexedAccess

This commit is contained in:
Nathan Shively-Sanders committed 2018-01-10 12:40:35 -08:00
commit 7dbea0e82d
1088 files changed
+40517 -11748

No files matched your search

+41 -29
View File
@@ -303,7 +303,7 @@ namespace ts {
// without names can only come from JSDocFunctionTypes.
Debug.assert(node.parent.kind === SyntaxKind.JSDocFunctionType);
const functionType = <JSDocFunctionType>node.parent;
const index = indexOf(functionType.parameters, node);
const index = functionType.parameters.indexOf(node as ParameterDeclaration);
return "arg" + index as __String;
case SyntaxKind.JSDocTypedefTag:
const name = getNameOfJSDocTypedef(node as JSDocTypedefTag);
@@ -746,7 +746,11 @@ namespace ts {
}
function isNarrowingTypeofOperands(expr1: Expression, expr2: Expression) {
return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((<TypeOfExpression>expr1).expression) && expr2.kind === SyntaxKind.StringLiteral;
return expr1.kind === SyntaxKind.TypeOfExpression && isNarrowableOperand((<TypeOfExpression>expr1).expression) && (expr2.kind === SyntaxKind.StringLiteral || expr2.kind === SyntaxKind.NoSubstitutionTemplateLiteral);
}
function isNarrowableInOperands(left: Expression, right: Expression) {
return (left.kind === SyntaxKind.StringLiteral || left.kind === SyntaxKind.NoSubstitutionTemplateLiteral) && isNarrowingExpression(right);
}
function isNarrowingBinaryExpression(expr: BinaryExpression) {
@@ -761,6 +765,8 @@ namespace ts {
isNarrowingTypeofOperands(expr.right, expr.left) || isNarrowingTypeofOperands(expr.left, expr.right);
case SyntaxKind.InstanceOfKeyword:
return isNarrowableOperand(expr.left);
case SyntaxKind.InKeyword:
return isNarrowableInOperands(expr.left, expr.right);
case SyntaxKind.CommaToken:
return isNarrowingExpression(expr.right);
}
@@ -1627,7 +1633,7 @@ namespace ts {
// to the one we would get for: { <...>(...): T }
//
// We do that by making an anonymous type literal symbol, and then setting the function
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
// symbol as its sole member. To the rest of the system, this symbol will be indistinguishable
// from an actual type literal symbol you would have gotten had you used the long form.
const symbol = createSymbol(SymbolFlags.Signature, getDeclarationName(node));
addDeclarationToSymbol(symbol, node, SymbolFlags.Signature);
@@ -2283,30 +2289,13 @@ namespace ts {
declareSymbol(file.symbol.exports, file.symbol, <PropertyAccessExpression>node.left, SymbolFlags.Property | SymbolFlags.ExportValue, SymbolFlags.None);
}
function isExportsOrModuleExportsOrAlias(node: Node): boolean {
return isExportsIdentifier(node) ||
isModuleExportsPropertyAccessExpression(node) ||
isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(node);
}
function isNameOfExportsOrModuleExportsAliasDeclaration(node: Identifier): boolean {
const symbol = lookupSymbolForName(node.escapedText);
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(symbol.valueDeclaration.initializer);
}
function isExportsOrModuleExportsOrAliasOrAssignment(node: Node): boolean {
return isExportsOrModuleExportsOrAlias(node) ||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (isExportsOrModuleExportsOrAliasOrAssignment(node.left) || isExportsOrModuleExportsOrAliasOrAssignment(node.right)));
}
function bindModuleExportsAssignment(node: BinaryExpression) {
// A common practice in node modules is to set 'export = module.exports = {}', this ensures that 'exports'
// is still pointing to 'module.exports'.
// We do not want to consider this as 'export=' since a module can have only one of these.
// Similarly we do not want to treat 'module.exports = exports' as an 'export='.
const assignedExpression = getRightMostAssignedExpression(node.right);
if (isEmptyObjectLiteral(assignedExpression) || isExportsOrModuleExportsOrAlias(assignedExpression)) {
if (isEmptyObjectLiteral(assignedExpression) || container === file && isExportsOrModuleExportsOrAlias(file, assignedExpression)) {
// Mark it as a module in case there are no other exports in the file
setCommonJsModuleIndicator(node);
return;
@@ -2387,7 +2376,7 @@ namespace ts {
if (node.kind === SyntaxKind.BinaryExpression) {
leftSideOfAssignment.parent = node;
}
if (isNameOfExportsOrModuleExportsAliasDeclaration(target)) {
if (container === file && isNameOfExportsOrModuleExportsAliasDeclaration(file, target)) {
// This can be an alias for the 'exports' or 'module.exports' names, e.g.
// var util = module.exports;
// util.property = function ...
@@ -2400,11 +2389,7 @@ namespace ts {
}
function lookupSymbolForName(name: __String) {
const local = container.locals && container.locals.get(name);
if (local) {
return local.exportSymbol || local;
}
return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
return lookupSymbolForNameWorker(container, name);
}
function bindPropertyAssignment(functionName: __String, propertyAccess: PropertyAccessExpression, isPrototypeProperty: boolean) {
@@ -2425,7 +2410,7 @@ namespace ts {
if (!isPrototypeProperty && (!targetSymbol || !(targetSymbol.flags & SymbolFlags.Namespace)) && isLegalPosition) {
Debug.assert(isIdentifier(propertyAccess.expression));
const identifier = propertyAccess.expression as Identifier;
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer;
if (targetSymbol) {
addDeclarationToSymbol(symbol, identifier, flags);
@@ -2532,7 +2517,7 @@ namespace ts {
}
if (isBindingPattern(node.name)) {
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + indexOf(node.parent.parameters, node) as __String);
bindAnonymousDeclaration(node, SymbolFlags.FunctionScopedVariable, "__" + node.parent.parameters.indexOf(node) as __String);
}
else {
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
@@ -2643,6 +2628,33 @@ namespace ts {
}
}
/* @internal */
export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean {
return isExportsIdentifier(node) ||
isModuleExportsPropertyAccessExpression(node) ||
isIdentifier(node) && isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile, node);
}
function isNameOfExportsOrModuleExportsAliasDeclaration(sourceFile: SourceFile, node: Identifier): boolean {
const symbol = lookupSymbolForNameWorker(sourceFile, node.escapedText);
return symbol && symbol.valueDeclaration && isVariableDeclaration(symbol.valueDeclaration) &&
symbol.valueDeclaration.initializer && isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, symbol.valueDeclaration.initializer);
}
function isExportsOrModuleExportsOrAliasOrAssignment(sourceFile: SourceFile, node: Expression): boolean {
return isExportsOrModuleExportsOrAlias(sourceFile, node) ||
(isAssignmentExpression(node, /*excludeCompoundAssignements*/ true) && (
isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.left) || isExportsOrModuleExportsOrAliasOrAssignment(sourceFile, node.right)));
}
function lookupSymbolForNameWorker(container: Node, name: __String): Symbol | undefined {
const local = container.locals && container.locals.get(name);
if (local) {
return local.exportSymbol || local;
}
return container.symbol && container.symbol.exports && container.symbol.exports.get(name);
}
/**
* Computes the transform flags for a node, given the transform flags of its subtree
*
+3 -3
View File
@@ -468,9 +468,9 @@ namespace ts {
}
function getReferencedByPaths(referencedFilePath: Path) {
return mapDefinedIter(references.entries(), ([filePath, referencesInFile]) =>
return arrayFrom(mapDefinedIterator(references.entries(), ([filePath, referencesInFile]) =>
referencesInFile.has(referencedFilePath) ? filePath as Path : undefined
);
));
}
function getFilesAffectedByUpdatedShape(program: Program, sourceFile: SourceFile): ReadonlyArray<SourceFile> {
@@ -504,7 +504,7 @@ namespace ts {
}
// Return array of values that needs emit
return flatMapIter(seenFileNamesMap.values(), value => value);
return arrayFrom(mapDefinedIterator(seenFileNamesMap.values(), value => value));
}
}
}
+958 -517
View File
File diff suppressed because it is too large. Load diff
+12 -20
View File
@@ -144,7 +144,9 @@ namespace ts {
"es2017.string": "lib.es2017.string.d.ts",
"es2017.intl": "lib.es2017.intl.d.ts",
"es2017.typedarrays": "lib.es2017.typedarrays.d.ts",
"esnext.array": "lib.esnext.array.d.ts",
"esnext.asynciterable": "lib.esnext.asynciterable.d.ts",
"esnext.promise": "lib.esnext.promise.d.ts",
}),
},
showInSimplifiedHelpView: true,
@@ -400,6 +402,13 @@ namespace ts {
category: Diagnostics.Module_Resolution_Options,
description: Diagnostics.Allow_default_imports_from_modules_with_no_default_export_This_does_not_affect_code_emit_just_typechecking
},
{
name: "esModuleInterop",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Module_Resolution_Options,
description: Diagnostics.Enables_emit_interoperability_between_CommonJS_and_ES_Modules_via_creation_of_namespace_objects_for_all_imports_Implies_allowSyntheticDefaultImports
},
{
name: "preserveSymlinks",
type: "boolean",
@@ -702,7 +711,8 @@ namespace ts {
export const defaultInitCompilerOptions: CompilerOptions = {
module: ModuleKind.CommonJS,
target: ScriptTarget.ES5,
strict: true
strict: true,
esModuleInterop: true
};
let optionNameMapCache: OptionNameMap;
@@ -1863,7 +1873,7 @@ namespace ts {
return normalizeNonListOptionValue(option, basePath, value);
}
function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
function normalizeNonListOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
if (option.isFilePath) {
value = normalizePath(combinePaths(basePath, value));
if (value === "") {
@@ -1906,21 +1916,6 @@ namespace ts {
*/
const invalidTrailingRecursionPattern = /(^|\/)\*\*\/?$/;
/**
* Tests for a path with multiple recursive directory wildcards.
* Matches **\** and **\a\**, but not **\a**b.
*
* NOTE: used \ in place of / above to avoid issues with multiline comments.
*
* Breakdown:
* (^|\/) # matches either the beginning of the string or a directory separator.
* \*\*\/ # matches a recursive directory wildcard "**" followed by a directory separator.
* (.*\/)? # optionally matches any number of characters followed by a directory separator.
* \*\* # matches a recursive directory wildcard "**"
* ($|\/) # matches either the end of the string or a directory separator.
*/
const invalidMultipleRecursionPatterns = /(^|\/)\*\*\/(.*\/)?\*\*($|\/)/;
/**
* Tests for a path where .. appears after a recursive directory wildcard.
* Matches **\..\*, **\a\..\*, and **\.., but not ..\**\*
@@ -2115,9 +2110,6 @@ namespace ts {
if (!allowTrailingRecursion && invalidTrailingRecursionPattern.test(spec)) {
return Diagnostics.File_specification_cannot_end_in_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
}
else if (invalidMultipleRecursionPatterns.test(spec)) {
return Diagnostics.File_specification_cannot_contain_multiple_recursive_directory_wildcards_Asterisk_Asterisk_Colon_0;
}
else if (invalidDotDotAfterRecursiveWildcardPattern.test(spec)) {
return Diagnostics.File_specification_cannot_contain_a_parent_directory_that_appears_after_a_recursive_directory_wildcard_Asterisk_Asterisk_Colon_0;
}
+113 -61
View File
@@ -191,6 +191,19 @@ namespace ts {
return undefined;
}
export function firstDefinedIterator<T, U>(iter: Iterator<T>, callback: (element: T) => U | undefined): U | undefined {
while (true) {
const { value, done } = iter.next();
if (done) {
return undefined;
}
const result = callback(value);
if (result !== undefined) {
return result;
}
}
}
/**
* Iterates through the parent chain of a node and performs the callback on each parent until the callback
* returns a truthy value, then returns that value.
@@ -215,13 +228,27 @@ namespace ts {
export function zipWith<T, U, V>(arrayA: ReadonlyArray<T>, arrayB: ReadonlyArray<U>, callback: (a: T, b: U, index: number) => V): V[] {
const result: V[] = [];
Debug.assert(arrayA.length === arrayB.length);
Debug.assertEqual(arrayA.length, arrayB.length);
for (let i = 0; i < arrayA.length; i++) {
result.push(callback(arrayA[i], arrayB[i], i));
}
return result;
}
export function zipToIterator<T, U>(arrayA: ReadonlyArray<T>, arrayB: ReadonlyArray<U>): Iterator<[T, U]> {
Debug.assertEqual(arrayA.length, arrayB.length);
let i = 0;
return {
next() {
if (i === arrayA.length) {
return { value: undefined as never, done: true };
}
i++;
return { value: [arrayA[i - 1], arrayB[i - 1]], done: false };
}
};
}
export function zipToMap<T>(keys: ReadonlyArray<string>, values: ReadonlyArray<T>): Map<T> {
Debug.assert(keys.length === values.length);
const map = createMap<T>();
@@ -261,6 +288,8 @@ namespace ts {
return undefined;
}
export function findLast<T, U extends T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => element is U): U | undefined;
export function findLast<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): T | undefined;
export function findLast<T>(array: ReadonlyArray<T>, predicate: (element: T, index: number) => boolean): T | undefined {
for (let i = array.length - 1; i >= 0; i--) {
const value = array[i];
@@ -306,17 +335,6 @@ namespace ts {
return false;
}
export function indexOf<T>(array: ReadonlyArray<T>, value: T): number {
if (array) {
for (let i = 0; i < array.length; i++) {
if (array[i] === value) {
return i;
}
}
}
return -1;
}
export function indexOfAnyCharCode(text: string, charCodes: ReadonlyArray<number>, start?: number): number {
for (let i = start || 0; i < text.length; i++) {
if (contains(charCodes, text.charCodeAt(i))) {
@@ -394,12 +412,14 @@ namespace ts {
return result;
}
export function mapIterator<T, U>(iter: Iterator<T>, mapFn: (x: T) => U): Iterator<U> {
return { next };
function next(): { value: U, done: false } | { value: never, done: true } {
const iterRes = iter.next();
return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false };
}
return {
next() {
const iterRes = iter.next();
return iterRes.done ? iterRes : { value: mapFn(iterRes.value), done: false };
}
};
}
// Maps from T to T and avoids allocation if all elements map to themselves
@@ -474,22 +494,32 @@ namespace ts {
return result;
}
export function flatMapIter<T, U>(iter: Iterator<T>, mapfn: (x: T) => U | U[] | undefined): U[] {
const result: U[] = [];
while (true) {
const { value, done } = iter.next();
if (done) break;
const res = mapfn(value);
if (res) {
if (isArray(res)) {
result.push(...res);
export function flatMapIterator<T, U>(iter: Iterator<T>, mapfn: (x: T) => U[] | Iterator<U> | undefined): Iterator<U> {
const first = iter.next();
if (first.done) {
return emptyIterator;
}
let currentIter = getIterator(first.value);
return {
next() {
while (true) {
const currentRes = currentIter.next();
if (!currentRes.done) {
return currentRes;
}
const iterRes = iter.next();
if (iterRes.done) {
return iterRes;
}
currentIter = getIterator(iterRes.value);
}
else {
result.push(res);
}
}
},
};
function getIterator(x: T): Iterator<U> {
const res = mapfn(x);
return res === undefined ? emptyIterator : isArray(res) ? arrayIterator(res) : res;
}
return result;
}
/**
@@ -523,12 +553,23 @@ namespace ts {
return result || array;
}
export function mapAllOrFail<T, U>(array: ReadonlyArray<T>, mapFn: (x: T, i: number) => U | undefined): U[] | undefined {
const result: U[] = [];
for (let i = 0; i < array.length; i++) {
const mapped = mapFn(array[i], i);
if (mapped === undefined) {
return undefined;
}
result.push(mapped);
}
return result;
}
export function mapDefined<T, U>(array: ReadonlyArray<T> | undefined, mapFn: (x: T, i: number) => U | undefined): U[] {
const result: U[] = [];
if (array) {
for (let i = 0; i < array.length; i++) {
const item = array[i];
const mapped = mapFn(item, i);
const mapped = mapFn(array[i], i);
if (mapped !== undefined) {
result.push(mapped);
}
@@ -537,17 +578,34 @@ namespace ts {
return result;
}
export function mapDefinedIter<T, U>(iter: Iterator<T>, mapFn: (x: T) => U | undefined): U[] {
const result: U[] = [];
while (true) {
const { value, done } = iter.next();
if (done) break;
const res = mapFn(value);
if (res !== undefined) {
result.push(res);
export function mapDefinedIterator<T, U>(iter: Iterator<T>, mapFn: (x: T) => U | undefined): Iterator<U> {
return {
next() {
while (true) {
const res = iter.next();
if (res.done) {
return res;
}
const value = mapFn(res.value);
if (value !== undefined) {
return { value, done: false };
}
}
}
}
return result;
};
}
export const emptyIterator: Iterator<never> = { next: () => ({ value: undefined as never, done: true }) };
export function singleIterator<T>(value: T): Iterator<T> {
let done = false;
return {
next() {
const wasDone = done;
done = true;
return wasDone ? { value: undefined as never, done: true } : { value, done: false };
}
};
}
/**
@@ -1345,7 +1403,6 @@ namespace ts {
this.set(key, values = [value]);
}
return values;
}
function multiMapRemove<T>(this: MultiMap<T>, key: string, value: T) {
const values = this.get(key);
@@ -1360,12 +1417,12 @@ namespace ts {
/**
* Tests whether a value is an array.
*/
export function isArray(value: any): value is ReadonlyArray<any> {
export function isArray(value: any): value is ReadonlyArray<{}> {
return Array.isArray ? Array.isArray(value) : value instanceof Array;
}
export function toArray<T>(value: T | ReadonlyArray<T>): ReadonlyArray<T>;
export function toArray<T>(value: T | T[]): T[];
export function toArray<T>(value: T | ReadonlyArray<T>): ReadonlyArray<T>;
export function toArray<T>(value: T | T[]): T[] {
return isArray(value) ? value : [value];
}
@@ -1939,11 +1996,6 @@ namespace ts {
return /^\.\.?($|[\\/])/.test(path);
}
/** @deprecated Use `!isExternalModuleNameRelative(moduleName)` instead. */
export function moduleHasNonRelativeName(moduleName: string): boolean {
return !isExternalModuleNameRelative(moduleName);
}
export function getEmitScriptTarget(compilerOptions: CompilerOptions) {
return compilerOptions.target || ScriptTarget.ES3;
}
@@ -1966,7 +2018,9 @@ namespace ts {
const moduleKind = getEmitModuleKind(compilerOptions);
return compilerOptions.allowSyntheticDefaultImports !== undefined
? compilerOptions.allowSyntheticDefaultImports
: moduleKind === ModuleKind.System;
: compilerOptions.esModuleInterop
? moduleKind !== ModuleKind.None && moduleKind < ModuleKind.ES2015
: moduleKind === ModuleKind.System;
}
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
@@ -2030,7 +2084,7 @@ namespace ts {
function getNormalizedPathComponentsOfUrl(url: string) {
// Get root length of http://www.website.com/folder1/folder2/
// In this example the root is: http://www.website.com/
// In this example the root is: http://www.website.com/
// normalized path components should be ["http://www.website.com/", "folder1", "folder2"]
const urlLength = url.length;
@@ -2063,7 +2117,7 @@ namespace ts {
}
else {
// Can't find the host assume the rest of the string as component
// but make sure we append "/" to it as root is not joined using "/"
// but make sure we append "/" to it as root is not joined using "/"
// eg. if url passed in was http://website.com we want to use root as [http://website.com/]
// so that other path manipulations will be correct and it can be merged with relative paths correctly
return [url + directorySeparator];
@@ -2084,7 +2138,7 @@ namespace ts {
const directoryComponents = getNormalizedPathOrUrlComponents(directoryPathOrUrl, currentDirectory);
if (directoryComponents.length > 1 && lastOrUndefined(directoryComponents) === "") {
// If the directory path given was of type test/cases/ then we really need components of directory to be only till its name
// that is ["test", "cases", ""] needs to be actually ["test", "cases"]
// that is ["test", "cases", ""] needs to be actually ["test", "cases"]
directoryComponents.pop();
}
@@ -2326,7 +2380,6 @@ namespace ts {
function getSubPatternFromSpec(spec: string, basePath: string, usage: "files" | "directories" | "exclude", { singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter }: WildcardMatcher): string | undefined {
let subpattern = "";
let hasRecursiveDirectoryWildcard = false;
let hasWrittenComponent = false;
const components = getNormalizedPathComponents(spec, basePath);
const lastComponent = lastOrUndefined(components);
@@ -2345,12 +2398,7 @@ namespace ts {
let optionalCount = 0;
for (let component of components) {
if (component === "**") {
if (hasRecursiveDirectoryWildcard) {
return undefined;
}
subpattern += doubleAsteriskRegexFragment;
hasRecursiveDirectoryWildcard = true;
}
else {
if (usage === "directories") {
@@ -3213,4 +3261,8 @@ namespace ts {
cachedReadDirectoryResult.clear();
}
}
export function singleElementArray<T>(t: T | undefined): T[] | undefined {
return t === undefined ? undefined : [t];
}
}
+11 -5
View File
@@ -64,7 +64,7 @@ namespace ts {
let currentIdentifiers: Map<string>;
let isCurrentFileExternalModule: boolean;
let reportedDeclarationError = false;
let errorNameNode: DeclarationName;
let errorNameNode: DeclarationName | QualifiedName;
const emitJsDocComments = compilerOptions.removeComments ? noop : writeJsDocComments;
const emit = compilerOptions.stripInternal ? stripInternal : emitNode;
let needsDeclare = true;
@@ -148,8 +148,8 @@ namespace ts {
moduleElementDeclarationEmitInfo = [];
}
if (!isBundledEmit && isExternalModule(sourceFile) && sourceFile.moduleAugmentations.length && !resultHasExternalModuleIndicator) {
// if file was external module with augmentations - this fact should be preserved in .d.ts as well.
if (!isBundledEmit && isExternalModule(sourceFile) && !resultHasExternalModuleIndicator) {
// if file was external module this fact should be preserved in .d.ts as well.
// in case if we didn't write any external module specifiers in .d.ts we need to emit something
// that will force compiler to think that this file is an external module - 'export {}' is a reasonable choice here.
write("export {};");
@@ -651,6 +651,9 @@ namespace ts {
}
function emitExportAssignment(node: ExportAssignment) {
if (isSourceFile(node.parent)) {
resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators
}
if (node.expression.kind === SyntaxKind.Identifier) {
write(node.isExportEquals ? "export = " : "export default ");
writeTextOfNode(currentText, node.expression);
@@ -745,6 +748,7 @@ namespace ts {
const modifiers = getModifierFlags(node);
// If the node is exported
if (modifiers & ModifierFlags.Export) {
resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators
write("export ");
}
@@ -901,6 +905,7 @@ namespace ts {
}
function emitExportDeclaration(node: ExportDeclaration) {
resultHasExternalModuleIndicator = true; // Top-level exports are external module indicators
emitJsDocComments(node);
write("export ");
if (node.exportClause) {
@@ -1199,7 +1204,7 @@ namespace ts {
write(">");
}
}
else {
else {
emitHeritageClause([baseTypeNode], /*isImplementsList*/ false);
}
}
@@ -1372,7 +1377,7 @@ namespace ts {
// if this is property of type literal,
// or is parameter of method/call/construct/index signature of type literal
// emit only if type is specified
if (node.type) {
if (hasType(node)) {
write(": ");
emitType(node.type);
}
@@ -1866,6 +1871,7 @@ namespace ts {
// it allows emitSeparatedList to write separator appropriately)
// Example:
// original: function foo([, x, ,]) {}
// tslint:disable-next-line no-double-space
// emit : function foo([ , x, , ]) {}
write(" ");
}
+69 -7
View File
@@ -939,6 +939,14 @@
"category": "Error",
"code": 1335
},
"An index signature parameter type cannot be a type alias. Consider writing '[{0}: {1}]: {2}' instead.": {
"category": "Error",
"code": 1336
},
"An index signature parameter type cannot be a union type. Consider using a mapped object type instead.": {
"category": "Error",
"code": 1337
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -1396,6 +1404,10 @@
"category": "Error",
"code": 2415
},
"Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.": {
"category": "Error",
"code": 2416
},
"Class static side '{0}' incorrectly extends base class static side '{1}'.": {
"category": "Error",
"code": 2417
@@ -1612,7 +1624,7 @@
"category": "Error",
"code": 2474
},
"'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment.": {
"'const' enums can only be used in property or index access expressions or the right hand side of an import declaration or export assignment or type query.": {
"category": "Error",
"code": 2475
},
@@ -2276,7 +2288,22 @@
"category": "Error",
"code": 2719
},
"Class '{0}' incorrectly implements class '{1}'. Did you mean to extend '{1}' and inherit its members as a subclass?": {
"category": "Error",
"code": 2720
},
"Cannot invoke an object which is possibly 'null'.": {
"category": "Error",
"code": 2721
},
"Cannot invoke an object which is possibly 'undefined'.": {
"category": "Error",
"code": 2722
},
"Cannot invoke an object which is possibly 'null' or 'undefined'.": {
"category": "Error",
"code": 2723
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
"code": 4000
@@ -2623,10 +2650,6 @@
"category": "Error",
"code": 5010
},
"File specification cannot contain multiple recursive directory wildcards ('**'): '{0}'.": {
"category": "Error",
"code": 5011
},
"Cannot read file '{0}': {1}.": {
"category": "Error",
"code": 5012
@@ -2828,6 +2851,10 @@
"category": "Message",
"code": 6030
},
"Starting compilation in watch mode...": {
"category": "Message",
"code": 6031
},
"File change detected. Starting incremental compilation...": {
"category": "Message",
"code": 6032
@@ -3416,6 +3443,14 @@
"category": "Message",
"code": 6187
},
"Numeric separators are not allowed here.": {
"category": "Error",
"code": 6188
},
"Multiple consecutive numeric separators are not permitted.": {
"category": "Error",
"code": 6189
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
@@ -3528,7 +3563,18 @@
"category": "Error",
"code": 7036
},
"Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'.": {
"category": "Message",
"code": 7037
},
"A namespace-style import cannot be called or constructed, and will cause a failure at runtime.": {
"category": "Error",
"code": 7038
},
"Mapped object type implicitly has an 'any' template type.": {
"category": "Error",
"code": 7039
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
@@ -3831,6 +3877,10 @@
"category": "Message",
"code": 90028
},
"Add async modifier to containing function": {
"category": "Message",
"code": 90029
},
"Convert function to an ES2015 class": {
"category": "Message",
"code": 95001
@@ -3886,5 +3936,17 @@
"Install '{0}'": {
"category": "Message",
"code": 95014
},
"Replace import with '{0}'.": {
"category": "Message",
"code": 95015
},
"Use synthetic 'default' member.": {
"category": "Message",
"code": 95016
},
"Convert to ES6 module": {
"category": "Message",
"code": 95017
}
}
+8 -20
View File
@@ -1194,27 +1194,15 @@ namespace ts {
//
function emitObjectBindingPattern(node: ObjectBindingPattern) {
const elements = node.elements;
if (elements.length === 0) {
write("{}");
}
else {
write("{");
emitList(node, elements, ListFormat.ObjectBindingPatternElements);
write("}");
}
write("{");
emitList(node, node.elements, ListFormat.ObjectBindingPatternElements);
write("}");
}
function emitArrayBindingPattern(node: ArrayBindingPattern) {
const elements = node.elements;
if (elements.length === 0) {
write("[]");
}
else {
write("[");
emitList(node, node.elements, ListFormat.ArrayBindingPatternElements);
write("]");
}
write("[");
emitList(node, node.elements, ListFormat.ArrayBindingPatternElements);
write("]");
}
function emitBindingElement(node: BindingElement) {
@@ -3167,8 +3155,8 @@ namespace ts {
TupleTypeElements = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented,
UnionTypeConstituents = BarDelimited | SpaceBetweenSiblings | SingleLine,
IntersectionTypeConstituents = AmpersandDelimited | SpaceBetweenSiblings | SingleLine,
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings,
ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings,
ObjectBindingPatternElements = SingleLine | AllowTrailingComma | SpaceBetweenBraces | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty,
ArrayBindingPatternElements = SingleLine | AllowTrailingComma | CommaDelimited | SpaceBetweenSiblings | NoSpaceIfEmpty,
ObjectLiteralExpressionProperties = PreserveLines | CommaDelimited | SpaceBetweenSiblings | SpaceBetweenBraces | Indented | Braces | NoSpaceIfEmpty,
ArrayLiteralExpressionElements = PreserveLines | CommaDelimited | SpaceBetweenSiblings | AllowTrailingComma | Indented | SquareBrackets,
CommaListElements = CommaDelimited | SpaceBetweenSiblings | SingleLine,
+8 -8
View File
@@ -71,11 +71,11 @@ namespace ts {
// Literals
/** If a node is passed, creates a string literal whose source text is read from a source node during emit. */
export function createLiteral(value: string | StringLiteral | NumericLiteral | Identifier): StringLiteral;
export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral;
export function createLiteral(value: number): NumericLiteral;
export function createLiteral(value: boolean): BooleanLiteral;
export function createLiteral(value: string | number | boolean): PrimaryExpression;
export function createLiteral(value: string | number | boolean | StringLiteral | NumericLiteral | Identifier): PrimaryExpression {
export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): PrimaryExpression {
if (typeof value === "number") {
return createNumericLiteral(value + "");
}
@@ -101,7 +101,7 @@ namespace ts {
return node;
}
function createLiteralFromNode(sourceNode: StringLiteral | NumericLiteral | Identifier): StringLiteral {
function createLiteralFromNode(sourceNode: StringLiteralLike | NumericLiteral | Identifier): StringLiteral {
const node = createStringLiteral(getTextOfIdentifierOrLiteral(sourceNode));
node.textSourceNode = sourceNode;
return node;
@@ -3626,7 +3626,7 @@ namespace ts {
return qualifiedName;
}
export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean) {
export function convertToFunctionBody(node: ConciseBody, multiLine?: boolean): Block {
return isBlock(node) ? node : setTextRange(createBlock([setTextRange(createReturn(node), node)], multiLine), node);
}
@@ -3831,13 +3831,13 @@ namespace ts {
if (isLeftSideOfBinary) {
// No need to parenthesize the left operand when the binary operator is
// left associative:
// (a*b)/x -> a*b/x
// (a**b)/x -> a**b/x
// (a*b)/x -> a*b/x
// (a**b)/x -> a**b/x
//
// Parentheses are needed for the left operand when the binary operator is
// right associative:
// (a/b)**x -> (a/b)**x
// (a**b)**x -> (a**b)**x
// (a/b)**x -> (a/b)**x
// (a**b)**x -> (a**b)**x
return binaryOperatorAssociativity === Associativity.Right;
}
else {
+17 -10
View File
@@ -64,9 +64,9 @@ namespace ts {
return { fileName: resolved.path, packageId: resolved.packageId };
}
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
function createResolvedModuleWithFailedLookupLocations(resolved: Resolved | undefined, originalPath: string | undefined, isExternalLibraryImport: boolean, failedLookupLocations: string[]): ResolvedModuleWithFailedLookupLocations {
return {
resolvedModule: resolved && { resolvedFileName: resolved.path, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
resolvedModule: resolved && { resolvedFileName: resolved.path, originalPath, extension: resolved.extension, isExternalLibraryImport, packageId: resolved.packageId },
failedLookupLocations
};
}
@@ -732,12 +732,12 @@ namespace ts {
const result = jsOnly ? tryResolve(Extensions.JavaScript) : (tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript));
if (result && result.value) {
const { resolved, isExternalLibraryImport } = result.value;
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
const { resolved, originalPath, isExternalLibraryImport } = result.value;
return createResolvedModuleWithFailedLookupLocations(resolved, originalPath, isExternalLibraryImport, failedLookupLocations);
}
return { resolvedModule: undefined, failedLookupLocations };
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, isExternalLibraryImport: boolean }> {
function tryResolve(extensions: Extensions): SearchResult<{ resolved: Resolved, originalPath?: string, isExternalLibraryImport: boolean }> {
const loader: ResolutionKindSpecificLoader = (extensions, candidate, failedLookupLocations, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, failedLookupLocations, onlyRecordFailures, state, /*considerPackageJson*/ true);
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, failedLookupLocations, state);
if (resolved) {
@@ -752,11 +752,17 @@ namespace ts {
if (!resolved) return undefined;
let resolvedValue = resolved.value;
if (!compilerOptions.preserveSymlinks) {
resolvedValue = resolvedValue && { ...resolved.value, path: realPath(resolved.value.path, host, traceEnabled), extension: resolved.value.extension };
let originalPath: string | undefined;
if (!compilerOptions.preserveSymlinks && resolvedValue) {
originalPath = resolvedValue.path;
const path = realPath(resolved.value.path, host, traceEnabled);
if (path === originalPath) {
originalPath = undefined;
}
resolvedValue = { ...resolvedValue, path };
}
// For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
return { value: resolvedValue && { resolved: resolvedValue, isExternalLibraryImport: true } };
return { value: resolvedValue && { resolved: resolvedValue, originalPath, isExternalLibraryImport: true } };
}
else {
const { path: candidate, parts } = normalizePathAndParts(combinePaths(containingDirectory, moduleName));
@@ -1115,7 +1121,8 @@ namespace ts {
const containingDirectory = getDirectoryPath(containingFile);
const resolved = tryResolve(Extensions.TypeScript) || tryResolve(Extensions.JavaScript);
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*isExternalLibraryImport*/ false, failedLookupLocations);
// No originalPath because classic resolution doesn't resolve realPath
return createResolvedModuleWithFailedLookupLocations(resolved && resolved.value, /*originalPath*/ undefined, /*isExternalLibraryImport*/ false, failedLookupLocations);
function tryResolve(extensions: Extensions): SearchResult<Resolved> {
const resolvedUsingSettings = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loadModuleFromFileNoPackageId, failedLookupLocations, state);
@@ -1162,7 +1169,7 @@ namespace ts {
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled };
const failedLookupLocations: string[] = [];
const resolved = loadModuleFromNodeModulesOneLevel(Extensions.DtsOnly, moduleName, globalCache, failedLookupLocations, state);
return createResolvedModuleWithFailedLookupLocations(resolved, /*isExternalLibraryImport*/ true, failedLookupLocations);
return createResolvedModuleWithFailedLookupLocations(resolved, /*originalPath*/ undefined, /*isExternalLibraryImport*/ true, failedLookupLocations);
}
/**
+87 -62
View File
@@ -88,20 +88,48 @@ namespace ts {
case SyntaxKind.SpreadAssignment:
return visitNode(cbNode, (<SpreadAssignment>node).expression);
case SyntaxKind.Parameter:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<ParameterDeclaration>node).dotDotDotToken) ||
visitNode(cbNode, (<ParameterDeclaration>node).name) ||
visitNode(cbNode, (<ParameterDeclaration>node).questionToken) ||
visitNode(cbNode, (<ParameterDeclaration>node).type) ||
visitNode(cbNode, (<ParameterDeclaration>node).initializer);
case SyntaxKind.PropertyDeclaration:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<PropertyDeclaration>node).name) ||
visitNode(cbNode, (<PropertyDeclaration>node).questionToken) ||
visitNode(cbNode, (<PropertyDeclaration>node).exclamationToken) ||
visitNode(cbNode, (<PropertyDeclaration>node).type) ||
visitNode(cbNode, (<PropertyDeclaration>node).initializer);
case SyntaxKind.PropertySignature:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<PropertySignature>node).name) ||
visitNode(cbNode, (<PropertySignature>node).questionToken) ||
visitNode(cbNode, (<PropertySignature>node).type) ||
visitNode(cbNode, (<PropertySignature>node).initializer);
case SyntaxKind.PropertyAssignment:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<PropertyAssignment>node).name) ||
visitNode(cbNode, (<PropertyAssignment>node).questionToken) ||
visitNode(cbNode, (<PropertyAssignment>node).initializer);
case SyntaxKind.VariableDeclaration:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<VariableDeclaration>node).name) ||
visitNode(cbNode, (<VariableDeclaration>node).exclamationToken) ||
visitNode(cbNode, (<VariableDeclaration>node).type) ||
visitNode(cbNode, (<VariableDeclaration>node).initializer);
case SyntaxKind.BindingElement:
return visitNodes(cbNode, cbNodes, node.decorators) ||
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).propertyName) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).dotDotDotToken) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).name) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).questionToken) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).exclamationToken) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).type) ||
visitNode(cbNode, (<VariableLikeDeclaration>node).initializer);
visitNode(cbNode, (<BindingElement>node).propertyName) ||
visitNode(cbNode, (<BindingElement>node).dotDotDotToken) ||
visitNode(cbNode, (<BindingElement>node).name) ||
visitNode(cbNode, (<BindingElement>node).initializer);
case SyntaxKind.FunctionType:
case SyntaxKind.ConstructorType:
case SyntaxKind.CallSignature:
@@ -557,7 +585,7 @@ namespace ts {
// 'disallow-in' set to 'false'. Otherwise, if we had 'allowsIn' set to 'true', then almost
// all nodes would need extra state on them to store this info.
//
// Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
// Note: 'allowIn' and 'allowYield' track 1:1 with the [in] and [yield] concepts in the ES6
// grammar specification.
//
// An important thing about these context concepts. By default they are effectively inherited
@@ -673,7 +701,7 @@ namespace ts {
function getLanguageVariant(scriptKind: ScriptKind) {
// .tsx and .jsx files are treated as jsx language variant.
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
return scriptKind === ScriptKind.TSX || scriptKind === ScriptKind.JSX || scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSON ? LanguageVariant.JSX : LanguageVariant.Standard;
}
function initializeState(_sourceText: string, languageVersion: ScriptTarget, _syntaxCursor: IncrementalParser.SyntaxCursor, scriptKind: ScriptKind) {
@@ -758,15 +786,7 @@ namespace ts {
const comments = getJSDocCommentRanges(node, sourceFile.text);
if (comments) {
for (const comment of comments) {
const jsDoc = JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos);
if (jsDoc) {
if (!node.jsDoc) {
node.jsDoc = [jsDoc];
}
else {
node.jsDoc.push(jsDoc);
}
}
node.jsDoc = append(node.jsDoc, JSDocParser.parseJSDocComment(node, comment.pos, comment.end - comment.pos));
}
}
@@ -1401,9 +1421,13 @@ namespace ts {
return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isIdentifierOrPattern();
case ParsingContext.TypeParameters:
return isIdentifier();
case ParsingContext.ArgumentExpressions:
case ParsingContext.ArrayLiteralMembers:
return token() === SyntaxKind.CommaToken || token() === SyntaxKind.DotDotDotToken || isStartOfExpression();
if (token() === SyntaxKind.CommaToken) {
return true;
}
// falls through
case ParsingContext.ArgumentExpressions:
return token() === SyntaxKind.DotDotDotToken || isStartOfExpression();
case ParsingContext.Parameters:
return isStartOfParameter();
case ParsingContext.TypeArguments:
@@ -1425,7 +1449,7 @@ namespace ts {
function isValidHeritageClauseObjectLiteral() {
Debug.assert(token() === SyntaxKind.OpenBraceToken);
if (nextToken() === SyntaxKind.CloseBraceToken) {
// if we see "extends {}" then only treat the {} as what we're extending (and not
// if we see "extends {}" then only treat the {} as what we're extending (and not
// the class body) if we have:
//
// extends {} {
@@ -1521,7 +1545,7 @@ namespace ts {
function isVariableDeclaratorListTerminator(): boolean {
// If we can consume a semicolon (either explicitly, or with ASI), then consider us done
// with parsing the list of variable declarators.
// with parsing the list of variable declarators.
if (canParseSemicolon()) {
return true;
}
@@ -1647,6 +1671,11 @@ namespace ts {
return undefined;
}
if ((node as JSDocContainer).jsDocCache) {
// jsDocCache may include tags from parent nodes, which might have been modified.
(node as JSDocContainer).jsDocCache = undefined;
}
return node;
}
@@ -2241,7 +2270,7 @@ namespace ts {
//
// <T extends "">
//
// We do *not* want to consume the > as we're consuming the expression for "".
// We do *not* want to consume the `>` as we're consuming the expression for "".
node.expression = parseUnaryExpressionOrHigher();
}
}
@@ -3061,7 +3090,7 @@ namespace ts {
// And production (2) is parsed in "tryParseParenthesizedArrowFunctionExpression".
//
// If we do successfully parse arrow-function, we must *not* recurse for productions 1, 2 or 3. An ArrowFunction is
// not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
// not a LeftHandSideExpression, nor does it start a ConditionalExpression. So we are done
// with AssignmentExpression if we see one.
const arrowExpression = tryParseParenthesizedArrowFunctionExpression() || tryParseAsyncSimpleArrowFunctionExpression();
if (arrowExpression) {
@@ -3091,7 +3120,7 @@ namespace ts {
// we're in '2' or '3'. Consume the assignment and return.
//
// Note: we call reScanGreaterToken so that we get an appropriately merged token
// for cases like > > = becoming >>=
// for cases like `> > =` becoming `>>=`
if (isLeftHandSideExpression(expr) && isAssignmentOperator(reScanGreaterToken())) {
return makeBinaryExpression(expr, <BinaryOperatorToken>parseTokenNode(), parseAssignmentExpressionOrHigher());
}
@@ -3247,7 +3276,7 @@ namespace ts {
if (first === SyntaxKind.OpenParenToken) {
if (second === SyntaxKind.CloseParenToken) {
// Simple cases: "() =>", "(): ", and "() {".
// Simple cases: "() =>", "(): ", and "() {".
// This is an arrow function with no parameters.
// The last one is not actually an arrow function,
// but this is probably what the user intended.
@@ -3472,7 +3501,9 @@ namespace ts {
node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher);
node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition*/ false,
Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken));
node.whenFalse = parseAssignmentExpressionOrHigher();
node.whenFalse = nodeIsPresent(node.colonToken)
? parseAssignmentExpressionOrHigher()
: createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken));
return finishNode(node);
}
@@ -3867,7 +3898,8 @@ namespace ts {
// We don't want to eagerly consume all import keyword as import call expression so we look a head to find "("
// For example:
// var foo3 = require("subfolder
// import * as foo1 from "module-from-node -> we want this import to be a statement rather than import call expression
// import * as foo1 from "module-from-node
// We want this import to be a statement rather than import call expression
sourceFile.flags |= NodeFlags.PossiblyContainsDynamicImport;
expression = parseTokenNode<PrimaryExpression>();
}
@@ -3917,7 +3949,7 @@ namespace ts {
// treated as the invocation of "new Foo". We disambiguate that in code (to match
// the original grammar) by making sure that if we see an ObjectCreationExpression
// we always consume arguments if they are there. So we treat "new Foo()" as an
// object creation only, and not at all as an invocation) Another way to think
// object creation only, and not at all as an invocation. Another way to think
// about this is that for every "new" that we see, we will consume an argument list if
// it is there as part of the *associated* object creation node. Any additional
// argument lists we see, will become invocation expressions.
@@ -4333,7 +4365,7 @@ namespace ts {
const typeArguments = parseDelimitedList(ParsingContext.TypeArguments, parseType);
if (!parseExpected(SyntaxKind.GreaterThanToken)) {
// If it doesn't have the closing > then it's definitely not an type argument list.
// If it doesn't have the closing `>` then it's definitely not an type argument list.
return undefined;
}
@@ -5366,8 +5398,8 @@ namespace ts {
// off. The grammar would look something like this:
//
// MemberVariableDeclaration[Yield]:
// AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In];
// AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield];
// AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initializer_opt[In];
// AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initializer_opt[In, ?Yield];
//
// The checker may still error in the static case to explicitly disallow the yield expression.
node.initializer = hasModifier(node, ModifierFlags.Static)
@@ -5462,6 +5494,7 @@ namespace ts {
switch (token()) {
case SyntaxKind.OpenParenToken: // Method declaration
case SyntaxKind.LessThanToken: // Generic Method declaration
case SyntaxKind.ExclamationToken: // Non-null assertion on property name
case SyntaxKind.ColonToken: // Type Annotation for declaration
case SyntaxKind.EqualsToken: // Initializer for declaration
case SyntaxKind.QuestionToken: // Not valid, but permitted so that it gets caught later on.
@@ -6240,17 +6273,17 @@ namespace ts {
indent += text.length;
}
nextJSDocToken();
while (token() === SyntaxKind.WhitespaceTrivia) {
nextJSDocToken();
let t = nextJSDocToken();
while (t === SyntaxKind.WhitespaceTrivia) {
t = nextJSDocToken();
}
if (token() === SyntaxKind.NewLineTrivia) {
if (t === SyntaxKind.NewLineTrivia) {
state = JSDocState.BeginningOfLine;
indent = 0;
nextJSDocToken();
t = nextJSDocToken();
}
while (token() !== SyntaxKind.EndOfFileToken) {
switch (token()) {
loop: while (true) {
switch (t) {
case SyntaxKind.AtToken:
if (state === JSDocState.BeginningOfLine || state === JSDocState.SawAsterisk) {
removeTrailingNewlines(comments);
@@ -6304,7 +6337,7 @@ namespace ts {
indent += whitespace.length;
break;
case SyntaxKind.EndOfFileToken:
break;
break loop;
default:
// anything other than whitespace or asterisk at the beginning of the line starts the comment text
state = JSDocState.SavingComments;
@@ -6312,10 +6345,11 @@ namespace ts {
break;
}
if (advanceToken) {
nextJSDocToken();
t = nextJSDocToken();
}
else {
advanceToken = true;
t = currentToken as JsDocSyntaxKind;
}
}
removeLeadingNewlines(comments);
@@ -6426,8 +6460,9 @@ namespace ts {
comments.push(text);
indent += text.length;
}
while (token() !== SyntaxKind.AtToken && token() !== SyntaxKind.EndOfFileToken) {
switch (token()) {
let tok = token() as JsDocSyntaxKind;
loop: while (true) {
switch (tok) {
case SyntaxKind.NewLineTrivia:
if (state >= JSDocState.SawAsterisk) {
state = JSDocState.BeginningOfLine;
@@ -6436,8 +6471,9 @@ namespace ts {
indent = 0;
break;
case SyntaxKind.AtToken:
case SyntaxKind.EndOfFileToken:
// Done
break;
break loop;
case SyntaxKind.WhitespaceTrivia:
if (state === JSDocState.SavingComments) {
pushComment(scanner.getTokenText());
@@ -6465,11 +6501,7 @@ namespace ts {
pushComment(scanner.getTokenText());
break;
}
if (token() === SyntaxKind.AtToken) {
// Done
break;
}
nextJSDocToken();
tok = nextJSDocToken();
}
removeLeadingNewlines(comments);
@@ -6571,10 +6603,7 @@ namespace ts {
const start = scanner.getStartPos();
let children: JSDocParameterTag[];
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.Parameter, name))) {
if (!children) {
children = [];
}
children.push(child);
children = append(children, child);
}
if (children) {
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
@@ -6691,10 +6720,7 @@ namespace ts {
}
}
else {
if (!jsdocTypeLiteral.jsDocPropertyTags) {
jsdocTypeLiteral.jsDocPropertyTags = [] as MutableNodeArray<JSDocPropertyTag>;
}
(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray<JSDocPropertyTag>).push(child);
jsdocTypeLiteral.jsDocPropertyTags = append(jsdocTypeLiteral.jsDocPropertyTags as MutableNodeArray<JSDocPropertyTag>, child);
}
}
if (jsdocTypeLiteral) {
@@ -6747,8 +6773,7 @@ namespace ts {
let canParseTag = true;
let seenAsterisk = false;
while (true) {
nextJSDocToken();
switch (token()) {
switch (nextJSDocToken()) {
case SyntaxKind.AtToken:
if (canParseTag) {
const child = tryParseChildTag(target);
@@ -6844,7 +6869,7 @@ namespace ts {
return result;
}
function nextJSDocToken(): SyntaxKind {
function nextJSDocToken(): JsDocSyntaxKind {
return currentToken = scanner.scanJSDocToken();
}
@@ -7048,7 +7073,7 @@ namespace ts {
// If the 'pos' is before the start of the change, then we don't need to touch it.
// If it isn't, then the 'pos' must be inside the change. How we update it will
// depend if delta is positive or negative. If delta is positive then we have
// depend if delta is positive or negative. If delta is positive then we have
// something like:
//
// -------------------AAA-----------------
@@ -7073,7 +7098,7 @@ namespace ts {
// If the 'end' is after the change range, then we always adjust it by the delta
// amount. However, if the end is in the change range, then how we adjust it
// will depend on if delta is positive or negative. If delta is positive then we
// will depend on if delta is positive or negative. If delta is positive then we
// have something like:
//
// -------------------AAA-----------------
+39 -23
View File
@@ -6,7 +6,7 @@
namespace ts {
const ignoreDiagnosticCommentRegEx = /(^\s*$)|(^\s*\/\/\/?\s*(@ts-ignore)?)/;
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string {
export function findConfigFile(searchPath: string, fileExists: (fileName: string) => boolean, configName = "tsconfig.json"): string | undefined {
return forEachAncestorDirectory(searchPath, ancestor => {
const fileName = combinePaths(ancestor, configName);
return fileExists(fileName) ? fileName : undefined;
@@ -241,22 +241,28 @@ namespace ts {
return errorMessage;
}
const redForegroundEscapeSequence = "\u001b[91m";
const yellowForegroundEscapeSequence = "\u001b[93m";
const blueForegroundEscapeSequence = "\u001b[93m";
/** @internal */
export enum ForegroundColorEscapeSequences {
Grey = "\u001b[90m",
Red = "\u001b[91m",
Yellow = "\u001b[93m",
Blue = "\u001b[94m",
Cyan = "\u001b[96m"
}
const gutterStyleSequence = "\u001b[30;47m";
const gutterSeparator = " ";
const resetEscapeSequence = "\u001b[0m";
const ellipsis = "...";
function getCategoryFormat(category: DiagnosticCategory): string {
switch (category) {
case DiagnosticCategory.Warning: return yellowForegroundEscapeSequence;
case DiagnosticCategory.Error: return redForegroundEscapeSequence;
case DiagnosticCategory.Message: return blueForegroundEscapeSequence;
case DiagnosticCategory.Warning: return ForegroundColorEscapeSequences.Yellow;
case DiagnosticCategory.Error: return ForegroundColorEscapeSequences.Red;
case DiagnosticCategory.Message: return ForegroundColorEscapeSequences.Blue;
}
}
function formatAndReset(text: string, formatStyle: string) {
/** @internal */
export function formatColorAndReset(text: string, formatStyle: string) {
return formatStyle + text + resetEscapeSequence;
}
@@ -289,7 +295,7 @@ namespace ts {
// If the error spans over 5 lines, we'll only show the first 2 and last 2 lines,
// so we'll skip ahead to the second-to-last line.
if (hasMoreThanFiveLines && firstLine + 1 < i && i < lastLine - 1) {
context += formatAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
context += formatColorAndReset(padLeft(ellipsis, gutterWidth), gutterStyleSequence) + gutterSeparator + host.getNewLine();
i = lastLine - 1;
}
@@ -300,12 +306,12 @@ namespace ts {
lineContent = lineContent.replace("\t", " "); // convert tabs to single spaces
// Output the gutter and the actual contents of the line.
context += formatAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
context += formatColorAndReset(padLeft(i + 1 + "", gutterWidth), gutterStyleSequence) + gutterSeparator;
context += lineContent + host.getNewLine();
// Output the gutter and the error span for the line using tildes.
context += formatAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
context += redForegroundEscapeSequence;
context += formatColorAndReset(padLeft("", gutterWidth), gutterStyleSequence) + gutterSeparator;
context += ForegroundColorEscapeSequences.Red;
if (i === firstLine) {
// If we're on the last line, then limit it to the last character of the last line.
// Otherwise, we'll just squiggle the rest of the line, giving 'slice' no end position.
@@ -324,13 +330,19 @@ namespace ts {
context += resetEscapeSequence;
}
output += host.getNewLine();
output += `${ relativeFileName }(${ firstLine + 1 },${ firstLineChar + 1 }): `;
output += formatColorAndReset(relativeFileName, ForegroundColorEscapeSequences.Cyan);
output += ":";
output += formatColorAndReset(`${ firstLine + 1 }`, ForegroundColorEscapeSequences.Yellow);
output += ":";
output += formatColorAndReset(`${ firstLineChar + 1 }`, ForegroundColorEscapeSequences.Yellow);
output += " - ";
}
const categoryColor = getCategoryFormat(diagnostic.category);
const category = DiagnosticCategory[diagnostic.category].toLowerCase();
output += `${ formatAndReset(category, categoryColor) } TS${ diagnostic.code }: ${ flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine()) }`;
output += formatColorAndReset(category, categoryColor);
output += formatColorAndReset(` TS${ diagnostic.code }: `, ForegroundColorEscapeSequences.Grey);
output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
if (diagnostic.file) {
output += host.getNewLine();
@@ -339,7 +351,7 @@ namespace ts {
output += host.getNewLine();
}
return output;
return output + host.getNewLine();
}
export function flattenDiagnosticMessageText(messageText: string | DiagnosticMessageChain, newLine: string): string {
@@ -704,7 +716,7 @@ namespace ts {
interface OldProgramState {
program: Program | undefined;
file: SourceFile;
oldSourceFile: SourceFile | undefined;
/** The collection of paths modified *since* the old program. */
modifiedFilePaths: Path[];
}
@@ -754,7 +766,6 @@ namespace ts {
/** A transient placeholder 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];
// If the source file is unchanged and doesnt have invalidated resolution, reuse the module resolutions
@@ -825,9 +836,13 @@ namespace ts {
// If we change our policy of rechecking failed lookups on each program create,
// we should adjust the value returned here.
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState: OldProgramState): boolean {
const resolutionToFile = getResolvedModule(oldProgramState.file, moduleName);
if (resolutionToFile) {
// module used to be resolved to file - ignore it
const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile, moduleName);
const resolvedFile = resolutionToFile && oldProgramState.program && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName);
if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) {
// In the old program, we resolved to an ambient module that was in the same
// place as we expected to find an actual module file.
// We actually need to return 'false' here even though this seems like a 'true' case
// because the normal module resolution algorithm will find this anyway.
return false;
}
const ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
@@ -1001,7 +1016,7 @@ namespace ts {
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory);
if (resolveModuleNamesWorker) {
const moduleNames = getModuleNames(newSourceFile);
const oldProgramState = { program: oldProgram, file: oldSourceFile, modifiedFilePaths };
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile, modifiedFilePaths };
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
// ensure that module resolution results are still correct
const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo);
@@ -1586,6 +1601,7 @@ namespace ts {
// synthesize 'import "tslib"' declaration
const externalHelpersModuleReference = createLiteral(externalHelpersModuleNameText);
const importDecl = createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, /*importClause*/ undefined);
addEmitFlags(importDecl, EmitFlags.NeverApplyImportHelper);
externalHelpersModuleReference.parent = importDecl;
importDecl.parent = file;
imports = [externalHelpersModuleReference];
@@ -1945,7 +1961,7 @@ namespace ts {
if (file.imports.length || file.moduleAugmentations.length) {
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
const moduleNames = getModuleNames(file);
const oldProgramState = { program: oldProgram, file, modifiedFilePaths };
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile: oldProgram && oldProgram.getSourceFile(file.fileName), modifiedFilePaths };
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory), file, oldProgramState);
Debug.assert(resolutions.length === moduleNames.length);
for (let i = 0; i < moduleNames.length; i++) {
+136 -55
View File
@@ -35,7 +35,7 @@ namespace ts {
scanJsxAttributeValue(): SyntaxKind;
reScanJsxToken(): SyntaxKind;
scanJsxToken(): SyntaxKind;
scanJSDocToken(): SyntaxKind;
scanJSDocToken(): JsDocSyntaxKind;
scan(): SyntaxKind;
getText(): string;
// Sets the text for the scanner to scan. An optional subrange starting point and length
@@ -193,7 +193,7 @@ namespace ts {
/*
As per ECMAScript Language Specification 3th Edition, Section 7.6: Identifiers
IdentifierStart ::
Can contain Unicode 3.0.0 categories:
Can contain Unicode 3.0.0 categories:
Uppercase letter (Lu),
Lowercase letter (Ll),
Titlecase letter (Lt),
@@ -201,7 +201,7 @@ namespace ts {
Other letter (Lo), or
Letter number (Nl).
IdentifierPart :: =
Can contain IdentifierStart + Unicode 3.0.0 categories:
Can contain IdentifierStart + Unicode 3.0.0 categories:
Non-spacing mark (Mn),
Combining spacing mark (Mc),
Decimal number (Nd), or
@@ -216,7 +216,7 @@ namespace ts {
/*
As per ECMAScript Language Specification 5th Edition, Section 7.6: ISyntaxToken Names and Identifiers
IdentifierStart ::
Can contain Unicode 6.2 categories:
Can contain Unicode 6.2 categories:
Uppercase letter (Lu),
Lowercase letter (Ll),
Titlecase letter (Lt),
@@ -224,7 +224,7 @@ namespace ts {
Other letter (Lo), or
Letter number (Nl).
IdentifierPart ::
Can contain IdentifierStart + Unicode 6.2 categories:
Can contain IdentifierStart + Unicode 6.2 categories:
Non-spacing mark (Mn),
Combining spacing mark (Mc),
Decimal number (Nd),
@@ -561,9 +561,9 @@ namespace ts {
return false;
}
function scanConflictMarkerTrivia(text: string, pos: number, error?: ErrorCallback) {
function scanConflictMarkerTrivia(text: string, pos: number, error?: (diag: DiagnosticMessage, pos?: number, len?: number) => void) {
if (error) {
error(Diagnostics.Merge_conflict_marker_encountered, mergeConflictMarkerLength);
error(Diagnostics.Merge_conflict_marker_encountered, pos, mergeConflictMarkerLength);
}
const ch = text.charCodeAt(pos);
@@ -852,34 +852,92 @@ namespace ts {
scanRange,
};
function error(message: DiagnosticMessage, length?: number): void {
function error(message: DiagnosticMessage): void;
function error(message: DiagnosticMessage, errPos: number, length: number): void;
function error(message: DiagnosticMessage, errPos: number = pos, length?: number): void {
if (onError) {
const oldPos = pos;
pos = errPos;
onError(message, length || 0);
pos = oldPos;
}
}
function scanNumberFragment(): string {
let start = pos;
let allowSeparator = false;
let isPreviousTokenSeparator = false;
let result = "";
while (true) {
const ch = text.charCodeAt(pos);
if (ch === CharacterCodes._) {
tokenFlags |= TokenFlags.ContainsSeparator;
if (allowSeparator) {
allowSeparator = false;
isPreviousTokenSeparator = true;
result += text.substring(start, pos);
}
else if (isPreviousTokenSeparator) {
error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
}
else {
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
}
pos++;
start = pos;
continue;
}
if (isDigit(ch)) {
allowSeparator = true;
isPreviousTokenSeparator = false;
pos++;
continue;
}
break;
}
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
}
return result + text.substring(start, pos);
}
function scanNumber(): string {
const start = pos;
while (isDigit(text.charCodeAt(pos))) pos++;
const mainFragment = scanNumberFragment();
let decimalFragment: string;
let scientificFragment: string;
if (text.charCodeAt(pos) === CharacterCodes.dot) {
pos++;
while (isDigit(text.charCodeAt(pos))) pos++;
decimalFragment = scanNumberFragment();
}
let end = pos;
if (text.charCodeAt(pos) === CharacterCodes.E || text.charCodeAt(pos) === CharacterCodes.e) {
pos++;
tokenFlags |= TokenFlags.Scientific;
if (text.charCodeAt(pos) === CharacterCodes.plus || text.charCodeAt(pos) === CharacterCodes.minus) pos++;
if (isDigit(text.charCodeAt(pos))) {
pos++;
while (isDigit(text.charCodeAt(pos))) pos++;
end = pos;
}
else {
const preNumericPart = pos;
const finalFragment = scanNumberFragment();
if (!finalFragment) {
error(Diagnostics.Digit_expected);
}
else {
scientificFragment = text.substring(end, preNumericPart) + finalFragment;
end = pos;
}
}
if (tokenFlags & TokenFlags.ContainsSeparator) {
let result = mainFragment;
if (decimalFragment) {
result += "." + decimalFragment;
}
if (scientificFragment) {
result += scientificFragment;
}
return "" + +result;
}
else {
return "" + +(text.substring(start, end)); // No need to use all the fragments; no _ removal needed
}
return "" + +(text.substring(start, end));
}
function scanOctalDigits(): number {
@@ -894,23 +952,41 @@ namespace ts {
* Scans the given number of hexadecimal digits in the text,
* returning -1 if the given number is unavailable.
*/
function scanExactNumberOfHexDigits(count: number): number {
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false);
function scanExactNumberOfHexDigits(count: number, canHaveSeparators: boolean): number {
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
}
/**
* Scans as many hexadecimal digits as are available in the text,
* returning -1 if the given number of digits was unavailable.
*/
function scanMinimumNumberOfHexDigits(count: number): number {
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true);
function scanMinimumNumberOfHexDigits(count: number, canHaveSeparators: boolean): number {
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators);
}
function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean): number {
function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean, canHaveSeparators: boolean): number {
let digits = 0;
let value = 0;
let allowSeparator = false;
let isPreviousTokenSeparator = false;
while (digits < minCount || scanAsManyAsPossible) {
const ch = text.charCodeAt(pos);
if (canHaveSeparators && ch === CharacterCodes._) {
tokenFlags |= TokenFlags.ContainsSeparator;
if (allowSeparator) {
allowSeparator = false;
isPreviousTokenSeparator = true;
}
else if (isPreviousTokenSeparator) {
error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
}
else {
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
}
pos++;
continue;
}
allowSeparator = canHaveSeparators;
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
value = value * 16 + ch - CharacterCodes._0;
}
@@ -925,10 +1001,14 @@ namespace ts {
}
pos++;
digits++;
isPreviousTokenSeparator = false;
}
if (digits < minCount) {
value = -1;
}
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
}
return value;
}
@@ -1097,7 +1177,7 @@ namespace ts {
}
function scanHexadecimalEscape(numDigits: number): string {
const escapedValue = scanExactNumberOfHexDigits(numDigits);
const escapedValue = scanExactNumberOfHexDigits(numDigits, /*canHaveSeparators*/ false);
if (escapedValue >= 0) {
return String.fromCharCode(escapedValue);
@@ -1109,7 +1189,7 @@ namespace ts {
}
function scanExtendedUnicodeEscape(): string {
const escapedValue = scanMinimumNumberOfHexDigits(1);
const escapedValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
let isInvalidExtendedEscape = false;
// Validate the value of the digit
@@ -1162,7 +1242,7 @@ namespace ts {
if (pos + 5 < end && text.charCodeAt(pos + 1) === CharacterCodes.u) {
const start = pos;
pos += 2;
const value = scanExactNumberOfHexDigits(4);
const value = scanExactNumberOfHexDigits(4, /*canHaveSeparators*/ false);
pos = start;
return value;
}
@@ -1218,8 +1298,27 @@ namespace ts {
// For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
// Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
let numberOfDigits = 0;
let separatorAllowed = false;
let isPreviousTokenSeparator = false;
while (true) {
const ch = text.charCodeAt(pos);
// Numeric seperators are allowed anywhere within a numeric literal, except not at the beginning, or following another separator
if (ch === CharacterCodes._) {
tokenFlags |= TokenFlags.ContainsSeparator;
if (separatorAllowed) {
separatorAllowed = false;
isPreviousTokenSeparator = true;
}
else if (isPreviousTokenSeparator) {
error(Diagnostics.Multiple_consecutive_numeric_separators_are_not_permitted, pos, 1);
}
else {
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos, 1);
}
pos++;
continue;
}
separatorAllowed = true;
const valueOfCh = ch - CharacterCodes._0;
if (!isDigit(ch) || valueOfCh >= base) {
break;
@@ -1227,11 +1326,17 @@ namespace ts {
value = value * base + valueOfCh;
pos++;
numberOfDigits++;
isPreviousTokenSeparator = false;
}
// Invalid binaryIntegerLiteral or octalIntegerLiteral
if (numberOfDigits === 0) {
return -1;
}
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
// Literal ends with underscore - not allowed
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
return value;
}
return value;
}
@@ -1435,7 +1540,7 @@ namespace ts {
case CharacterCodes._0:
if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.X || text.charCodeAt(pos + 1) === CharacterCodes.x)) {
pos += 2;
let value = scanMinimumNumberOfHexDigits(1);
let value = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
if (value < 0) {
error(Diagnostics.Hexadecimal_digit_expected);
value = 0;
@@ -1489,7 +1594,7 @@ namespace ts {
return token = SyntaxKind.NumericLiteral;
case CharacterCodes.colon:
pos++;
return token = SyntaxKind.ColonToken;
return token = SyntaxKind.ColonToken;
case CharacterCodes.semicolon:
pos++;
return token = SyntaxKind.SemicolonToken;
@@ -1800,7 +1905,7 @@ namespace ts {
break;
}
}
tokenValue += text.substr(firstCharPosition, pos - firstCharPosition);
tokenValue += text.substring(firstCharPosition, pos);
}
return token;
}
@@ -1819,7 +1924,7 @@ namespace ts {
}
}
function scanJSDocToken(): SyntaxKind {
function scanJSDocToken(): JsDocSyntaxKind {
if (pos >= end) {
return token = SyntaxKind.EndOfFileToken;
}
@@ -1828,6 +1933,7 @@ namespace ts {
tokenPos = pos;
const ch = text.charCodeAt(pos);
pos++;
switch (ch) {
case CharacterCodes.tab:
case CharacterCodes.verticalTab:
@@ -1838,56 +1944,31 @@ namespace ts {
}
return token = SyntaxKind.WhitespaceTrivia;
case CharacterCodes.at:
pos++;
return token = SyntaxKind.AtToken;
case CharacterCodes.lineFeed:
case CharacterCodes.carriageReturn:
pos++;
return token = SyntaxKind.NewLineTrivia;
case CharacterCodes.asterisk:
pos++;
return token = SyntaxKind.AsteriskToken;
case CharacterCodes.openBrace:
pos++;
return token = SyntaxKind.OpenBraceToken;
case CharacterCodes.closeBrace:
pos++;
return token = SyntaxKind.CloseBraceToken;
case CharacterCodes.openBracket:
pos++;
return token = SyntaxKind.OpenBracketToken;
case CharacterCodes.closeBracket:
pos++;
return token = SyntaxKind.CloseBracketToken;
case CharacterCodes.lessThan:
pos++;
return token = SyntaxKind.LessThanToken;
case CharacterCodes.greaterThan:
pos++;
return token = SyntaxKind.GreaterThanToken;
case CharacterCodes.equals:
pos++;
return token = SyntaxKind.EqualsToken;
case CharacterCodes.comma:
pos++;
return token = SyntaxKind.CommaToken;
case CharacterCodes.dot:
pos++;
if (text.substr(tokenPos, pos + 2) === "...") {
pos += 2;
return token = SyntaxKind.DotDotDotToken;
}
return token = SyntaxKind.DotToken;
case CharacterCodes.exclamation:
pos++;
return token = SyntaxKind.ExclamationToken;
case CharacterCodes.question:
pos++;
return token = SyntaxKind.QuestionToken;
}
if (isIdentifierStart(ch, ScriptTarget.Latest)) {
pos++;
while (isIdentifierPart(text.charCodeAt(pos), ScriptTarget.Latest) && pos < end) {
pos++;
}
@@ -1895,7 +1976,7 @@ namespace ts {
return token = SyntaxKind.Identifier;
}
else {
return pos += 1, token = SyntaxKind.Unknown;
return token = SyntaxKind.Unknown;
}
}
+1 -1
View File
@@ -420,7 +420,7 @@ namespace ts {
host.getCanonicalFileName,
/*isAbsolutePathAnUrl*/ true);
sourceMapSourceIndex = indexOf(sourceMapData.sourceMapSources, source);
sourceMapSourceIndex = sourceMapData.sourceMapSources.indexOf(source);
if (sourceMapSourceIndex === -1) {
sourceMapSourceIndex = sourceMapData.sourceMapSources.length;
sourceMapData.sourceMapSources.push(source);
+4 -2
View File
@@ -2,6 +2,7 @@
namespace ts {
export function createGetSymbolWalker(
getRestTypeOfSignature: (sig: Signature) => Type,
getTypePredicateOfSignature: (sig: Signature) => TypePredicate | undefined,
getReturnTypeOfSignature: (sig: Signature) => Type,
getBaseTypes: (type: Type) => Type[],
resolveStructuredTypeMembers: (type: ObjectType) => ResolvedType,
@@ -117,8 +118,9 @@ namespace ts {
}
function visitSignature(signature: Signature): void {
if (signature.typePredicate) {
visitType(signature.typePredicate.type);
const typePredicate = getTypePredicateOfSignature(signature);
if (typePredicate) {
visitType(typePredicate.type);
}
forEach(signature.typeParameters, visitType);
+1 -1
View File
@@ -859,7 +859,7 @@ namespace ts {
statements.push(
setTextRange(
createStatement(
createExtendsHelper(context, getLocalName(node))
createExtendsHelper(context, getInternalName(node))
),
/*location*/ extendsClauseElement
)
+1 -1
View File
@@ -968,7 +968,7 @@ namespace ts {
name: "typescript:asyncValues",
scoped: false,
text: `
var __asyncValues = (this && this.__asyncIterator) || function (o) {
var __asyncValues = (this && this.__asyncValues) || function (o) {
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator];
return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator]();
+2 -2
View File
@@ -3190,8 +3190,8 @@ namespace ts {
// `throw` methods that step through the generator when invoked.
//
// parameters:
// thisArg The value to use as the `this` binding for the transformed generator body.
// body A function that acts as the transformed generator body.
// @param thisArg The value to use as the `this` binding for the transformed generator body.
// @param body A function that acts as the transformed generator body.
//
// variables:
// _ Persistent state for the generator that is shared between the helper and the
+7 -7
View File
@@ -25,14 +25,14 @@ namespace ts {
if (externalHelpersModuleName) {
const statements: Statement[] = [];
const statementOffset = addPrologue(statements, node.statements);
append(statements,
createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText)
)
const tslibImport = createImportDeclaration(
/*decorators*/ undefined,
/*modifiers*/ undefined,
createImportClause(/*name*/ undefined, createNamespaceImport(externalHelpersModuleName)),
createLiteral(externalHelpersModuleNameText)
);
addEmitFlags(tslibImport, EmitFlags.NeverApplyImportHelper);
append(statements, tslibImport);
addRange(statements, visitNodes(node.statements, visitor, isStatement, statementOffset));
return updateSourceFileNode(
+76 -6
View File
@@ -148,7 +148,7 @@ namespace ts {
// Create an updated SourceFile:
//
// define(moduleName?, ["module1", "module2"], function ...
return updateSourceFileNode(node,
const updated = updateSourceFileNode(node,
setTextRange(
createNodeArray([
createStatement(
@@ -192,6 +192,9 @@ namespace ts {
/*location*/ node.statements
)
);
addEmitHelpers(updated, context.readEmitHelpers());
return updated;
}
/**
@@ -296,7 +299,7 @@ namespace ts {
// }
// })(function ...)
return updateSourceFileNode(
const updated = updateSourceFileNode(
node,
setTextRange(
createNodeArray([
@@ -328,6 +331,9 @@ namespace ts {
/*location*/ node.statements
)
);
addEmitHelpers(updated, context.readEmitHelpers());
return updated;
}
/**
@@ -385,6 +391,18 @@ namespace ts {
return { aliasedModuleNames, unaliasedModuleNames, importAliasNames };
}
function getAMDImportExpressionForImport(node: ImportDeclaration | ExportDeclaration | ImportEqualsDeclaration) {
if (isImportEqualsDeclaration(node) || isExportDeclaration(node) || !getExternalModuleNameLiteral(node, currentSourceFile, host, resolver, compilerOptions)) {
return undefined;
}
const name = getLocalNameForExternalImport(node, currentSourceFile);
const expr = getHelperExpressionForImport(node, name);
if (expr === name) {
return undefined;
}
return createStatement(createAssignment(name, expr));
}
/**
* Transforms a SourceFile into an AMD or UMD module body.
*
@@ -402,6 +420,9 @@ namespace ts {
// Visit each statement of the module body.
append(statements, visitNode(currentModuleInfo.externalHelpersImportDeclaration, sourceElementVisitor, isStatement));
if (moduleKind === ModuleKind.AMD) {
addRange(statements, mapDefined(currentModuleInfo.externalImports, getAMDImportExpressionForImport));
}
addRange(statements, visitNodes(node.statements, sourceElementVisitor, isStatement, statementOffset));
// Append the 'export =' statement if provided.
@@ -617,7 +638,12 @@ namespace ts {
}
}
return createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
const promise = createNew(createIdentifier("Promise"), /*typeArguments*/ undefined, [func]);
if (compilerOptions.esModuleInterop) {
context.requestEmitHelper(importStarHelper);
return createCall(createPropertyAccess(promise, createIdentifier("then")), /*typeArguments*/ undefined, [getHelperName("__importStar")]);
}
return promise;
}
function createImportCallExpressionCommonJS(arg: Expression | undefined, containsLexicalThis: boolean): Expression {
@@ -627,7 +653,11 @@ namespace ts {
// We have to wrap require in then callback so that require is done in asynchronously
// if we simply do require in resolve callback in Promise constructor. We will execute the loading immediately
const promiseResolveCall = createCall(createPropertyAccess(createIdentifier("Promise"), "resolve"), /*typeArguments*/ undefined, /*argumentsArray*/ []);
const requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
let requireCall = createCall(createIdentifier("require"), /*typeArguments*/ undefined, arg ? [arg] : []);
if (compilerOptions.esModuleInterop) {
context.requestEmitHelper(importStarHelper);
requireCall = createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [requireCall]);
}
let func: FunctionExpression | ArrowFunction;
if (languageVersion >= ScriptTarget.ES2015) {
@@ -660,6 +690,22 @@ namespace ts {
return createCall(createPropertyAccess(promiseResolveCall, "then"), /*typeArguments*/ undefined, [func]);
}
function getHelperExpressionForImport(node: ImportDeclaration, innerExpr: Expression) {
if (!compilerOptions.esModuleInterop || getEmitFlags(node) & EmitFlags.NeverApplyImportHelper) {
return innerExpr;
}
if (getNamespaceDeclarationNode(node)) {
context.requestEmitHelper(importStarHelper);
return createCall(getHelperName("__importStar"), /*typeArguments*/ undefined, [innerExpr]);
}
if (isDefaultImport(node)) {
context.requestEmitHelper(importDefaultHelper);
return createCall(getHelperName("__importDefault"), /*typeArguments*/ undefined, [innerExpr]);
}
return innerExpr;
}
/**
* Visits an ImportDeclaration node.
*
@@ -681,7 +727,7 @@ namespace ts {
createVariableDeclaration(
getSynthesizedClone(namespaceDeclaration.name),
/*type*/ undefined,
createRequireCall(node)
getHelperExpressionForImport(node, createRequireCall(node))
)
);
}
@@ -694,7 +740,7 @@ namespace ts {
createVariableDeclaration(
getGeneratedNameForNode(node),
/*type*/ undefined,
createRequireCall(node)
getHelperExpressionForImport(node, createRequireCall(node))
)
);
@@ -1671,4 +1717,28 @@ namespace ts {
text: `
var __syncRequire = typeof module === "object" && typeof module.exports === "object";`
};
// emit helper for `import * as Name from "foo"`
const importStarHelper: EmitHelper = {
name: "typescript:commonjsimportstar",
scoped: false,
text: `
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
}`
};
// emit helper for `import Name from "foo"`
const importDefaultHelper: EmitHelper = {
name: "typescript:commonjsimportdefault",
scoped: false,
text: `
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
}`
};
}
+1 -1
View File
@@ -81,7 +81,7 @@ namespace ts {
let classAliases: Identifier[];
/**
* Keeps track of whether we are within any containing namespaces when performing
* Keeps track of whether we are within any containing namespaces when performing
* just-in-time substitution while printing an expression identifier.
*/
let applicableSubstitutions: TypeScriptSubstitutionFlags;
+1
View File
@@ -143,6 +143,7 @@ namespace ts {
createLiteral(externalHelpersModuleNameText));
if (externalHelpersImportDeclaration) {
addEmitFlags(externalHelpersImportDeclaration, EmitFlags.NeverApplyImportHelper);
externalImports.unshift(externalHelpersImportDeclaration);
}
+157 -59
View File
@@ -58,6 +58,23 @@ namespace ts {
end: number;
}
export type JsDocSyntaxKind =
| SyntaxKind.EndOfFileToken
| SyntaxKind.WhitespaceTrivia
| SyntaxKind.AtToken
| SyntaxKind.NewLineTrivia
| SyntaxKind.AsteriskToken
| SyntaxKind.OpenBraceToken
| SyntaxKind.CloseBraceToken
| SyntaxKind.LessThanToken
| SyntaxKind.OpenBracketToken
| SyntaxKind.CloseBracketToken
| SyntaxKind.EqualsToken
| SyntaxKind.CommaToken
| SyntaxKind.DotToken
| SyntaxKind.Identifier
| SyntaxKind.Unknown;
// token > SyntaxKind.Identifer => token is a keyword
// Also, If you add a new SyntaxKind be sure to keep the `Markers` section at the bottom in sync
export const enum SyntaxKind {
@@ -438,24 +455,24 @@ namespace ts {
}
export const enum NodeFlags {
None = 0,
Let = 1 << 0, // Variable declaration
Const = 1 << 1, // Variable declaration
NestedNamespace = 1 << 2, // Namespace declaration
Synthesized = 1 << 3, // Node was synthesized during transformation
Namespace = 1 << 4, // Namespace declaration
ExportContext = 1 << 5, // Export context (initialized by binding)
ContainsThis = 1 << 6, // Interface contains references to "this"
HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding)
None = 0,
Let = 1 << 0, // Variable declaration
Const = 1 << 1, // Variable declaration
NestedNamespace = 1 << 2, // Namespace declaration
Synthesized = 1 << 3, // Node was synthesized during transformation
Namespace = 1 << 4, // Namespace declaration
ExportContext = 1 << 5, // Export context (initialized by binding)
ContainsThis = 1 << 6, // Interface contains references to "this"
HasImplicitReturn = 1 << 7, // If function implicitly returns on one of codepaths (initialized by binding)
HasExplicitReturn = 1 << 8, // If function has explicit reachable return on one of codepaths (initialized by binding)
GlobalAugmentation = 1 << 9, // Set if module declaration is an augmentation for the global scope
HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding)
DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed
YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator
DecoratorContext = 1 << 13, // If node was parsed as part of a decorator
AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript
HasAsyncFunctions = 1 << 10, // If the file has async functions (initialized by binding)
DisallowInContext = 1 << 11, // If node was parsed in a context where 'in-expressions' are not allowed
YieldContext = 1 << 12, // If node was parsed in the 'yield' context created when parsing a generator
DecoratorContext = 1 << 13, // If node was parsed as part of a decorator
AwaitContext = 1 << 14, // If node was parsed in the 'await' context created when parsing an async function
ThisNodeHasError = 1 << 15, // If the parser encountered an error when parsing the code that created this node
JavaScriptFile = 1 << 16, // If node was parsed in a JavaScript
ThisNodeOrAnySubNodesHasError = 1 << 17, // If this node or any of its children had an error
HasAggregatedChildData = 1 << 18, // If we've computed data from children and cached it in this node
@@ -584,6 +601,40 @@ namespace ts {
| JSDocFunctionType
| EndOfFileToken;
export type HasType =
| SignatureDeclaration
| VariableDeclaration
| ParameterDeclaration
| PropertySignature
| PropertyDeclaration
| TypePredicateNode
| ParenthesizedTypeNode
| TypeOperatorNode
| MappedTypeNode
| AssertionExpression
| TypeAliasDeclaration
| JSDocTypeExpression
| JSDocNonNullableType
| JSDocNullableType
| JSDocOptionalType
| JSDocVariadicType;
export type HasInitializer =
| HasExpressionInitializer
| ForStatement
| ForInStatement
| ForOfStatement
| JsxAttribute;
export type HasExpressionInitializer =
| VariableDeclaration
| ParameterDeclaration
| BindingElement
| PropertySignature
| PropertyDeclaration
| PropertyAssignment
| EnumMember;
/* @internal */
export type MutableNodeArray<T extends Node> = NodeArray<T> & T[];
@@ -793,6 +844,9 @@ namespace ts {
initializer?: Expression; // Optional initializer
}
/*@internal*/
export type BindingElementGrandparent = BindingElement["parent"]["parent"];
export interface PropertySignature extends TypeElement, JSDocContainer {
kind: SyntaxKind.PropertySignature;
name: PropertyName; // Declared property name
@@ -848,25 +902,18 @@ namespace ts {
expression: Expression;
}
// SyntaxKind.VariableDeclaration
// SyntaxKind.Parameter
// SyntaxKind.BindingElement
// SyntaxKind.Property
// SyntaxKind.PropertyAssignment
// SyntaxKind.JsxAttribute
// SyntaxKind.ShorthandPropertyAssignment
// SyntaxKind.EnumMember
// SyntaxKind.JSDocPropertyTag
// SyntaxKind.JSDocParameterTag
export interface VariableLikeDeclaration extends NamedDeclaration {
propertyName?: PropertyName;
dotDotDotToken?: DotDotDotToken;
name: DeclarationName;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
type?: TypeNode;
initializer?: Expression;
}
export type VariableLikeDeclaration =
| VariableDeclaration
| ParameterDeclaration
| BindingElement
| PropertyDeclaration
| PropertyAssignment
| PropertySignature
| JsxAttribute
| ShorthandPropertyAssignment
| EnumMember
| JSDocPropertyTag
| JSDocParameterTag;
export interface PropertyLikeDeclaration extends NamedDeclaration {
name: PropertyName;
@@ -949,7 +996,7 @@ namespace ts {
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer {
kind: SyntaxKind.Constructor;
parent?: ClassDeclaration | ClassExpression;
parent?: ClassLikeDeclaration;
body?: FunctionBody;
/* @internal */ returnFlowNode?: FlowNode;
}
@@ -957,14 +1004,14 @@ namespace ts {
/** For when we encounter a semicolon in a class declaration. ES6 allows these as class elements. */
export interface SemicolonClassElement extends ClassElement {
kind: SyntaxKind.SemicolonClassElement;
parent?: ClassDeclaration | ClassExpression;
parent?: ClassLikeDeclaration;
}
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
// ClassElement and an ObjectLiteralElement.
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
kind: SyntaxKind.GetAccessor;
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
parent?: ClassLikeDeclaration | ObjectLiteralExpression;
name: PropertyName;
body?: FunctionBody;
}
@@ -973,7 +1020,7 @@ namespace ts {
// ClassElement and an ObjectLiteralElement.
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
kind: SyntaxKind.SetAccessor;
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
parent?: ClassLikeDeclaration | ObjectLiteralExpression;
name: PropertyName;
body?: FunctionBody;
}
@@ -982,7 +1029,7 @@ namespace ts {
export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement {
kind: SyntaxKind.IndexSignature;
parent?: ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode;
parent?: ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode;
}
export interface TypeNode extends Node {
@@ -1102,11 +1149,13 @@ namespace ts {
export interface StringLiteral extends LiteralExpression {
kind: SyntaxKind.StringLiteral;
/* @internal */ textSourceNode?: Identifier | StringLiteral | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
/* @internal */ textSourceNode?: Identifier | StringLiteralLike | NumericLiteral; // Allows a StringLiteral to get its text from another node (used by transforms).
/** Note: this is only set when synthesizing a node, not during parsing. */
/* @internal */ singleQuote?: boolean;
}
/* @internal */ export type StringLiteralLike = StringLiteral | NoSubstitutionTemplateLiteral;
// Note: 'brands' in our syntax nodes serve to give us a small amount of nominal typing.
// Consider 'Expression'. Without the brand, 'Expression' is actually no different
// (structurally) than 'Node'. Because of this you can pass any Node to a function that
@@ -1364,7 +1413,7 @@ namespace ts {
export type BinaryOperatorToken = Token<BinaryOperator>;
export interface BinaryExpression extends Expression, Declaration {
export interface BinaryExpression extends Expression, Declaration {
kind: SyntaxKind.BinaryExpression;
left: Expression;
operatorToken: BinaryOperatorToken;
@@ -1452,6 +1501,7 @@ namespace ts {
kind: SyntaxKind.ArrowFunction;
equalsGreaterThanToken: EqualsGreaterThanToken;
body: ConciseBody;
name: never;
}
// The text property of a LiteralExpression stores the interpreted value of the literal in text form. For a StringLiteral,
@@ -1490,8 +1540,9 @@ namespace ts {
HexSpecifier = 1 << 6, // e.g. `0x00000000`
BinarySpecifier = 1 << 7, // e.g. `0b0110010000000000`
OctalSpecifier = 1 << 8, // e.g. `0o777`
ContainsSeparator = 1 << 9, // e.g. `0b1100_0101`
BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier,
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinarySpecifier | OctalSpecifier
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinarySpecifier | OctalSpecifier | ContainsSeparator
}
export interface NumericLiteral extends LiteralExpression {
@@ -1986,7 +2037,7 @@ namespace ts {
export interface HeritageClause extends Node {
kind: SyntaxKind.HeritageClause;
parent?: InterfaceDeclaration | ClassDeclaration | ClassExpression;
parent?: InterfaceDeclaration | ClassLikeDeclaration;
token: SyntaxKind.ExtendsKeyword | SyntaxKind.ImplementsKeyword;
types: NodeArray<ExpressionWithTypeArguments>;
}
@@ -2108,6 +2159,7 @@ namespace ts {
export interface ExportDeclaration extends DeclarationStatement {
kind: SyntaxKind.ExportDeclaration;
parent?: SourceFile | ModuleBlock;
/** Will not be assigned in the case of `export * from "foo";` */
exportClause?: NamedExports;
/** If this is not a StringLiteral it will be a grammar error. */
moduleSpecifier?: Expression;
@@ -2478,7 +2530,7 @@ 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<ResolvedModuleFull>;
/* @internal */ resolvedModules: Map<ResolvedModuleFull | undefined>;
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
/* @internal */ imports: ReadonlyArray<StringLiteral>;
// Identifier only if `declare global`
@@ -2509,7 +2561,7 @@ namespace ts {
export interface ParseConfigHost {
useCaseSensitiveFileNames: boolean;
readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string>, includes: ReadonlyArray<string>, depth: number): string[];
readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
/**
* Gets a value indicating whether the specified path exists and is a file.
@@ -2738,6 +2790,8 @@ namespace ts {
getAugmentedPropertiesOfType(type: Type): Symbol[];
getRootSymbols(symbol: Symbol): Symbol[];
getContextualType(node: Expression): Type | undefined;
/* @internal */ isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean;
/**
* returns unknownSignature in the case of an error.
* @param argumentCount Apparent number of arguments, passed in case of a possibly incomplete call. This should come from an ArgumentListInfo. See `signatureHelp.ts`.
@@ -2752,6 +2806,8 @@ namespace ts {
getConstantValue(node: EnumMember | PropertyAccessExpression | ElementAccessExpression): string | number | undefined;
isValidPropertyAccess(node: PropertyAccessExpression | QualifiedName, propertyName: string): boolean;
/** Exclude accesses to private properties or methods with a `this` parameter that `type` doesn't satisfy. */
/* @internal */ isValidPropertyAccessForCompletions(node: PropertyAccessExpression, type: Type, property: Symbol): boolean;
/** Follow all aliases to get the original symbol. */
getAliasedSymbol(symbol: Symbol): Symbol;
/** Follow a *single* alias to get the immediately aliased symbol. */
@@ -2786,12 +2842,22 @@ namespace ts {
/* @internal */ getNullType(): Type;
/* @internal */ getESSymbolType(): Type;
/* @internal */ getNeverType(): Type;
/* @internal */ getUnionType(types: Type[], subtypeReduction?: boolean): Type;
/* @internal */ getUnionType(types: Type[], subtypeReduction?: UnionReduction): Type;
/* @internal */ createArrayType(elementType: Type): Type;
/* @internal */ createPromiseType(type: Type): Type;
/* @internal */ createAnonymousType(symbol: Symbol, members: SymbolTable, callSignatures: Signature[], constructSignatures: Signature[], stringIndexInfo: IndexInfo, numberIndexInfo: IndexInfo): Type;
/* @internal */ createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[], resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature;
/* @internal */ createSignature(
declaration: SignatureDeclaration,
typeParameters: TypeParameter[],
thisParameter: Symbol | undefined,
parameters: Symbol[],
resolvedReturnType: Type,
typePredicate: TypePredicate | undefined,
minArgumentCount: number,
hasRestParameter: boolean,
hasLiteralTypes: boolean,
): Signature;
/* @internal */ createSymbol(flags: SymbolFlags, name: __String): TransientSymbol;
/* @internal */ createIndexInfo(type: Type, isReadonly: boolean, declaration?: SignatureDeclaration): IndexInfo;
/* @internal */ isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
@@ -2816,7 +2882,7 @@ namespace ts {
*/
/* @internal */ isArrayLikeType(type: Type): boolean;
/* @internal */ getAllPossiblePropertiesOfTypes(type: ReadonlyArray<Type>): Symbol[];
/* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags): Symbol | undefined;
/* @internal */ resolveName(name: string, location: Node, meaning: SymbolFlags, excludeGlobals: boolean): Symbol | undefined;
/* @internal */ getJsxNamespace(): string;
/**
@@ -2829,6 +2895,15 @@ namespace ts {
* This should be called in a loop climbing parents of the symbol, so we'll get `N`.
*/
/* @internal */ getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined;
/* @internal */ resolveExternalModuleSymbol(symbol: Symbol): Symbol;
}
/* @internal */
export const enum UnionReduction {
None = 0,
Literal,
Subtype
}
export enum NodeBuilderFlags {
@@ -2925,9 +3000,9 @@ namespace ts {
None = 0x00000000,
// Write symbols's type argument if it is instantiated symbol
// eg. class C<T> { p: T } <-- Show p as C<T>.p here
// eg. class C<T> { p: T } <-- Show p as C<T>.p here
// var a: C<number>;
// var p = a.p; <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
// var p = a.p; <--- Here p is property of C<number> so show it as C<number>.p instead of just C.p
WriteTypeParametersOrArguments = 0x00000001,
// Use only external alias information to get the symbol name in the given context
@@ -3177,6 +3252,7 @@ namespace ts {
bindingElement?: BindingElement; // Binding element associated with property symbol
exportsSomeValue?: boolean; // True if module exports some value (not just types)
enumKind?: EnumKind; // Enum declaration classification
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
lateSymbol?: Symbol; // Late-bound symbol for a computed property
}
@@ -3199,6 +3275,7 @@ namespace ts {
ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s)
ContainsStatic = 1 << 9, // Synthetic property with static constituent(s)
Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name
ReverseMapped = 1 << 11, // property of reverse-inferred homomorphic mapped type.
Synthetic = SyntheticProperty | SyntheticMethod
}
@@ -3208,6 +3285,12 @@ namespace ts {
isRestParameter?: boolean;
}
/* @internal */
export interface ReverseMappedSymbol extends TransientSymbol {
propertyType: Type;
mappedType: MappedType;
}
export const enum InternalSymbolName {
Call = "__call", // Call signatures
Constructor = "__constructor", // Constructor implementations
@@ -3313,7 +3396,7 @@ namespace ts {
resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element
resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element
hasSuperCall?: boolean; // recorded result when we try to find super-call. We only try to find one if this flag is undefined, indicating that we haven't made an attempt.
superCall?: ExpressionStatement; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing
superCall?: SuperCall; // Cached first super-call found in the constructor. Used in checking whether super is called before this-accessing
switchTypes?: Type[]; // Cached array of switch case expression types
}
@@ -3442,6 +3525,7 @@ namespace ts {
EvolvingArray = 1 << 8, // Evolving array type
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
ContainsSpread = 1 << 10, // Object literal contains spread operation
ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type
ClassOrInterface = Class | Interface
}
@@ -3549,6 +3633,12 @@ namespace ts {
finalArrayType?: Type; // Final array type of evolving array type
}
/* @internal */
export interface ReverseMappedType extends ObjectType {
source: Type;
mappedType: MappedType;
}
/* @internal */
// Resolved object, union, or intersection type
export interface ResolvedType extends ObjectType, UnionOrIntersectionType {
@@ -3562,7 +3652,7 @@ namespace ts {
/* @internal */
// Object literals are initially marked fresh. Freshness disappears following an assignment,
// before a type assertion, or when an object literal's type is widened. The regular
// before a type assertion, or when an object literal's type is widened. The regular
// version of a fresh type is identical except for the TypeFlags.FreshObjectLiteral flag.
export interface FreshObjectLiteralType extends ResolvedType {
regularType: ResolvedType; // Regular version of fresh type
@@ -3638,7 +3728,13 @@ namespace ts {
/* @internal */
thisParameter?: Symbol; // symbol of this-type parameter
/* @internal */
resolvedReturnType: Type; // Resolved return type
// See comment in `instantiateSignature` for why these are set lazily.
resolvedReturnType: Type | undefined; // Lazily set by `getReturnTypeOfSignature`.
/* @internal */
// Lazily set by `getTypePredicateOfSignature`.
// `undefined` indicates a type predicate that has not yet been computed.
// Uses a special `noTypePredicate` sentinel value to indicate that there is no type predicate. This looks like a TypePredicate at runtime to avoid polymorphism.
resolvedTypePredicate: TypePredicate | undefined;
/* @internal */
minArgumentCount: number; // Number of non-optional parameters
/* @internal */
@@ -3658,8 +3754,6 @@ namespace ts {
/* @internal */
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
/* @internal */
typePredicate?: TypePredicate;
/* @internal */
instantiations?: Map<Signature>; // Generic signature instantiation cache
}
@@ -3889,6 +3983,7 @@ namespace ts {
typeRoots?: string[];
/*@internal*/ version?: boolean;
/*@internal*/ watch?: boolean;
esModuleInterop?: boolean;
[option: string]: CompilerOptionsValue | JsonSourceFile | undefined;
}
@@ -4229,6 +4324,8 @@ namespace ts {
* If changing this, remember to change `moduleResolutionIsEqualTo`.
*/
export interface ResolvedModuleFull extends ResolvedModule {
/* @internal */
readonly originalPath?: string;
/**
* 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.
@@ -4308,11 +4405,11 @@ namespace ts {
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
* 'throw new Error("NotImplemented")'
*/
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
/**
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
*/
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): (ResolvedTypeReferenceDirective | undefined)[];
getEnvironmentVariable?(name: string): string;
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void;
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
@@ -4454,6 +4551,7 @@ namespace ts {
Iterator = 1 << 23, // The expression to a `yield*` should be treated as an Iterator when down-leveling, not an Iterable.
NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
/*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform.
/*@internal*/ NeverApplyImportHelper = 1 << 26, // Indicates the node should never be wrapped with an import star helper (because, for example, it imports tslib itself)
}
export interface EmitHelper {
+70 -12
View File
@@ -3,7 +3,9 @@
/* @internal */
namespace ts {
export const emptyArray: never[] = [] as never[];
export const resolvingEmptyArray: never[] = [] as never[];
export const emptyMap: ReadonlyMap<never> = createMap<never>();
export const emptyUnderscoreEscapedMap: ReadonlyUnderscoreEscapedMap<never> = emptyMap as ReadonlyUnderscoreEscapedMap<never>;
export const externalHelpersModuleNameText = "tslib";
@@ -101,6 +103,7 @@ namespace ts {
return oldResolution.isExternalLibraryImport === newResolution.isExternalLibraryImport &&
oldResolution.extension === newResolution.extension &&
oldResolution.resolvedFileName === newResolution.resolvedFileName &&
oldResolution.originalPath === newResolution.originalPath &&
packageIdIsEqual(oldResolution.packageId, newResolution.packageId);
}
@@ -345,7 +348,7 @@ namespace ts {
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile) {
// If we don't need to downlevel and we can reach the original source text using
// the node's parent reference, then simply get the text as it was originally written.
if (!nodeIsSynthesized(node) && node.parent) {
if (!nodeIsSynthesized(node) && node.parent && !(isNumericLiteral(node) && node.numericLiteralFlags & TokenFlags.ContainsSeparator)) {
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
}
@@ -547,7 +550,7 @@ namespace ts {
// 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.
export function declarationNameToString(name: DeclarationName) {
export function declarationNameToString(name: DeclarationName | QualifiedName) {
return getFullWidth(name) === 0 ? "(Missing)" : getTextOfNode(name);
}
@@ -783,7 +786,7 @@ namespace ts {
case SyntaxKind.PropertySignature:
case SyntaxKind.Parameter:
case SyntaxKind.VariableDeclaration:
return node === (<VariableLikeDeclaration>parent).type;
return node === (parent as HasType).type;
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
@@ -801,7 +804,7 @@ namespace ts {
return node === (<TypeAssertion>parent).type;
case SyntaxKind.CallExpression:
case SyntaxKind.NewExpression:
return (<CallExpression>parent).typeArguments && indexOf((<CallExpression>parent).typeArguments, node) >= 0;
return contains((<CallExpression>parent).typeArguments, node);
case SyntaxKind.TaggedTemplateExpression:
// TODO (drosen): TaggedTemplateExpressions may eventually support type arguments.
return false;
@@ -1339,7 +1342,7 @@ namespace ts {
case SyntaxKind.EnumMember:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.BindingElement:
return (<VariableLikeDeclaration>parent).initializer === node;
return (parent as HasInitializer).initializer === node;
case SyntaxKind.ExpressionStatement:
case SyntaxKind.IfStatement:
case SyntaxKind.DoStatement:
@@ -1417,6 +1420,8 @@ namespace ts {
* exactly one argument (of the form 'require("name")').
* This function does not test if the node is in a JavaScript file or not.
*/
export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: true): callExpression is CallExpression & { expression: Identifier, arguments: [StringLiteralLike] };
export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression;
export function isRequireCall(callExpression: Node, checkArgumentIsStringLiteral: boolean): callExpression is CallExpression {
if (callExpression.kind !== SyntaxKind.CallExpression) {
return false;
@@ -1454,7 +1459,7 @@ namespace ts {
return false;
}
export function getRightMostAssignedExpression(node: Node) {
export function getRightMostAssignedExpression(node: Expression): Expression {
while (isAssignmentExpression(node, /*excludeCompoundAssignements*/ true)) {
node = node.right;
}
@@ -1649,7 +1654,7 @@ namespace ts {
result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration));
}
if (isVariableLike(node) && node.initializer && hasJSDocNodes(node.initializer)) {
if (isVariableLike(node) && hasInitializer(node) && hasJSDocNodes(node.initializer)) {
result = addRange(result, node.initializer.jsDoc);
}
@@ -2117,6 +2122,10 @@ namespace ts {
return "__@" + symbolName as __String;
}
export function isKnownSymbol(symbol: Symbol): boolean {
return startsWith(symbol.escapedName as string, "__@");
}
/**
* Includes the word "Symbol" with unicode escapes
*/
@@ -2815,8 +2824,8 @@ namespace ts {
* Gets the effective type annotation of a variable, parameter, or property. If the node was
* parsed in a JavaScript file, gets the type annotation from JSDoc.
*/
export function getEffectiveTypeAnnotationNode(node: VariableLikeDeclaration, checkJSDoc?: boolean): TypeNode | undefined {
if (node.type) {
export function getEffectiveTypeAnnotationNode(node: Node, checkJSDoc?: boolean): TypeNode | undefined {
if (hasType(node)) {
return node.type;
}
if (checkJSDoc || isInJavaScriptFile(node)) {
@@ -3696,6 +3705,10 @@ namespace ts {
export function typeHasCallOrConstructSignatures(type: Type, checker: TypeChecker) {
return checker.getSignaturesOfType(type, SignatureKind.Call).length !== 0 || checker.getSignaturesOfType(type, SignatureKind.Construct).length !== 0;
}
export function forSomeAncestorDirectory(directory: string, callback: (directory: string) => boolean): boolean {
return !!forEachAncestorDirectory(directory, d => callback(d) ? true : undefined);
}
}
namespace ts {
@@ -3911,8 +3924,8 @@ namespace ts {
//
// {
// oldStart3: Min(oldStart1, oldStart2),
// oldEnd3 : Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
// newEnd3 : Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
// oldEnd3: Max(oldEnd1, oldEnd1 + (oldEnd2 - newEnd1)),
// newEnd3: Max(newEnd2, newEnd2 + (newEnd1 - oldEnd2))
// }
const oldStart1 = oldStartN;
@@ -4397,7 +4410,7 @@ namespace ts {
return node.kind === SyntaxKind.RegularExpressionLiteral;
}
export function isNoSubstitutionTemplateLiteral(node: Node): node is LiteralExpression {
export function isNoSubstitutionTemplateLiteral(node: Node): node is NoSubstitutionTemplateLiteral {
return node.kind === SyntaxKind.NoSubstitutionTemplateLiteral;
}
@@ -5228,6 +5241,18 @@ namespace ts {
return node && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor);
}
/* @internal */
export function isMethodOrAccessor(node: Node): node is MethodDeclaration | AccessorDeclaration {
switch (node.kind) {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return true;
default:
return false;
}
}
// Type members
export function isTypeElement(node: Node): node is TypeElement {
@@ -5807,4 +5832,37 @@ namespace ts {
export function hasJSDocNodes(node: Node): node is HasJSDoc {
return !!(node as JSDocContainer).jsDoc && (node as JSDocContainer).jsDoc.length > 0;
}
/** True if has type node attached to it. */
/* @internal */
export function hasType(node: Node): node is HasType {
return !!(node as HasType).type;
}
/** True if has initializer node attached to it. */
/* @internal */
export function hasInitializer(node: Node): node is HasInitializer {
return !!(node as HasInitializer).initializer;
}
/** True if has initializer node attached to it. */
/* @internal */
export function hasOnlyExpressionInitializer(node: Node): node is HasExpressionInitializer {
return hasInitializer(node) && !isForStatement(node) && !isForInStatement(node) && !isForOfStatement(node) && !isJsxAttribute(node);
}
export function isObjectLiteralElement(node: Node): node is ObjectLiteralElement {
switch (node.kind) {
case SyntaxKind.JsxAttribute:
case SyntaxKind.JsxSpreadAttribute:
case SyntaxKind.PropertyAssignment:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return true;
default:
return false;
}
}
}
+1 -1
View File
@@ -622,7 +622,7 @@ namespace ts {
case SyntaxKind.ForOfStatement:
return updateForOf(<ForOfStatement>node,
(<ForOfStatement>node).awaitModifier,
visitNode((<ForOfStatement>node).awaitModifier, visitor, isToken),
visitNode((<ForOfStatement>node).initializer, visitor, isForInitializer),
visitNode((<ForOfStatement>node).expression, visitor, isExpression),
visitNode((<ForOfStatement>node).statement, visitor, isStatement, liftToBlock));
+17 -2
View File
@@ -48,6 +48,15 @@ namespace ts {
};
}
/** @internal */
export function createWatchDiagnosticReporterWithColor(system = sys): DiagnosticReporter {
return diagnostic => {
let output = `[${ formatColorAndReset(new Date().toLocaleTimeString(), ForegroundColorEscapeSequences.Grey) }] `;
output += `${flattenDiagnosticMessageText(diagnostic.messageText, system.newLine)}${system.newLine + system.newLine + system.newLine}`;
system.write(output);
};
}
export function reportDiagnostics(diagnostics: Diagnostic[], reportDiagnostic: DiagnosticReporter): void {
for (const diagnostic of diagnostics) {
reportDiagnostic(diagnostic);
@@ -131,7 +140,7 @@ namespace ts {
reportWatchDiagnostic?: DiagnosticReporter
): WatchingSystemHost {
reportDiagnostic = reportDiagnostic || createDiagnosticReporter(system, pretty ? reportDiagnosticWithColorAndContext : reportDiagnosticSimply);
reportWatchDiagnostic = reportWatchDiagnostic || createWatchDiagnosticReporter(system);
reportWatchDiagnostic = reportWatchDiagnostic || pretty ? createWatchDiagnosticReporterWithColor(system) : createWatchDiagnosticReporter(system);
parseConfigFile = parseConfigFile || ts.parseConfigFile;
return {
system,
@@ -302,6 +311,8 @@ namespace ts {
// There is no extra check needed since we can just rely on the program to decide emit
const builder = createBuilder({ getCanonicalFileName, computeHash });
clearHostScreen();
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.Starting_compilation_in_watch_mode));
synchronizeProgram();
// Update the wild card directory watch
@@ -492,10 +503,14 @@ namespace ts {
scheduleProgramUpdate();
}
function updateProgram() {
function clearHostScreen() {
if (watchingHost.system.clearScreen) {
watchingHost.system.clearScreen();
}
}
function updateProgram() {
clearHostScreen();
timerToUpdateProgram = undefined;
reportWatchDiagnostic(createCompilerDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation));