Merge branch 'master' into typesVersions

This commit is contained in:
Ron Buckton committed 2018-09-07 13:52:12 -07:00
commit a255d9a163
679 files changed
+22403 -12971

No files matched your search

+22 -24
View File
@@ -236,8 +236,9 @@ namespace ts {
if (symbolFlags & SymbolFlags.Value) {
const { valueDeclaration } = symbol;
if (!valueDeclaration ||
(isAssignmentDeclaration(valueDeclaration) && !isAssignmentDeclaration(node)) ||
(valueDeclaration.kind !== node.kind && isEffectiveModuleDeclaration(valueDeclaration))) {
// other kinds of value declarations take precedence over modules
// other kinds of value declarations take precedence over modules and assignment declarations
symbol.valueDeclaration = node;
}
}
@@ -373,7 +374,8 @@ namespace ts {
// prototype symbols like methods.
symbolTable.set(name, symbol = createSymbol(SymbolFlags.None, name));
}
else {
else if (!(includes & SymbolFlags.Variable && symbol.flags & SymbolFlags.JSContainer)) {
// JSContainers are allowed to merge with variables, no matter what other flags they have.
if (isNamedDeclaration(node)) {
node.name.parent = node;
}
@@ -733,6 +735,8 @@ namespace ts {
return isNarrowingBinaryExpression(<BinaryExpression>expr);
case SyntaxKind.PrefixUnaryExpression:
return (<PrefixUnaryExpression>expr).operator === SyntaxKind.ExclamationToken && isNarrowingExpression((<PrefixUnaryExpression>expr).operand);
case SyntaxKind.TypeOfExpression:
return isNarrowingExpression((<TypeOfExpression>expr).expression);
}
return false;
}
@@ -1729,10 +1733,6 @@ namespace ts {
}
}
function bindBlockScopedVariableDeclaration(node: Declaration) {
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable, SymbolFlags.BlockScopedVariableExcludes);
}
function delayedBindJSDocTypedefTag() {
if (!delayedTypeAliases) {
return;
@@ -2078,8 +2078,8 @@ namespace ts {
if (isInJavaScriptFile(node) &&
file.commonJsModuleIndicator &&
isModuleExportsPropertyAccessExpression(node as PropertyAccessExpression) &&
!lookupSymbolForNameWorker(container, "module" as __String)) {
declareSymbol(container.locals!, /*parent*/ undefined, (node as PropertyAccessExpression).expression as Identifier,
!lookupSymbolForNameWorker(blockScopeContainer, "module" as __String)) {
declareSymbol(file.locals!, /*parent*/ undefined, (node as PropertyAccessExpression).expression as Identifier,
SymbolFlags.FunctionScopedVariable | SymbolFlags.ModuleExports, SymbolFlags.FunctionScopedVariableExcludes);
}
break;
@@ -2510,11 +2510,10 @@ namespace ts {
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
const isToplevelNamespaceableInitializer = isBinaryExpression(propertyAccess.parent)
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile &&
!!getJavascriptInitializer(getInitializerOfBinaryExpression(propertyAccess.parent), isPrototypeAccess(propertyAccess.parent.left))
const isToplevel = isBinaryExpression(propertyAccess.parent)
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevelNamespaceableInitializer) {
if (!isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace)) && isToplevel) {
// make symbols or add declarations for intermediate containers
const flags = SymbolFlags.Module | SymbolFlags.JSContainer;
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.JSContainer;
@@ -2537,12 +2536,10 @@ namespace ts {
(namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) :
(namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable()));
// Declare the method/property
const jsContainerFlag = isToplevelNamespaceableInitializer ? SymbolFlags.JSContainer : 0;
const isMethod = isFunctionLikeDeclaration(getAssignedJavascriptInitializer(propertyAccess)!);
const symbolFlags = (isMethod ? SymbolFlags.Method : SymbolFlags.Property) | jsContainerFlag;
const symbolExcludes = (isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes) & ~jsContainerFlag;
declareSymbol(symbolTable, namespaceSymbol, propertyAccess, symbolFlags, symbolExcludes);
const includes = isMethod ? SymbolFlags.Method : SymbolFlags.Property;
const excludes = isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes;
declareSymbol(symbolTable, namespaceSymbol, propertyAccess, includes | SymbolFlags.JSContainer, excludes & ~SymbolFlags.JSContainer);
}
/**
@@ -2573,7 +2570,7 @@ namespace ts {
return false;
}
function getParentOfBinaryExpression(expr: BinaryExpression) {
function getParentOfBinaryExpression(expr: Node) {
while (isBinaryExpression(expr.parent)) {
expr = expr.parent;
}
@@ -2660,8 +2657,11 @@ namespace ts {
}
if (!isBindingPattern(node.name)) {
const isEnum = !!getJSDocEnumTag(node);
const enumFlags = (isEnum ? SymbolFlags.RegularEnum : SymbolFlags.None);
const enumExcludes = (isEnum ? SymbolFlags.RegularEnumExcludes : SymbolFlags.None);
if (isBlockOrCatchScoped(node)) {
bindBlockScopedVariableDeclaration(node);
bindBlockScopedDeclaration(node, SymbolFlags.BlockScopedVariable | enumFlags, SymbolFlags.BlockScopedVariableExcludes | enumExcludes);
}
else if (isParameterDeclaration(node)) {
// It is safe to walk up parent chain to find whether the node is a destructuring parameter declaration
@@ -2676,7 +2676,7 @@ namespace ts {
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.ParameterExcludes);
}
else {
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable, SymbolFlags.FunctionScopedVariableExcludes);
declareSymbolAndAddToSymbolTable(node, SymbolFlags.FunctionScopedVariable | enumFlags, SymbolFlags.FunctionScopedVariableExcludes | enumExcludes);
}
}
}
@@ -2804,9 +2804,7 @@ namespace ts {
// report error on class declarations
node.kind === SyntaxKind.ClassDeclaration ||
// report error on instantiated modules or const-enums only modules if preserveConstEnums is set
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<ModuleDeclaration>node)) ||
// report error on regular enums and const enums if preserveConstEnums is set
(isEnumDeclaration(node) && (!isEnumConst(node) || options.preserveConstEnums));
(node.kind === SyntaxKind.ModuleDeclaration && shouldReportErrorOnModuleDeclaration(<ModuleDeclaration>node));
if (reportError) {
currentFlow = reportedUnreachableFlow;
@@ -2851,7 +2849,7 @@ namespace ts {
// As opposed to a pure declaration like an `interface`
function isExecutableStatement(s: Statement): boolean {
// Don't remove statements that can validly be used before they appear.
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) &&
return !isFunctionDeclaration(s) && !isPurelyTypeDeclaration(s) && !isEnumDeclaration(s) &&
// `var x;` may declare a variable used above
!(isVariableStatement(s) && !(getCombinedNodeFlags(s) & (NodeFlags.Let | NodeFlags.Const)) && s.declarationList.declarations.some(d => !d.initializer));
}
+496 -183
View File
File diff suppressed because it is too large. Load diff
+106 -18
View File
@@ -62,9 +62,7 @@ namespace ts {
/* @internal */
export const libMap = createMapFromEntries(libEntries);
/* @internal */
export const optionDeclarations: CommandLineOption[] = [
// CommandLine only options
const commonOptionsWithBuild: CommandLineOption[] = [
{
name: "help",
shortName: "h",
@@ -78,6 +76,27 @@ namespace ts {
shortName: "?",
type: "boolean"
},
{
name: "preserveWatchOutput",
type: "boolean",
showInSimplifiedHelpView: false,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
},
{
name: "watch",
shortName: "w",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Watch_input_files,
},
];
/* @internal */
export const optionDeclarations: CommandLineOption[] = [
// CommandLine only options
...commonOptionsWithBuild,
{
name: "all",
type: "boolean",
@@ -125,21 +144,6 @@ namespace ts {
category: Diagnostics.Command_line_Options,
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
},
{
name: "preserveWatchOutput",
type: "boolean",
showInSimplifiedHelpView: false,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
},
{
name: "watch",
shortName: "w",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Watch_input_files,
},
// Basic
{
@@ -754,6 +758,38 @@ namespace ts {
}
];
/* @internal */
export const buildOpts: CommandLineOption[] = [
...commonOptionsWithBuild,
{
name: "verbose",
shortName: "v",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Enable_verbose_logging,
type: "boolean"
},
{
name: "dry",
shortName: "d",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean,
type: "boolean"
},
{
name: "force",
shortName: "f",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date,
type: "boolean"
},
{
name: "clean",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Delete_the_outputs_of_all_projects,
type: "boolean"
}
];
/* @internal */
export const typeAcquisitionDeclarations: CommandLineOption[] = [
{
@@ -997,6 +1033,58 @@ namespace ts {
return optionNameMap.get(optionName);
}
/*@internal*/
export interface ParsedBuildCommand {
buildOptions: BuildOptions;
projects: string[];
errors: ReadonlyArray<Diagnostic>;
}
/*@internal*/
export function parseBuildCommand(args: string[]): ParsedBuildCommand {
let buildOptionNameMap: OptionNameMap | undefined;
const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts)));
const buildOptions: BuildOptions = {};
const projects: string[] = [];
let errors: Diagnostic[] | undefined;
for (const arg of args) {
if (arg.charCodeAt(0) === CharacterCodes.minus) {
const opt = getOptionDeclarationFromName(returnBuildOptionNameMap, arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
if (opt) {
buildOptions[opt.name as keyof BuildOptions] = true;
}
else {
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Unknown_build_option_0, arg));
}
}
else {
// Not a flag, parse as filename
projects.push(arg);
}
}
if (projects.length === 0) {
// tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ."
projects.push(".");
}
// Nonsensical combinations
if (buildOptions.clean && buildOptions.force) {
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
}
if (buildOptions.clean && buildOptions.verbose) {
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
}
if (buildOptions.clean && buildOptions.watch) {
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
}
if (buildOptions.watch && buildOptions.dry) {
(errors || (errors = [])).push(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
}
return { buildOptions, projects, errors: errors || emptyArray };
}
function getDiagnosticText(_message: DiagnosticMessage, ..._args: any[]): string {
const diagnostic = createCompilerDiagnostic.apply(undefined, arguments);
+4 -10
View File
@@ -790,11 +790,8 @@ namespace ts {
* @param comparer An optional `Comparer` used to sort entries before comparison, though the
* result will remain in the original order in `array`.
*/
export function deduplicate<T>(array: ReadonlyArray<T>, equalityComparer?: EqualityComparer<T>, comparer?: Comparer<T>): T[];
export function deduplicate<T>(array: ReadonlyArray<T> | undefined, equalityComparer?: EqualityComparer<T>, comparer?: Comparer<T>): T[] | undefined;
export function deduplicate<T>(array: ReadonlyArray<T> | undefined, equalityComparer: EqualityComparer<T>, comparer?: Comparer<T>): T[] | undefined {
return !array ? undefined :
array.length === 0 ? [] :
export function deduplicate<T>(array: ReadonlyArray<T>, equalityComparer: EqualityComparer<T>, comparer?: Comparer<T>): T[] {
return array.length === 0 ? [] :
array.length === 1 ? array.slice() :
comparer ? deduplicateRelational(array, equalityComparer, comparer) :
deduplicateEquality(array, equalityComparer);
@@ -803,10 +800,7 @@ namespace ts {
/**
* Deduplicates an array that has already been sorted.
*/
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[];
function deduplicateSorted<T>(array: ReadonlyArray<T> | undefined, comparer: EqualityComparer<T> | Comparer<T>): T[] | undefined;
function deduplicateSorted<T>(array: ReadonlyArray<T> | undefined, comparer: EqualityComparer<T> | Comparer<T>): T[] | undefined {
if (!array) return undefined;
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[] {
if (array.length === 0) return [];
let last = array[0];
@@ -1273,7 +1267,7 @@ namespace ts {
if (!left || !right) return false;
for (const key in left) {
if (hasOwnProperty.call(left, key)) {
if (!hasOwnProperty.call(right, key) === undefined) return false;
if (!hasOwnProperty.call(right, key)) return false;
if (!equalityComparer(left[key], right[key])) return false;
}
}
+22 -2
View File
@@ -835,7 +835,7 @@
"category": "Error",
"code": 1253
},
"A 'const' initializer in an ambient context must be a string or numeric literal.": {
"A 'const' initializer in an ambient context must be a string or numeric literal or literal enum reference.": {
"category": "Error",
"code": 1254
},
@@ -991,6 +991,22 @@
"category": "Error",
"code": 1345
},
"This parameter is not allowed with 'use strict' directive.": {
"category": "Error",
"code": 1346
},
"'use strict' directive cannot be used with non-simple parameter list.": {
"category": "Error",
"code": 1347
},
"Non-simple parameter declared here.": {
"category": "Error",
"code": 1348
},
"'use strict' directive used here.": {
"category": "Error",
"code": 1349
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@@ -2437,6 +2453,10 @@
"category": "Error",
"code": 2732
},
"Index '{0}' is out-of-bounds in tuple of length {1}.": {
"category": "Error",
"code": 2733
},
"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
@@ -2892,7 +2912,7 @@
"category": "Error",
"code": 5070
},
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs'.": {
"Option '--resolveJsonModule' can only be specified when module code generation is 'commonjs', 'amd', 'es2015' or 'esNext'.": {
"category": "Error",
"code": 5071
},
+3 -1
View File
@@ -1780,7 +1780,9 @@ namespace ts {
function emitExpressionStatement(node: ExpressionStatement) {
emitExpression(node.expression);
if (!isJsonSourceFile(currentSourceFile)) {
// Emit semicolon in non json files
// or if json file that created synthesized expression(eg.define expression statement when --out and amd code generation)
if (!isJsonSourceFile(currentSourceFile) || nodeIsSynthesized(node.expression)) {
writeSemicolon();
}
}
+15 -12
View File
@@ -3894,6 +3894,20 @@ namespace ts {
return statementOffset;
}
export function findUseStrictPrologue(statements: ReadonlyArray<Statement>): Statement | undefined {
for (const statement of statements) {
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement)) {
return statement;
}
}
else {
break;
}
}
return undefined;
}
export function startsWithUseStrict(statements: ReadonlyArray<Statement>) {
const firstStatement = firstOrUndefined(statements);
return firstStatement !== undefined
@@ -3907,18 +3921,7 @@ namespace ts {
* @param statements An array of statements
*/
export function ensureUseStrict(statements: NodeArray<Statement>): NodeArray<Statement> {
let foundUseStrict = false;
for (const statement of statements) {
if (isPrologueDirective(statement)) {
if (isUseStrictPrologue(statement as ExpressionStatement)) {
foundUseStrict = true;
break;
}
}
else {
break;
}
}
const foundUseStrict = findUseStrictPrologue(statements);
if (!foundUseStrict) {
return setTextRange(
+20 -58
View File
@@ -75,10 +75,10 @@ namespace ts.moduleSpecifiers {
const info = getInfo(importingSourceFileName, host);
const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap);
return firstDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions)) ||
first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences));
getLocalModuleSpecifier(toFileName, info, compilerOptions, preferences);
}
// For each symlink/original for a module, returns a list of ways to import that file.
// Returns an import for each symlink and for the realpath.
export function getModuleSpecifiers(
moduleSymbol: Symbol,
compilerOptions: CompilerOptions,
@@ -87,9 +87,9 @@ namespace ts.moduleSpecifiers {
files: ReadonlyArray<SourceFile>,
userPreferences: UserPreferences,
redirectTargetsMap: RedirectTargetsMap,
): ReadonlyArray<ReadonlyArray<string>> {
): ReadonlyArray<string> {
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
if (ambient) return [[ambient]];
if (ambient) return [ambient];
const info = getInfo(importingSourceFile.path, host);
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration || getNonAugmentationDeclaration(moduleSymbol));
@@ -97,8 +97,7 @@ namespace ts.moduleSpecifiers {
const preferences = getPreferences(userPreferences, compilerOptions, importingSourceFile);
const global = mapDefined(modulePaths, moduleFileName => tryGetModuleNameAsNodeModule(moduleFileName, info, host, compilerOptions));
return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName =>
getLocalModuleSpecifiers(moduleFileName, info, compilerOptions, preferences));
return global.length ? global : modulePaths.map(moduleFileName => getLocalModuleSpecifier(moduleFileName, info, compilerOptions, preferences));
}
interface Info {
@@ -112,68 +111,40 @@ namespace ts.moduleSpecifiers {
return { getCanonicalFileName, sourceDirectory };
}
function getLocalModuleSpecifiers(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): ReadonlyArray<string> {
function getLocalModuleSpecifier(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, compilerOptions: CompilerOptions, { ending, relativePreference }: Preferences): string {
const { baseUrl, paths, rootDirs } = compilerOptions;
const relativePath = rootDirs && tryGetModuleNameFromRootDirs(rootDirs, moduleFileName, sourceDirectory, getCanonicalFileName) ||
removeExtensionAndIndexPostFix(ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, moduleFileName, getCanonicalFileName)), ending, compilerOptions);
if (!baseUrl || relativePreference === RelativePreference.Relative) {
return [relativePath];
return relativePath;
}
const relativeToBaseUrl = getRelativePathIfInDirectory(moduleFileName, baseUrl, getCanonicalFileName);
if (!relativeToBaseUrl) {
return [relativePath];
return relativePath;
}
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix(relativeToBaseUrl, ending, compilerOptions);
if (paths) {
const fromPaths = tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
if (fromPaths) {
return [fromPaths];
}
}
const fromPaths = paths && tryGetModuleNameFromPaths(removeFileExtension(relativeToBaseUrl), importRelativeToBaseUrl, paths);
const nonRelative = fromPaths === undefined ? importRelativeToBaseUrl : fromPaths;
if (relativePreference === RelativePreference.NonRelative) {
return [importRelativeToBaseUrl];
return nonRelative;
}
if (relativePreference !== RelativePreference.Auto) Debug.assertNever(relativePreference);
if (isPathRelativeToParent(relativeToBaseUrl)) {
return [relativePath];
// Prefer a relative import over a baseUrl import if it has fewer components.
return isPathRelativeToParent(nonRelative) || countPathComponents(relativePath) < countPathComponents(nonRelative) ? relativePath : nonRelative;
}
function countPathComponents(path: string): number {
let count = 0;
for (let i = startsWith(path, "./") ? 2 : 0; i < path.length; i++) {
if (path.charCodeAt(i) === CharacterCodes.slash) count++;
}
/*
Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl.
Suppose we have:
baseUrl = /base
sourceDirectory = /base/a/b
moduleFileName = /base/foo/bar
Then:
relativePath = ../../foo/bar
getRelativePathNParents(relativePath) = 2
pathFromSourceToBaseUrl = ../../
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
2 < 2 = false
In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar".
Suppose we have:
baseUrl = /base
sourceDirectory = /base/foo/a
moduleFileName = /base/foo/bar
Then:
relativePath = ../a
getRelativePathNParents(relativePath) = 1
pathFromSourceToBaseUrl = ../../
getRelativePathNParents(pathFromSourceToBaseUrl) = 2
1 < 2 = true
In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a".
*/
const pathFromSourceToBaseUrl = ensurePathIsNonModuleName(getRelativePathFromDirectory(sourceDirectory, baseUrl, getCanonicalFileName));
const relativeFirst = getRelativePathNParents(relativePath) < getRelativePathNParents(pathFromSourceToBaseUrl);
return relativeFirst ? [relativePath, importRelativeToBaseUrl] : [importRelativeToBaseUrl, relativePath];
return count;
}
function usesJsExtensionOnImports({ imports }: SourceFile): boolean {
@@ -245,15 +216,6 @@ namespace ts.moduleSpecifiers {
return result;
}
function getRelativePathNParents(relativePath: string): number {
const components = getPathComponents(relativePath);
if (components[0] || components.length === 1) return 0;
for (let i = 1; i < components.length; i++) {
if (components[i] !== "..") return i - 1;
}
return components.length - 1;
}
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {
const decl = find(moduleSymbol.declarations,
d => isNonGlobalAmbientModule(d) && (!isExternalModuleAugmentation(d) || !isExternalModuleNameRelative(getTextOfIdentifierOrLiteral(d.name)))
+8 -2
View File
@@ -86,6 +86,7 @@ namespace ts {
visitNodes(cbNode, cbNodes, node.modifiers) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).name) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).questionToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).exclamationToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).equalsToken) ||
visitNode(cbNode, (<ShorthandPropertyAssignment>node).objectAssignmentInitializer);
case SyntaxKind.SpreadAssignment:
@@ -156,6 +157,7 @@ namespace ts {
visitNode(cbNode, (<FunctionLikeDeclaration>node).asteriskToken) ||
visitNode(cbNode, (<FunctionLikeDeclaration>node).name) ||
visitNode(cbNode, (<FunctionLikeDeclaration>node).questionToken) ||
visitNode(cbNode, (<FunctionLikeDeclaration>node).exclamationToken) ||
visitNodes(cbNode, cbNodes, (<FunctionLikeDeclaration>node).typeParameters) ||
visitNodes(cbNode, cbNodes, (<FunctionLikeDeclaration>node).parameters) ||
visitNode(cbNode, (<FunctionLikeDeclaration>node).type) ||
@@ -2377,8 +2379,10 @@ namespace ts {
}
function parseJSDocType(): TypeNode {
scanner.setInJSDocType(true);
const dotdotdot = parseOptionalToken(SyntaxKind.DotDotDotToken);
let type = parseTypeOrTypePredicate();
scanner.setInJSDocType(false);
if (dotdotdot) {
const variadic = createNode(SyntaxKind.JSDocVariadicType, dotdotdot.pos) as JSDocVariadicType;
variadic.type = type;
@@ -4711,8 +4715,10 @@ namespace ts {
const asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
const tokenIsIdentifier = isIdentifier();
node.name = parsePropertyName();
// Disallowing of optional property assignments happens in the grammar checker.
// Disallowing of optional property assignments and definite assignment assertion happens in the grammar checker.
(<MethodDeclaration>node).questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
(<MethodDeclaration>node).exclamationToken = parseOptionalToken(SyntaxKind.ExclamationToken);
if (asteriskToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.LessThanToken) {
return parseMethodDeclaration(<MethodDeclaration>node, asteriskToken);
}
@@ -6856,7 +6862,7 @@ namespace ts {
function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag {
const typeExpression = tryParseTypeExpression();
skipWhitespace();
skipWhitespaceOrAsterisk();
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
typedefTag.atToken = atToken;
+20 -21
View File
@@ -953,8 +953,11 @@ 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 {
if (!oldProgramState.program) {
return false;
}
const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile!, moduleName); // TODO: GH#18217
const resolvedFile = resolutionToFile && oldProgramState.program && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName);
const resolvedFile = resolutionToFile && 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.
@@ -962,16 +965,11 @@ namespace ts {
// because the normal module resolution algorithm will find this anyway.
return false;
}
const ambientModule = oldProgramState.program && oldProgramState.program.getTypeChecker().tryFindAmbientModuleWithoutAugmentations(moduleName);
if (!(ambientModule && ambientModule.declarations)) {
return false;
}
// at least one of declarations should come from non-modified source file
const firstUnmodifiedFile = forEach(ambientModule.declarations, d => {
const f = getSourceFileOfNode(d);
return !contains(oldProgramState.modifiedFilePaths, f.path) && f;
});
const firstUnmodifiedFile = oldProgramState.program.getSourceFiles().find(
f => !contains(oldProgramState.modifiedFilePaths, f.path) && contains(f.ambientModuleNames, moduleName)
);
if (!firstUnmodifiedFile) {
return false;
@@ -1180,7 +1178,8 @@ namespace ts {
}
}
if (resolveTypeReferenceDirectiveNamesWorker) {
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, x => x.fileName);
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase());
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
// ensure that types resolutions are still correct
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
@@ -1259,8 +1258,6 @@ namespace ts {
}
function getProjectReferences() {
if (!resolvedProjectReferences) return;
return resolvedProjectReferences;
}
@@ -2434,12 +2431,14 @@ namespace ts {
}
// List of collected files is complete; validate exhautiveness if this is a project with a file list
if (options.composite && rootNames.length < files.length) {
const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase());
const sourceFiles = files.filter(f => !f.isDeclarationFile).map(f => normalizePath(f.path).toLowerCase());
for (const file of sourceFiles) {
if (normalizedRootNames.every(r => r !== file)) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file));
if (options.composite) {
const sourceFiles = files.filter(f => !f.isDeclarationFile);
if (rootNames.length < sourceFiles.length) {
const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase());
for (const file of sourceFiles.map(f => normalizePath(f.path).toLowerCase())) {
if (normalizedRootNames.indexOf(file) === -1) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file));
}
}
}
}
@@ -2551,9 +2550,9 @@ namespace ts {
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy, "resolveJsonModule");
}
// Any emit other than common js is error
else if (getEmitModuleKind(options) !== ModuleKind.CommonJS) {
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs, "resolveJsonModule", "module");
// Any emit other than common js, amd, es2015 or esnext is error
else if (!hasJsonModuleEmitEnabled(options)) {
createDiagnosticForOptionName(Diagnostics.Option_resolveJsonModule_can_only_be_specified_when_module_code_generation_is_commonjs_amd_es2015_or_esNext, "resolveJsonModule", "module");
}
}
+33
View File
@@ -42,6 +42,8 @@ namespace ts {
setScriptTarget(scriptTarget: ScriptTarget): void;
setLanguageVariant(variant: LanguageVariant): void;
setTextPos(textPos: number): void;
/* @internal */
setInJSDocType(inType: boolean): void;
// Invokes the provided callback then unconditionally restores the scanner to the state it
// was in immediately prior to invoking the callback. The result of invoking the callback
// is returned from this function.
@@ -824,6 +826,8 @@ namespace ts {
let tokenValue!: string;
let tokenFlags: TokenFlags;
let inJSDocType = 0;
setText(text, start, length);
return {
@@ -854,6 +858,7 @@ namespace ts {
setLanguageVariant,
setOnError,
setTextPos,
setInJSDocType,
tryScan,
lookAhead,
scanRange,
@@ -1350,6 +1355,7 @@ namespace ts {
function scan(): SyntaxKind {
startPos = pos;
tokenFlags = 0;
let asteriskSeen = false;
while (true) {
tokenPos = pos;
if (pos >= end) {
@@ -1390,6 +1396,24 @@ namespace ts {
case CharacterCodes.verticalTab:
case CharacterCodes.formFeed:
case CharacterCodes.space:
case CharacterCodes.nonBreakingSpace:
case CharacterCodes.ogham:
case CharacterCodes.enQuad:
case CharacterCodes.emQuad:
case CharacterCodes.enSpace:
case CharacterCodes.emSpace:
case CharacterCodes.threePerEmSpace:
case CharacterCodes.fourPerEmSpace:
case CharacterCodes.sixPerEmSpace:
case CharacterCodes.figureSpace:
case CharacterCodes.punctuationSpace:
case CharacterCodes.thinSpace:
case CharacterCodes.hairSpace:
case CharacterCodes.zeroWidthSpace:
case CharacterCodes.narrowNoBreakSpace:
case CharacterCodes.mathematicalSpace:
case CharacterCodes.ideographicSpace:
case CharacterCodes.byteOrderMark:
if (skipTrivia) {
pos++;
continue;
@@ -1447,6 +1471,11 @@ namespace ts {
return pos += 2, token = SyntaxKind.AsteriskAsteriskToken;
}
pos++;
if (inJSDocType && !asteriskSeen && (tokenFlags & TokenFlags.PrecedingLineBreak)) {
// decoration at the start of a JSDoc comment line
asteriskSeen = true;
continue;
}
return token = SyntaxKind.AsteriskToken;
case CharacterCodes.plus:
if (text.charCodeAt(pos + 1) === CharacterCodes.plus) {
@@ -2078,5 +2107,9 @@ namespace ts {
tokenValue = undefined!;
tokenFlags = 0;
}
function setInJSDocType(inType: boolean) {
inJSDocType += inType ? 1 : -1;
}
}
}
+3 -2
View File
@@ -1331,12 +1331,13 @@ namespace ts {
}
type CanHaveLiteralInitializer = VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration;
function canHaveLiteralInitializer(node: Node): node is CanHaveLiteralInitializer {
function canHaveLiteralInitializer(node: Node): boolean {
switch (node.kind) {
case SyntaxKind.VariableDeclaration:
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.PropertySignature:
return !hasModifier(node, ModifierFlags.Private);
case SyntaxKind.Parameter:
case SyntaxKind.VariableDeclaration:
return true;
}
return false;
+14 -6
View File
@@ -2060,14 +2060,11 @@ namespace ts {
setTextRange(declarationList, node);
setCommentRange(declarationList, node);
// If the first or last declaration is a binding pattern, we need to modify
// the source map range for the declaration list.
if (node.transformFlags & TransformFlags.ContainsBindingPattern
&& (isBindingPattern(node.declarations[0].name) || isBindingPattern(last(node.declarations).name))) {
// If the first or last declaration is a binding pattern, we need to modify
// the source map range for the declaration list.
const firstDeclaration = firstOrUndefined(declarations);
if (firstDeclaration) {
setSourceMapRange(declarationList, createRange(firstDeclaration.pos, last(declarations).end));
}
setSourceMapRange(declarationList, getRangeUnion(declarations));
}
return declarationList;
@@ -2075,6 +2072,17 @@ namespace ts {
return visitEachChild(node, visitor, context);
}
function getRangeUnion(declarations: ReadonlyArray<Node>): TextRange {
// declarations may not be sorted by position.
// pos should be the minimum* position over all nodes (that's not -1), end should be the maximum end over all nodes.
let pos = -1, end = -1;
for (const node of declarations) {
pos = pos === -1 ? node.pos : node.pos === -1 ? pos : Math.min(pos, node.pos);
end = Math.max(end, node.end);
}
return createRange(pos, end);
}
/**
* Gets a value indicating whether we should emit an explicit initializer for a variable
* declaration in a `let` declaration list.
+9 -3
View File
@@ -53,7 +53,10 @@ namespace ts {
* @param node The SourceFile node.
*/
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile || !(isEffectiveExternalModule(node, compilerOptions) || node.transformFlags & TransformFlags.ContainsDynamicImport)) {
if (node.isDeclarationFile ||
!(isEffectiveExternalModule(node, compilerOptions) ||
node.transformFlags & TransformFlags.ContainsDynamicImport ||
(isJsonSourceFile(node) && hasJsonModuleEmitEnabled(compilerOptions) && (compilerOptions.out || compilerOptions.outFile)))) {
return node;
}
@@ -117,6 +120,7 @@ namespace ts {
function transformAMDModule(node: SourceFile) {
const define = createIdentifier("define");
const moduleName = tryGetModuleNameFromFile(node, host, compilerOptions);
const jsonSourceFile = isJsonSourceFile(node) && node;
// An AMD define function has the following shape:
//
@@ -158,7 +162,7 @@ namespace ts {
// Add the dependency array argument:
//
// ["require", "exports", module1", "module2", ...]
createArrayLiteral([
createArrayLiteral(jsonSourceFile ? emptyArray : [
createLiteral("require"),
createLiteral("exports"),
...aliasedModuleNames,
@@ -168,7 +172,9 @@ namespace ts {
// Add the module body function argument:
//
// function (require, exports, module1, module2) ...
createFunctionExpression(
jsonSourceFile ?
jsonSourceFile.statements.length ? jsonSourceFile.statements[0].expression : createObjectLiteral() :
createFunctionExpression(
/*modifiers*/ undefined,
/*asteriskToken*/ undefined,
/*name*/ undefined,
+7 -1
View File
@@ -429,6 +429,7 @@ namespace ts {
projectPendingBuild.removeKey(proj);
if (!projectPendingBuild.getSize()) {
invalidatedProjectQueue.length = 0;
nextIndex = 0;
}
return proj;
}
@@ -506,6 +507,7 @@ namespace ts {
const configFileCache = createConfigFileCache(host);
let context = createBuildContext(defaultOptions);
let timerToBuildInvalidatedProject: any;
let reportFileChangeDetected = false;
const existingWatchersForWildcards = createMap<WildcardDirectoryWatcher>();
return {
@@ -583,7 +585,7 @@ namespace ts {
}
function invalidateProjectAndScheduleBuilds(resolved: ResolvedConfigFileName) {
reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation);
reportFileChangeDetected = true;
invalidateProject(resolved);
scheduleBuildInvalidatedProject();
}
@@ -816,6 +818,10 @@ namespace ts {
function buildInvalidatedProject() {
timerToBuildInvalidatedProject = undefined;
if (reportFileChangeDetected) {
reportFileChangeDetected = false;
reportWatchStatus(Diagnostics.File_change_detected_Starting_incremental_compilation);
}
const buildProject = context.getNextInvalidatedProject();
buildSomeProjects(p => p === buildProject);
if (context.hasPendingInvalidatedProjects()) {
+8 -6
View File
@@ -739,6 +739,7 @@ namespace ts {
}
export interface ComputedPropertyName extends Node {
parent: Declaration;
kind: SyntaxKind.ComputedPropertyName;
expression: Expression;
}
@@ -883,6 +884,7 @@ namespace ts {
kind: SyntaxKind.ShorthandPropertyAssignment;
name: Identifier;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
// used when ObjectLiteralExpression is used in ObjectAssignmentPattern
// it is grammar error to appear in actual object initializer
equalsToken?: Token<SyntaxKind.EqualsToken>;
@@ -941,6 +943,7 @@ namespace ts {
asteriskToken?: AsteriskToken;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
body?: Block | Expression;
}
@@ -3441,8 +3444,8 @@ namespace ts {
Enum = RegularEnum | ConstEnum,
Variable = FunctionScopedVariable | BlockScopedVariable,
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | JSContainer,
Type = Class | Interface | Enum | EnumMember | TypeLiteral | ObjectLiteral | TypeParameter | TypeAlias | JSContainer,
Value = Variable | Property | EnumMember | ObjectLiteral | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | JSContainer,
Type = Class | Interface | Enum | EnumMember | TypeLiteral | TypeParameter | TypeAlias | JSContainer,
Namespace = ValueModule | NamespaceModule | Enum,
Module = ValueModule | NamespaceModule,
Accessor = GetAccessor | SetAccessor,
@@ -3463,7 +3466,7 @@ namespace ts {
InterfaceExcludes = Type & ~(Interface | Class),
RegularEnumExcludes = (Value | Type) & ~(RegularEnum | ValueModule), // regular enums merge only with regular enums and modules
ConstEnumExcludes = (Value | Type) & ~ConstEnum, // const enums merge only with const enums
ValueModuleExcludes = Value & ~(Function | Class | RegularEnum | ValueModule),
ValueModuleExcludes = Value & ~(Function | Class | RegularEnum | ValueModule | JSContainer),
NamespaceModuleExcludes = 0,
MethodExcludes = Value & ~Method,
GetAccessorExcludes = Value & ~SetAccessor,
@@ -4175,9 +4178,8 @@ namespace ts {
/* @internal */
export const enum InferenceFlags {
None = 0, // No special inference behaviors
InferUnionTypes = 1 << 0, // Infer union types for disjoint candidates (otherwise unknownType)
NoDefault = 1 << 1, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
AnyDefault = 1 << 2, // Infer anyType for no inferences (otherwise emptyObjectType)
NoDefault = 1 << 0, // Infer unknownType for no inferences (otherwise anyType or emptyObjectType)
AnyDefault = 1 << 1, // Infer anyType for no inferences (otherwise emptyObjectType)
}
/**
+73 -24
View File
@@ -489,12 +489,23 @@ namespace ts {
return getTextOfNodeFromSourceText(sourceFile.text, node, includeTrivia);
}
function isJSDocTypeExpressionOrChild(node: Node): boolean {
return node.kind === SyntaxKind.JSDocTypeExpression || (node.parent && isJSDocTypeExpressionOrChild(node.parent));
}
export function getTextOfNodeFromSourceText(sourceText: string, node: Node, includeTrivia = false): string {
if (nodeIsMissing(node)) {
return "";
}
return sourceText.substring(includeTrivia ? node.pos : skipTrivia(sourceText, node.pos), node.end);
let text = sourceText.substring(includeTrivia ? node.pos : skipTrivia(sourceText, node.pos), node.end);
if (isJSDocTypeExpressionOrChild(node)) {
// strip space + asterisk at line start
text = text.replace(/(^|\r?\n|\r)\s*\*\s*/g, "$1");
}
return text;
}
export function getTextOfNode(node: Node, includeTrivia = false): string {
@@ -910,6 +921,10 @@ namespace ts {
return !!(getCombinedModifierFlags(node) & ModifierFlags.Const);
}
export function isDeclarationReadonly(declaration: Declaration): boolean {
return !!(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration));
}
export function isVarConst(node: VariableDeclaration | VariableDeclarationList): boolean {
return !!(getCombinedNodeFlags(node) & NodeFlags.Const);
}
@@ -1761,6 +1776,10 @@ namespace ts {
return decl;
}
export function isAssignmentDeclaration(decl: Declaration) {
return isBinaryExpression(decl) || isPropertyAccessExpression(decl) || isIdentifier(decl);
}
/** Get the initializer, taking into account defaulted Javascript initializers */
export function getEffectiveInitializer(node: HasExpressionInitializer) {
if (isInJavaScriptFile(node) && node.initializer &&
@@ -2111,6 +2130,10 @@ namespace ts {
result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration));
break;
}
if (node.kind === SyntaxKind.TypeParameter) {
result = addRange(result, getJSDocTypeParameterTags(node as TypeParameterDeclaration));
break;
}
node = getNextJSDocCommentLocation(node);
}
return result || emptyArray;
@@ -2360,29 +2383,33 @@ namespace ts {
}
// See GH#16030
export function isAnyDeclarationName(name: Node): boolean {
export function getDeclarationFromName(name: Node): Declaration | undefined {
const parent = name.parent;
switch (name.kind) {
case SyntaxKind.Identifier:
case SyntaxKind.StringLiteral:
case SyntaxKind.NumericLiteral: {
const parent = name.parent;
case SyntaxKind.NumericLiteral:
if (isComputedPropertyName(parent)) return parent.parent;
// falls through
case SyntaxKind.Identifier:
if (isDeclaration(parent)) {
return parent.name === name;
return parent.name === name ? parent : undefined;
}
else if (isQualifiedName(name.parent)) {
const tag = name.parent.parent;
return isJSDocParameterTag(tag) && tag.name === name.parent;
else if (isQualifiedName(parent)) {
const tag = parent.parent;
return isJSDocParameterTag(tag) && tag.name === parent ? tag : undefined;
}
else {
const binExp = name.parent.parent;
const binExp = parent.parent;
return isBinaryExpression(binExp) &&
getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None &&
(binExp.left.symbol || binExp.symbol) &&
getNameOfDeclaration(binExp) === name;
getNameOfDeclaration(binExp) === name
? binExp
: undefined;
}
}
default:
return false;
return undefined;
}
}
@@ -3742,7 +3769,7 @@ namespace ts {
return false;
}
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): boolean {
export function isExpressionWithTypeArgumentsInClassExtendsClause(node: Node): node is ExpressionWithTypeArguments {
return tryGetClassExtendingExpressionWithTypeArguments(node) !== undefined;
}
@@ -4057,7 +4084,8 @@ namespace ts {
* @param pos The start position.
* @param end The end position.
*/
export function createRange(pos: number, end: number): TextRange {
export function createRange(pos: number, end: number = pos): TextRange {
Debug.assert(end >= pos || end === -1);
return { pos, end };
}
@@ -4521,12 +4549,6 @@ namespace ts {
return { start, length };
}
/* @internal */
export function createTextRange(pos: number, end: number = pos): TextRange {
Debug.assert(end >= pos);
return { pos, end };
}
export function createTextSpanFromBounds(start: number, end: number) {
return createTextSpan(start, end - start);
}
@@ -5010,15 +5032,14 @@ namespace ts {
/**
* Gets the JSDoc parameter tags for the node if present.
*
* @remarks Returns any JSDoc param tag that matches the provided
* @remarks Returns any JSDoc param tag whose name matches the provided
* parameter, whether a param tag on a containing function
* expression, or a param tag on a variable declaration whose
* initializer is the containing function. The tags closest to the
* node are returned first, so in the previous example, the param
* tag on the containing function expression would be first.
*
* Does not return tags for binding patterns, because JSDoc matches
* parameters by name and binding patterns do not have a name.
* For binding patterns, parameter tags are matched by position.
*/
export function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag> {
if (param.name) {
@@ -5039,6 +5060,22 @@ namespace ts {
return emptyArray;
}
/**
* Gets the JSDoc type parameter tags for the node if present.
*
* @remarks Returns any JSDoc template tag whose names match the provided
* parameter, whether a template tag on a containing function
* expression, or a template tag on a variable declaration whose
* initializer is the containing function. The tags closest to the
* node are returned first, so in the previous example, the template
* tag on the containing function expression would be first.
*/
export function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray<JSDocTemplateTag> {
const name = param.name.escapedText;
return getJSDocTags(param.parent).filter((tag): tag is JSDocTemplateTag =>
isJSDocTemplateTag(tag) && tag.typeParameters.some(tp => tp.name.escapedText === name));
}
/**
* Return true if the node has JSDoc parameter tags.
*
@@ -7020,6 +7057,18 @@ namespace ts {
return moduleResolution;
}
export function hasJsonModuleEmitEnabled(options: CompilerOptions) {
switch (getEmitModuleKind(options)) {
case ModuleKind.CommonJS:
case ModuleKind.AMD:
case ModuleKind.ES2015:
case ModuleKind.ESNext:
return true;
default:
return false;
}
}
export function unreachableCodeIsError(options: CompilerOptions): boolean {
return options.allowUnreachableCode === false;
}
+10
View File
@@ -1378,6 +1378,16 @@ type Extract<T, U> = T extends U ? T : never;
*/
type NonNullable<T> = T extends null | undefined ? never : T;
/**
* Obtain the parameters of a function type in a tuple
*/
type Parameters<T extends (...args: any[]) => any> = T extends (...args: infer P) => any ? P : never;
/**
* Obtain the parameters of a constructor function type in a tuple
*/
type ConstructorParameters<T extends new (...args: any[]) => any> = T extends new (...args: infer P) => any ? P : never;
/**
* Obtain the return type of a function type
*/
+2 -2
View File
@@ -11,7 +11,7 @@ interface ReadonlyArray<T> {
* thisArg is omitted, undefined is used as the this value.
*/
flatMap<U, This = undefined> (
callback: (this: This, value: T, index: number, array: T[]) => U|U[],
callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray<U>,
thisArg?: This
): U[]
@@ -125,7 +125,7 @@ interface Array<T> {
* thisArg is omitted, undefined is used as the this value.
*/
flatMap<U, This = undefined> (
callback: (this: This, value: T, index: number, array: T[]) => U|U[],
callback: (this: This, value: T, index: number, array: T[]) => U|ReadonlyArray<U>,
thisArg?: This
): U[]
File diff suppressed because it is too large. Load diff
@@ -588,7 +588,7 @@
<Str Cat="Text">
<Val><![CDATA[A rest element cannot have a property name.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Um elemento restante não pode ter um nome de propriedade.]]></Val>
<Val><![CDATA[Um elemento rest não pode ter um nome de propriedade.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
+1 -1
View File
@@ -487,7 +487,7 @@ namespace ts.server {
this.globalPlugins = opts.globalPlugins || emptyArray;
this.pluginProbeLocations = opts.pluginProbeLocations || emptyArray;
this.allowLocalPluginLoads = !!opts.allowLocalPluginLoads;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(this.getExecutingFilePath(), "../typesMap.json") : opts.typesMapLocation;
this.typesMapLocation = (opts.typesMapLocation === undefined) ? combinePaths(getDirectoryPath(this.getExecutingFilePath()), "typesMap.json") : opts.typesMapLocation;
this.syntaxOnly = opts.syntaxOnly;
Debug.assert(!!this.host.createHash, "'ServerHost.createHash' is required for ProjectService");
+1 -6
View File
@@ -266,8 +266,6 @@ namespace ts.server {
getValue: (path: Path) => T,
projects: Projects,
action: (project: Project, value: T) => ReadonlyArray<U> | U | undefined,
comparer?: (a: U, b: U) => number,
areEqual?: (a: U, b: U) => boolean,
): U[] {
const outputs = flatMap(isArray(projects) ? projects : projects.projects, project => action(project, defaultValue));
if (!isArray(projects) && projects.symLinkedProjects) {
@@ -276,10 +274,7 @@ namespace ts.server {
outputs.push(...flatMap(projects, project => action(project, value)));
});
}
return comparer
? sortAndDeduplicate(outputs, comparer, areEqual)
: deduplicate(outputs, areEqual);
return deduplicate(outputs, equateValues);
}
function combineProjectOutputFromEveryProject<T>(projectService: ProjectService, action: (project: Project) => ReadonlyArray<T>, areEqual: (a: T, b: T) => boolean) {
@@ -42,7 +42,18 @@ namespace ts.codefix {
function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void {
// get the function declaration - returns a promise
const functionToConvert: FunctionLikeDeclaration = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration;
const tokenAtPosition = getTokenAtPosition(sourceFile, position);
let functionToConvert: FunctionLikeDeclaration | undefined;
// if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name
if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) &&
tokenAtPosition.parent.initializer && isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) {
functionToConvert = tokenAtPosition.parent.initializer;
}
else {
functionToConvert = tryCast(getContainingFunction(getTokenAtPosition(sourceFile, position)), isFunctionLikeDeclaration);
}
if (!functionToConvert) {
return;
}
+1 -1
View File
@@ -208,7 +208,7 @@ namespace ts.codefix {
return replacement[1];
}
else {
changes.replaceRangeWithText(sourceFile, createTextRange(left.getStart(sourceFile), right.pos), "export default");
changes.replaceRangeWithText(sourceFile, createRange(left.getStart(sourceFile), right.pos), "export default");
return true;
}
}
+5 -6
View File
@@ -283,14 +283,13 @@ namespace ts.codefix {
preferences: UserPreferences,
): ReadonlyArray<FixAddNewImport | FixUseImportType> {
const isJs = isSourceFileJavaScript(sourceFile);
const choicesForEachExportingModule = flatMap<SymbolExportInfo, ReadonlyArray<FixAddNewImport | FixUseImportType>>(moduleSymbols, ({ moduleSymbol, importKind, exportedSymbolIsTypeOnly }) => {
const modulePathsGroups = moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap);
return modulePathsGroups.map(group => group.map((moduleSpecifier): FixAddNewImport | FixUseImportType =>
const choicesForEachExportingModule = flatMap(moduleSymbols, ({ moduleSymbol, importKind, exportedSymbolIsTypeOnly }) =>
moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences, program.redirectTargetsMap)
.map((moduleSpecifier): FixAddNewImport | FixUseImportType =>
// `position` should only be undefined at a missing jsx namespace, in which case we shouldn't be looking for pure types.
exportedSymbolIsTypeOnly && isJs ? { kind: ImportFixKind.ImportType, moduleSpecifier, position: Debug.assertDefined(position) } : { kind: ImportFixKind.AddNew, moduleSpecifier, importKind }));
});
// Sort to keep the shortest paths first, but keep [relativePath, importRelativeToBaseUrl] groups together
return flatten<FixAddNewImport | FixUseImportType>(choicesForEachExportingModule.sort((a, b) => first(a).moduleSpecifier.length - first(b).moduleSpecifier.length));
// Sort to keep the shortest paths first
return choicesForEachExportingModule.sort((a, b) => a.moduleSpecifier.length - b.moduleSpecifier.length);
}
function getFixesForAddImport(
+7 -1
View File
@@ -264,6 +264,9 @@ namespace ts.Completions {
}
function quote(text: string, preferences: UserPreferences): string {
if (/^\d+$/.test(text)) {
return text;
}
const quoted = JSON.stringify(text);
switch (preferences.quotePreference) {
case undefined:
@@ -983,7 +986,10 @@ namespace ts.Completions {
break;
case SyntaxKind.Identifier:
// For `<div x=[|f/**/|]`, `parent` will be `x` and `previousToken.parent` will be `f` (which is its own JsxAttribute)
if (parent !== previousToken.parent && !(parent as JsxAttribute).initializer) {
// Note for `<div someBool f>` we don't want to treat this as a jsx inializer, instead it's the attribute name.
if (parent !== previousToken.parent &&
!(parent as JsxAttribute).initializer &&
findChildOfKind(parent, SyntaxKind.EqualsToken, sourceFile)) {
isJsxInitializer = previousToken as Identifier;
}
}
+82 -19
View File
@@ -5,12 +5,13 @@ namespace ts.FindAllReferences {
references: Entry[];
}
export const enum DefinitionKind { Symbol, Label, Keyword, This, String }
export type Definition =
| { type: "symbol"; symbol: Symbol }
| { type: "label"; node: Identifier }
| { type: "keyword"; node: Node }
| { type: "this"; node: Node }
| { type: "string"; node: StringLiteral };
| { readonly type: DefinitionKind.Symbol; readonly symbol: Symbol }
| { readonly type: DefinitionKind.Label; readonly node: Identifier }
| { readonly type: DefinitionKind.Keyword; readonly node: Node }
| { readonly type: DefinitionKind.This; readonly node: Node }
| { readonly type: DefinitionKind.String; readonly node: StringLiteral };
export type Entry = NodeEntry | SpanEntry;
export interface NodeEntry {
@@ -98,29 +99,29 @@ namespace ts.FindAllReferences {
function definitionToReferencedSymbolDefinitionInfo(def: Definition, checker: TypeChecker, originalNode: Node): ReferencedSymbolDefinitionInfo {
const info = (() => {
switch (def.type) {
case "symbol": {
case DefinitionKind.Symbol: {
const { symbol } = def;
const { displayParts, kind } = getDefinitionKindAndDisplayParts(symbol, checker, originalNode);
const name = displayParts.map(p => p.text).join("");
return { node: symbol.declarations ? getNameOfDeclaration(first(symbol.declarations)) || first(symbol.declarations) : originalNode, name, kind, displayParts };
}
case "label": {
case DefinitionKind.Label: {
const { node } = def;
return { node, name: node.text, kind: ScriptElementKind.label, displayParts: [displayPart(node.text, SymbolDisplayPartKind.text)] };
}
case "keyword": {
case DefinitionKind.Keyword: {
const { node } = def;
const name = tokenToString(node.kind)!;
return { node, name, kind: ScriptElementKind.keyword, displayParts: [{ text: name, kind: ScriptElementKind.keyword }] };
}
case "this": {
case DefinitionKind.This: {
const { node } = def;
const symbol = checker.getSymbolAtLocation(node);
const displayParts = symbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(
checker, symbol, node.getSourceFile(), getContainerNode(node), node).displayParts || [textPart("this")];
return { node, name: "this", kind: ScriptElementKind.variableElement, displayParts };
}
case "string": {
case DefinitionKind.String: {
const { node } = def;
return { node, name: node.text, kind: ScriptElementKind.variableElement, displayParts: [displayPart(getTextOfNode(node), SymbolDisplayPartKind.stringLiteral)] };
}
@@ -154,7 +155,7 @@ namespace ts.FindAllReferences {
textSpan: getTextSpan(node, sourceFile),
isWriteAccess: isWriteAccessForReference(node),
isDefinition: node.kind === SyntaxKind.DefaultKeyword
|| isAnyDeclarationName(node)
|| !!getDeclarationFromName(node)
|| isLiteralComputedPropertyDeclarationName(node),
isInString,
};
@@ -223,7 +224,68 @@ namespace ts.FindAllReferences {
/** A node is considered a writeAccess iff it is a name of a declaration or a target of an assignment */
function isWriteAccessForReference(node: Node): boolean {
return node.kind === SyntaxKind.DefaultKeyword || isAnyDeclarationName(node) || isWriteAccess(node);
const decl = getDeclarationFromName(node);
return !!decl && declarationIsWriteAccess(decl) || node.kind === SyntaxKind.DefaultKeyword || isWriteAccess(node);
}
/**
* True if 'decl' provides a value, as in `function f() {}`;
* false if 'decl' is just a location for a future write, as in 'let x;'
*/
function declarationIsWriteAccess(decl: Declaration): boolean {
// Consider anything in an ambient declaration to be a write access since it may be coming from JS.
if (!!(decl.flags & NodeFlags.Ambient)) return true;
switch (decl.kind) {
case SyntaxKind.BinaryExpression:
case SyntaxKind.BindingElement:
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.DefaultKeyword:
case SyntaxKind.EnumDeclaration:
case SyntaxKind.EnumMember:
case SyntaxKind.ExportSpecifier:
case SyntaxKind.ImportClause: // default import
case SyntaxKind.ImportEqualsDeclaration:
case SyntaxKind.ImportSpecifier:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.JSDocCallbackTag:
case SyntaxKind.JSDocTypedefTag:
case SyntaxKind.JsxAttribute:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.NamespaceExportDeclaration:
case SyntaxKind.NamespaceImport:
case SyntaxKind.Parameter:
case SyntaxKind.ShorthandPropertyAssignment:
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.TypeParameter:
return true;
case SyntaxKind.PropertyAssignment:
// In `({ x: y } = 0);`, `x` is not a write access. (Won't call this function for `y`.)
return !isArrayLiteralOrObjectLiteralDestructuringPattern((decl as PropertyAssignment).parent);
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.Constructor:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
return !!(decl as FunctionDeclaration | FunctionExpression | ConstructorDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration).body;
case SyntaxKind.VariableDeclaration:
case SyntaxKind.PropertyDeclaration:
return !!(decl as VariableDeclaration | PropertyDeclaration).initializer || isCatchClause(decl.parent);
case SyntaxKind.MethodSignature:
case SyntaxKind.PropertySignature:
case SyntaxKind.JSDocPropertyTag:
case SyntaxKind.JSDocParameterTag:
return false;
default:
return Debug.failBadSyntaxKind(decl);
}
}
}
@@ -313,7 +375,7 @@ namespace ts.FindAllReferences.Core {
}
}
return references.length ? [{ definition: { type: "symbol", symbol }, references }] : emptyArray;
return references.length ? [{ definition: { type: DefinitionKind.Symbol, symbol }, references }] : emptyArray;
}
/** getReferencedSymbols for special node kinds. */
@@ -524,7 +586,7 @@ namespace ts.FindAllReferences.Core {
let references = this.symbolIdToReferences[symbolId];
if (!references) {
references = this.symbolIdToReferences[symbolId] = [];
this.result.push({ definition: { type: "symbol", symbol: searchSymbol }, references });
this.result.push({ definition: { type: DefinitionKind.Symbol, symbol: searchSymbol }, references });
}
return node => references.push(nodeEntry(node));
}
@@ -818,7 +880,7 @@ namespace ts.FindAllReferences.Core {
const references = mapDefined(getPossibleSymbolReferenceNodes(sourceFile, labelName, container), node =>
// Only pick labels that are either the target label, or have a target that is the target label
node === targetLabel || (isJumpStatementTarget(node) && getTargetLabel(node, labelName) === targetLabel) ? nodeEntry(node) : undefined);
return [{ definition: { type: "label", node: targetLabel }, references }];
return [{ definition: { type: DefinitionKind.Label, node: targetLabel }, references }];
}
function isValidReferencePosition(node: Node, searchSymbolName: string): boolean {
@@ -850,7 +912,7 @@ namespace ts.FindAllReferences.Core {
return mapDefined(getPossibleSymbolReferenceNodes(sourceFile, tokenToString(keywordKind)!, sourceFile), referenceLocation =>
referenceLocation.kind === keywordKind ? nodeEntry(referenceLocation) : undefined);
});
return references.length ? [{ definition: { type: "keyword", node: references[0].node }, references }] : undefined;
return references.length ? [{ definition: { type: DefinitionKind.Keyword, node: references[0].node }, references }] : undefined;
}
function getReferencesInSourceFile(sourceFile: SourceFile, search: Search, state: State, addReferencesHere = true): void {
@@ -1292,7 +1354,7 @@ namespace ts.FindAllReferences.Core {
return container && (ModifierFlags.Static & getModifierFlags(container)) === staticFlag && container.parent.symbol === searchSpaceNode.symbol ? nodeEntry(node) : undefined;
});
return [{ definition: { type: "symbol", symbol: searchSpaceNode.symbol }, references }];
return [{ definition: { type: DefinitionKind.Symbol, symbol: searchSpaceNode.symbol }, references }];
}
function getReferencesForThisKeyword(thisOrSuperKeyword: Node, sourceFiles: ReadonlyArray<SourceFile>, cancellationToken: CancellationToken): SymbolAndEntries[] | undefined {
@@ -1355,8 +1417,9 @@ namespace ts.FindAllReferences.Core {
});
}).map(n => nodeEntry(n));
const thisParameter = firstDefined(references, r => isParameter(r.node.parent) ? r.node : undefined);
return [{
definition: { type: "this", node: thisOrSuperKeyword },
definition: { type: DefinitionKind.This, node: thisParameter || thisOrSuperKeyword },
references
}];
}
@@ -1369,7 +1432,7 @@ namespace ts.FindAllReferences.Core {
});
return [{
definition: { type: "string", node },
definition: { type: DefinitionKind.String, node },
references
}];
}
+1 -1
View File
@@ -221,7 +221,7 @@ namespace ts {
}
function createStringRange(node: StringLiteralLike, sourceFile: SourceFileLike): TextRange {
return createTextRange(node.getStart(sourceFile) + 1, node.end - 1);
return createRange(node.getStart(sourceFile) + 1, node.end - 1);
}
function forEachProperty(objectLiteral: Expression, cb: (property: PropertyAssignment, propertyName: string) => void) {
+1 -1
View File
@@ -591,6 +591,6 @@ namespace ts.SignatureHelp {
const param = checker.typeParameterToDeclaration(typeParameter, enclosingDeclaration)!;
printer.writeNode(EmitHint.Unspecified, param, sourceFile, writer);
});
return { name: typeParameter.symbol.name, documentation: emptyArray, displayParts, isOptional: false };
return { name: typeParameter.symbol.name, documentation: typeParameter.symbol.getDocumentationComment(checker), displayParts, isOptional: false };
}
}
+4 -3
View File
@@ -3,7 +3,7 @@ namespace ts {
export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] {
program.getSemanticDiagnostics(sourceFile, cancellationToken);
const diags: DiagnosticWithLocation[] = [];
const checker = program.getDiagnosticsProducingTypeChecker();
const checker = program.getTypeChecker();
if (sourceFile.commonJsModuleIndicator &&
(programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) &&
@@ -115,11 +115,12 @@ namespace ts {
function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: DiagnosticWithLocation[]): void {
const functionType = node.type ? checker.getTypeFromTypeNode(node.type) : undefined;
if (isAsyncFunction(node) || !node.body || !functionType) {
if (isAsyncFunction(node) || !node.body) {
return;
}
const functionType = checker.getTypeAtLocation(node);
const callSignatures = checker.getSignaturesOfType(functionType, SignatureKind.Call);
const returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined;
+8 -8
View File
@@ -291,7 +291,7 @@ namespace ts.textChanges {
}
public insertNodeAt(sourceFile: SourceFile, pos: number, newNode: Node, options: InsertNodeOptions = {}) {
this.replaceRange(sourceFile, createTextRange(pos), newNode, options);
this.replaceRange(sourceFile, createRange(pos), newNode, options);
}
private insertNodesAt(sourceFile: SourceFile, pos: number, newNodes: ReadonlyArray<Node>, options: ReplaceWithMultipleNodesOptions = {}): void {
@@ -334,7 +334,7 @@ namespace ts.textChanges {
}
public insertText(sourceFile: SourceFile, pos: number, text: string): void {
this.replaceRangeWithText(sourceFile, createTextRange(pos), text);
this.replaceRangeWithText(sourceFile, createRange(pos), text);
}
/** Prefer this over replacing a node with another that has a type annotation, as it avoids reformatting the other parts of the node. */
@@ -456,7 +456,7 @@ namespace ts.textChanges {
// check if previous statement ends with semicolon
// if not - insert semicolon to preserve the code from changing the meaning due to ASI
if (sourceFile.text.charCodeAt(after.end - 1) !== CharacterCodes.semicolon) {
this.replaceRange(sourceFile, createTextRange(after.end), createToken(SyntaxKind.SemicolonToken));
this.replaceRange(sourceFile, createRange(after.end), createToken(SyntaxKind.SemicolonToken));
}
}
const endPosition = getAdjustedEndPosition(sourceFile, after, {});
@@ -595,7 +595,7 @@ namespace ts.textChanges {
// write separator and leading trivia of the next element as suffix
const suffix = `${tokenToString(nextToken.kind)}${sourceFile.text.substring(nextToken.end, containingList[index + 1].getStart(sourceFile))}`;
this.replaceRange(sourceFile, createTextRange(startPos, containingList[index + 1].getStart(sourceFile)), newNode, { prefix, suffix });
this.replaceRange(sourceFile, createRange(startPos, containingList[index + 1].getStart(sourceFile)), newNode, { prefix, suffix });
}
}
else {
@@ -629,7 +629,7 @@ namespace ts.textChanges {
}
if (multilineList) {
// insert separator immediately following the 'after' node to preserve comments in trailing trivia
this.replaceRange(sourceFile, createTextRange(end), createToken(separator));
this.replaceRange(sourceFile, createRange(end), createToken(separator));
// use the same indentation as 'after' item
const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(afterStartLinePosition, afterStart, sourceFile, this.formatContext.options);
// insert element before the line break on the line that contains 'after' element
@@ -637,10 +637,10 @@ namespace ts.textChanges {
if (insertPos !== end && isLineBreak(sourceFile.text.charCodeAt(insertPos - 1))) {
insertPos--;
}
this.replaceRange(sourceFile, createTextRange(insertPos), newNode, { indentation, prefix: this.newLineCharacter });
this.replaceRange(sourceFile, createRange(insertPos), newNode, { indentation, prefix: this.newLineCharacter });
}
else {
this.replaceRange(sourceFile, createTextRange(end), newNode, { prefix: `${tokenToString(separator)} ` });
this.replaceRange(sourceFile, createRange(end), newNode, { prefix: `${tokenToString(separator)} ` });
}
}
return this;
@@ -652,7 +652,7 @@ namespace ts.textChanges {
const [openBraceEnd, closeBraceEnd] = getClassBraceEnds(cls, sourceFile);
// For `class C { }` remove the whitespace inside the braces.
if (positionsAreOnSameLine(openBraceEnd, closeBraceEnd, sourceFile) && openBraceEnd !== closeBraceEnd - 1) {
this.deleteRange(sourceFile, createTextRange(openBraceEnd, closeBraceEnd - 1));
this.deleteRange(sourceFile, createRange(openBraceEnd, closeBraceEnd - 1));
}
});
}
+7 -9
View File
@@ -755,7 +755,7 @@ namespace ts {
return result;
function find(n: Node): Node | undefined {
if (isNonWhitespaceToken(n)) {
if (isNonWhitespaceToken(n) && n.kind !== SyntaxKind.EndOfFileToken) {
return n;
}
@@ -786,16 +786,14 @@ namespace ts {
}
}
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || isJSDocCommentContainingNode(n));
Debug.assert(startNode !== undefined || n.kind === SyntaxKind.SourceFile || n.kind === SyntaxKind.EndOfFileToken || isJSDocCommentContainingNode(n));
// Here we know that none of child token nodes embrace the position,
// the only known case is when position is at the end of the file.
// Try to find the rightmost token in the file without filtering.
// Namely we are skipping the check: 'position < node.end'
if (children.length) {
const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile);
return candidate && findRightmostToken(candidate, sourceFile);
}
const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ children.length, sourceFile);
return candidate && findRightmostToken(candidate, sourceFile);
}
}
@@ -1048,7 +1046,7 @@ namespace ts {
function nodeHasTokens(n: Node, sourceFile: SourceFileLike): boolean {
// If we have a token or node that has a non-zero width, it must have tokens.
// Note: getWidth() does not take trivia into account.
return n.getWidth(sourceFile) !== 0;
return n.kind === SyntaxKind.EndOfFileToken ? !!(n as EndOfFileToken).jsDoc : n.getWidth(sourceFile) !== 0;
}
export function getNodeModifiers(node: Node): string {
@@ -1165,7 +1163,7 @@ namespace ts {
}
export function createTextRangeFromNode(node: Node, sourceFile: SourceFile): TextRange {
return createTextRange(node.getStart(sourceFile), node.end);
return createRange(node.getStart(sourceFile), node.end);
}
export function createTextSpanFromRange(range: TextRange): TextSpan {
@@ -1173,7 +1171,7 @@ namespace ts {
}
export function createTextRangeFromSpan(span: TextSpan): TextRange {
return createTextRange(span.start, span.start + span.length);
return createRange(span.start, span.start + span.length);
}
export function createTextChangeFromStartLength(start: number, length: number, newText: string): TextChange {
+1
View File
@@ -46,6 +46,7 @@
"unittests/cancellableLanguageServiceOperations.ts",
"unittests/commandLineParsing.ts",
"unittests/compileOnSave.ts",
"unittests/compilerCore.ts",
"unittests/configurationExtension.ts",
"unittests/convertCompilerOptionsFromJson.ts",
"unittests/convertToAsyncFunction.ts",
@@ -366,4 +366,120 @@ namespace ts {
});
});
});
describe("parseBuildOptions", () => {
function assertParseResult(commandLine: string[], expectedParsedBuildCommand: ParsedBuildCommand) {
const parsed = parseBuildCommand(commandLine);
const parsedBuildOptions = JSON.stringify(parsed.buildOptions);
const expectedBuildOptions = JSON.stringify(expectedParsedBuildCommand.buildOptions);
assert.equal(parsedBuildOptions, expectedBuildOptions);
const parsedErrors = parsed.errors;
const expectedErrors = expectedParsedBuildCommand.errors;
assert.isTrue(parsedErrors.length === expectedErrors.length, `Expected error: ${JSON.stringify(expectedErrors)}. Actual error: ${JSON.stringify(parsedErrors)}.`);
for (let i = 0; i < parsedErrors.length; i++) {
const parsedError = parsedErrors[i];
const expectedError = expectedErrors[i];
assert.equal(parsedError.code, expectedError.code);
assert.equal(parsedError.category, expectedError.category);
assert.equal(parsedError.messageText, expectedError.messageText);
}
const parsedProjects = parsed.projects;
const expectedProjects = expectedParsedBuildCommand.projects;
assert.deepEqual(parsedProjects, expectedProjects, `Expected projects: [${JSON.stringify(expectedProjects)}]. Actual projects: [${JSON.stringify(parsedProjects)}].`);
}
it("parse build without any options ", () => {
// --lib es6 0.ts
assertParseResult([],
{
errors: [],
projects: ["."],
buildOptions: {}
});
});
it("Parse multiple options", () => {
// --lib es5,es2015.symbol.wellknown 0.ts
assertParseResult(["--verbose", "--force", "tests"],
{
errors: [],
projects: ["tests"],
buildOptions: { verbose: true, force: true }
});
});
it("Parse option with invalid option ", () => {
// --lib es5,invalidOption 0.ts
assertParseResult(["--verbose", "--invalidOption"],
{
errors: [{
messageText: "Unknown build option '--invalidOption'.",
category: Diagnostics.Unknown_build_option_0.category,
code: Diagnostics.Unknown_build_option_0.code,
file: undefined,
start: undefined,
length: undefined,
}],
projects: ["."],
buildOptions: { verbose: true }
});
});
it("Parse multiple flags with input projects at the end", () => {
// --lib es5,es2015.symbol.wellknown --target es5 0.ts
assertParseResult(["--force", "--verbose", "src", "tests"],
{
errors: [],
projects: ["src", "tests"],
buildOptions: { force: true, verbose: true }
});
});
it("Parse multiple flags with input projects in the middle", () => {
// --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown
assertParseResult(["--force", "src", "tests", "--verbose"],
{
errors: [],
projects: ["src", "tests"],
buildOptions: { force: true, verbose: true }
});
});
it("Parse multiple flags with input projects in the beginning", () => {
// --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown
assertParseResult(["src", "tests", "--force", "--verbose"],
{
errors: [],
projects: ["src", "tests"],
buildOptions: { force: true, verbose: true }
});
});
describe("Combining options that make no sense together", () => {
function verifyInvalidCombination(flag1: keyof BuildOptions, flag2: keyof BuildOptions) {
it(`--${flag1} and --${flag2} together is invalid`, () => {
// --module commonjs --target es5 0.ts --lib es5,es2015.symbol.wellknown
assertParseResult([`--${flag1}`, `--${flag2}`],
{
errors: [{
messageText: `Options '${flag1}' and '${flag2}' cannot be combined.`,
category: Diagnostics.Options_0_and_1_cannot_be_combined.category,
code: Diagnostics.Options_0_and_1_cannot_be_combined.code,
file: undefined,
start: undefined,
length: undefined,
}],
projects: ["."],
buildOptions: { [flag1]: true, [flag2]: true }
});
});
}
verifyInvalidCombination("clean", "force");
verifyInvalidCombination("clean", "verbose");
verifyInvalidCombination("clean", "watch");
verifyInvalidCombination("watch", "dry");
});
});
}
+33
View File
@@ -0,0 +1,33 @@
namespace ts {
describe("compilerCore", () => {
describe("equalOwnProperties", () => {
it("correctly equates objects", () => {
assert.isTrue(equalOwnProperties({}, {}));
assert.isTrue(equalOwnProperties({ a: 1 }, { a: 1 }));
assert.isTrue(equalOwnProperties({ a: 1, b: 2 }, { b: 2, a: 1 }));
});
it("correctly identifies unmatched objects", () => {
assert.isFalse(equalOwnProperties({}, { a: 1 }), "missing left property");
assert.isFalse(equalOwnProperties({ a: 1 }, {}), "missing right property");
assert.isFalse(equalOwnProperties({ a: 1 }, { a: 2 }), "differing property");
});
it("correctly identifies undefined vs hasOwnProperty", () => {
assert.isFalse(equalOwnProperties({}, { a: undefined }), "missing left property");
assert.isFalse(equalOwnProperties({ a: undefined }, {}), "missing right property");
});
it("truthiness", () => {
const trythyTest = (l: any, r: any) => !!l === !!r;
assert.isFalse(equalOwnProperties({}, { a: 1 }, trythyTest), "missing left truthy property");
assert.isFalse(equalOwnProperties({}, { a: 0 }, trythyTest), "missing left falsey property");
assert.isFalse(equalOwnProperties({ a: 1 }, {}, trythyTest), "missing right truthy property");
assert.isFalse(equalOwnProperties({ a: 0 }, {}, trythyTest), "missing right falsey property");
assert.isTrue(equalOwnProperties({ a: 1 }, { a: "foo" }, trythyTest), "valid equality");
});
it("all equal", () => {
assert.isFalse(equalOwnProperties({}, { a: 1 }, () => true), "missing left property");
assert.isFalse(equalOwnProperties({ a: 1 }, {}, () => true), "missing right property");
assert.isTrue(equalOwnProperties({ a: 1 }, { a: 2 }, () => true), "valid equality");
});
});
});
}
@@ -319,7 +319,7 @@ interface String { charAt: any; }
interface Array<T> {}`
};
function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) {
function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, diagnosticDescription: DiagnosticMessage, codeFixDescription: DiagnosticMessage, includeLib?: boolean) {
const t = getTest(text);
const selectionRange = t.ranges.get("selection")!;
if (!selectionRange) {
@@ -361,12 +361,14 @@ interface Array<T> {}`
};
const diagnostics = languageService.getSuggestionDiagnostics(f.path);
const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === description.message);
assert.isNotNull(diagnostic);
const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === diagnosticDescription.message);
assert.exists(diagnostic);
assert.equal(diagnostic!.start, context.span.start);
assert.equal(diagnostic!.length, context.span.length);
const actions = codefix.getFixes(context);
const action = find(actions, action => action.description === description.message)!;
assert.isNotNull(action);
const action = find(actions, action => action.description === codeFixDescription.message)!;
assert.exists(action);
const data: string[] = [];
data.push(`// ==ORIGINAL==`);
@@ -423,6 +425,10 @@ interface Array<T> {}`
_testConvertToAsyncFunction("convertToAsyncFunction_basic", `
function [#|f|](): Promise<void>{
return fetch('https://typescriptlang.org').then(result => { console.log(result) });
}`);
_testConvertToAsyncFunction("convertToAsyncFunction_basicNoReturnTypeAnnotation", `
function [#|f|]() {
return fetch('https://typescriptlang.org').then(result => { console.log(result) });
}`);
_testConvertToAsyncFunction("convertToAsyncFunction_basicWithComments", `
function [#|f|](): Promise<void>{
@@ -436,6 +442,10 @@ function [#|f|](): Promise<void>{
_testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunction", `
[#|():Promise<void> => {|]
return fetch('https://typescriptlang.org').then(result => console.log(result));
}`);
_testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunctionNoAnnotation", `
[#|() => {|]
return fetch('https://typescriptlang.org').then(result => console.log(result));
}`);
_testConvertToAsyncFunction("convertToAsyncFunction_Catch", `
function [#|f|]():Promise<void> {
@@ -1178,11 +1188,17 @@ function [#|f|]() {
}
`);
_testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpression", `
const [#|foo|] = function () {
return fetch('https://typescriptlang.org').then(result => { console.log(result) });
}
`);
});
function _testConvertToAsyncFunction(caption: string, text: string) {
testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.Convert_to_async_function, /*includeLib*/ true);
testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.This_may_be_converted_to_an_async_function, Diagnostics.Convert_to_async_function, /*includeLib*/ true);
}
function _testConvertToAsyncFunctionFailed(caption: string, text: string) {
+20 -9
View File
@@ -1,14 +1,21 @@
namespace ts {
export function checkResolvedModule(expected: ResolvedModuleFull | undefined, actual: ResolvedModuleFull): boolean {
if (!expected === !actual) {
if (expected) {
assert.isTrue(expected.resolvedFileName === actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.isTrue(expected.extension === actual.extension, `'ext': expected '${expected.extension}' to be equal to '${actual.extension}'`);
assert.isTrue(expected.isExternalLibraryImport === actual.isExternalLibraryImport, `'isExternalLibraryImport': expected '${expected.isExternalLibraryImport}' to be equal to '${actual.isExternalLibraryImport}'`);
export function checkResolvedModule(actual: ResolvedModuleFull | undefined, expected: ResolvedModuleFull | undefined): boolean {
if (!expected) {
if (actual) {
assert.fail(actual, expected, "expected resolved module to be undefined");
return false;
}
return true;
}
return false;
else if (!actual) {
assert.fail(actual, expected, "expected resolved module to be defined");
return false;
}
assert.isTrue(actual.resolvedFileName === expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`);
assert.isTrue(actual.extension === expected.extension, `'ext': expected '${actual.extension}' to be equal to '${expected.extension}'`);
assert.isTrue(actual.isExternalLibraryImport === expected.isExternalLibraryImport, `'isExternalLibraryImport': expected '${actual.isExternalLibraryImport}' to be equal to '${expected.isExternalLibraryImport}'`);
return true;
}
export function checkResolvedModuleWithFailedLookupLocations(actual: ResolvedModuleWithFailedLookupLocations, expectedResolvedModule: ResolvedModuleFull, expectedFailedLookupLocations: string[]): void {
@@ -396,8 +403,12 @@ namespace ts {
function testPreserveSymlinks(preserveSymlinks: boolean) {
it(`preserveSymlinks: ${preserveSymlinks}`, () => {
const realFileName = "/linked/index.d.ts";
const symlinkFileName = "/app/node_modulex/linked/index.d.ts";
const host = createModuleResolutionHost(/*hasDirectoryExists*/ true, { name: realFileName, symlinks: [symlinkFileName] });
const symlinkFileName = "/app/node_modules/linked/index.d.ts";
const host = createModuleResolutionHost(
/*hasDirectoryExists*/ true,
{ name: realFileName, symlinks: [symlinkFileName] },
{ name: "/app/node_modules/linked/package.json", content: '{"version": "0.0.0", "main": "./index"}' },
);
const resolution = nodeModuleNameResolver("linked", "/app/app.ts", { preserveSymlinks }, host);
const resolvedFileName = preserveSymlinks ? symlinkFileName : realFileName;
checkResolvedModule(resolution.resolvedModule, createResolvedModule(resolvedFileName, /*isExternalLibraryImport*/ true));
@@ -177,15 +177,10 @@ namespace ts {
file.text = file.text.updateProgram(newProgramText);
}
function checkResolvedTypeDirective(expected: ResolvedTypeReferenceDirective, actual: ResolvedTypeReferenceDirective): boolean {
if (!expected === !actual) {
if (expected) {
assert.equal(expected.resolvedFileName, actual.resolvedFileName, `'resolvedFileName': expected '${expected.resolvedFileName}' to be equal to '${actual.resolvedFileName}'`);
assert.equal(expected.primary, actual.primary, `'primary': expected '${expected.primary}' to be equal to '${actual.primary}'`);
}
return true;
}
return false;
function checkResolvedTypeDirective(actual: ResolvedTypeReferenceDirective, expected: ResolvedTypeReferenceDirective) {
assert.equal(actual.resolvedFileName, expected.resolvedFileName, `'resolvedFileName': expected '${actual.resolvedFileName}' to be equal to '${expected.resolvedFileName}'`);
assert.equal(actual.primary, expected.primary, `'primary': expected '${actual.primary}' to be equal to '${expected.primary}'`);
return true;
}
function checkCache<T>(caption: string, program: Program, fileName: string, expectedContent: Map<T> | undefined, getCache: (f: SourceFile) => Map<T> | undefined, entryChecker: (expected: T, original: T) => boolean): void {
@@ -399,6 +394,30 @@ namespace ts {
assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use");
});
it("works with updated SourceFiles", () => {
// adapted repro from https://github.com/Microsoft/TypeScript/issues/26166
const files = [
{ name: "/a.ts", text: SourceText.New("", "", 'import * as a from "a";a;') },
{ name: "/types/zzz/index.d.ts", text: SourceText.New("", "", 'declare module "a" { }') },
];
const host = createTestCompilerHost(files, target);
const options: CompilerOptions = { target, typeRoots: ["/types"] };
const program1 = createProgram(["/a.ts"], options, host);
let sourceFile = program1.getSourceFile("/a.ts")!;
assert.isDefined(sourceFile, "'/a.ts' is included in the program");
sourceFile = updateSourceFile(sourceFile, "'use strict';" + sourceFile.text, { newLength: "'use strict';".length, span: { start: 0, length: 0 } });
assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are updated");
const updateHost: TestCompilerHost = {
...host,
getSourceFile(fileName) {
return fileName === sourceFile.fileName ? sourceFile : program1.getSourceFile(fileName);
}
};
const program2 = createProgram(["/a.ts"], options, updateHost, program1);
assert.isDefined(program2.getSourceFile("/a.ts")!.resolvedModules!.get("a"), "'a' is not an unresolved module after re-use");
assert.strictEqual(sourceFile.statements[2].getSourceFile(), sourceFile, "parent pointers are not altered");
});
it("resolved type directives cache follows type directives", () => {
const files = [
{ name: "/a.ts", text: SourceText.New("/// <reference types='typedefs'/>", "", "var x = $") },
+42 -21
View File
@@ -98,34 +98,55 @@ namespace ts.tscWatch {
for (const stamp of outputFileStamps) {
assert.isDefined(stamp[1], `${stamp[0]} expected to be present`);
}
return { host, outputFileStamps };
return host;
}
it("creates solution in watch mode", () => {
createSolutionInWatchMode();
});
it("change builds changes and reports found errors message", () => {
const { host, outputFileStamps } = createSolutionInWatchMode();
host.writeFile(core[1].path, `${core[1].content}
const host = createSolutionInWatchMode();
verifyChange(`${core[1].content}
export class someClass { }`);
host.checkTimeoutQueueLengthAndRun(1); // Builds core
const changedCore = getOutputFileStamps(host);
verifyChangedFiles(changedCore, outputFileStamps, [
...getOutputFileNames(SubProject.core, "anotherModule"), // This should not be written really
...getOutputFileNames(SubProject.core, "index")
]);
host.checkTimeoutQueueLengthAndRun(1); // Builds tests
const changedTests = getOutputFileStamps(host);
verifyChangedFiles(changedTests, changedCore, [
...getOutputFileNames(SubProject.tests, "index") // Again these need not be written
]);
host.checkTimeoutQueueLengthAndRun(1); // Builds logic
const changedLogic = getOutputFileStamps(host);
verifyChangedFiles(changedLogic, changedTests, [
...getOutputFileNames(SubProject.logic, "index") // Again these need not be written
]);
host.checkTimeoutQueueLength(0);
checkOutputErrorsIncremental(host, emptyArray);
// Another change requeues and builds it
verifyChange(core[1].content);
// Two changes together report only single time message: File change detected. Starting incremental compilation...
const outputFileStamps = getOutputFileStamps(host);
const change1 = `${core[1].content}
export class someClass { }`;
host.writeFile(core[1].path, change1);
host.writeFile(core[1].path, `${change1}
export class someClass2 { }`);
verifyChangeAfterTimeout(outputFileStamps);
function verifyChange(coreContent: string) {
const outputFileStamps = getOutputFileStamps(host);
host.writeFile(core[1].path, coreContent);
verifyChangeAfterTimeout(outputFileStamps);
}
function verifyChangeAfterTimeout(outputFileStamps: OutputFileStamp[]) {
host.checkTimeoutQueueLengthAndRun(1); // Builds core
const changedCore = getOutputFileStamps(host);
verifyChangedFiles(changedCore, outputFileStamps, [
...getOutputFileNames(SubProject.core, "anotherModule"), // This should not be written really
...getOutputFileNames(SubProject.core, "index")
]);
host.checkTimeoutQueueLengthAndRun(1); // Builds tests
const changedTests = getOutputFileStamps(host);
verifyChangedFiles(changedTests, changedCore, [
...getOutputFileNames(SubProject.tests, "index") // Again these need not be written
]);
host.checkTimeoutQueueLengthAndRun(1); // Builds logic
const changedLogic = getOutputFileStamps(host);
verifyChangedFiles(changedLogic, changedTests, [
...getOutputFileNames(SubProject.logic, "index") // Again these need not be written
]);
host.checkTimeoutQueueLength(0);
checkOutputErrorsIncremental(host, emptyArray);
}
});
// TODO: write tests reporting errors but that will have more involved work since file
@@ -9555,6 +9555,65 @@ export function Test2() {
});
});
describe("tsserverProjectSystem typeReferenceDirectives", () => {
it("when typeReferenceDirective contains UpperCasePackage", () => {
const projectLocation = "/user/username/projects/myproject";
const libProjectLocation = `${projectLocation}/lib`;
const typeLib: File = {
path: `${libProjectLocation}/@types/UpperCasePackage/index.d.ts`,
content: `declare class BrokenTest {
constructor(name: string, width: number, height: number, onSelect: Function);
Name: string;
SelectedFile: string;
}`
};
const appLib: File = {
path: `${libProjectLocation}/@app/lib/index.d.ts`,
content: `/// <reference types="UpperCasePackage" />
declare class TestLib {
issue: BrokenTest;
constructor();
test(): void;
}`
};
const testProjectLocation = `${projectLocation}/test`;
const testFile: File = {
path: `${testProjectLocation}/test.ts`,
content: `class TestClass1 {
constructor() {
var l = new TestLib();
}
public test2() {
var x = new BrokenTest('',0,0,null);
}
}`
};
const testConfig: File = {
path: `${testProjectLocation}/tsconfig.json`,
content: JSON.stringify({
compilerOptions: {
module: "amd",
typeRoots: ["../lib/@types", "../lib/@app"]
}
})
};
const files = [typeLib, appLib, testFile, testConfig, libFile];
const host = createServerHost(files);
const service = createProjectService(host);
service.openClientFile(testFile.path);
checkNumberOfProjects(service, { configuredProjects: 1 });
const project = service.configuredProjects.get(testConfig.path)!;
checkProjectActualFiles(project, files.map(f => f.path));
host.writeFile(appLib.path, appLib.content.replace("test()", "test2()"));
host.checkTimeoutQueueLengthAndRun(2);
});
});
describe("tsserverProjectSystem project references", () => {
const aTs: File = {
path: "/a/a.ts",
+19 -105
View File
@@ -165,79 +165,10 @@ namespace ts {
}
function performBuild(args: string[]): number | undefined {
const buildOpts: CommandLineOption[] = [
{
name: "help",
shortName: "h",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Command_line_Options,
description: Diagnostics.Print_this_message,
},
{
name: "help",
shortName: "?",
type: "boolean"
},
{
name: "verbose",
shortName: "v",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Enable_verbose_logging,
type: "boolean"
},
{
name: "dry",
shortName: "d",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Show_what_would_be_built_or_deleted_if_specified_with_clean,
type: "boolean"
},
{
name: "force",
shortName: "f",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Build_all_projects_including_those_that_appear_to_be_up_to_date,
type: "boolean"
},
{
name: "clean",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Delete_the_outputs_of_all_projects,
type: "boolean"
},
{
name: "watch",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Watch_input_files,
type: "boolean"
},
{
name: "preserveWatchOutput",
type: "boolean",
category: Diagnostics.Command_line_Options,
description: Diagnostics.Whether_to_keep_outdated_console_output_in_watch_mode_instead_of_clearing_the_screen,
},
];
let buildOptionNameMap: OptionNameMap | undefined;
const returnBuildOptionNameMap = () => (buildOptionNameMap || (buildOptionNameMap = createOptionNameMap(buildOpts)));
const buildOptions: BuildOptions = {};
const projects: string[] = [];
for (const arg of args) {
if (arg.charCodeAt(0) === CharacterCodes.minus) {
const opt = getOptionDeclarationFromName(returnBuildOptionNameMap, arg.slice(arg.charCodeAt(1) === CharacterCodes.minus ? 2 : 1), /*allowShort*/ true);
if (opt) {
buildOptions[opt.name as keyof BuildOptions] = true;
}
else {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Unknown_build_option_0, arg));
}
}
else {
// Not a flag, parse as filename
addProject(arg);
}
const { buildOptions, projects: buildProjects, errors } = parseBuildCommand(args);
if (errors.length > 0) {
errors.forEach(reportDiagnostic);
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
if (buildOptions.help) {
@@ -248,6 +179,21 @@ namespace ts {
// Update to pretty if host supports it
updateReportDiagnostic();
const projects = mapDefined(buildProjects, project => {
const fileName = resolvePath(sys.getCurrentDirectory(), project);
const refPath = resolveProjectReferencePath(sys, { path: fileName });
if (!sys.fileExists(refPath)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName));
return undefined;
}
return refPath;
});
if (projects.length === 0) {
printVersion();
printHelp(buildOpts, "--build ");
return ExitStatus.Success;
}
if (!sys.getModifiedTime || !sys.setModifiedTime || (buildOptions.clean && !sys.deleteFile)) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.The_current_host_does_not_support_the_0_option, "--build"));
@@ -257,29 +203,6 @@ namespace ts {
reportWatchModeWithoutSysSupport();
}
// Nonsensical combinations
if (buildOptions.clean && buildOptions.force) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "force"));
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
if (buildOptions.clean && buildOptions.verbose) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "verbose"));
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
if (buildOptions.clean && buildOptions.watch) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "clean", "watch"));
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
if (buildOptions.watch && buildOptions.dry) {
reportDiagnostic(createCompilerDiagnostic(Diagnostics.Options_0_and_1_cannot_be_combined, "watch", "dry"));
return ExitStatus.DiagnosticsPresent_OutputsSkipped;
}
if (projects.length === 0) {
// tsc -b invoked with no extra arguments; act as if invoked with "tsc -b ."
addProject(".");
}
// TODO: change this to host if watch => watchHost otherwiue without wathc
const builder = createSolutionBuilder(createSolutionBuilderWithWatchHost(sys, reportDiagnostic, createBuilderStatusReporter(sys, shouldBePretty()), createWatchStatusReporter()), projects, buildOptions);
if (buildOptions.clean) {
@@ -293,15 +216,6 @@ namespace ts {
}
return builder.buildAllProjects();
function addProject(projectSpecification: string) {
const fileName = resolvePath(sys.getCurrentDirectory(), projectSpecification);
const refPath = resolveProjectReferencePath(sys, { path: fileName });
if (!sys.fileExists(refPath)) {
return reportDiagnostic(createCompilerDiagnostic(Diagnostics.File_0_does_not_exist, fileName));
}
projects.push(refPath);
}
}
function performCompilation(rootNames: string[], projectReferences: ReadonlyArray<ProjectReference> | undefined, options: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
+1 -1
View File
@@ -924,7 +924,7 @@ namespace ts.server {
setStackTraceLimit();
const typingSafeListLocation = findArgument(Arguments.TypingSafeListLocation)!; // TODO: GH#18217
const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(sys.getExecutingFilePath(), "../typesMap.json");
const typesMapLocation = findArgument(Arguments.TypesMapLocation) || combinePaths(getDirectoryPath(sys.getExecutingFilePath()), "typesMap.json");
const npmLocation = findArgument(Arguments.NpmLocation);
function parseStringArray(argName: string): ReadonlyArray<string> {
@@ -1,9 +1,10 @@
tests/cases/compiler/abstractPropertyInConstructor.ts(4,24): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
tests/cases/compiler/abstractPropertyInConstructor.ts(7,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstract property 'cb' in class 'AbstractClass' cannot be accessed in the constructor.
tests/cases/compiler/abstractPropertyInConstructor.ts(25,18): error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
==== tests/cases/compiler/abstractPropertyInConstructor.ts (3 errors) ====
==== tests/cases/compiler/abstractPropertyInConstructor.ts (4 errors) ====
abstract class AbstractClass {
constructor(str: string, other: AbstractClass) {
this.method(parseInt(str));
@@ -34,6 +35,11 @@ tests/cases/compiler/abstractPropertyInConstructor.ts(9,14): error TS2715: Abstr
abstract method(num: number): void;
other = this.prop;
~~~~
!!! error TS2715: Abstract property 'prop' in class 'AbstractClass' cannot be accessed in the constructor.
fn = () => this.prop;
method2() {
this.prop = this.prop + "!";
}
@@ -23,6 +23,9 @@ abstract class AbstractClass {
abstract method(num: number): void;
other = this.prop;
fn = () => this.prop;
method2() {
this.prop = this.prop + "!";
}
@@ -42,6 +45,8 @@ class User {
var AbstractClass = /** @class */ (function () {
function AbstractClass(str, other) {
var _this = this;
this.other = this.prop;
this.fn = function () { return _this.prop; };
this.method(parseInt(str));
var val = this.prop.toLowerCase();
if (!str) {
@@ -67,8 +67,20 @@ abstract class AbstractClass {
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
>num : Symbol(num, Decl(abstractPropertyInConstructor.ts, 22, 20))
other = this.prop;
>other : Symbol(AbstractClass.other, Decl(abstractPropertyInConstructor.ts, 22, 39))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
fn = () => this.prop;
>fn : Symbol(AbstractClass.fn, Decl(abstractPropertyInConstructor.ts, 24, 22))
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>this : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
method2() {
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39))
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25))
this.prop = this.prop + "!";
>this.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
@@ -81,31 +93,31 @@ abstract class AbstractClass {
}
class User {
>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 27, 1))
>User : Symbol(User, Decl(abstractPropertyInConstructor.ts, 30, 1))
constructor(a: AbstractClass) {
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
>AbstractClass : Symbol(AbstractClass, Decl(abstractPropertyInConstructor.ts, 0, 0))
a.prop;
>a.prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
>prop : Symbol(AbstractClass.prop, Decl(abstractPropertyInConstructor.ts, 17, 5))
a.cb("hi");
>a.cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
>cb : Symbol(AbstractClass.cb, Decl(abstractPropertyInConstructor.ts, 19, 26))
a.method(12);
>a.method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
>method : Symbol(AbstractClass.method, Decl(abstractPropertyInConstructor.ts, 20, 37))
a.method2();
>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 30, 16))
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 22, 39))
>a.method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25))
>a : Symbol(a, Decl(abstractPropertyInConstructor.ts, 33, 16))
>method2 : Symbol(AbstractClass.method2, Decl(abstractPropertyInConstructor.ts, 25, 25))
}
}
@@ -75,6 +75,19 @@ abstract class AbstractClass {
>method : (num: number) => void
>num : number
other = this.prop;
>other : string
>this.prop : string
>this : this
>prop : string
fn = () => this.prop;
>fn : () => string
>() => this.prop : () => string
>this.prop : string
>this : this
>prop : string
method2() {
>method2 : () => void
@@ -3,7 +3,7 @@ function f<T>(x: T): T {
return x;
}
enum E { A, B, C }
enum E { A, B, C, "non identifier" }
const c1 = "abc";
const c2 = 123;
@@ -13,6 +13,7 @@ const c5 = f(123);
const c6 = f(-123);
const c7 = true;
const c8 = E.A;
const c8b = E["non identifier"];
const c9 = { x: "abc" };
const c10 = [123];
const c11 = "abc" + "def";
@@ -29,6 +30,7 @@ var E;
E[E["A"] = 0] = "A";
E[E["B"] = 1] = "B";
E[E["C"] = 2] = "C";
E[E["non identifier"] = 3] = "non identifier";
})(E || (E = {}));
var c1 = "abc";
var c2 = 123;
@@ -38,6 +40,7 @@ var c5 = f(123);
var c6 = f(-123);
var c7 = true;
var c8 = E.A;
var c8b = E["non identifier"];
var c9 = { x: "abc" };
var c10 = [123];
var c11 = "abc" + "def";
@@ -51,7 +54,8 @@ declare function f<T>(x: T): T;
declare enum E {
A = 0,
B = 1,
C = 2
C = 2,
"non identifier" = 3
}
declare const c1 = "abc";
declare const c2 = 123;
@@ -60,7 +64,8 @@ declare const c4 = 123;
declare const c5 = 123;
declare const c6 = -123;
declare const c7: boolean;
declare const c8: E;
declare const c8 = E.A;
declare const c8b = E["non identifier"];
declare const c9: {
x: string;
};
@@ -10,11 +10,12 @@ function f<T>(x: T): T {
>x : Symbol(x, Decl(ambientConstLiterals.ts, 0, 14))
}
enum E { A, B, C }
enum E { A, B, C, "non identifier" }
>E : Symbol(E, Decl(ambientConstLiterals.ts, 2, 1))
>A : Symbol(E.A, Decl(ambientConstLiterals.ts, 4, 8))
>B : Symbol(E.B, Decl(ambientConstLiterals.ts, 4, 11))
>C : Symbol(E.C, Decl(ambientConstLiterals.ts, 4, 14))
>"non identifier" : Symbol(E["non identifier"], Decl(ambientConstLiterals.ts, 4, 17))
const c1 = "abc";
>c1 : Symbol(c1, Decl(ambientConstLiterals.ts, 6, 5))
@@ -47,27 +48,32 @@ const c8 = E.A;
>E : Symbol(E, Decl(ambientConstLiterals.ts, 2, 1))
>A : Symbol(E.A, Decl(ambientConstLiterals.ts, 4, 8))
const c8b = E["non identifier"];
>c8b : Symbol(c8b, Decl(ambientConstLiterals.ts, 14, 5))
>E : Symbol(E, Decl(ambientConstLiterals.ts, 2, 1))
>"non identifier" : Symbol(E["non identifier"], Decl(ambientConstLiterals.ts, 4, 17))
const c9 = { x: "abc" };
>c9 : Symbol(c9, Decl(ambientConstLiterals.ts, 14, 5))
>x : Symbol(x, Decl(ambientConstLiterals.ts, 14, 12))
>c9 : Symbol(c9, Decl(ambientConstLiterals.ts, 15, 5))
>x : Symbol(x, Decl(ambientConstLiterals.ts, 15, 12))
const c10 = [123];
>c10 : Symbol(c10, Decl(ambientConstLiterals.ts, 15, 5))
>c10 : Symbol(c10, Decl(ambientConstLiterals.ts, 16, 5))
const c11 = "abc" + "def";
>c11 : Symbol(c11, Decl(ambientConstLiterals.ts, 16, 5))
>c11 : Symbol(c11, Decl(ambientConstLiterals.ts, 17, 5))
const c12 = 123 + 456;
>c12 : Symbol(c12, Decl(ambientConstLiterals.ts, 17, 5))
>c12 : Symbol(c12, Decl(ambientConstLiterals.ts, 18, 5))
const c13 = Math.random() > 0.5 ? "abc" : "def";
>c13 : Symbol(c13, Decl(ambientConstLiterals.ts, 18, 5))
>c13 : Symbol(c13, Decl(ambientConstLiterals.ts, 19, 5))
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
const c14 = Math.random() > 0.5 ? 123 : 456;
>c14 : Symbol(c14, Decl(ambientConstLiterals.ts, 19, 5))
>c14 : Symbol(c14, Decl(ambientConstLiterals.ts, 20, 5))
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
@@ -7,11 +7,12 @@ function f<T>(x: T): T {
>x : T
}
enum E { A, B, C }
enum E { A, B, C, "non identifier" }
>E : E
>A : E.A
>B : E.B
>C : E.C
>"non identifier" : E.non identifier
const c1 = "abc";
>c1 : "abc"
@@ -52,6 +53,12 @@ const c8 = E.A;
>E : typeof E
>A : E.A
const c8b = E["non identifier"];
>c8b : E.non identifier
>E["non identifier"] : E.non identifier
>E : typeof E
>"non identifier" : "non identifier"
const c9 = { x: "abc" };
>c9 : { x: string; }
>{ x: "abc" } : { x: string; }
+1 -1
View File
@@ -3,7 +3,7 @@
>E1 : E1
y = 4.23
>y : E1
>y : E1.y
>4.23 : 4.23
}
@@ -3,6 +3,6 @@ declare enum E {
>E : E
e = 3
>e : E
>e : E.e
>3 : 3
}
@@ -3,7 +3,7 @@ declare enum E {
>E : E
e = -3 // Negative
>e : E
>e : E.e
>-3 : -3
>3 : 3
}
@@ -3,6 +3,6 @@ declare enum E {
>E : E
e = 3.3 // Decimal
>e : E
>e : E.e
>3.3 : 3.3
}
@@ -3,6 +3,6 @@ declare enum E {
>E : E
e = 0xA
>e : E
>e : E.e
>0xA : 10
}
@@ -3,7 +3,7 @@ declare enum E {
>E : E
e = -0xA
>e : E
>e : E.e
>-0xA : -10
>0xA : 10
}
@@ -6,7 +6,7 @@ declare module M {
>E : E
e = 3
>e : E
>e : E.e
>3 : 3
}
}
@@ -1,8 +1,8 @@
tests/cases/conformance/ambient/ambientErrors.ts(2,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(2,17): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(17,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(29,9): error TS1066: In ambient enum declarations member initializer must be constant expression.
tests/cases/conformance/ambient/ambientErrors.ts(34,11): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(34,13): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(37,20): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(38,13): error TS1039: Initializers are not allowed in ambient contexts.
@@ -17,7 +17,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
==== tests/cases/conformance/ambient/ambientErrors.ts (14 errors) ====
// Ambient variable with an initializer
declare var x = 4;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
// Ambient functions with invalid overloads
@@ -57,7 +57,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
// Ambient module with initializers for values, bodies for functions / classes
declare module M1 {
var x = 3;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
function fn() { }
~
@@ -46,7 +46,7 @@ declare enum E1 {
>E1 : E1
y = 4.23
>y : E1
>y : E1.y
>4.23 : 4.23
}
@@ -1,7 +1,7 @@
tests/cases/compiler/ambientErrors1.ts(1,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/ambientErrors1.ts(1,17): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/ambientErrors1.ts (1 errors) ====
declare var x = 4;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
@@ -1,5 +1,5 @@
tests/cases/compiler/ambientStatement1.ts(2,6): error TS1036: Statements are not allowed in ambient contexts.
tests/cases/compiler/ambientStatement1.ts(4,20): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/ambientStatement1.ts(4,22): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/ambientStatement1.ts (2 errors) ====
@@ -9,6 +9,6 @@ tests/cases/compiler/ambientStatement1.ts(4,20): error TS1039: Initializers are
!!! error TS1036: Statements are not allowed in ambient contexts.
export var v1 = () => false;
~
~~~~~~~~~~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}
@@ -199,7 +199,7 @@ var r3 = foo3(a); // any
enum E { A }
>E : E
>A : E
>A : E.A
declare function foo14(x: E): E;
>foo14 : { (x: E): E; (x: any): any; }
@@ -20,7 +20,7 @@ var ai: I;
enum E { A }
>E : E
>A : E
>A : E.A
var ae: E;
>ae : E
@@ -129,7 +129,7 @@ interface I13 {
enum E { A }
>E : E
>A : E
>A : E.A
interface I14 {
[x: string]: E;
+29 -16
View File
@@ -536,6 +536,7 @@ declare namespace ts {
name?: Identifier | StringLiteral | NumericLiteral;
}
interface ComputedPropertyName extends Node {
parent: Declaration;
kind: SyntaxKind.ComputedPropertyName;
expression: Expression;
}
@@ -632,6 +633,7 @@ declare namespace ts {
kind: SyntaxKind.ShorthandPropertyAssignment;
name: Identifier;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
equalsToken?: Token<SyntaxKind.EqualsToken>;
objectAssignmentInitializer?: Expression;
}
@@ -668,6 +670,7 @@ declare namespace ts {
_functionLikeDeclarationBrand: any;
asteriskToken?: AsteriskToken;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
body?: Block | Expression;
}
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
@@ -2060,28 +2063,28 @@ declare namespace ts {
ModuleExports = 134217728,
Enum = 384,
Variable = 3,
Value = 67216319,
Type = 67901928,
Value = 67220415,
Type = 67897832,
Namespace = 1920,
Module = 1536,
Accessor = 98304,
FunctionScopedVariableExcludes = 67216318,
BlockScopedVariableExcludes = 67216319,
ParameterExcludes = 67216319,
FunctionScopedVariableExcludes = 67220414,
BlockScopedVariableExcludes = 67220415,
ParameterExcludes = 67220415,
PropertyExcludes = 0,
EnumMemberExcludes = 68008959,
FunctionExcludes = 67215791,
FunctionExcludes = 67219887,
ClassExcludes = 68008383,
InterfaceExcludes = 67901832,
InterfaceExcludes = 67897736,
RegularEnumExcludes = 68008191,
ConstEnumExcludes = 68008831,
ValueModuleExcludes = 67215503,
ValueModuleExcludes = 110735,
NamespaceModuleExcludes = 0,
MethodExcludes = 67208127,
GetAccessorExcludes = 67150783,
SetAccessorExcludes = 67183551,
TypeParameterExcludes = 67639784,
TypeAliasExcludes = 67901928,
MethodExcludes = 67212223,
GetAccessorExcludes = 67154879,
SetAccessorExcludes = 67187647,
TypeParameterExcludes = 67635688,
TypeAliasExcludes = 67897832,
AliasExcludes = 2097152,
ModuleMember = 2623475,
ExportHasLocal = 944,
@@ -3208,17 +3211,27 @@ declare namespace ts {
/**
* Gets the JSDoc parameter tags for the node if present.
*
* @remarks Returns any JSDoc param tag that matches the provided
* @remarks Returns any JSDoc param tag whose name matches the provided
* parameter, whether a param tag on a containing function
* expression, or a param tag on a variable declaration whose
* initializer is the containing function. The tags closest to the
* node are returned first, so in the previous example, the param
* tag on the containing function expression would be first.
*
* Does not return tags for binding patterns, because JSDoc matches
* parameters by name and binding patterns do not have a name.
* For binding patterns, parameter tags are matched by position.
*/
function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag>;
/**
* Gets the JSDoc type parameter tags for the node if present.
*
* @remarks Returns any JSDoc template tag whose names match the provided
* parameter, whether a template tag on a containing function
* expression, or a template tag on a variable declaration whose
* initializer is the containing function. The tags closest to the
* node are returned first, so in the previous example, the template
* tag on the containing function expression would be first.
*/
function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray<JSDocTemplateTag>;
/**
* Return true if the node has JSDoc parameter tags.
*
+29 -16
View File
@@ -536,6 +536,7 @@ declare namespace ts {
name?: Identifier | StringLiteral | NumericLiteral;
}
interface ComputedPropertyName extends Node {
parent: Declaration;
kind: SyntaxKind.ComputedPropertyName;
expression: Expression;
}
@@ -632,6 +633,7 @@ declare namespace ts {
kind: SyntaxKind.ShorthandPropertyAssignment;
name: Identifier;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
equalsToken?: Token<SyntaxKind.EqualsToken>;
objectAssignmentInitializer?: Expression;
}
@@ -668,6 +670,7 @@ declare namespace ts {
_functionLikeDeclarationBrand: any;
asteriskToken?: AsteriskToken;
questionToken?: QuestionToken;
exclamationToken?: ExclamationToken;
body?: Block | Expression;
}
type FunctionLikeDeclaration = FunctionDeclaration | MethodDeclaration | GetAccessorDeclaration | SetAccessorDeclaration | ConstructorDeclaration | FunctionExpression | ArrowFunction;
@@ -2060,28 +2063,28 @@ declare namespace ts {
ModuleExports = 134217728,
Enum = 384,
Variable = 3,
Value = 67216319,
Type = 67901928,
Value = 67220415,
Type = 67897832,
Namespace = 1920,
Module = 1536,
Accessor = 98304,
FunctionScopedVariableExcludes = 67216318,
BlockScopedVariableExcludes = 67216319,
ParameterExcludes = 67216319,
FunctionScopedVariableExcludes = 67220414,
BlockScopedVariableExcludes = 67220415,
ParameterExcludes = 67220415,
PropertyExcludes = 0,
EnumMemberExcludes = 68008959,
FunctionExcludes = 67215791,
FunctionExcludes = 67219887,
ClassExcludes = 68008383,
InterfaceExcludes = 67901832,
InterfaceExcludes = 67897736,
RegularEnumExcludes = 68008191,
ConstEnumExcludes = 68008831,
ValueModuleExcludes = 67215503,
ValueModuleExcludes = 110735,
NamespaceModuleExcludes = 0,
MethodExcludes = 67208127,
GetAccessorExcludes = 67150783,
SetAccessorExcludes = 67183551,
TypeParameterExcludes = 67639784,
TypeAliasExcludes = 67901928,
MethodExcludes = 67212223,
GetAccessorExcludes = 67154879,
SetAccessorExcludes = 67187647,
TypeParameterExcludes = 67635688,
TypeAliasExcludes = 67897832,
AliasExcludes = 2097152,
ModuleMember = 2623475,
ExportHasLocal = 944,
@@ -3208,17 +3211,27 @@ declare namespace ts {
/**
* Gets the JSDoc parameter tags for the node if present.
*
* @remarks Returns any JSDoc param tag that matches the provided
* @remarks Returns any JSDoc param tag whose name matches the provided
* parameter, whether a param tag on a containing function
* expression, or a param tag on a variable declaration whose
* initializer is the containing function. The tags closest to the
* node are returned first, so in the previous example, the param
* tag on the containing function expression would be first.
*
* Does not return tags for binding patterns, because JSDoc matches
* parameters by name and binding patterns do not have a name.
* For binding patterns, parameter tags are matched by position.
*/
function getJSDocParameterTags(param: ParameterDeclaration): ReadonlyArray<JSDocParameterTag>;
/**
* Gets the JSDoc type parameter tags for the node if present.
*
* @remarks Returns any JSDoc template tag whose names match the provided
* parameter, whether a template tag on a containing function
* expression, or a template tag on a variable declaration whose
* initializer is the containing function. The tags closest to the
* node are returned first, so in the previous example, the template
* tag on the containing function expression would be first.
*/
function getJSDocTypeParameterTags(param: TypeParameterDeclaration): ReadonlyArray<JSDocTemplateTag>;
/**
* Return true if the node has JSDoc parameter tags.
*
+12
View File
@@ -0,0 +1,12 @@
//// [arrayFlatMap.ts]
const array: number[] = [];
const readonlyArray: ReadonlyArray<number> = [];
array.flatMap((): ReadonlyArray<number> => []); // ok
readonlyArray.flatMap((): ReadonlyArray<number> => []); // ok
//// [arrayFlatMap.js]
var array = [];
var readonlyArray = [];
array.flatMap(function () { return []; }); // ok
readonlyArray.flatMap(function () { return []; }); // ok
@@ -0,0 +1,20 @@
=== tests/cases/compiler/arrayFlatMap.ts ===
const array: number[] = [];
>array : Symbol(array, Decl(arrayFlatMap.ts, 0, 5))
const readonlyArray: ReadonlyArray<number> = [];
>readonlyArray : Symbol(readonlyArray, Decl(arrayFlatMap.ts, 1, 5))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.esnext.array.d.ts, --, --))
array.flatMap((): ReadonlyArray<number> => []); // ok
>array.flatMap : Symbol(Array.flatMap, Decl(lib.esnext.array.d.ts, --, --))
>array : Symbol(array, Decl(arrayFlatMap.ts, 0, 5))
>flatMap : Symbol(Array.flatMap, Decl(lib.esnext.array.d.ts, --, --))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.esnext.array.d.ts, --, --))
readonlyArray.flatMap((): ReadonlyArray<number> => []); // ok
>readonlyArray.flatMap : Symbol(ReadonlyArray.flatMap, Decl(lib.esnext.array.d.ts, --, --))
>readonlyArray : Symbol(readonlyArray, Decl(arrayFlatMap.ts, 1, 5))
>flatMap : Symbol(ReadonlyArray.flatMap, Decl(lib.esnext.array.d.ts, --, --))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.core.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2016.array.include.d.ts, --, --), Decl(lib.esnext.array.d.ts, --, --))
@@ -0,0 +1,25 @@
=== tests/cases/compiler/arrayFlatMap.ts ===
const array: number[] = [];
>array : number[]
>[] : undefined[]
const readonlyArray: ReadonlyArray<number> = [];
>readonlyArray : ReadonlyArray<number>
>[] : undefined[]
array.flatMap((): ReadonlyArray<number> => []); // ok
>array.flatMap((): ReadonlyArray<number> => []) : number[]
>array.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>array : number[]
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>(): ReadonlyArray<number> => [] : () => ReadonlyArray<number>
>[] : undefined[]
readonlyArray.flatMap((): ReadonlyArray<number> => []); // ok
>readonlyArray.flatMap((): ReadonlyArray<number> => []) : number[]
>readonlyArray.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>readonlyArray : ReadonlyArray<number>
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>(): ReadonlyArray<number> => [] : () => ReadonlyArray<number>
>[] : undefined[]
@@ -0,0 +1,9 @@
tests/cases/compiler/arrayIndexWithArrayFails.ts(3,16): error TS2538: Type 'string[]' cannot be used as an index type.
==== tests/cases/compiler/arrayIndexWithArrayFails.ts (1 errors) ====
declare const arr1: (string | string[])[];
declare const arr2: number[];
const j = arr2[arr1[0]]; // should error
~~~~~~~
!!! error TS2538: Type 'string[]' cannot be used as an index type.
@@ -0,0 +1,7 @@
//// [arrayIndexWithArrayFails.ts]
declare const arr1: (string | string[])[];
declare const arr2: number[];
const j = arr2[arr1[0]]; // should error
//// [arrayIndexWithArrayFails.js]
var j = arr2[arr1[0]]; // should error
@@ -0,0 +1,12 @@
=== tests/cases/compiler/arrayIndexWithArrayFails.ts ===
declare const arr1: (string | string[])[];
>arr1 : Symbol(arr1, Decl(arrayIndexWithArrayFails.ts, 0, 13))
declare const arr2: number[];
>arr2 : Symbol(arr2, Decl(arrayIndexWithArrayFails.ts, 1, 13))
const j = arr2[arr1[0]]; // should error
>j : Symbol(j, Decl(arrayIndexWithArrayFails.ts, 2, 5))
>arr2 : Symbol(arr2, Decl(arrayIndexWithArrayFails.ts, 1, 13))
>arr1 : Symbol(arr1, Decl(arrayIndexWithArrayFails.ts, 0, 13))
@@ -0,0 +1,15 @@
=== tests/cases/compiler/arrayIndexWithArrayFails.ts ===
declare const arr1: (string | string[])[];
>arr1 : (string | string[])[]
declare const arr2: number[];
>arr2 : number[]
const j = arr2[arr1[0]]; // should error
>j : any
>arr2[arr1[0]] : any
>arr2 : number[]
>arr1[0] : string | string[]
>arr1 : (string | string[])[]
>0 : 0
@@ -1,13 +1,11 @@
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
Types of property 'concat' are incompatible.
Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
Type 'A[]' is not assignable to type 'B[]'.
Type 'A' is not assignable to type 'B'.
Property 'b' is missing in type 'A'.
Type 'A' is not assignable to type 'B'.
Property 'b' is missing in type 'A'.
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C<A>' is not assignable to type 'ReadonlyArray<B>'.
Types of property 'concat' are incompatible.
Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
Type 'A[]' is not assignable to type 'B[]'.
Type 'A' is not assignable to type 'B'.
==== tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts (2 errors) ====
@@ -26,11 +24,8 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T
rrb = ara; // error: 'A' is not assignable to 'B'
~~~
!!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
!!! error TS2322: Types of property 'concat' are incompatible.
!!! error TS2322: Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
!!! error TS2322: Property 'b' is missing in type 'A'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
!!! error TS2322: Property 'b' is missing in type 'A'.
rra = cra;
rra = crb; // OK, C<B> is assignable to ReadonlyArray<A>
@@ -41,4 +36,5 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T
!!! error TS2322: Types of property 'concat' are incompatible.
!!! error TS2322: Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'.
!!! error TS2322: Type 'A' is not assignable to type 'B'.
@@ -42,7 +42,7 @@ enum E {
>E : E
A
>A : E
>A : E.A
}
var g: E = x;
@@ -76,7 +76,7 @@ enum E {
>E : E
A
>A : E
>A : E.A
}
x = E.A;
@@ -1,8 +1,6 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(17,1): error TS2322: Type '[number, string]' is not assignable to type 'number[]'.
Types of property 'pop' are incompatible.
Type '() => string | number' is not assignable to type '() => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatBetweenTupleAndArray.ts(18,1): error TS2322: Type '{}[]' is not assignable to type '[{}]'.
Property '0' is missing in type '{}[]'.
@@ -27,10 +25,8 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
numArray = numStrTuple;
~~~~~~~~
!!! error TS2322: Type '[number, string]' is not assignable to type 'number[]'.
!!! error TS2322: Types of property 'pop' are incompatible.
!!! error TS2322: Type '() => string | number' is not assignable to type '() => number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
emptyObjTuple = emptyObjArray;
~~~~~~~~~~~~~
!!! error TS2322: Type '{}[]' is not assignable to type '[{}]'.
@@ -1,7 +1,5 @@
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(1,10): error TS2391: Function implementation is missing or not immediately following the declaration.
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(4,5): error TS2345: Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
Types of property 'name' are incompatible.
Type 'boolean' is not assignable to type 'string'.
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(4,17): error TS2322: Type 'false' is not assignable to type 'string'.
tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(5,5): error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
Property 'id' is missing in type '{ name: string; }'.
@@ -13,10 +11,9 @@ tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts(5,5): error TS
foo({ id: 1234 }); // Ok
foo({ id: 1234, name: "hello" }); // Ok
foo({ id: 1234, name: false }); // Error, name of wrong type
~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ id: number; name: boolean; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
!!! error TS2345: Types of property 'name' are incompatible.
!!! error TS2345: Type 'boolean' is not assignable to type 'string'.
~~~~
!!! error TS2322: Type 'false' is not assignable to type 'string'.
!!! related TS6500 tests/cases/compiler/assignmentCompatFunctionsWithOptionalArgs.ts:1:31: The expected type comes from property 'name' which is declared here on type '{ id: number; name?: string; }'
foo({ name: "hello" }); // Error, id required but missing
~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ name: string; }' is not assignable to parameter of type '{ id: number; name?: string; }'.
@@ -45,6 +45,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Property 'baz' is missing in type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(83,1): error TS2322: Type '(x: Base[], y: Derived[]) => Derived[]' is not assignable to type '<T extends Derived[]>(x: Base[], y: T) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(85,1): error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => Object'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
Types of property 'b' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts(86,1): error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
@@ -52,7 +57,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Type 'T' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (14 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures3.ts (15 errors) ====
// these are all permitted with the current rules, since we do not do contextual signature instantiation
class Base { foo: string; }
@@ -198,6 +203,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
var b14: <T>(x: { a: T; b: T }) => T;
a14 = b14; // ok
~~~
!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => Object'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
b14 = a14; // ok
~~~
!!! error TS2322: Type '(x: { a: string; b: number; }) => Object' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
@@ -22,8 +22,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(66,9): error TS2322: Type '(x: Base[], y: Derived2[]) => Derived[]' is not assignable to type '<T extends Derived2[]>(x: Base[], y: Base[]) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(69,9): error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
Types of property 'b' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures4.ts(70,9): error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
@@ -156,8 +158,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
a15 = b15;
~~~
!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T' is not assignable to type '(x: { a: string; b: number; }) => number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
b15 = a15;
~~~
!!! error TS2322: Type '(x: { a: string; b: number; }) => number' is not assignable to type '<T>(x: { a: T; b: T; }) => T'.
@@ -1,9 +1,15 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(40,1): error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(52,1): error TS2322: Type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '<T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
Types of parameters 'y' and 'y' are incompatible.
Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
Types of property 'foo' are incompatible.
Type 'U' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(55,1): error TS2322: Type '<T>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
Type '(U | V)[]' is not assignable to type 'U[]'.
Type 'U | V' is not assignable to type 'U'.
Type 'V' is not assignable to type 'U'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'.
Types of property 'b' are incompatible.
Type 'V' is not assignable to type 'U'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts(58,1): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
@@ -11,7 +17,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Type 'U' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (3 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures5.ts (4 errors) ====
// checking assignment compat for function types. No errors in this file
class Base { foo: string; }
@@ -67,14 +73,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b11: <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
a11 = b11; // ok
b11 = a11; // ok
~~~
!!! error TS2322: Type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '<T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type 'T'.
var b15: <U, V>(x: { a: U; b: V; }) => U[];
a15 = b15; // ok, T = U, T = V
b15 = a15; // ok
~~~
!!! error TS2322: Type '<T>(x: { a: T; b: T; }) => T[]' is not assignable to type '<U, V>(x: { a: U; b: V; }) => U[]'.
!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'.
!!! error TS2322: Type 'U | V' is not assignable to type 'U'.
!!! error TS2322: Type 'V' is not assignable to type 'U'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'V' is not assignable to type 'U'.
var b16: <T>(x: { a: T; b: T }) => T[];
a15 = b16; // ok
b15 = a16; // ok
@@ -1,5 +1,10 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(30,1): error TS2322: Type '<T>(x: T) => void' is not assignable to type '<T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(39,1): error TS2322: Type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '<T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
Types of parameters 'y' and 'y' are incompatible.
Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
Types of property 'foo' are incompatible.
Type 'U' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts(42,1): error TS2322: Type '<T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type '<T>(x: { a: T; b: T; }) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
@@ -7,7 +12,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Type 'T' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (2 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithCallSignatures6.ts (3 errors) ====
// checking assignment compatibility relations for function types. All valid
class Base { foo: string; }
@@ -50,6 +55,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b11: <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
x.a11 = b11;
b11 = x.a11;
~~~
!!! error TS2322: Type '<T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type '<T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type 'T'.
var b16: <T>(x: { a: T; b: T }) => T[];
x.a16 = b16;
b16 = x.a16;
@@ -45,6 +45,11 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Property 'baz' is missing in type 'Base'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(83,1): error TS2322: Type 'new (x: Base[], y: Derived[]) => Derived[]' is not assignable to type 'new <T extends Derived[]>(x: Base[], y: T) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(85,1): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => Object'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
Types of property 'b' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts(86,1): error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
@@ -52,7 +57,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Type 'T' is not assignable to type 'string'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (14 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures3.ts (15 errors) ====
// checking assignment compatibility relations for function types. All of these are valid.
class Base { foo: string; }
@@ -198,6 +203,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
!!! error TS2322: Type 'Derived[]' is not assignable to type 'T'.
var b14: new <T>(x: { a: T; b: T }) => T;
a14 = b14; // ok
~~~
!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => Object'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
b14 = a14; // ok
~~~
!!! error TS2322: Type 'new (x: { a: string; b: number; }) => Object' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
@@ -22,8 +22,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(66,9): error TS2322: Type 'new (x: Base[], y: Derived2[]) => Derived[]' is not assignable to type 'new <T extends Derived2[]>(x: Base[], y: Base[]) => T'.
Type 'Derived[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(69,9): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
Types of property 'b' are incompatible.
Type 'number' is not assignable to type 'string'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures4.ts(70,9): error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: string; b: number; }'.
@@ -172,8 +174,10 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
a15 = b15; // ok
~~~
!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T' is not assignable to type 'new (x: { a: string; b: number; }) => number'.
!!! error TS2322: Type 'string | number' is not assignable to type 'number'.
!!! error TS2322: Type 'string' is not assignable to type 'number'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: string; b: number; }' is not assignable to type '{ a: string; b: string; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'number' is not assignable to type 'string'.
b15 = a15; // ok
~~~
!!! error TS2322: Type 'new (x: { a: string; b: number; }) => number' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T'.
@@ -1,9 +1,15 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(40,1): error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(52,1): error TS2322: Type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new <T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
Types of parameters 'y' and 'y' are incompatible.
Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
Types of property 'foo' are incompatible.
Type 'U' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(55,1): error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
Type '(U | V)[]' is not assignable to type 'U[]'.
Type 'U | V' is not assignable to type 'U'.
Type 'V' is not assignable to type 'U'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'.
Types of property 'b' are incompatible.
Type 'V' is not assignable to type 'U'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts(58,1): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: U; b: V; }' is not assignable to type '{ a: Base; b: Base; }'.
@@ -11,7 +17,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Type 'U' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (3 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures5.ts (4 errors) ====
// checking assignment compat for function types. All valid
class Base { foo: string; }
@@ -67,14 +73,21 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b11: new <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
a11 = b11; // ok
b11 = a11; // ok
~~~
!!! error TS2322: Type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new <T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type 'T'.
var b15: new <U, V>(x: { a: U; b: V; }) => U[];
a15 = b15; // ok
b15 = a15; // ok
~~~
!!! error TS2322: Type 'new <T>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <U, V>(x: { a: U; b: V; }) => U[]'.
!!! error TS2322: Type '(U | V)[]' is not assignable to type 'U[]'.
!!! error TS2322: Type 'U | V' is not assignable to type 'U'.
!!! error TS2322: Type 'V' is not assignable to type 'U'.
!!! error TS2322: Types of parameters 'x' and 'x' are incompatible.
!!! error TS2322: Type '{ a: U; b: V; }' is not assignable to type '{ a: U; b: U; }'.
!!! error TS2322: Types of property 'b' are incompatible.
!!! error TS2322: Type 'V' is not assignable to type 'U'.
var b16: new <T>(x: { a: T; b: T }) => T[];
a15 = b16; // ok
b15 = a16; // ok
@@ -1,5 +1,10 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(30,1): error TS2322: Type 'new <T>(x: T) => void' is not assignable to type 'new <T>(x: T) => T'.
Type 'void' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(39,1): error TS2322: Type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new <T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
Types of parameters 'y' and 'y' are incompatible.
Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
Types of property 'foo' are incompatible.
Type 'U' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts(42,1): error TS2322: Type 'new <T extends Base>(x: { a: T; b: T; }) => T[]' is not assignable to type 'new <T>(x: { a: T; b: T; }) => T[]'.
Types of parameters 'x' and 'x' are incompatible.
Type '{ a: T; b: T; }' is not assignable to type '{ a: Base; b: Base; }'.
@@ -7,7 +12,7 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
Type 'T' is not assignable to type 'Base'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (2 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithConstructSignatures6.ts (3 errors) ====
// checking assignment compatibility relations for function types. All valid.
class Base { foo: string; }
@@ -50,6 +55,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var b11: new <T, U>(x: { foo: T }, y: { foo: U; bar: U }) => Base;
x.a11 = b11;
b11 = x.a11;
~~~
!!! error TS2322: Type 'new <T>(x: { foo: T; }, y: { foo: T; bar: T; }) => Base' is not assignable to type 'new <T, U>(x: { foo: T; }, y: { foo: U; bar: U; }) => Base'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type '{ foo: U; bar: U; }' is not assignable to type '{ foo: T; bar: T; }'.
!!! error TS2322: Types of property 'foo' are incompatible.
!!! error TS2322: Type 'U' is not assignable to type 'T'.
var b16: new <T>(x: { a: T; b: T }) => T[];
x.a16 = b16;
b16 = x.a16;
@@ -1,9 +1,12 @@
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(15,1): error TS2322: Type 'B' is not assignable to type 'A'.
Types of parameters 'y' and 'y' are incompatible.
Type 'T[]' is not assignable to type 'T'.
tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts(16,1): error TS2322: Type 'A' is not assignable to type 'B'.
Types of parameters 'y' and 'y' are incompatible.
Type 'S' is not assignable to type 'S[]'.
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (1 errors) ====
==== tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignmentCompatWithGenericCallSignatures2.ts (2 errors) ====
// some complex cases of assignment compat of generic signatures. No contextual signature instantiation
interface A {
@@ -17,8 +20,12 @@ tests/cases/conformance/types/typeRelationships/assignmentCompatibility/assignme
var a: A;
var b: B;
// Both ok
// Both errors
a = b;
~
!!! error TS2322: Type 'B' is not assignable to type 'A'.
!!! error TS2322: Types of parameters 'y' and 'y' are incompatible.
!!! error TS2322: Type 'T[]' is not assignable to type 'T'.
b = a;
~
!!! error TS2322: Type 'A' is not assignable to type 'B'.
@@ -12,7 +12,7 @@ interface B {
var a: A;
var b: B;
// Both ok
// Both errors
a = b;
b = a;
@@ -21,6 +21,6 @@ b = a;
// some complex cases of assignment compat of generic signatures. No contextual signature instantiation
var a;
var b;
// Both ok
// Both errors
a = b;
b = a;
@@ -31,7 +31,7 @@ var b: B;
>b : Symbol(b, Decl(assignmentCompatWithGenericCallSignatures2.ts, 11, 3))
>B : Symbol(B, Decl(assignmentCompatWithGenericCallSignatures2.ts, 4, 1))
// Both ok
// Both errors
a = b;
>a : Symbol(a, Decl(assignmentCompatWithGenericCallSignatures2.ts, 10, 3))
>b : Symbol(b, Decl(assignmentCompatWithGenericCallSignatures2.ts, 11, 3))
@@ -19,7 +19,7 @@ var a: A;
var b: B;
>b : B
// Both ok
// Both errors
a = b;
>a = b : B
>a : A
@@ -294,7 +294,7 @@ enum E {
>E : E
A
>A : E
>A : E.A
}
E = undefined; // Error
>E = undefined : undefined
+1 -1
View File
@@ -24,7 +24,7 @@ C = null; // Error
enum E { A }
>E : E
>A : E
>A : E.A
E = null; // Error
>E = null : null
@@ -3,5 +3,5 @@ async enum E {
>E : E
Value
>Value : E
>Value : E.Value
}
@@ -3,5 +3,5 @@ async enum E {
>E : E
Value
>Value : E
>Value : E.Value
}
@@ -15,5 +15,5 @@ class c4 { public foo() { } }
enum c4 { One } // error
>c4 : c4
>One : c4
>One : c4.One
@@ -32,7 +32,7 @@ class c33 {
}
enum c33 { One };
>c33 : c33
>One : c33
>One : c33.One
// class then import
class c44 {
@@ -2,7 +2,7 @@
// enum then var
enum e1111 { One } // error
>e1111 : e1111
>One : e1111
>One : e1111.One
var e1111 = 1; // error
>e1111 : number
@@ -11,14 +11,14 @@ var e1111 = 1; // error
// enum then function
enum e2 { One } // error
>e2 : e2
>One : e2
>One : e2.One
function e2() { } // error
>e2 : () => void
enum e3 { One } // error
>e3 : e3
>One : e3
>One : e3.One
var e3 = () => { } // error
>e3 : () => void
@@ -27,7 +27,7 @@ var e3 = () => { } // error
// enum then class
enum e4 { One } // error
>e4 : e4
>One : e4
>One : e4.One
class e4 { public foo() { } } // error
>e4 : e4
@@ -36,30 +36,30 @@ class e4 { public foo() { } } // error
// enum then enum
enum e5 { One }
>e5 : e5
>One : e5
>One : e5.One
enum e5 { Two } // error
>e5 : e5
>Two : e5
>Two : e5.One
enum e5a { One } // error
>e5a : e5a
>One : e5a
>One : e5a.One
enum e5a { One } // error
>e5a : e5a
>One : e5a
>One : e5a.One
// enum then internal module
enum e6 { One }
>e6 : e6
>One : e6
>One : e6.One
module e6 { } // ok
enum e6a { One }
>e6a : e6a
>One : e6a
>One : e6a.One
module e6a { var y = 2; } // should be error
>e6a : typeof e6a
@@ -68,7 +68,7 @@ module e6a { var y = 2; } // should be error
enum e6b { One }
>e6b : e6b
>One : e6b
>One : e6b.One
module e6b { export var y = 2; } // should be error
>e6b : typeof e6b
@@ -2,7 +2,7 @@
// enum then interface
enum e1 { One } // error
>e1 : e1
>One : e1
>One : e1.One
interface e1 { // error
foo(): void;
@@ -14,7 +14,7 @@ interface e1 { // error
// enum then class
enum e2 { One }; // error
>e2 : e2
>One : e2
>One : e2.One
class e2 { // error
>e2 : e2
@@ -25,13 +25,13 @@ enum A {
>A : A
b
>b : A
>b : A.b
}
enum A {
>A : A
c
>c : A
>c : A.b
}
module A {
>A : typeof A
@@ -41,7 +41,7 @@ function y4() { } // error
enum y4 { One } // error
>y4 : y4
>One : y4
>One : y4.One
// function then internal module
function y5() { }
Loaded 100 of 679 files, more files were not shown because too many files have changed in this diff. Show more