From ce2d70494b50024ca1d28610805b5ef349a720c0 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 Mar 2023 16:42:07 -0800 Subject: [PATCH 1/9] Consistently use '...args' for diagnostic args --- src/compiler/binder.ts | 8 +- src/compiler/checker.ts | 96 +++++++++---------- src/compiler/commandLineParser.ts | 4 +- src/compiler/parser.ts | 31 +++--- src/compiler/program.ts | 58 +++++------ src/compiler/utilities.ts | 12 +-- src/testRunner/unittests/config/matchFiles.ts | 4 +- 7 files changed, 107 insertions(+), 106 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 00bf031c18321..8b0a3fa52773a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -556,8 +556,8 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations. */ - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { - return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, arg0, arg1, arg2); + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { + return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, ...args); } function bindSourceFile(f: SourceFile, opts: CompilerOptions) { @@ -2613,9 +2613,9 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { } } - function errorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any) { + function errorOnFirstToken(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { const span = getSpanOfTokenAtPosition(file, node.pos); - file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, arg0, arg1, arg2)); + file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, ...args)); } function errorOrSuggestionOnNode(isError: boolean, node: Node, message: DiagnosticMessage): void { diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5359974ff87f3..d50f12f7e534b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2296,10 +2296,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return emitResolver; } - function lookupOrIssueError(location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + function lookupOrIssueError(location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { const diagnostic = location - ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) - : createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); + ? createDiagnosticForNode(location, message, ...args) + : createCompilerDiagnostic(message, ...args); const existing = diagnostics.lookup(diagnostic); if (existing) { return existing; @@ -2310,20 +2310,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function errorSkippedOn(key: keyof CompilerOptions, location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { - const diagnostic = error(location, message, arg0, arg1, arg2, arg3); + function errorSkippedOn(key: keyof CompilerOptions, location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { + const diagnostic = error(location, message, ...args); diagnostic.skippedOn = key; return diagnostic; } - function createError(location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { + function createError(location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { return location - ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) - : createCompilerDiagnostic(message, arg0, arg1, arg2, arg3); + ? createDiagnosticForNode(location, message, ...args) + : createCompilerDiagnostic(message, ...args); } - function error(location: Node | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): Diagnostic { - const diagnostic = createError(location, message, arg0, arg1, arg2, arg3); + function error(location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { + const diagnostic = createError(location, message, ...args); diagnostics.add(diagnostic); return diagnostic; } @@ -2336,7 +2336,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { suggestionDiagnostics.add({ ...diagnostic, category: DiagnosticCategory.Suggestion }); } } - function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { + function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): void { // Pseudo-synthesized input node if (location.pos < 0 || location.end < 0) { if (!isError) { @@ -2344,18 +2344,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // Issue errors globally const file = getSourceFileOfNode(location); - addErrorOrSuggestion(isError, "message" in message ? createFileDiagnostic(file, 0, 0, message, arg0, arg1, arg2, arg3) : createDiagnosticForFileFromMessageChain(file, message)); // eslint-disable-line local/no-in-operator + addErrorOrSuggestion(isError, "message" in message ? createFileDiagnostic(file, 0, 0, message, ...args) : createDiagnosticForFileFromMessageChain(file, message)); // eslint-disable-line local/no-in-operator return; } - addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, arg0, arg1, arg2, arg3) : createDiagnosticForNodeFromMessageChain(getSourceFileOfNode(location), location, message)); // eslint-disable-line local/no-in-operator + addErrorOrSuggestion(isError, "message" in message ? createDiagnosticForNode(location, message, ...args) : createDiagnosticForNodeFromMessageChain(getSourceFileOfNode(location), location, message)); // eslint-disable-line local/no-in-operator } function errorAndMaybeSuggestAwait( location: Node, maybeMissingAwait: boolean, message: DiagnosticMessage, - arg0?: string | number | undefined, arg1?: string | number | undefined, arg2?: string | number | undefined, arg3?: string | number | undefined): Diagnostic { - const diagnostic = error(location, message, arg0, arg1, arg2, arg3); + ...args: (string | number | undefined)[]): Diagnostic { + const diagnostic = error(location, message, ...args); if (maybeMissingAwait) { const related = createDiagnosticForNode(location, Diagnostics.Did_you_forget_to_use_await); addRelatedInfo(diagnostic, related); @@ -19738,7 +19738,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== Ternary.False; } - type ErrorReporter = (message: DiagnosticMessage, arg0?: string, arg1?: string) => void; + type ErrorReporter = (message: DiagnosticMessage, ...args: (string | number | undefined)[]) => void; /** * Returns true if `s` is `(...args: A) => R` where `A` is `any`, `any[]`, `never`, or `never[]`, and `R` is `any` or `unknown`. @@ -20166,7 +20166,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let overflow = false; let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid let lastSkippedInfo: [Type, Type] | undefined; - let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] | undefined; + let incompatibleStack: [message: DiagnosticMessage, ...args: (string | number | undefined)[]][] | undefined; Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); @@ -20239,10 +20239,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { }; } - function reportIncompatibleError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { + function reportIncompatibleError(message: DiagnosticMessage, ...args: (string | number | undefined)[]) { overrideNextErrorInfo++; // Suppress the next relation error lastSkippedInfo = undefined; // Reset skipped info cache - (incompatibleStack ||= []).push([message, arg0, arg1, arg2, arg3]); + (incompatibleStack ||= []).push([message, ...args]); } function reportIncompatibleStack() { @@ -20353,11 +20353,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { + function reportError(message: DiagnosticMessage, ...args: (string | number | undefined)[]): void { Debug.assert(!!errorNode); if (incompatibleStack) reportIncompatibleStack(); if (message.elidedInCompatabilityPyramid) return; - errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3); + errorInfo = chainDiagnosticMessages(errorInfo, message, ...args); } function associateRelatedInfo(info: DiagnosticRelatedInformation) { @@ -32672,17 +32672,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return { start, length, sourceFile }; } - function getDiagnosticForCallNode(node: CallLikeExpression, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { + function getDiagnosticForCallNode(node: CallLikeExpression, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): DiagnosticWithLocation { if (isCallExpression(node)) { const { sourceFile, start, length } = getDiagnosticSpanForCallNode(node); if ("message" in message) { // eslint-disable-line local/no-in-operator - return createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2, arg3); + return createFileDiagnostic(sourceFile, start, length, message, ...args); } return createDiagnosticForFileFromMessageChain(sourceFile, message); } else { if ("message" in message) { // eslint-disable-line local/no-in-operator - return createDiagnosticForNode(node, message, arg0, arg1, arg2, arg3); + return createDiagnosticForNode(node, message, ...args); } return createDiagnosticForNodeFromMessageChain(getSourceFileOfNode(node), node, message); } @@ -39084,9 +39084,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function getAwaitedTypeOfPromise(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { + function getAwaitedTypeOfPromise(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): Type | undefined { const promisedType = getPromisedTypeOfPromise(type, errorNode); - return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, arg0); + return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, ...args); } /** @@ -39183,10 +39183,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Promise-like type; otherwise, it is the type of the expression. This is used to reflect * The runtime behavior of the `await` keyword. */ - function checkAwaitedType(type: Type, withAlias: boolean, errorNode: Node, diagnosticMessage: DiagnosticMessage, arg0?: string | number): Type { + function checkAwaitedType(type: Type, withAlias: boolean, errorNode: Node, diagnosticMessage: DiagnosticMessage, ...args: (string | number | undefined)[]): Type { const awaitedType = withAlias ? - getAwaitedType(type, errorNode, diagnosticMessage, arg0) : - getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); + getAwaitedType(type, errorNode, diagnosticMessage, ...args) : + getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, ...args); return awaitedType || errorType; } @@ -39289,8 +39289,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * * This is used to reflect the runtime behavior of the `await` keyword. */ - function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { - const awaitedType = getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, arg0); + function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): Type | undefined { + const awaitedType = getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, ...args); return awaitedType && createAwaitedTypeIfNeeded(awaitedType); } @@ -39299,7 +39299,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * * @see {@link getAwaitedType} */ - function getAwaitedTypeNoAlias(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, arg0?: string | number): Type | undefined { + function getAwaitedTypeNoAlias(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): Type | undefined { if (isTypeAny(type)) { return type; } @@ -39324,7 +39324,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } - const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, arg0) : getAwaitedTypeNoAlias; + const mapper = errorNode ? (constituentType: Type) => getAwaitedTypeNoAlias(constituentType, errorNode, diagnosticMessage, ...args) : getAwaitedTypeNoAlias; awaitedTypeStack.push(type.id); const mapped = mapType(type, mapper); @@ -39384,7 +39384,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Keep track of the type we're about to unwrap to avoid bad recursive promise types. // See the comments above for more information. awaitedTypeStack.push(type.id); - const awaitedType = getAwaitedTypeNoAlias(promisedType, errorNode, diagnosticMessage, arg0); + const awaitedType = getAwaitedTypeNoAlias(promisedType, errorNode, diagnosticMessage, ...args); awaitedTypeStack.pop(); if (!awaitedType) { @@ -39416,7 +39416,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (thisTypeForErrorOut.value) { chain = chainDiagnosticMessages(chain, Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1, typeToString(type), typeToString(thisTypeForErrorOut.value)); } - chain = chainDiagnosticMessages(chain, diagnosticMessage, arg0); + chain = chainDiagnosticMessages(chain, diagnosticMessage, ...args); diagnostics.add(createDiagnosticForNodeFromMessageChain(getSourceFileOfNode(errorNode), errorNode, chain)); } return undefined; @@ -42198,7 +42198,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { forEachKey(catchClause.locals!, caughtName => { const blockLocal = blockLocals.get(caughtName); if (blockLocal?.valueDeclaration && (blockLocal.flags & SymbolFlags.BlockScopedVariable) !== 0) { - grammarErrorOnNode(blockLocal.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, caughtName); + grammarErrorOnNode(blockLocal.valueDeclaration, Diagnostics.Cannot_redeclare_identifier_0_in_catch_clause, unescapeLeadingUnderscores(caughtName)); } }); } @@ -48145,12 +48145,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { switch (node.keywordToken) { case SyntaxKind.NewKeyword: if (escapedText !== "target") { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "target"); + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "target"); } break; case SyntaxKind.ImportKeyword: if (escapedText !== "meta") { - return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, node.name.escapedText, tokenToString(node.keywordToken), "meta"); + return grammarErrorOnNode(node.name, Diagnostics._0_is_not_a_valid_meta_property_for_keyword_1_Did_you_mean_2, unescapeLeadingUnderscores(node.name.escapedText), tokenToString(node.keywordToken), "meta"); } break; } @@ -48160,38 +48160,38 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return sourceFile.parseDiagnostics.length > 0; } - function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2)); + diagnostics.add(createFileDiagnostic(sourceFile, span.start, span.length, message, ...args)); return true; } return false; } - function grammarErrorAtPos(nodeForSourceFile: Node, start: number, length: number, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + function grammarErrorAtPos(nodeForSourceFile: Node, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { const sourceFile = getSourceFileOfNode(nodeForSourceFile); if (!hasParseDiagnostics(sourceFile)) { - diagnostics.add(createFileDiagnostic(sourceFile, start, length, message, arg0, arg1, arg2)); + diagnostics.add(createFileDiagnostic(sourceFile, start, length, message, ...args)); return true; } return false; } - function grammarErrorOnNodeSkippedOn(key: keyof CompilerOptions, node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + function grammarErrorOnNodeSkippedOn(key: keyof CompilerOptions, node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - errorSkippedOn(key, node, message, arg0, arg1, arg2); + errorSkippedOn(key, node, message, ...args); return true; } return false; } - function grammarErrorOnNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + function grammarErrorOnNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { - diagnostics.add(createDiagnosticForNode(node, message, arg0, arg1, arg2)); + diagnostics.add(createDiagnosticForNode(node, message, ...args)); return true; } return false; @@ -48406,11 +48406,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): boolean { + function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { const span = getSpanOfTokenAtPosition(sourceFile, node.pos); - diagnostics.add(createFileDiagnostic(sourceFile, textSpanEnd(span), /*length*/ 0, message, arg0, arg1, arg2)); + diagnostics.add(createFileDiagnostic(sourceFile, textSpanEnd(span), /*length*/ 0, message, ...args)); return true; } return false; diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index ab3909d8e2385..3cb5b69f819de 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -3094,9 +3094,9 @@ function parseJsonConfigFileContentWorker( return "no-prop"; } - function createCompilerDiagnosticOnlyIfJson(message: DiagnosticMessage, arg0?: string, arg1?: string) { + function createCompilerDiagnosticOnlyIfJson(message: DiagnosticMessage, ...args: (string | number | undefined)[]) { if (!sourceFile) { - errors.push(createCompilerDiagnostic(message, arg0, arg1)); + errors.push(createCompilerDiagnostic(message, ...args)); } } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ce9163c50cac1..cfd2953ba9c73 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -379,6 +379,7 @@ import { TypeQueryNode, TypeReferenceNode, UnaryExpression, + unescapeLeadingUnderscores, UnionOrIntersectionTypeNode, UnionTypeNode, UpdateExpression, @@ -2095,16 +2096,16 @@ namespace Parser { return inContext(NodeFlags.AwaitContext); } - function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { - return parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), message, arg0); + function parseErrorAtCurrentToken(message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation | undefined { + return parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), message, ...args); } - function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { + function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation | undefined { // Don't report another error if it would just be at the same position as the last error. const lastError = lastOrUndefined(parseDiagnostics); let result: DiagnosticWithDetachedLocation | undefined; if (!lastError || start !== lastError.start) { - result = createDetachedDiagnostic(fileName, start, length, message, arg0); + result = createDetachedDiagnostic(fileName, start, length, message, ...args); parseDiagnostics.push(result); } @@ -2114,12 +2115,12 @@ namespace Parser { return result; } - function parseErrorAt(start: number, end: number, message: DiagnosticMessage, arg0?: any): DiagnosticWithDetachedLocation | undefined { - return parseErrorAtPosition(start, end - start, message, arg0); + function parseErrorAt(start: number, end: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation | undefined { + return parseErrorAtPosition(start, end - start, message, ...args); } - function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, arg0?: any): void { - parseErrorAt(range.pos, range.end, message, arg0); + function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, ...args: (string | number | undefined)[]): void { + parseErrorAt(range.pos, range.end, message, ...args); } function scanError(message: DiagnosticMessage, length: number): void { @@ -2564,14 +2565,14 @@ namespace Parser { return node; } - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, arg0?: any): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, arg0?: any): T { + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, ...args: (string | number | undefined)[]): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): T { if (reportAtCurrentPosition) { - parseErrorAtPosition(scanner.getTokenFullStart(), 0, diagnosticMessage!, arg0); + parseErrorAtPosition(scanner.getTokenFullStart(), 0, diagnosticMessage!, ...args); } else if (diagnosticMessage) { - parseErrorAtCurrentToken(diagnosticMessage, arg0); + parseErrorAtCurrentToken(diagnosticMessage, ...args); } const pos = getNodePos(); @@ -9118,7 +9119,7 @@ namespace Parser { function parseReturnTag(start: number, tagName: Identifier, indent: number, indentText: string): JSDocReturnTag { if (some(tags, isJSDocReturnTag)) { - parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, tagName.escapedText); + parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, unescapeLeadingUnderscores(tagName.escapedText)); } const typeExpression = tryParseTypeExpression(); @@ -9127,7 +9128,7 @@ namespace Parser { function parseTypeTag(start: number, tagName: Identifier, indent?: number, indentText?: string): JSDocTypeTag { if (some(tags, isJSDocTypeTag)) { - parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, tagName.escapedText); + parseErrorAt(tagName.pos, scanner.getTokenStart(), Diagnostics._0_tag_already_specified, unescapeLeadingUnderscores(tagName.escapedText)); } const typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true); diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 219c87614ccf0..58eccfa0bdc73 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3071,15 +3071,15 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } - function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { + function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { const start = nodes.pos; - return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2); + return createFileDiagnostic(sourceFile, start, nodes.end - start, message, ...args); } // Since these are syntactic diagnostics, parent might not have been set // this means the sourceFile cannot be infered from the node - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number): DiagnosticWithLocation { - return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2); + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { + return createDiagnosticForNodeInSourceFile(sourceFile, node, message, ...args); } }); } @@ -4339,7 +4339,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg function checkDeprecations( deprecatedIn: string, removedIn: string, - createDiagnostic: (name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) => void, + createDiagnostic: (name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]) => void, fn: (createDeprecatedDiagnostic: (name: string, value?: string, useInstead?: string) => void) => void, ) { const deprecatedInVersion = new Version(deprecatedIn); @@ -4373,14 +4373,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function verifyDeprecatedCompilerOptions() { - function createDiagnostic(name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { + function createDiagnostic(name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { if (useInstead) { const details = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Use_0_instead, useInstead); - const chain = chainDiagnosticMessages(details, message, arg0, arg1, arg2, arg3); + const chain = chainDiagnosticMessages(details, message, ...args); createDiagnosticForOption(/*onKey*/ !value, name, /*option2*/ undefined, chain); } else { - createDiagnosticForOption(/*onKey*/ !value, name, /*option2*/ undefined, message, arg0, arg1, arg2, arg3); + createDiagnosticForOption(/*onKey*/ !value, name, /*option2*/ undefined, message, ...args); } } @@ -4419,8 +4419,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function verifyDeprecatedProjectReference(ref: ProjectReference, parentFile: JsonSourceFile | undefined, index: number) { - function createDiagnostic(_name: string, _value: string | undefined, _useInstead: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { - createDiagnosticForReference(parentFile, index, message, arg0, arg1, arg2, arg3); + function createDiagnostic(_name: string, _value: string | undefined, _useInstead: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + createDiagnosticForReference(parentFile, index, message, ...args); } checkDeprecations("5.0", "5.5", createDiagnostic, createDeprecatedDiagnostic => { @@ -4602,7 +4602,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg }); } - function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number) { + function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { let needCompilerDiagnostic = true; const pathsSyntax = getOptionPathsSyntax(); for (const pathProp of pathsSyntax) { @@ -4610,7 +4610,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg for (const keyProps of getPropertyAssignment(pathProp.initializer, key)) { const initializer = keyProps.initializer; if (isArrayLiteralExpression(initializer) && initializer.elements.length > valueIndex) { - programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, initializer.elements[valueIndex], message, arg0, arg1, arg2)); + programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, initializer.elements[valueIndex], message, ...args)); needCompilerDiagnostic = false; } } @@ -4618,23 +4618,23 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } if (needCompilerDiagnostic) { - programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2)); + programDiagnostics.add(createCompilerDiagnostic(message, ...args)); } } - function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, arg0: string | number) { + function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { let needCompilerDiagnostic = true; const pathsSyntax = getOptionPathsSyntax(); for (const pathProp of pathsSyntax) { if (isObjectLiteralExpression(pathProp.initializer) && createOptionDiagnosticInObjectLiteralSyntax( pathProp.initializer, onKey, key, /*key2*/ undefined, - message, arg0)) { + message, ...args)) { needCompilerDiagnostic = false; } } if (needCompilerDiagnostic) { - programDiagnostics.add(createCompilerDiagnostic(message, arg0)); + programDiagnostics.add(createCompilerDiagnostic(message, ...args)); } } @@ -4661,27 +4661,27 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3); } - function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, arg0?: string, arg1?: string) { - createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0, arg1); + function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, ...args); } - function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) { + function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { const referencesSyntax = firstDefined(getTsConfigPropArray(sourceFile || options.configFile, "references"), property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined); if (referencesSyntax && referencesSyntax.elements.length > index) { - programDiagnostics.add(createDiagnosticForNodeInSourceFile(sourceFile || options.configFile!, referencesSyntax.elements[index], message, arg0, arg1, arg2, arg3)); + programDiagnostics.add(createDiagnosticForNodeInSourceFile(sourceFile || options.configFile!, referencesSyntax.elements[index], message, ...args)); } else { - programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2, arg3)); + programDiagnostics.add(createCompilerDiagnostic(message, ...args)); } } function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessageChain): void; - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void; - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void { + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): void; + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): void { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || - !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, arg0, arg1, arg2, arg3); + !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, ...args); if (needCompilerDiagnostic) { // eslint-disable-next-line local/no-in-operator @@ -4689,7 +4689,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg programDiagnostics.add(createCompilerDiagnosticFromMessageChain(message)); } else { - programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1, arg2, arg3)); + programDiagnostics.add(createCompilerDiagnostic(message, ...args)); } } } @@ -4711,9 +4711,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, messageChain: DiagnosticMessageChain): boolean; - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): boolean; - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): boolean; - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): boolean { + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean; + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): boolean; + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): boolean { const props = getPropertyAssignment(objectLiteral, key1, key2); for (const prop of props) { // eslint-disable-next-line local/no-in-operator @@ -4721,7 +4721,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg programDiagnostics.add(createDiagnosticForNodeFromMessageChain(options.configFile!, onKey ? prop.name : prop.initializer, message)); } else { - programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, arg0, arg1, arg2, arg3)); + programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, onKey ? prop.name : prop.initializer, message, ...args)); } } return !!props.length; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 159aedabbf228..8059c7fd6c6de 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -2058,21 +2058,21 @@ export function entityNameToString(name: EntityNameOrEntityNameExpression | JSDo } /** @internal */ -export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { +export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { const sourceFile = getSourceFileOfNode(node); - return createDiagnosticForNodeInSourceFile(sourceFile, node, message, arg0, arg1, arg2, arg3); + return createDiagnosticForNodeInSourceFile(sourceFile, node, message, ...args); } /** @internal */ -export function createDiagnosticForNodeArray(sourceFile: SourceFile, nodes: NodeArray, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { +export function createDiagnosticForNodeArray(sourceFile: SourceFile, nodes: NodeArray, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { const start = skipTrivia(sourceFile.text, nodes.pos); - return createFileDiagnostic(sourceFile, start, nodes.end - start, message, arg0, arg1, arg2, arg3); + return createFileDiagnostic(sourceFile, start, nodes.end - start, message, ...args); } /** @internal */ -export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): DiagnosticWithLocation { +export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { const span = getErrorSpanForNode(sourceFile, node); - return createFileDiagnostic(sourceFile, span.start, span.length, message, arg0, arg1, arg2, arg3); + return createFileDiagnostic(sourceFile, span.start, span.length, message, ...args); } /** @internal */ diff --git a/src/testRunner/unittests/config/matchFiles.ts b/src/testRunner/unittests/config/matchFiles.ts index a7ecae0425221..d2df7779623be 100644 --- a/src/testRunner/unittests/config/matchFiles.ts +++ b/src/testRunner/unittests/config/matchFiles.ts @@ -137,14 +137,14 @@ function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ts.Par } } -function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: ts.DiagnosticMessage, arg0: string) { +function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: ts.DiagnosticMessage, ...args: (string | number | undefined)[]) { const text = JSON.stringify(json); const file = { fileName: caseInsensitiveTsconfigPath, kind: ts.SyntaxKind.SourceFile, text } as ts.SourceFile; - return ts.createFileDiagnostic(file, start, length, diagnosticMessage, arg0); + return ts.createFileDiagnostic(file, start, length, diagnosticMessage, ...args); } describe("unittests:: config:: matchFiles", () => { From bf2499391582919768fe52575aad2fcd2d684d07 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 Mar 2023 16:54:41 -0800 Subject: [PATCH 2/9] Name the type --- src/compiler/binder.ts | 5 ++- src/compiler/checker.ts | 41 ++++++++++--------- src/compiler/commandLineParser.ts | 3 +- src/compiler/parser.ts | 15 +++---- src/compiler/program.ts | 35 ++++++++-------- src/compiler/tsbuildPublic.ts | 3 +- src/compiler/types.ts | 7 +++- src/compiler/utilities.ts | 17 ++++---- src/testRunner/unittests/config/matchFiles.ts | 3 +- 9 files changed, 70 insertions(+), 59 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 8b0a3fa52773a..f988786dbe35a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -44,6 +44,7 @@ import { declarationNameToString, DeleteExpression, DestructuringAssignment, + DiagnosticArguments, DiagnosticCategory, DiagnosticMessage, DiagnosticRelatedInformation, @@ -556,7 +557,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { * If so, the node _must_ be in the current file (as that's the only way anything could have traversed to it to yield it as the error node) * This version of `createDiagnosticForNode` uses the binder's context to account for this, and always yields correct diagnostics even in these situations. */ - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { return createDiagnosticForNodeInSourceFile(getSourceFileOfNode(node) || file, node, message, ...args); } @@ -2613,7 +2614,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { } } - function errorOnFirstToken(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function errorOnFirstToken(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments) { const span = getSpanOfTokenAtPosition(file, node.pos); file.bindDiagnostics.push(createFileDiagnostic(file, span.start, span.length, message, ...args)); } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d50f12f7e534b..ad9ec23c5ee68 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -133,6 +133,7 @@ import { DeferredTypeReference, DeleteExpression, Diagnostic, + DiagnosticArguments, DiagnosticCategory, DiagnosticMessage, DiagnosticMessageChain, @@ -2296,7 +2297,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return emitResolver; } - function lookupOrIssueError(location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { + function lookupOrIssueError(location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic { const diagnostic = location ? createDiagnosticForNode(location, message, ...args) : createCompilerDiagnostic(message, ...args); @@ -2310,19 +2311,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function errorSkippedOn(key: keyof CompilerOptions, location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { + function errorSkippedOn(key: keyof CompilerOptions, location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic { const diagnostic = error(location, message, ...args); diagnostic.skippedOn = key; return diagnostic; } - function createError(location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { + function createError(location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic { return location ? createDiagnosticForNode(location, message, ...args) : createCompilerDiagnostic(message, ...args); } - function error(location: Node | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic { + function error(location: Node | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic { const diagnostic = createError(location, message, ...args); diagnostics.add(diagnostic); return diagnostic; @@ -2336,7 +2337,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { suggestionDiagnostics.add({ ...diagnostic, category: DiagnosticCategory.Suggestion }); } } - function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): void { + function errorOrSuggestion(isError: boolean, location: Node, message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): void { // Pseudo-synthesized input node if (location.pos < 0 || location.end < 0) { if (!isError) { @@ -2354,7 +2355,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { location: Node, maybeMissingAwait: boolean, message: DiagnosticMessage, - ...args: (string | number | undefined)[]): Diagnostic { + ...args: DiagnosticArguments): Diagnostic { const diagnostic = error(location, message, ...args); if (maybeMissingAwait) { const related = createDiagnosticForNode(location, Diagnostics.Did_you_forget_to_use_await); @@ -19738,7 +19739,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { /*errorReporter*/ undefined, /*errorReporter*/ undefined, compareTypesAssignable, /*reportUnreliableMarkers*/ undefined) !== Ternary.False; } - type ErrorReporter = (message: DiagnosticMessage, ...args: (string | number | undefined)[]) => void; + type ErrorReporter = (message: DiagnosticMessage, ...args: DiagnosticArguments) => void; /** * Returns true if `s` is `(...args: A) => R` where `A` is `any`, `any[]`, `never`, or `never[]`, and `R` is `any` or `unknown`. @@ -20166,7 +20167,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let overflow = false; let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid let lastSkippedInfo: [Type, Type] | undefined; - let incompatibleStack: [message: DiagnosticMessage, ...args: (string | number | undefined)[]][] | undefined; + let incompatibleStack: [message: DiagnosticMessage, ...args: DiagnosticArguments][] | undefined; Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); @@ -20239,7 +20240,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { }; } - function reportIncompatibleError(message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function reportIncompatibleError(message: DiagnosticMessage, ...args: DiagnosticArguments) { overrideNextErrorInfo++; // Suppress the next relation error lastSkippedInfo = undefined; // Reset skipped info cache (incompatibleStack ||= []).push([message, ...args]); @@ -20353,7 +20354,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function reportError(message: DiagnosticMessage, ...args: (string | number | undefined)[]): void { + function reportError(message: DiagnosticMessage, ...args: DiagnosticArguments): void { Debug.assert(!!errorNode); if (incompatibleStack) reportIncompatibleStack(); if (message.elidedInCompatabilityPyramid) return; @@ -32672,7 +32673,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return { start, length, sourceFile }; } - function getDiagnosticForCallNode(node: CallLikeExpression, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): DiagnosticWithLocation { + function getDiagnosticForCallNode(node: CallLikeExpression, message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): DiagnosticWithLocation { if (isCallExpression(node)) { const { sourceFile, start, length } = getDiagnosticSpanForCallNode(node); if ("message" in message) { // eslint-disable-line local/no-in-operator @@ -39084,7 +39085,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function getAwaitedTypeOfPromise(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): Type | undefined { + function getAwaitedTypeOfPromise(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): Type | undefined { const promisedType = getPromisedTypeOfPromise(type, errorNode); return promisedType && getAwaitedType(promisedType, errorNode, diagnosticMessage, ...args); } @@ -39183,7 +39184,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * Promise-like type; otherwise, it is the type of the expression. This is used to reflect * The runtime behavior of the `await` keyword. */ - function checkAwaitedType(type: Type, withAlias: boolean, errorNode: Node, diagnosticMessage: DiagnosticMessage, ...args: (string | number | undefined)[]): Type { + function checkAwaitedType(type: Type, withAlias: boolean, errorNode: Node, diagnosticMessage: DiagnosticMessage, ...args: DiagnosticArguments): Type { const awaitedType = withAlias ? getAwaitedType(type, errorNode, diagnosticMessage, ...args) : getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, ...args); @@ -39289,7 +39290,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * * This is used to reflect the runtime behavior of the `await` keyword. */ - function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): Type | undefined { + function getAwaitedType(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): Type | undefined { const awaitedType = getAwaitedTypeNoAlias(type, errorNode, diagnosticMessage, ...args); return awaitedType && createAwaitedTypeIfNeeded(awaitedType); } @@ -39299,7 +39300,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * * @see {@link getAwaitedType} */ - function getAwaitedTypeNoAlias(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): Type | undefined { + function getAwaitedTypeNoAlias(type: Type, errorNode?: Node, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): Type | undefined { if (isTypeAny(type)) { return type; } @@ -48160,7 +48161,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return sourceFile.parseDiagnostics.length > 0; } - function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { + function grammarErrorOnFirstToken(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { const span = getSpanOfTokenAtPosition(sourceFile, node.pos); @@ -48170,7 +48171,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function grammarErrorAtPos(nodeForSourceFile: Node, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { + function grammarErrorAtPos(nodeForSourceFile: Node, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean { const sourceFile = getSourceFileOfNode(nodeForSourceFile); if (!hasParseDiagnostics(sourceFile)) { diagnostics.add(createFileDiagnostic(sourceFile, start, length, message, ...args)); @@ -48179,7 +48180,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function grammarErrorOnNodeSkippedOn(key: keyof CompilerOptions, node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { + function grammarErrorOnNodeSkippedOn(key: keyof CompilerOptions, node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { errorSkippedOn(key, node, message, ...args); @@ -48188,7 +48189,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function grammarErrorOnNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { + function grammarErrorOnNode(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { diagnostics.add(createDiagnosticForNode(node, message, ...args)); @@ -48406,7 +48407,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } - function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean { + function grammarErrorAfterFirstToken(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean { const sourceFile = getSourceFileOfNode(node); if (!hasParseDiagnostics(sourceFile)) { const span = getSpanOfTokenAtPosition(sourceFile, node.pos); diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index 3cb5b69f819de..da98da4b6ba5e 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -22,6 +22,7 @@ import { createGetCanonicalFileName, Debug, Diagnostic, + DiagnosticArguments, DiagnosticMessage, Diagnostics, DidYouMeanOptionsDiagnostics, @@ -3094,7 +3095,7 @@ function parseJsonConfigFileContentWorker( return "no-prop"; } - function createCompilerDiagnosticOnlyIfJson(message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createCompilerDiagnosticOnlyIfJson(message: DiagnosticMessage, ...args: DiagnosticArguments) { if (!sourceFile) { errors.push(createCompilerDiagnostic(message, ...args)); } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cfd2953ba9c73..8bf642c7f90df 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -64,6 +64,7 @@ import { DefaultClause, DeleteExpression, Diagnostic, + DiagnosticArguments, DiagnosticMessage, Diagnostics, DiagnosticWithDetachedLocation, @@ -2096,11 +2097,11 @@ namespace Parser { return inContext(NodeFlags.AwaitContext); } - function parseErrorAtCurrentToken(message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation | undefined { + function parseErrorAtCurrentToken(message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { return parseErrorAt(scanner.getTokenStart(), scanner.getTokenEnd(), message, ...args); } - function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation | undefined { + function parseErrorAtPosition(start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { // Don't report another error if it would just be at the same position as the last error. const lastError = lastOrUndefined(parseDiagnostics); let result: DiagnosticWithDetachedLocation | undefined; @@ -2115,11 +2116,11 @@ namespace Parser { return result; } - function parseErrorAt(start: number, end: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation | undefined { + function parseErrorAt(start: number, end: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation | undefined { return parseErrorAtPosition(start, end - start, message, ...args); } - function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, ...args: (string | number | undefined)[]): void { + function parseErrorAtRange(range: TextRange, message: DiagnosticMessage, ...args: DiagnosticArguments): void { parseErrorAt(range.pos, range.end, message, ...args); } @@ -2565,9 +2566,9 @@ namespace Parser { return node; } - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, ...args: (string | number | undefined)[]): T; - function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, ...args: (string | number | undefined)[]): T { + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: false, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, ...args: DiagnosticArguments): T; + function createMissingNode(kind: T["kind"], reportAtCurrentPosition: boolean, diagnosticMessage?: DiagnosticMessage, ...args: DiagnosticArguments): T { if (reportAtCurrentPosition) { parseErrorAtPosition(scanner.getTokenFullStart(), 0, diagnosticMessage!, ...args); } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 58eccfa0bdc73..75d32a6263a2d 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -57,6 +57,7 @@ import { Debug, DeclarationWithTypeParameterChildren, Diagnostic, + DiagnosticArguments, DiagnosticCategory, diagnosticCategoryName, DiagnosticMessage, @@ -3071,14 +3072,14 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } - function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { + function createDiagnosticForNodeArray(nodes: NodeArray, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { const start = nodes.pos; return createFileDiagnostic(sourceFile, start, nodes.end - start, message, ...args); } // Since these are syntactic diagnostics, parent might not have been set // this means the sourceFile cannot be infered from the node - function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { + function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { return createDiagnosticForNodeInSourceFile(sourceFile, node, message, ...args); } }); @@ -4339,7 +4340,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg function checkDeprecations( deprecatedIn: string, removedIn: string, - createDiagnostic: (name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]) => void, + createDiagnostic: (name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments) => void, fn: (createDeprecatedDiagnostic: (name: string, value?: string, useInstead?: string) => void) => void, ) { const deprecatedInVersion = new Version(deprecatedIn); @@ -4373,7 +4374,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function verifyDeprecatedCompilerOptions() { - function createDiagnostic(name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createDiagnostic(name: string, value: string | undefined, useInstead: string | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments) { if (useInstead) { const details = chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Use_0_instead, useInstead); const chain = chainDiagnosticMessages(details, message, ...args); @@ -4419,7 +4420,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function verifyDeprecatedProjectReference(ref: ProjectReference, parentFile: JsonSourceFile | undefined, index: number) { - function createDiagnostic(_name: string, _value: string | undefined, _useInstead: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createDiagnostic(_name: string, _value: string | undefined, _useInstead: string | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments) { createDiagnosticForReference(parentFile, index, message, ...args); } @@ -4430,7 +4431,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg }); } - function createDiagnosticExplainingFile(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason | undefined, diagnostic: DiagnosticMessage, args: (string | number | undefined)[] | undefined): Diagnostic { + function createDiagnosticExplainingFile(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason | undefined, diagnostic: DiagnosticMessage, args: DiagnosticArguments | undefined): Diagnostic { let fileIncludeReasons: DiagnosticMessageChain[] | undefined; let relatedInfo: Diagnostic[] | undefined; let locationReason = isReferencedFile(fileProcessingReason) ? fileProcessingReason : undefined; @@ -4460,7 +4461,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } - function addFilePreprocessingFileExplainingDiagnostic(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason, diagnostic: DiagnosticMessage, args?: (string | number | undefined)[]) { + function addFilePreprocessingFileExplainingDiagnostic(file: SourceFile | undefined, fileProcessingReason: FileIncludeReason, diagnostic: DiagnosticMessage, args?: DiagnosticArguments) { (fileProcessingDiagnostics ||= []).push({ kind: FilePreprocessingDiagnosticsKind.FilePreprocessingFileExplainingDiagnostic, file: file && file.path, @@ -4470,7 +4471,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg }); } - function addProgramDiagnosticExplainingFile(file: SourceFile, diagnostic: DiagnosticMessage, args?: (string | number | undefined)[]) { + function addProgramDiagnosticExplainingFile(file: SourceFile, diagnostic: DiagnosticMessage, args?: DiagnosticArguments) { programDiagnostics.add(createDiagnosticExplainingFile(file, /*fileProcessingReason*/ undefined, diagnostic, args)); } @@ -4602,7 +4603,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg }); } - function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, ...args: DiagnosticArguments) { let needCompilerDiagnostic = true; const pathsSyntax = getOptionPathsSyntax(); for (const pathProp of pathsSyntax) { @@ -4622,7 +4623,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } } - function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createDiagnosticForOptionPaths(onKey: boolean, key: string, message: DiagnosticMessage, ...args: DiagnosticArguments) { let needCompilerDiagnostic = true; const pathsSyntax = getOptionPathsSyntax(); for (const pathProp of pathsSyntax) { @@ -4661,11 +4662,11 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3); } - function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, ...args: DiagnosticArguments) { createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, ...args); } - function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { + function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, ...args: DiagnosticArguments) { const referencesSyntax = firstDefined(getTsConfigPropArray(sourceFile || options.configFile, "references"), property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined); if (referencesSyntax && referencesSyntax.elements.length > index) { @@ -4677,8 +4678,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessageChain): void; - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): void; - function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): void { + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): void; + function createDiagnosticForOption(onKey: boolean, option1: string, option2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): void { const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax(); const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax || !createOptionDiagnosticInObjectLiteralSyntax(compilerOptionsObjectLiteralSyntax, onKey, option1, option2, message, ...args); @@ -4711,9 +4712,9 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, messageChain: DiagnosticMessageChain): boolean; - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): boolean; - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): boolean; - function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: (string | number | undefined)[]): boolean { + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): boolean; + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): boolean; + function createOptionDiagnosticInObjectLiteralSyntax(objectLiteral: ObjectLiteralExpression, onKey: boolean, key1: string, key2: string | undefined, message: DiagnosticMessage | DiagnosticMessageChain, ...args: DiagnosticArguments): boolean { const props = getPropertyAssignment(objectLiteral, key1, key2); for (const prop of props) { // eslint-disable-next-line local/no-in-operator diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 572306483c438..9bfe0d347788f 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -33,6 +33,7 @@ import { CustomTransformers, Debug, Diagnostic, + DiagnosticArguments, DiagnosticCollection, DiagnosticMessage, DiagnosticReporter, @@ -2470,7 +2471,7 @@ function reportStatus(state: SolutionBuilderState, state.host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args)); } -function reportWatchStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: (string | number | undefined)[]) { +function reportWatchStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: DiagnosticArguments) { state.hostWithWatch.onWatchStatusChange?.(createCompilerDiagnostic(message, ...args), state.host.getNewLine(), state.baseCompilerOptions); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 936fe425cc1e4..8599fb45b5417 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4665,7 +4665,7 @@ export interface FilePreprocessingReferencedDiagnostic { kind: FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic; reason: ReferencedFile; diagnostic: DiagnosticMessage; - args?: (string | number | undefined)[]; + args?: DiagnosticArguments; } /** @internal */ @@ -4674,7 +4674,7 @@ export interface FilePreprocessingFileExplainingDiagnostic { file?: Path; fileProcessingReason: FileIncludeReason; diagnostic: DiagnosticMessage; - args?: (string | number | undefined)[]; + args?: DiagnosticArguments; } /** @internal */ @@ -6908,6 +6908,9 @@ export interface Diagnostic extends DiagnosticRelatedInformation { /** @internal */ skippedOn?: keyof CompilerOptions; } +/** @internal */ +export type DiagnosticArguments = (string | number | undefined)[]; + export interface DiagnosticRelatedInformation { category: DiagnosticCategory; code: number; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8059c7fd6c6de..d256c57c2aff8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -90,6 +90,7 @@ import { DefaultClause, DestructuringAssignment, Diagnostic, + DiagnosticArguments, DiagnosticCollection, DiagnosticMessage, DiagnosticMessageChain, @@ -2058,19 +2059,19 @@ export function entityNameToString(name: EntityNameOrEntityNameExpression | JSDo } /** @internal */ -export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { +export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { const sourceFile = getSourceFileOfNode(node); return createDiagnosticForNodeInSourceFile(sourceFile, node, message, ...args); } /** @internal */ -export function createDiagnosticForNodeArray(sourceFile: SourceFile, nodes: NodeArray, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { +export function createDiagnosticForNodeArray(sourceFile: SourceFile, nodes: NodeArray, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { const start = skipTrivia(sourceFile.text, nodes.pos); return createFileDiagnostic(sourceFile, start, nodes.end - start, message, ...args); } /** @internal */ -export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation { +export function createDiagnosticForNodeInSourceFile(sourceFile: SourceFile, node: Node, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation { const span = getErrorSpanForNode(sourceFile, node); return createFileDiagnostic(sourceFile, span.start, span.length, message, ...args); } @@ -7995,7 +7996,7 @@ export function getLocaleSpecificMessage(message: DiagnosticMessage) { } /** @internal */ -export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithDetachedLocation; +export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithDetachedLocation; /** @internal */ export function createDetachedDiagnostic(fileName: string, start: number, length: number, message: DiagnosticMessage): DiagnosticWithDetachedLocation { assertDiagnosticLocation(/*file*/ undefined, start, length); @@ -8066,7 +8067,7 @@ export function attachFileToDiagnostics(diagnostics: DiagnosticWithDetachedLocat } /** @internal */ -export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation; +export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticWithLocation; /** @internal */ export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation { assertDiagnosticLocation(file, start, length); @@ -8091,7 +8092,7 @@ export function createFileDiagnostic(file: SourceFile, start: number, length: nu } /** @internal */ -export function formatMessage(_dummy: any, message: DiagnosticMessage, ...args: (string | number | undefined)[]): string; +export function formatMessage(_dummy: any, message: DiagnosticMessage, ...args: DiagnosticArguments): string; /** @internal */ export function formatMessage(_dummy: any, message: DiagnosticMessage): string { let text = getLocaleSpecificMessage(message); @@ -8104,7 +8105,7 @@ export function formatMessage(_dummy: any, message: DiagnosticMessage): string { } /** @internal */ -export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic; +export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: DiagnosticArguments): Diagnostic; /** @internal */ export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic { let text = getLocaleSpecificMessage(message); @@ -8141,7 +8142,7 @@ export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessag } /** @internal */ -export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticMessageChain; +export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticMessageChain; /** @internal */ export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage): DiagnosticMessageChain { let text = getLocaleSpecificMessage(message); diff --git a/src/testRunner/unittests/config/matchFiles.ts b/src/testRunner/unittests/config/matchFiles.ts index d2df7779623be..42adbae0ffa1c 100644 --- a/src/testRunner/unittests/config/matchFiles.ts +++ b/src/testRunner/unittests/config/matchFiles.ts @@ -1,5 +1,6 @@ import * as fakes from "../../_namespaces/fakes"; import * as ts from "../../_namespaces/ts"; +import { DiagnosticArguments } from "../../_namespaces/ts"; import * as vfs from "../../_namespaces/vfs"; const caseInsensitiveBasePath = "c:/dev/"; @@ -137,7 +138,7 @@ function validateMatches(expected: ts.ParsedCommandLine, json: any, host: ts.Par } } -function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: ts.DiagnosticMessage, ...args: (string | number | undefined)[]) { +function createDiagnosticForConfigFile(json: any, start: number, length: number, diagnosticMessage: ts.DiagnosticMessage, ...args: DiagnosticArguments) { const text = JSON.stringify(json); const file = { fileName: caseInsensitiveTsconfigPath, From 35605c248e67f945b84fb555bd8258028665a295 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Thu, 9 Mar 2023 16:57:52 -0800 Subject: [PATCH 3/9] One more consistency --- src/compiler/tsbuildPublic.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index 9bfe0d347788f..b09b9a7d67b36 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -2009,7 +2009,7 @@ function updateOutputTimestampsWorker( // For incremental projects, only buildinfo needs to be upto date with timestamp check // as we dont check output files for up-to-date ness if (!skipOutputs?.has(toPath(state, buildInfoPath))) { - if (!!state.options.verbose) reportStatus(state, verboseMessage, proj.options.configFilePath!); + if (!!state.options.verbose) reportStatus(state, verboseMessage, proj.options.configFilePath); state.host.setModifiedTime(buildInfoPath, now = getCurrentTime(state.host)); getBuildInfoCacheEntry(state, buildInfoPath, projectPath)!.modifiedTime = now; } @@ -2028,7 +2028,7 @@ function updateOutputTimestampsWorker( if (skipOutputs?.has(path)) continue; if (reportVerbose) { reportVerbose = false; - reportStatus(state, verboseMessage, proj.options.configFilePath!); + reportStatus(state, verboseMessage, proj.options.configFilePath); } host.setModifiedTime(file, now ||= getCurrentTime(state.host)); // Store output timestamps in a map because non incremental build will need to check them to determine up-to-dateness @@ -2058,7 +2058,7 @@ function getLatestChangedDtsTime(state: SolutionBuilde function updateOutputTimestamps(state: SolutionBuilderState, proj: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath) { if (state.options.dry) { - return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath!); + return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath); } updateOutputTimestampsWorker(state, proj, resolvedPath, Diagnostics.Updating_output_timestamps_of_project_0); state.projectStatus.set(resolvedPath, { @@ -2467,7 +2467,7 @@ function relName(state: SolutionBuilderState, path: return convertToRelativePath(path, state.compilerHost.getCurrentDirectory(), state.compilerHost.getCanonicalFileName); } -function reportStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: string[]) { +function reportStatus(state: SolutionBuilderState, message: DiagnosticMessage, ...args: DiagnosticArguments) { state.host.reportSolutionBuilderStatus(createCompilerDiagnostic(message, ...args)); } From 9202756f752448aecd35b3223afb5045ab6f4c3d Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 10 Mar 2023 17:02:04 -0800 Subject: [PATCH 4/9] Remove undefined, plus some TODOs --- src/compiler/binder.ts | 4 +- src/compiler/checker.ts | 40 +++++++++--------- src/compiler/commandLineParser.ts | 4 +- src/compiler/parser.ts | 21 ++++++---- src/compiler/program.ts | 8 ++-- src/compiler/scanner.ts | 5 +++ src/compiler/transformers/declarations.ts | 8 ++-- src/compiler/tsbuildPublic.ts | 6 +-- src/compiler/types.ts | 8 +++- src/compiler/utilities.ts | 12 ++++++ src/compiler/watch.ts | 42 +++++++++---------- src/services/codeFixProvider.ts | 8 ++-- src/services/codefixes/fixImplicitThis.ts | 6 +-- src/services/codefixes/fixUnusedIdentifier.ts | 4 +- src/services/codefixes/importFixes.ts | 6 +-- src/services/utilities.ts | 10 ++--- 16 files changed, 109 insertions(+), 83 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index f988786dbe35a..27f2f52827b95 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -841,7 +841,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { const declarationName = getNameOfDeclaration(node) || node; forEach(symbol.declarations, (declaration, index) => { const decl = getNameOfDeclaration(declaration) || declaration; - const diag = createDiagnosticForNode(decl, message, messageNeedsName ? getDisplayName(declaration) : undefined); + const diag = messageNeedsName ? createDiagnosticForNode(decl, message, getDisplayName(declaration)) : createDiagnosticForNode(decl, message); file.bindDiagnostics.push( multipleDefaultExports ? addRelatedInfo(diag, createDiagnosticForNode(declarationName, index === 0 ? Diagnostics.Another_export_default_is_here : Diagnostics.and_here)) : diag ); @@ -850,7 +850,7 @@ function createBinder(): (file: SourceFile, options: CompilerOptions) => void { } }); - const diag = createDiagnosticForNode(declarationName, message, messageNeedsName ? getDisplayName(node) : undefined); + const diag = messageNeedsName ? createDiagnosticForNode(declarationName, message, getDisplayName(node)) : createDiagnosticForNode(declarationName, message); file.bindDiagnostics.push(addRelatedInfo(diag, ...relatedInformation)); symbol = createSymbol(SymbolFlags.None, name); diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ad9ec23c5ee68..8a5963539b56e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -33,7 +33,6 @@ import { BigIntLiteral, BigIntLiteralType, BinaryExpression, - BinaryOperator, BinaryOperatorToken, binarySearch, BindableObjectDefinePropertyCall, @@ -133,6 +132,7 @@ import { DeferredTypeReference, DeleteExpression, Diagnostic, + DiagnosticAndArguments, DiagnosticArguments, DiagnosticCategory, DiagnosticMessage, @@ -896,6 +896,7 @@ import { PropertySignature, PseudoBigInt, pseudoBigIntToString, + PunctuationSyntaxKind, pushIfUnique, QualifiedName, QuestionToken, @@ -9802,7 +9803,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result || types; } - function visibilityToString(flags: ModifierFlags): string | undefined { + function visibilityToString(flags: ModifierFlags): string { if (flags === ModifierFlags.Private) { return "private"; } @@ -20167,7 +20168,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let overflow = false; let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid let lastSkippedInfo: [Type, Type] | undefined; - let incompatibleStack: [message: DiagnosticMessage, ...args: DiagnosticArguments][] | undefined; + let incompatibleStack: DiagnosticAndArguments[] | undefined; Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking"); @@ -20262,7 +20263,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // The first error will be the innermost, while the last will be the outermost - so by popping off the end, // we can build from left to right let path = ""; - const secondaryRootErrors: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = []; + const secondaryRootErrors: DiagnosticAndArguments[] = []; while (stack.length) { const [msg, ...args] = stack.pop()!; switch (msg.code) { @@ -32767,13 +32768,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const parameter = closestSignature?.declaration?.parameters[closestSignature.thisParameter ? args.length + 1 : args.length]; if (parameter) { - const parameterError = createDiagnosticForNode( - parameter, - isBindingPattern(parameter.name) ? Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided - : isRestParameter(parameter) ? Diagnostics.Arguments_for_the_rest_parameter_0_were_not_provided - : Diagnostics.An_argument_for_0_was_not_provided, - !parameter.name ? args.length : !isBindingPattern(parameter.name) ? idText(getFirstIdentifier(parameter.name)) : undefined - ); + const messageAndArgs: DiagnosticAndArguments = + isBindingPattern(parameter.name) ? [Diagnostics.An_argument_matching_this_binding_pattern_was_not_provided] + : isRestParameter(parameter) ? [Diagnostics.Arguments_for_the_rest_parameter_0_were_not_provided, idText(getFirstIdentifier(parameter.name))] + : [Diagnostics.An_argument_for_0_was_not_provided, !parameter.name ? args.length : idText(getFirstIdentifier(parameter.name))]; + const parameterError = createDiagnosticForNode(parameter, ...messageAndArgs); return addRelatedInfo(diagnostic, parameterError); } return diagnostic; @@ -36509,7 +36508,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Note that this and `checkBinaryExpression` above should behave mostly the same, except this elides some // expression-wide checks and does not use a work stack to fold nested binary expressions into the same callstack frame - function checkBinaryLikeExpression(left: Expression, operatorToken: Node, right: Expression, checkMode?: CheckMode, errorNode?: Node): Type { + function checkBinaryLikeExpression(left: Expression, operatorToken: BinaryOperatorToken, right: Expression, checkMode?: CheckMode, errorNode?: Node): Type { const operator = operatorToken.kind; if (operator === SyntaxKind.EqualsToken && (left.kind === SyntaxKind.ObjectLiteralExpression || left.kind === SyntaxKind.ArrayLiteralExpression)) { return checkDestructuringAssignment(left, checkExpression(right, checkMode), checkMode, right.kind === SyntaxKind.ThisKeyword); @@ -36528,7 +36527,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function checkBinaryLikeExpressionWorker( left: Expression, - operatorToken: Node, + operatorToken: BinaryOperatorToken, right: Expression, leftType: Type, rightType: Type, @@ -36565,7 +36564,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { leftType = checkNonNullType(leftType, left); rightType = checkNonNullType(rightType, right); - let suggestedOperator: SyntaxKind | undefined; + let suggestedOperator: PunctuationSyntaxKind | undefined; // if a user tries to apply a bitwise operator to 2 boolean operands // try and return them a helpful suggestion if ((leftType.flags & TypeFlags.BooleanLike) && @@ -36794,7 +36793,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // Return true if there was no error, false if there was an error. - function checkForDisallowedESSymbolOperand(operator: SyntaxKind): boolean { + function checkForDisallowedESSymbolOperand(operator: PunctuationSyntaxKind): boolean { const offendingSymbolOperand = maybeTypeOfKindConsideringBaseConstraint(leftType, TypeFlags.ESSymbolLike) ? left : maybeTypeOfKindConsideringBaseConstraint(rightType, TypeFlags.ESSymbolLike) ? right : @@ -36808,7 +36807,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return true; } - function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind | undefined { + function getSuggestedBooleanOperator(operator: SyntaxKind): PunctuationSyntaxKind | undefined { switch (operator) { case SyntaxKind.BarToken: case SyntaxKind.BarEqualsToken: @@ -36833,7 +36832,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let assigneeType = leftType; // getters can be a subtype of setters, so to check for assignability we use the setter's type instead - if (isCompoundAssignment(operatorToken.kind as BinaryOperator) && left.kind === SyntaxKind.PropertyAccessExpression) { + if (isCompoundAssignment(operatorToken.kind) && left.kind === SyntaxKind.PropertyAccessExpression) { assigneeType = checkPropertyAccessExpression(left as PropertyAccessExpression, /*checkMode*/ undefined, /*writeOnly*/ true); } @@ -40158,9 +40157,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { : rangeOfTypeParameters(sourceFile, parent.typeParameters!); const only = parent.typeParameters!.length === 1; //TODO: following line is possible reason for bug #41974, unusedTypeParameters_TemplateTag - const message = only ? Diagnostics._0_is_declared_but_its_value_is_never_read : Diagnostics.All_type_parameters_are_unused; - const arg0 = only ? name : undefined; - addDiagnostic(typeParameter, UnusedKind.Parameter, createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, message, arg0)); + const messageAndArg: DiagnosticAndArguments = only + ? [Diagnostics._0_is_declared_but_its_value_is_never_read, name] + : [Diagnostics.All_type_parameters_are_unused]; + addDiagnostic(typeParameter, UnusedKind.Parameter, createFileDiagnostic(sourceFile, range.pos, range.end - range.pos, ...messageAndArg)); } } else { diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index da98da4b6ba5e..770a6e0463b22 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -1747,7 +1747,7 @@ function getOptionName(option: CommandLineOption) { function createUnknownOptionError( unknownOption: string, diagnostics: DidYouMeanOptionsDiagnostics, - createDiagnostics: (message: DiagnosticMessage, arg0: string, arg1?: string) => Diagnostic, + createDiagnostics: (message: DiagnosticMessage, ...args: DiagnosticArguments) => Diagnostic, unknownOptionErrorText?: string ) { if (diagnostics.alternateMode?.getOptionsNameMap().optionsNameMap.has(unknownOption.toLowerCase())) { @@ -3377,7 +3377,7 @@ function getExtendsConfigPath( host: ParseConfigHost, basePath: string, errors: Diagnostic[], - createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) { + createDiagnostic: (message: DiagnosticMessage, ...args: DiagnosticArguments) => Diagnostic) { extendedConfig = normalizeSlashes(extendedConfig); if (isRootedDiskPath(extendedConfig) || startsWith(extendedConfig, "./") || startsWith(extendedConfig, "../")) { let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8bf642c7f90df..a73bba6c158d9 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -150,6 +150,7 @@ import { isJsxOpeningElement, isJsxOpeningFragment, isKeyword, + isKeywordOrPunctuation, isLeftHandSideExpression, isLiteralKind, isMetaProperty, @@ -306,6 +307,8 @@ import { PropertyDeclaration, PropertyName, PropertySignature, + PunctuationOrKeywordSyntaxKind, + PunctuationSyntaxKind, QualifiedName, QuestionDotToken, QuestionToken, @@ -2290,7 +2293,7 @@ namespace Parser { return token() > SyntaxKind.LastReservedWord; } - function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean { + function parseExpected(kind: PunctuationOrKeywordSyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean { if (token() === kind) { if (shouldAdvance) { nextToken(); @@ -2445,11 +2448,12 @@ namespace Parser { nextTokenJSDoc(); return true; } + Debug.assert(isKeywordOrPunctuation(kind)); parseErrorAtCurrentToken(Diagnostics._0_expected, tokenToString(kind)); return false; } - function parseExpectedMatchingBrackets(openKind: SyntaxKind, closeKind: SyntaxKind, openParsed: boolean, openPosition: number) { + function parseExpectedMatchingBrackets(openKind: PunctuationSyntaxKind, closeKind: PunctuationSyntaxKind, openParsed: boolean, openPosition: number) { if (token() === closeKind) { nextToken(); return; @@ -2498,8 +2502,10 @@ namespace Parser { function parseExpectedTokenJSDoc(t: TKind): Token; function parseExpectedTokenJSDoc(t: JSDocSyntaxKind): Node { - return parseOptionalTokenJSDoc(t) || - createMissingNode(t, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(t)); + const optional = parseOptionalTokenJSDoc(t); + if (optional) return optional; + Debug.assert(isKeywordOrPunctuation(t)); + return createMissingNode(t, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(t)); } function parseTokenNode(): T { @@ -3357,7 +3363,7 @@ namespace Parser { case ParsingContext.HeritageClauseElement: return parseErrorAtCurrentToken(Diagnostics.Expression_expected); case ParsingContext.VariableDeclarations: return isKeyword(token()) - ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_variable_declaration_name, tokenToString(token())) + ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_variable_declaration_name, tokenToString(token())!) : parseErrorAtCurrentToken(Diagnostics.Variable_declaration_expected); case ParsingContext.ObjectBindingElements: return parseErrorAtCurrentToken(Diagnostics.Property_destructuring_pattern_expected); case ParsingContext.ArrayBindingElements: return parseErrorAtCurrentToken(Diagnostics.Array_element_destructuring_pattern_expected); @@ -3367,7 +3373,7 @@ namespace Parser { case ParsingContext.JSDocParameters: return parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); case ParsingContext.Parameters: return isKeyword(token()) - ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_parameter_name, tokenToString(token())) + ? parseErrorAtCurrentToken(Diagnostics._0_is_not_allowed_as_a_parameter_name, tokenToString(token())!) : parseErrorAtCurrentToken(Diagnostics.Parameter_declaration_expected); case ParsingContext.TypeParameters: return parseErrorAtCurrentToken(Diagnostics.Type_parameter_declaration_expected); case ParsingContext.TypeArguments: return parseErrorAtCurrentToken(Diagnostics.Type_argument_expected); @@ -3472,7 +3478,7 @@ namespace Parser { return !!(arr as MissingList).isMissingList; } - function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: SyntaxKind, close: SyntaxKind): NodeArray { + function parseBracketedList(kind: ParsingContext, parseElement: () => T, open: PunctuationSyntaxKind, close: PunctuationSyntaxKind): NodeArray { if (parseExpected(open)) { const result = parseDelimitedList(kind, parseElement); parseExpected(close); @@ -5654,6 +5660,7 @@ namespace Parser { parseErrorAt(pos, end, Diagnostics.A_type_assertion_expression_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses); } else { + Debug.assert(isKeywordOrPunctuation(unaryOperator)); parseErrorAt(pos, end, Diagnostics.An_unary_expression_with_the_0_operator_is_not_allowed_in_the_left_hand_side_of_an_exponentiation_expression_Consider_enclosing_the_expression_in_parentheses, tokenToString(unaryOperator)); } } diff --git a/src/compiler/program.ts b/src/compiler/program.ts index 75d32a6263a2d..979a38fdaa537 100644 --- a/src/compiler/program.ts +++ b/src/compiler/program.ts @@ -3782,7 +3782,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg existingFile, reason, Diagnostics.Conflicting_definitions_for_0_found_at_1_and_2_Consider_installing_a_specific_version_of_this_library_to_resolve_the_conflict, - [typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName, previousResolution.resolvedFileName] + [typeReferenceDirective, resolvedTypeReferenceDirective.resolvedFileName!, previousResolution.resolvedFileName!] ); } } @@ -3837,11 +3837,12 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg const unqualifiedLibName = removeSuffix(removePrefix(libName, "lib."), ".d.ts"); const suggestion = getSpellingSuggestion(unqualifiedLibName, libs, identity); const diagnostic = suggestion ? Diagnostics.Cannot_find_lib_definition_for_0_Did_you_mean_1 : Diagnostics.Cannot_find_lib_definition_for_0; + const args = suggestion ? [libName, suggestion] : [libName]; (fileProcessingDiagnostics ||= []).push({ kind: FilePreprocessingDiagnosticsKind.FilePreprocessingReferencedDiagnostic, reason: { kind: FileIncludeKind.LibReferenceDirective, file: file.path, index, }, diagnostic, - args: [libName, suggestion] + args, }); } }); @@ -4659,7 +4660,8 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg } function createDiagnosticForOptionName(message: DiagnosticMessage, option1: string, option2?: string, option3?: string) { - createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2, option3); + // TODO(jakebailey): this code makes assumptions about the format of the diagnostic messages. + createDiagnosticForOption(/*onKey*/ true, option1, option2, message, option1, option2!, option3!); } function createOptionValueDiagnostic(option1: string, message: DiagnosticMessage, ...args: DiagnosticArguments) { diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index 5045b0d5ce665..8a077dc81f40f 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -20,6 +20,7 @@ import { MapLike, parsePseudoBigInt, positionIsSynthesized, + PunctuationOrKeywordSyntaxKind, ScriptTarget, SourceFileLike, SyntaxKind, @@ -388,6 +389,10 @@ function makeReverseMap(source: Map): string[] { } const tokenStrings = makeReverseMap(textToToken); + +/** @internal */ +export function tokenToString(t: PunctuationOrKeywordSyntaxKind): string; +export function tokenToString(t: SyntaxKind): string | undefined; export function tokenToString(t: SyntaxKind): string | undefined { return tokenStrings[t]; } diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 39026c14736ca..bccf5f946c8b5 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -364,14 +364,14 @@ export function transformDeclarations(context: TransformationContext) { context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, getTextOfNode(errorInfo.typeName), - symbolAccessibilityResult.errorSymbolName, - symbolAccessibilityResult.errorModuleName)); + symbolAccessibilityResult.errorSymbolName!, + symbolAccessibilityResult.errorModuleName!)); } else { context.addDiagnostic(createDiagnosticForNode(symbolAccessibilityResult.errorNode || errorInfo.errorNode, errorInfo.diagnosticMessage, - symbolAccessibilityResult.errorSymbolName, - symbolAccessibilityResult.errorModuleName)); + symbolAccessibilityResult.errorSymbolName!, + symbolAccessibilityResult.errorModuleName!)); } return true; } diff --git a/src/compiler/tsbuildPublic.ts b/src/compiler/tsbuildPublic.ts index b09b9a7d67b36..b0c0a3ce0657f 100644 --- a/src/compiler/tsbuildPublic.ts +++ b/src/compiler/tsbuildPublic.ts @@ -2009,7 +2009,7 @@ function updateOutputTimestampsWorker( // For incremental projects, only buildinfo needs to be upto date with timestamp check // as we dont check output files for up-to-date ness if (!skipOutputs?.has(toPath(state, buildInfoPath))) { - if (!!state.options.verbose) reportStatus(state, verboseMessage, proj.options.configFilePath); + if (!!state.options.verbose) reportStatus(state, verboseMessage, proj.options.configFilePath!); state.host.setModifiedTime(buildInfoPath, now = getCurrentTime(state.host)); getBuildInfoCacheEntry(state, buildInfoPath, projectPath)!.modifiedTime = now; } @@ -2028,7 +2028,7 @@ function updateOutputTimestampsWorker( if (skipOutputs?.has(path)) continue; if (reportVerbose) { reportVerbose = false; - reportStatus(state, verboseMessage, proj.options.configFilePath); + reportStatus(state, verboseMessage, proj.options.configFilePath!); } host.setModifiedTime(file, now ||= getCurrentTime(state.host)); // Store output timestamps in a map because non incremental build will need to check them to determine up-to-dateness @@ -2058,7 +2058,7 @@ function getLatestChangedDtsTime(state: SolutionBuilde function updateOutputTimestamps(state: SolutionBuilderState, proj: ParsedCommandLine, resolvedPath: ResolvedConfigFilePath) { if (state.options.dry) { - return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath); + return reportStatus(state, Diagnostics.A_non_dry_build_would_update_timestamps_for_output_of_project_0, proj.options.configFilePath!); } updateOutputTimestampsWorker(state, proj, resolvedPath, Diagnostics.Updating_output_timestamps_of_project_0); state.projectStatus.set(resolvedPath, { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8599fb45b5417..cb4d880e35736 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -579,6 +579,9 @@ export type PunctuationSyntaxKind = | SyntaxKind.CaretEqualsToken ; +/** @internal */ +export type PunctuationOrKeywordSyntaxKind = PunctuationSyntaxKind | KeywordSyntaxKind; + export type KeywordSyntaxKind = | SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword @@ -6909,7 +6912,10 @@ export interface Diagnostic extends DiagnosticRelatedInformation { } /** @internal */ -export type DiagnosticArguments = (string | number | undefined)[]; +export type DiagnosticArguments = (string | number)[]; + +/** @internal */ +export type DiagnosticAndArguments = [message: DiagnosticMessage, ...args: DiagnosticArguments]; export interface DiagnosticRelatedInformation { category: DiagnosticCategory; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d256c57c2aff8..d1f5a69aea6fa 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -441,6 +441,8 @@ import { PropertyNameLiteral, PropertySignature, PseudoBigInt, + PunctuationOrKeywordSyntaxKind, + PunctuationSyntaxKind, QualifiedName, QuestionQuestionEqualsToken, ReadonlyCollection, @@ -4772,6 +4774,16 @@ export function isKeyword(token: SyntaxKind): token is KeywordSyntaxKind { return SyntaxKind.FirstKeyword <= token && token <= SyntaxKind.LastKeyword; } +/** @internal */ +export function isPunctuation(token: SyntaxKind): token is PunctuationSyntaxKind { + return SyntaxKind.FirstPunctuation <= token && token <= SyntaxKind.LastPunctuation; +} + +/** @internal */ +export function isKeywordOrPunctuation(token: SyntaxKind): token is PunctuationOrKeywordSyntaxKind { + return isKeyword(token) || isPunctuation(token); +} + /** @internal */ export function isContextualKeyword(token: SyntaxKind): boolean { return SyntaxKind.FirstContextualKeyword <= token && token <= SyntaxKind.LastContextualKeyword; diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 8c4d885d6ce4b..f321bf57a45f2 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -22,6 +22,7 @@ import { CustomTransformers, Debug, Diagnostic, + DiagnosticAndArguments, DiagnosticCategory, DiagnosticMessage, DiagnosticMessageChain, @@ -284,11 +285,13 @@ export function getErrorSummaryText( const firstFileReference = nonNilFiles[0] && prettyPathForFileError(nonNilFiles[0], host.getCurrentDirectory()); const d = errorCount === 1 ? + // TODO(jakebailey): this code has to be wrong; neither message take a second argument. Simpify. createCompilerDiagnostic( filesInError[0] !== undefined ? Diagnostics.Found_1_error_in_1 : Diagnostics.Found_1_error, errorCount, + // @ts-ignore-error TODO(jakebailey) firstFileReference) : createCompilerDiagnostic( distinctFileNamesWithLines.length === 0 ? @@ -297,6 +300,7 @@ export function getErrorSummaryText( Diagnostics.Found_0_errors_in_the_same_file_starting_at_Colon_1 : Diagnostics.Found_0_errors_in_1_files, errorCount, + // @ts-ignore-error TODO(jakebailey) distinctFileNamesWithLines.length === 1 ? firstFileReference : distinctFileNamesWithLines.length); const suffix = distinctFileNamesWithLines.length > 1 ? createTabularErrorsDisplay(nonNilFiles, host) : ""; @@ -489,7 +493,7 @@ export function fileIncludeReasonToDiagnostics(program: Program, reason: FileInc message, referenceText, toFileName(referenceLocation.file, fileNameConvertor), - referenceLocation.packageId && packageIdToString(referenceLocation.packageId) + (referenceLocation.packageId && packageIdToString(referenceLocation.packageId))! ); } switch (reason.kind) { @@ -527,29 +531,23 @@ export function fileIncludeReasonToDiagnostics(program: Program, reason: FileInc toFileName(referencedResolvedRef.sourceFile.fileName, fileNameConvertor), options.outFile ? "--outFile" : "--out", ); - case FileIncludeKind.AutomaticTypeDirectiveFile: - return chainDiagnosticMessages( - /*details*/ undefined, - options.types ? - reason.packageId ? - Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1 : - Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions : - reason.packageId ? - Diagnostics.Entry_point_for_implicit_type_library_0_with_packageId_1 : - Diagnostics.Entry_point_for_implicit_type_library_0, - reason.typeReference, - reason.packageId && packageIdToString(reason.packageId), - ); - case FileIncludeKind.LibFile: + case FileIncludeKind.AutomaticTypeDirectiveFile: { + const messageAndArgs: DiagnosticAndArguments = options.types ? + reason.packageId ? + [Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] : + [Diagnostics.Entry_point_of_type_library_0_specified_in_compilerOptions, reason.typeReference] : + reason.packageId ? + [Diagnostics.Entry_point_for_implicit_type_library_0_with_packageId_1, reason.typeReference, packageIdToString(reason.packageId)] : + [Diagnostics.Entry_point_for_implicit_type_library_0, reason.typeReference]; + + return chainDiagnosticMessages(/*details*/ undefined, ...messageAndArgs); + } + case FileIncludeKind.LibFile: { if (reason.index !== undefined) return chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Library_0_specified_in_compilerOptions, options.lib![reason.index]); const target = forEachEntry(targetOptionDeclaration.type, (value, key) => value === getEmitScriptTarget(options) ? key : undefined); - return chainDiagnosticMessages( - /*details*/ undefined, - target ? - Diagnostics.Default_library_for_target_0 : - Diagnostics.Default_library, - target, - ); + const messageAndArgs: DiagnosticAndArguments = target ? [Diagnostics.Default_library_for_target_0, target] : [Diagnostics.Default_library]; + return chainDiagnosticMessages(/*details*/ undefined, ...messageAndArgs); + } default: Debug.assertNever(reason); } diff --git a/src/services/codeFixProvider.ts b/src/services/codeFixProvider.ts index cf1594d7785cf..67dbdbc9a9280 100644 --- a/src/services/codeFixProvider.ts +++ b/src/services/codeFixProvider.ts @@ -13,7 +13,7 @@ import { createMultiMap, Debug, Diagnostic, - DiagnosticAndArguments, + DiagnosticOrDiagnosticAndArguments, diagnosticToString, DiagnosticWithLocation, FileTextChanges, @@ -28,17 +28,17 @@ const errorCodeToFixes = createMultiMap(); const fixIdToRegistration = new Map(); /** @internal */ -export function createCodeFixActionWithoutFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticAndArguments) { +export function createCodeFixActionWithoutFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, /*fixId*/ undefined, /*fixAllDescription*/ undefined); } /** @internal */ -export function createCodeFixAction(fixName: string, changes: FileTextChanges[], description: DiagnosticAndArguments, fixId: {}, fixAllDescription: DiagnosticAndArguments, command?: CodeActionCommand): CodeFixAction { +export function createCodeFixAction(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments, fixId: {}, fixAllDescription: DiagnosticOrDiagnosticAndArguments, command?: CodeActionCommand): CodeFixAction { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, diagnosticToString(fixAllDescription), command); } /** @internal */ -export function createCodeFixActionMaybeFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticAndArguments, fixId?: {}, fixAllDescription?: DiagnosticAndArguments, command?: CodeActionCommand) { +export function createCodeFixActionMaybeFixAll(fixName: string, changes: FileTextChanges[], description: DiagnosticOrDiagnosticAndArguments, fixId?: {}, fixAllDescription?: DiagnosticOrDiagnosticAndArguments, command?: CodeActionCommand) { return createCodeFixActionWorker(fixName, diagnosticToString(description), changes, fixId, fixAllDescription && diagnosticToString(fixAllDescription), command); } diff --git a/src/services/codefixes/fixImplicitThis.ts b/src/services/codefixes/fixImplicitThis.ts index c8f02aba81850..86c8adad40bd3 100644 --- a/src/services/codefixes/fixImplicitThis.ts +++ b/src/services/codefixes/fixImplicitThis.ts @@ -1,7 +1,7 @@ import { ANONYMOUS, Debug, - DiagnosticAndArguments, + DiagnosticOrDiagnosticAndArguments, Diagnostics, emptyArray, factory, @@ -30,7 +30,7 @@ registerCodeFix({ errorCodes, getCodeActions: function getCodeActionsToFixImplicitThis(context) { const { sourceFile, program, span } = context; - let diagnostic: DiagnosticAndArguments | undefined; + let diagnostic: DiagnosticOrDiagnosticAndArguments | undefined; const changes = textChanges.ChangeTracker.with(context, t => { diagnostic = doChange(t, sourceFile, span.start, program.getTypeChecker()); }); @@ -42,7 +42,7 @@ registerCodeFix({ }), }); -function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, checker: TypeChecker): DiagnosticAndArguments | undefined { +function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number, checker: TypeChecker): DiagnosticOrDiagnosticAndArguments | undefined { const token = getTokenAtPosition(sourceFile, pos); if (!isThis(token)) return undefined; diff --git a/src/services/codefixes/fixUnusedIdentifier.ts b/src/services/codefixes/fixUnusedIdentifier.ts index 881ce7478604b..4da1d6ce22d9c 100644 --- a/src/services/codefixes/fixUnusedIdentifier.ts +++ b/src/services/codefixes/fixUnusedIdentifier.ts @@ -5,8 +5,8 @@ import { CodeFixAction, CodeFixContext, Debug, - DiagnosticAndArguments, DiagnosticMessage, + DiagnosticOrDiagnosticAndArguments, Diagnostics, factory, FileTextChanges, @@ -220,7 +220,7 @@ function changeInferToUnknown(changes: textChanges.ChangeTracker, sourceFile: So changes.replaceNode(sourceFile, token.parent, factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword)); } -function createDeleteFix(changes: FileTextChanges[], diag: DiagnosticAndArguments): CodeFixAction { +function createDeleteFix(changes: FileTextChanges[], diag: DiagnosticOrDiagnosticAndArguments): CodeFixAction { return createCodeFixAction(fixName, changes, diag, fixIdDelete, Diagnostics.Delete_all_unused_declarations); } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index fe82e145ed8ca..90a3756f284ea 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -18,7 +18,7 @@ import { createMultiMap, createPackageJsonImportFilter, Debug, - DiagnosticAndArguments, + DiagnosticOrDiagnosticAndArguments, Diagnostics, DiagnosticWithLocation, emptyArray, @@ -1212,13 +1212,13 @@ function getExportEqualsImportKind(importingFile: SourceFile, compilerOptions: C } function codeActionForFix(context: textChanges.TextChangesContext, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, compilerOptions: CompilerOptions, preferences: UserPreferences): CodeFixAction { - let diag!: DiagnosticAndArguments; + let diag!: DiagnosticOrDiagnosticAndArguments; const changes = textChanges.ChangeTracker.with(context, tracker => { diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, includeSymbolNameInDescription, compilerOptions, preferences); }); return createCodeFixAction(importFixName, changes, diag, importFixId, Diagnostics.Add_all_missing_imports); } -function codeActionForFixWorker(changes: textChanges.ChangeTracker, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, compilerOptions: CompilerOptions, preferences: UserPreferences): DiagnosticAndArguments { +function codeActionForFixWorker(changes: textChanges.ChangeTracker, sourceFile: SourceFile, symbolName: string, fix: ImportFix, includeSymbolNameInDescription: boolean, compilerOptions: CompilerOptions, preferences: UserPreferences): DiagnosticOrDiagnosticAndArguments { const quotePreference = getQuotePreference(sourceFile, preferences); switch (fix.kind) { case ImportFixKind.UseNamespace: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 00446261547a4..fc411326dfcc4 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -42,6 +42,7 @@ import { defaultMaximumTruncationLength, DeleteExpression, Diagnostic, + DiagnosticAndArguments, DiagnosticMessage, DiagnosticWithLocation, directoryProbablyExists, @@ -2180,11 +2181,6 @@ export function isStringAndEmptyAnonymousObjectIntersection(type: Type) { (areIntersectedTypesAvoidingStringReduction(checker, types[0], types[1]) || areIntersectedTypesAvoidingStringReduction(checker, types[1], types[0])); } -/** @internal */ -export function isPunctuation(kind: SyntaxKind): boolean { - return SyntaxKind.FirstPunctuation <= kind && kind <= SyntaxKind.LastPunctuation; -} - /** @internal */ export function isInsideTemplateLiteral(node: TemplateLiteralToken, position: number, sourceFile: SourceFile): boolean { return isTemplateLiteralKind(node.kind) @@ -4058,9 +4054,9 @@ export function getNewLineKind(newLineCharacter: string): NewLineKind { } /** @internal */ -export type DiagnosticAndArguments = DiagnosticMessage | [DiagnosticMessage, string] | [DiagnosticMessage, string, string]; +export type DiagnosticOrDiagnosticAndArguments = DiagnosticMessage | DiagnosticAndArguments; /** @internal */ -export function diagnosticToString(diag: DiagnosticAndArguments): string { +export function diagnosticToString(diag: DiagnosticOrDiagnosticAndArguments): string { return isArray(diag) ? formatStringFromArgs(getLocaleSpecificMessage(diag[0]), diag.slice(1) as readonly string[]) : getLocaleSpecificMessage(diag); From 719e117e7eb88fdd46b954cb897790ced9cf50f1 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 10 Mar 2023 17:13:51 -0800 Subject: [PATCH 5/9] Fix message and code --- src/compiler/diagnosticMessages.json | 2 +- src/compiler/watch.ts | 30 +++++++++++----------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index f3c9c5d11cdf6..c18e503ea3bcf 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -5230,7 +5230,7 @@ "category": "Error", "code": 6258 }, - "Found 1 error in {1}": { + "Found 1 error in {0}": { "category": "Message", "code": 6259 }, diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index f321bf57a45f2..807779104e590 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -284,25 +284,19 @@ export function getErrorSummaryText( const firstFileReference = nonNilFiles[0] && prettyPathForFileError(nonNilFiles[0], host.getCurrentDirectory()); - const d = errorCount === 1 ? - // TODO(jakebailey): this code has to be wrong; neither message take a second argument. Simpify. - createCompilerDiagnostic( - filesInError[0] !== undefined ? - Diagnostics.Found_1_error_in_1 : - Diagnostics.Found_1_error, - errorCount, - // @ts-ignore-error TODO(jakebailey) - firstFileReference) : - createCompilerDiagnostic( - distinctFileNamesWithLines.length === 0 ? - Diagnostics.Found_0_errors : - distinctFileNamesWithLines.length === 1 ? - Diagnostics.Found_0_errors_in_the_same_file_starting_at_Colon_1 : - Diagnostics.Found_0_errors_in_1_files, - errorCount, - // @ts-ignore-error TODO(jakebailey) - distinctFileNamesWithLines.length === 1 ? firstFileReference : distinctFileNamesWithLines.length); + let messageAndArgs: DiagnosticAndArguments; + if (errorCount === 1) { + messageAndArgs = filesInError[0] !== undefined ? [Diagnostics.Found_1_error_in_0, firstFileReference!] : [Diagnostics.Found_1_error]; + } + else { + messageAndArgs = + distinctFileNamesWithLines.length === 0 ? [Diagnostics.Found_0_errors, errorCount] : + // TODO(jakebailey): grammer of "Found 1 errors" + distinctFileNamesWithLines.length === 1 ? [Diagnostics.Found_0_errors_in_the_same_file_starting_at_Colon_1, errorCount, firstFileReference!] : + [Diagnostics.Found_0_errors_in_1_files, errorCount, distinctFileNamesWithLines.length]; + } + const d = createCompilerDiagnostic(...messageAndArgs); const suffix = distinctFileNamesWithLines.length > 1 ? createTabularErrorsDisplay(nonNilFiles, host) : ""; return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}${suffix}`; } From 86ff1e9e7c51b1570d437727cfeca5e573529767 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 17 Mar 2023 16:16:18 -0700 Subject: [PATCH 6/9] Fix my TODO spelling --- src/compiler/watch.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 807779104e590..ef5715332db5f 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -291,7 +291,7 @@ export function getErrorSummaryText( else { messageAndArgs = distinctFileNamesWithLines.length === 0 ? [Diagnostics.Found_0_errors, errorCount] : - // TODO(jakebailey): grammer of "Found 1 errors" + // TODO(jakebailey): grammar of "Found 1 errors" is incorrect. distinctFileNamesWithLines.length === 1 ? [Diagnostics.Found_0_errors_in_the_same_file_starting_at_Colon_1, errorCount, firstFileReference!] : [Diagnostics.Found_0_errors_in_1_files, errorCount, distinctFileNamesWithLines.length]; } From a0bf2f17ff511dbbe87f4a71286bb5cb24323d46 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Fri, 17 Mar 2023 16:19:17 -0700 Subject: [PATCH 7/9] Improve cast in diagnosticToString --- src/services/utilities.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/utilities.ts b/src/services/utilities.ts index fc411326dfcc4..d118f336b66d4 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -43,6 +43,7 @@ import { DeleteExpression, Diagnostic, DiagnosticAndArguments, + DiagnosticArguments, DiagnosticMessage, DiagnosticWithLocation, directoryProbablyExists, @@ -4058,7 +4059,7 @@ export type DiagnosticOrDiagnosticAndArguments = DiagnosticMessage | DiagnosticA /** @internal */ export function diagnosticToString(diag: DiagnosticOrDiagnosticAndArguments): string { return isArray(diag) - ? formatStringFromArgs(getLocaleSpecificMessage(diag[0]), diag.slice(1) as readonly string[]) + ? formatStringFromArgs(getLocaleSpecificMessage(diag[0]), diag.slice(1) as DiagnosticArguments) : getLocaleSpecificMessage(diag); } From 5b63b22016c8116826b2dc5fef95d08d131f2e39 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 20 Mar 2023 11:24:48 -0700 Subject: [PATCH 8/9] Remove wrong todo; errorCount=1 is handled above --- src/compiler/watch.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index ef5715332db5f..916625460c259 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -291,7 +291,6 @@ export function getErrorSummaryText( else { messageAndArgs = distinctFileNamesWithLines.length === 0 ? [Diagnostics.Found_0_errors, errorCount] : - // TODO(jakebailey): grammar of "Found 1 errors" is incorrect. distinctFileNamesWithLines.length === 1 ? [Diagnostics.Found_0_errors_in_the_same_file_starting_at_Colon_1, errorCount, firstFileReference!] : [Diagnostics.Found_0_errors_in_1_files, errorCount, distinctFileNamesWithLines.length]; } From 9ec2f1439d76e9c5c225e6e924b9fa2a7de8249f Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 20 Mar 2023 12:20:42 -0700 Subject: [PATCH 9/9] Remove last arg0 any --- src/compiler/parser.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 6010461365aa7..d5b02a13d0b2b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -2495,10 +2495,10 @@ namespace Parser { return undefined; } - function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Token; - function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Node { + function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: string): Token; + function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: string): Node { return parseOptionalToken(t) || - createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)); + createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)!); } function parseExpectedTokenJSDoc(t: TKind): Token;