mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-30 15:15:38 -05:00
Fix location for duplicate function implementation errors
Use only the relevant declarations (by collecting them in the for loop), and use `declaration` if `getNameOfDeclaration` didn't work (useful for `export default` with anonymous functions). Fixes #39804. Also, use `nodeIsPresent` once, and a random `?.`.
This commit is contained in:
@@ -31280,6 +31280,7 @@ namespace ts {
|
||||
let duplicateFunctionDeclaration = false;
|
||||
let multipleConstructorImplementation = false;
|
||||
let hasNonAmbientClass = false;
|
||||
const functionDeclarations = [] as Declaration[];
|
||||
for (const current of declarations) {
|
||||
const node = <SignatureDeclaration | ClassDeclaration | ClassExpression>current;
|
||||
const inAmbientContext = node.flags & NodeFlags.Ambient;
|
||||
@@ -31300,13 +31301,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (node.kind === SyntaxKind.FunctionDeclaration || node.kind === SyntaxKind.MethodDeclaration || node.kind === SyntaxKind.MethodSignature || node.kind === SyntaxKind.Constructor) {
|
||||
functionDeclarations.push(node);
|
||||
const currentNodeFlags = getEffectiveDeclarationFlags(node, flagsToCheck);
|
||||
someNodeFlags |= currentNodeFlags;
|
||||
allNodeFlags &= currentNodeFlags;
|
||||
someHaveQuestionToken = someHaveQuestionToken || hasQuestionToken(node);
|
||||
allHaveQuestionToken = allHaveQuestionToken && hasQuestionToken(node);
|
||||
const bodyIsPresent = nodeIsPresent((node as FunctionLikeDeclaration).body);
|
||||
|
||||
if (nodeIsPresent((node as FunctionLikeDeclaration).body) && bodyDeclaration) {
|
||||
if (bodyIsPresent && bodyDeclaration) {
|
||||
if (isConstructor) {
|
||||
multipleConstructorImplementation = true;
|
||||
}
|
||||
@@ -31314,11 +31317,11 @@ namespace ts {
|
||||
duplicateFunctionDeclaration = true;
|
||||
}
|
||||
}
|
||||
else if (previousDeclaration && previousDeclaration.parent === node.parent && previousDeclaration.end !== node.pos) {
|
||||
else if (previousDeclaration?.parent === node.parent && previousDeclaration.end !== node.pos) {
|
||||
reportImplementationExpectedError(previousDeclaration);
|
||||
}
|
||||
|
||||
if (nodeIsPresent((node as FunctionLikeDeclaration).body)) {
|
||||
if (bodyIsPresent) {
|
||||
if (!bodyDeclaration) {
|
||||
bodyDeclaration = node as FunctionLikeDeclaration;
|
||||
}
|
||||
@@ -31336,14 +31339,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (multipleConstructorImplementation) {
|
||||
forEach(declarations, declaration => {
|
||||
forEach(functionDeclarations, declaration => {
|
||||
error(declaration, Diagnostics.Multiple_constructor_implementations_are_not_allowed);
|
||||
});
|
||||
}
|
||||
|
||||
if (duplicateFunctionDeclaration) {
|
||||
forEach(declarations, declaration => {
|
||||
error(getNameOfDeclaration(declaration), Diagnostics.Duplicate_function_implementation);
|
||||
forEach(functionDeclarations, declaration => {
|
||||
error(getNameOfDeclaration(declaration) || declaration, Diagnostics.Duplicate_function_implementation);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
tests/cases/compiler/exportDefaultInterfaceAndTwoFunctions.ts(2,1): error TS2393: Duplicate function implementation.
|
||||
tests/cases/compiler/exportDefaultInterfaceAndTwoFunctions.ts(3,1): error TS2393: Duplicate function implementation.
|
||||
|
||||
|
||||
==== tests/cases/compiler/exportDefaultInterfaceAndTwoFunctions.ts (2 errors) ====
|
||||
export default interface A { a: string; }
|
||||
export default function() { return 1; }
|
||||
~~~~~~
|
||||
!!! error TS2393: Duplicate function implementation.
|
||||
export default function() { return 2; }
|
||||
~~~~~~
|
||||
!!! error TS2393: Duplicate function implementation.
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//// [exportDefaultInterfaceAndTwoFunctions.ts]
|
||||
export default interface A { a: string; }
|
||||
export default function() { return 1; }
|
||||
export default function() { return 2; }
|
||||
|
||||
|
||||
//// [exportDefaultInterfaceAndTwoFunctions.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
function default_1() { return 1; }
|
||||
exports["default"] = default_1;
|
||||
function default_2() { return 2; }
|
||||
exports["default"] = default_2;
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/exportDefaultInterfaceAndTwoFunctions.ts ===
|
||||
export default interface A { a: string; }
|
||||
>A : Symbol(A, Decl(exportDefaultInterfaceAndTwoFunctions.ts, 0, 41), Decl(exportDefaultInterfaceAndTwoFunctions.ts, 1, 39), Decl(exportDefaultInterfaceAndTwoFunctions.ts, 0, 0))
|
||||
>a : Symbol(A.a, Decl(exportDefaultInterfaceAndTwoFunctions.ts, 0, 28))
|
||||
|
||||
export default function() { return 1; }
|
||||
export default function() { return 2; }
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
=== tests/cases/compiler/exportDefaultInterfaceAndTwoFunctions.ts ===
|
||||
export default interface A { a: string; }
|
||||
>a : string
|
||||
|
||||
export default function() { return 1; }
|
||||
>1 : 1
|
||||
|
||||
export default function() { return 2; }
|
||||
>2 : 2
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export default interface A { a: string; }
|
||||
export default function() { return 1; }
|
||||
export default function() { return 2; }
|
||||
Reference in New Issue
Block a user