Skip to content

Commit d71415a

Browse files
authored
Merge pull request #25702 from Microsoft/mergeMaster-7-16
Merge master into release-3.0
2 parents 0717478 + 39a7891 commit d71415a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+659
-190
lines changed

src/compiler/checker.ts

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,8 @@ namespace ts {
336336
}
337337

338338
function addUnusedDiagnostics() {
339-
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (kind, diag) => {
340-
if (!unusedIsError(kind)) {
339+
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(file), (containingNode, kind, diag) => {
340+
if (!containsParseError(containingNode) && !unusedIsError(kind)) {
341341
(diagnostics || (diagnostics = [])).push({ ...diag, category: DiagnosticCategory.Suggestion });
342342
}
343343
});
@@ -646,7 +646,8 @@ namespace ts {
646646
Local,
647647
Parameter,
648648
}
649-
type AddUnusedDiagnostic = (type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
649+
/** @param containingNode Node to check for parse error */
650+
type AddUnusedDiagnostic = (containingNode: Node, type: UnusedKind, diagnostic: DiagnosticWithLocation) => void;
650651

651652
const builtinGlobals = createSymbolTable();
652653
builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol);
@@ -4682,13 +4683,7 @@ namespace ts {
46824683
}
46834684
}
46844685
// Use contextual parameter type if one is available
4685-
let type: Type | undefined;
4686-
if (declaration.symbol.escapedName === "this") {
4687-
type = getContextualThisParameterType(func);
4688-
}
4689-
else {
4690-
type = getContextuallyTypedParameterType(declaration);
4691-
}
4686+
const type = declaration.symbol.escapedName === "this" ? getContextualThisParameterType(func) : getContextuallyTypedParameterType(declaration);
46924687
if (type) {
46934688
return addOptionality(type, isOptional);
46944689
}
@@ -16209,7 +16204,7 @@ namespace ts {
1620916204

1621016205
// If the given type is an object or union type with a single signature, and if that signature has at
1621116206
// least as many parameters as the given function, return the signature. Otherwise return undefined.
16212-
function getContextualCallSignature(type: Type, node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature | undefined {
16207+
function getContextualCallSignature(type: Type, node: SignatureDeclaration): Signature | undefined {
1621316208
const signatures = getSignaturesOfType(type, SignatureKind.Call);
1621416209
if (signatures.length === 1) {
1621516210
const signature = signatures[0];
@@ -16220,7 +16215,7 @@ namespace ts {
1622016215
}
1622116216

1622216217
/** If the contextual signature has fewer parameters than the function expression, do not use it */
16223-
function isAritySmaller(signature: Signature, target: FunctionExpression | ArrowFunction | MethodDeclaration) {
16218+
function isAritySmaller(signature: Signature, target: SignatureDeclaration) {
1622416219
let targetParameterCount = 0;
1622516220
for (; targetParameterCount < target.parameters.length; targetParameterCount++) {
1622616221
const param = target.parameters[targetParameterCount];
@@ -23538,12 +23533,13 @@ namespace ts {
2353823533
// yielded values. The only way to trigger these errors is to try checking its return type.
2353923534
getReturnTypeOfSignature(getSignatureFromDeclaration(node));
2354023535
}
23541-
// A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
23542-
if (isInJavaScriptFile(node)) {
23543-
const typeTag = getJSDocTypeTag(node);
23544-
if (typeTag && typeTag.typeExpression && !getSignaturesOfType(getTypeFromTypeNode(typeTag.typeExpression), SignatureKind.Call).length) {
23545-
error(typeTag, Diagnostics.The_type_of_a_function_declaration_must_be_callable);
23546-
}
23536+
}
23537+
23538+
// A js function declaration can have a @type tag instead of a return type node, but that type must have a call signature
23539+
if (isInJavaScriptFile(node)) {
23540+
const typeTag = getJSDocTypeTag(node);
23541+
if (typeTag && typeTag.typeExpression && !getContextualCallSignature(getTypeFromTypeNode(typeTag.typeExpression), node)) {
23542+
error(typeTag, Diagnostics.The_type_of_a_function_declaration_must_match_the_function_s_signature);
2354723543
}
2354823544
}
2354923545
}
@@ -23617,7 +23613,7 @@ namespace ts {
2361723613
function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) {
2361823614
const node = getNameOfDeclaration(declaration) || declaration;
2361923615
const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read;
23620-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(node, message, name));
23616+
addDiagnostic(declaration, UnusedKind.Local, createDiagnosticForNode(node, message, name));
2362123617
}
2362223618

2362323619
function isIdentifierThatStartsWithUnderscore(node: Node) {
@@ -23638,13 +23634,13 @@ namespace ts {
2363823634
}
2363923635
const symbol = getSymbolOfNode(member);
2364023636
if (!symbol.isReferenced && hasModifier(member, ModifierFlags.Private)) {
23641-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
23637+
addDiagnostic(member, UnusedKind.Local, createDiagnosticForNode(member.name!, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolToString(symbol)));
2364223638
}
2364323639
break;
2364423640
case SyntaxKind.Constructor:
2364523641
for (const parameter of (<ConstructorDeclaration>member).parameters) {
2364623642
if (!parameter.symbol.isReferenced && hasModifier(parameter, ModifierFlags.Private)) {
23647-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)));
23643+
addDiagnostic(parameter, UnusedKind.Local, createDiagnosticForNode(parameter.name, Diagnostics.Property_0_is_declared_but_its_value_is_never_read, symbolName(parameter.symbol)));
2364823644
}
2364923645
}
2365023646
break;
@@ -23669,7 +23665,7 @@ namespace ts {
2366923665
if (!(node.flags & NodeFlags.Ambient) && last(getSymbolOfNode(node).declarations) === node) {
2367023666
for (const typeParameter of typeParameters) {
2367123667
if (!(getMergedSymbol(typeParameter.symbol).isReferenced! & SymbolFlags.TypeParameter) && !isIdentifierThatStartsWithUnderscore(typeParameter.name)) {
23672-
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)));
23668+
addDiagnostic(typeParameter, UnusedKind.Parameter, createDiagnosticForNode(typeParameter.name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(typeParameter.symbol)));
2367323669
}
2367423670
}
2367523671
}
@@ -23728,7 +23724,7 @@ namespace ts {
2372823724
const name = local.valueDeclaration && getNameOfDeclaration(local.valueDeclaration);
2372923725
if (parameter && name) {
2373023726
if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !isIdentifierThatStartsWithUnderscore(name)) {
23731-
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
23727+
addDiagnostic(parameter, UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
2373223728
}
2373323729
}
2373423730
else {
@@ -23744,7 +23740,7 @@ namespace ts {
2374423740
(importClause.namedBindings.kind === SyntaxKind.NamespaceImport ? 1 : importClause.namedBindings.elements.length)
2374523741
: 0);
2374623742
if (nDeclarations === unuseds.length) {
23747-
addDiagnostic(UnusedKind.Local, unuseds.length === 1
23743+
addDiagnostic(importDecl, UnusedKind.Local, unuseds.length === 1
2374823744
? createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name!))
2374923745
: createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused));
2375023746
}
@@ -23759,26 +23755,26 @@ namespace ts {
2375923755
addToGroup(unusedVariables, bindingPattern.parent.parent, bindingPattern.parent, getNodeId);
2376023756
}
2376123757
else {
23762-
addDiagnostic(kind, bindingElements.length === 1
23758+
addDiagnostic(bindingPattern, kind, bindingElements.length === 1
2376323759
? createDiagnosticForNode(bindingPattern, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(first(bindingElements).name, isIdentifier)))
2376423760
: createDiagnosticForNode(bindingPattern, Diagnostics.All_destructured_elements_are_unused));
2376523761
}
2376623762
}
2376723763
else {
2376823764
for (const e of bindingElements) {
23769-
addDiagnostic(kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(e.name, isIdentifier))));
23765+
addDiagnostic(e, kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(e.name, isIdentifier))));
2377023766
}
2377123767
}
2377223768
});
2377323769
unusedVariables.forEach(([declarationList, declarations]) => {
2377423770
if (declarationList.declarations.length === declarations.length) {
23775-
addDiagnostic(UnusedKind.Local, declarations.length === 1
23771+
addDiagnostic(declarationList, UnusedKind.Local, declarations.length === 1
2377623772
? createDiagnosticForNode(first(declarations).name, Diagnostics._0_is_declared_but_its_value_is_never_read, bindingNameText(first(declarations).name))
2377723773
: createDiagnosticForNode(declarationList.parent.kind === SyntaxKind.VariableStatement ? declarationList.parent : declarationList, Diagnostics.All_variables_are_unused));
2377823774
}
2377923775
else {
2378023776
for (const decl of declarations) {
23781-
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(decl.name, isIdentifier))));
23777+
addDiagnostic(decl, UnusedKind.Local, createDiagnosticForNode(decl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(cast(decl.name, isIdentifier))));
2378223778
}
2378323779
}
2378423780
});
@@ -26631,8 +26627,8 @@ namespace ts {
2663126627
}
2663226628

2663326629
if (!node.isDeclarationFile && (compilerOptions.noUnusedLocals || compilerOptions.noUnusedParameters)) {
26634-
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (kind, diag) => {
26635-
if (unusedIsError(kind)) {
26630+
checkUnusedIdentifiers(getPotentiallyUnusedIdentifiers(node), (containingNode, kind, diag) => {
26631+
if (!containsParseError(containingNode) && unusedIsError(kind)) {
2663626632
diagnostics.add(diag);
2663726633
}
2663826634
});

src/compiler/diagnosticMessages.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4021,7 +4021,7 @@
40214021
"category": "Error",
40224022
"code": 8029
40234023
},
4024-
"The type of a function declaration must be callable.": {
4024+
"The type of a function declaration must match the function's signature.": {
40254025
"category": "Error",
40264026
"code": 8030
40274027
},

src/compiler/factory.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4355,6 +4355,11 @@ namespace ts {
43554355
case SyntaxKind.ConditionalExpression:
43564356
node = (<ConditionalExpression>node).condition;
43574357
continue;
4358+
4359+
case SyntaxKind.TaggedTemplateExpression:
4360+
node = (<TaggedTemplateExpression>node).tag;
4361+
continue;
4362+
43584363
case SyntaxKind.CallExpression:
43594364
if (stopAtCallExpressions) {
43604365
return node;

src/compiler/program.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,7 @@ namespace ts {
592592
const programDiagnostics = createDiagnosticCollection();
593593
const currentDirectory = host.getCurrentDirectory();
594594
const supportedExtensions = getSupportedExtensions(options);
595+
const supportedExtensionsWithJsonIfResolveJsonModule = options.resolveJsonModule ? [...supportedExtensions, Extension.Json] : undefined;
595596

596597
// Map storing if there is emit blocking diagnostics for given input
597598
const hasEmitBlockingDiagnostics = createMap<boolean>();
@@ -1925,7 +1926,7 @@ namespace ts {
19251926
refFile?: SourceFile): SourceFile | undefined {
19261927

19271928
if (hasExtension(fileName)) {
1928-
if (!options.allowNonTsExtensions && !forEach(supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
1929+
if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule || supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
19291930
if (fail) fail(Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
19301931
return undefined;
19311932
}

src/compiler/sys.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,7 @@ namespace ts {
503503
/*@internal*/ setBlocking?(): void;
504504
base64decode?(input: string): string;
505505
base64encode?(input: string): string;
506+
/*@internal*/ bufferFrom?(input: string, encoding?: string): Buffer;
506507
}
507508

508509
export interface FileWatcher {
@@ -558,7 +559,7 @@ namespace ts {
558559
getEnvironmentVariable?(name: string): string;
559560
};
560561

561-
// TODO: this is used as if it's certainly defined in many places.
562+
// TODO: GH#18217 this is used as if it's certainly defined in many places.
562563
export let sys: System = (() => {
563564
// NodeJS detects "\uFEFF" at the start of the string and *replaces* it with the actual
564565
// byte order mark from the specified encoding. Using any other byte order mark does
@@ -675,19 +676,19 @@ namespace ts {
675676
process.stdout._handle.setBlocking(true);
676677
}
677678
},
678-
base64decode: Buffer.from ? input => {
679-
return Buffer.from!(input, "base64").toString("utf8");
680-
} : input => {
681-
return new Buffer(input, "base64").toString("utf8");
682-
},
683-
base64encode: Buffer.from ? input => {
684-
return Buffer.from!(input).toString("base64");
685-
} : input => {
686-
return new Buffer(input).toString("base64");
687-
}
679+
bufferFrom,
680+
base64decode: input => bufferFrom(input, "base64").toString("utf8"),
681+
base64encode: input => bufferFrom(input).toString("base64"),
688682
};
689683
return nodeSystem;
690684

685+
function bufferFrom(input: string, encoding?: string): Buffer {
686+
// See https://github.com/Microsoft/TypeScript/issues/25652
687+
return Buffer.from && (Buffer.from as Function) !== Int8Array.from
688+
? Buffer.from(input, encoding)
689+
: new Buffer(input, encoding);
690+
}
691+
691692
function isFileSystemCaseSensitive(): boolean {
692693
// win32\win64 are case insensitive platforms
693694
if (platform === "win32" || platform === "win64") {

src/compiler/tsbuild.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ namespace ts {
488488
}
489489

490490
if (watch) {
491+
builder.buildAllProjects();
491492
builder.startWatching();
492493
return undefined;
493494
}

src/compiler/watch.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -475,16 +475,15 @@ namespace ts {
475475

476476
// From tsc we want to get already parsed result and hence check for rootFileNames
477477
let newLine = updateNewLine();
478+
if (configFileName && host.configFileParsingResult) {
479+
setConfigFileParsingResult(host.configFileParsingResult);
480+
newLine = updateNewLine();
481+
}
478482
reportWatchDiagnostic(Diagnostics.Starting_compilation_in_watch_mode);
479-
if (configFileName) {
483+
if (configFileName && !host.configFileParsingResult) {
480484
newLine = getNewLineCharacter(optionsToExtendForConfigFile, () => host.getNewLine());
481-
if (host.configFileParsingResult) {
482-
setConfigFileParsingResult(host.configFileParsingResult);
483-
}
484-
else {
485-
Debug.assert(!rootFileNames);
486-
parseConfigFile();
487-
}
485+
Debug.assert(!rootFileNames);
486+
parseConfigFile();
488487
newLine = updateNewLine();
489488
}
490489

src/compiler/watchUtilities.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ namespace ts {
434434

435435
function createFileWatcherWithTriggerLogging<H, T, U, V, X, Y>(host: H, file: string, cb: WatchCallback<U, V>, flags: T, passThrough: V | undefined, detailInfo1: X | undefined, detailInfo2: Y | undefined, addWatch: AddWatch<H, T, U, undefined>, log: (s: string) => void, watchCaption: string, getDetailWatchInfo: GetDetailWatchInfo<X, Y> | undefined): FileWatcher {
436436
return addWatch(host, file, (fileName, cbOptional) => {
437-
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName}${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
437+
const triggerredInfo = `${watchCaption}:: Triggered with ${fileName} ${cbOptional !== undefined ? cbOptional : ""}:: ${getWatchInfo(file, flags, detailInfo1, detailInfo2, getDetailWatchInfo)}`;
438438
log(triggerredInfo);
439439
const start = timestamp();
440440
cb(fileName, cbOptional, passThrough);

src/harness/documents.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ namespace documents {
148148

149149
public static fromUrl(url: string) {
150150
const match = SourceMap._dataURLRegExp.exec(url);
151-
return match ? new SourceMap(/*mapFile*/ undefined, (Buffer.from ? Buffer.from(match[1], "base64") : new Buffer(match[1], "base64")).toString("utf8")) : undefined;
151+
return match ? new SourceMap(/*mapFile*/ undefined, ts.sys.base64decode!(match[1])) : undefined;
152152
}
153153

154154
public static fromSource(text: string): SourceMap | undefined {

src/harness/harness.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,8 @@ namespace Utils {
6666

6767
export let currentExecutionEnvironment = getExecutionEnvironment();
6868

69-
// Thanks to browserify, Buffer is always available nowadays
70-
const Buffer: typeof global.Buffer = require("buffer").Buffer;
71-
7269
export function encodeString(s: string): string {
73-
return Buffer.from(s).toString("utf8");
70+
return ts.sys.bufferFrom!(s).toString("utf8");
7471
}
7572

7673
export function byteLength(s: string, encoding?: string): number {

0 commit comments

Comments
 (0)