diff --git a/src/compiler.ts b/src/compiler.ts index 0a91a5246d..96de35973e 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1471,6 +1471,26 @@ export class Compiler extends DiagnosticEmitter { } } + // ensure the function hasn't duplicate parameters + var parameters = instance.prototype.functionTypeNode.parameters; + var numParameters = parameters.length; + if (numParameters >= 2) { + let visited = new Set(); + visited.add(parameters[0].name.text); + for (let i = 1; i < numParameters; i++) { + let paramIdentifier = parameters[i].name; + let paramName = paramIdentifier.text; + if (!visited.has(paramName)) { + visited.add(paramName); + } else { + this.error( + DiagnosticCode.Duplicate_identifier_0, + paramIdentifier.range, paramName + ); + } + } + } + instance.set(CommonFlags.COMPILED); var pendingElements = this.pendingElements; pendingElements.add(instance); diff --git a/src/parser.ts b/src/parser.ts index 31987d8bf6..9e9684a627 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -845,7 +845,9 @@ export class Parser extends DiagnosticEmitter { return null; } this.tryParseSignatureIsSignature = true; + if (!parameters) parameters = []; + return Node.createFunctionType( parameters, returnType, diff --git a/tests/compiler/function-expression.json b/tests/compiler/function-expression.json index 73d40f91f2..60507dccd4 100644 --- a/tests/compiler/function-expression.json +++ b/tests/compiler/function-expression.json @@ -1,4 +1,7 @@ { "asc_flags": [ + ], + "stderr": [ + "TS2300: Duplicate identifier 'a'" ] -} \ No newline at end of file +} diff --git a/tests/compiler/function-expression.ts b/tests/compiler/function-expression.ts index b69ec8ca86..ebdc2a7c8f 100644 --- a/tests/compiler/function-expression.ts +++ b/tests/compiler/function-expression.ts @@ -93,3 +93,7 @@ export function semanticallyAnonymous(): void { assert(fnDecl != exprDecl); } semanticallyAnonymous(); + +var duplicateParams = (a: i32, a: i32): void => {}; +// TS2300: Duplicate identifier 'a' +duplicateParams(1, 2); diff --git a/tests/compiler/function.json b/tests/compiler/function.json index 73d40f91f2..60507dccd4 100644 --- a/tests/compiler/function.json +++ b/tests/compiler/function.json @@ -1,4 +1,7 @@ { "asc_flags": [ + ], + "stderr": [ + "TS2300: Duplicate identifier 'a'" ] -} \ No newline at end of file +} diff --git a/tests/compiler/function.ts b/tests/compiler/function.ts index 9f74a3cd1a..bc57107fc8 100644 --- a/tests/compiler/function.ts +++ b/tests/compiler/function.ts @@ -39,3 +39,7 @@ iii(1, 2); jjj(1, 2); fff(1, 2); ddd(1, 2); + +function duplicateParams(a: i32, a: i32): void {} +// TS2300: Duplicate identifier 'a' +duplicateParams(1, 2); diff --git a/tests/parser/function-type.ts b/tests/parser/function-type.ts index 39f741eaf4..4c9a385fe5 100644 --- a/tests/parser/function-type.ts +++ b/tests/parser/function-type.ts @@ -1,4 +1,5 @@ var a: () => void; var b: (a: i32, b: i32) => void; var c: (a: i32, b: i32) => (a: i32, b: i32) => void; -var d: (a) => void; // TS1110 +var d: (a: i32, a: i32) => void; // NOTE: duplicates in type signatures doesn't in TypeScript +var e: (a) => void; // TS1110 diff --git a/tests/parser/function-type.ts.fixture.ts b/tests/parser/function-type.ts.fixture.ts index da4cc376b9..061e00711d 100644 --- a/tests/parser/function-type.ts.fixture.ts +++ b/tests/parser/function-type.ts.fixture.ts @@ -1,5 +1,6 @@ var a: () => void; var b: (a: i32, b: i32) => void; var c: (a: i32, b: i32) => (a: i32, b: i32) => void; -var d: (a) => void; -// ERROR 1110: "Type expected." in function-type.ts(4,10+0) +var d: (a: i32, a: i32) => void; +var e: (a) => void; +// ERROR 1110: "Type expected." in function-type.ts(5,10+0)