Skip to content

Commit c2f46c3

Browse files
Merge pull request #4886 from Microsoft/diagnosticDuplicateCodes
Fix duplicate codes in diagnostics
2 parents c5a85c7 + 962ba82 commit c2f46c3

17 files changed

+211
-188
lines changed

scripts/processDiagnosticMessages.ts

+36-12
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,6 @@ interface InputDiagnosticMessageTable {
1010
[msg: string]: DiagnosticDetails;
1111
}
1212

13-
interface IIndexable<V> {
14-
[key: string]: V;
15-
}
16-
1713
function main(): void {
1814
var sys = ts.sys;
1915
if (sys.args.length < 1) {
@@ -25,21 +21,49 @@ function main(): void {
2521
var inputFilePath = sys.args[0].replace(/\\/g, "/");
2622
var inputStr = sys.readFile(inputFilePath);
2723

28-
var diagnosticMesages: InputDiagnosticMessageTable = JSON.parse(inputStr);
24+
var diagnosticMessages: InputDiagnosticMessageTable = JSON.parse(inputStr);
2925

30-
var names = Utilities.getObjectKeys(diagnosticMesages);
26+
var names = Utilities.getObjectKeys(diagnosticMessages);
3127
var nameMap = buildUniqueNameMap(names);
3228

33-
var infoFileOutput = buildInfoFileOutput(diagnosticMesages, nameMap);
34-
29+
var infoFileOutput = buildInfoFileOutput(diagnosticMessages, nameMap);
30+
checkForUniqueCodes(names, diagnosticMessages);
31+
3532
// TODO: Fix path joining
3633
var inputDirectory = inputFilePath.substr(0,inputFilePath.lastIndexOf("/"));
3734
var fileOutputPath = inputDirectory + "/diagnosticInformationMap.generated.ts";
3835
sys.writeFile(fileOutputPath, infoFileOutput);
3936
}
4037

41-
function buildUniqueNameMap(names: string[]): IIndexable<string> {
42-
var nameMap: IIndexable<string> = {};
38+
function checkForUniqueCodes(messages: string[], diagnosticTable: InputDiagnosticMessageTable) {
39+
const originalMessageForCode: string[] = [];
40+
let numConflicts = 0;
41+
42+
for (const currentMessage of messages) {
43+
const code = diagnosticTable[currentMessage].code;
44+
45+
if (code in originalMessageForCode) {
46+
const originalMessage = originalMessageForCode[code];
47+
ts.sys.write("\x1b[91m"); // High intensity red.
48+
ts.sys.write("Error");
49+
ts.sys.write("\x1b[0m"); // Reset formatting.
50+
ts.sys.write(`: Diagnostic code '${code}' conflicts between "${originalMessage}" and "${currentMessage}".`);
51+
ts.sys.write(ts.sys.newLine + ts.sys.newLine);
52+
53+
numConflicts++;
54+
}
55+
else {
56+
originalMessageForCode[code] = currentMessage;
57+
}
58+
}
59+
60+
if (numConflicts > 0) {
61+
throw new Error(`Found ${numConflicts} conflict(s) in diagnostic codes.`);
62+
}
63+
}
64+
65+
function buildUniqueNameMap(names: string[]): ts.Map<string> {
66+
var nameMap: ts.Map<string> = {};
4367

4468
var uniqueNames = NameGenerator.ensureUniqueness(names, /* isCaseSensitive */ false, /* isFixed */ undefined);
4569

@@ -50,7 +74,7 @@ function buildUniqueNameMap(names: string[]): IIndexable<string> {
5074
return nameMap;
5175
}
5276

53-
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: IIndexable<string>): string {
77+
function buildInfoFileOutput(messageTable: InputDiagnosticMessageTable, nameMap: ts.Map<string>): string {
5478
var result =
5579
'// <auto-generated />\r\n' +
5680
'/// <reference path="types.ts" />\r\n' +
@@ -172,7 +196,7 @@ module Utilities {
172196
}
173197

174198
// Like Object.keys
175-
export function getObjectKeys(obj: any): string[]{
199+
export function getObjectKeys(obj: any): string[] {
176200
var result: string[] = [];
177201

178202
for (var name in obj) {

src/compiler/diagnosticInformationMap.generated.ts

+6-6
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ namespace ts {
140140
Property_destructuring_pattern_expected: { code: 1180, category: DiagnosticCategory.Error, key: "Property destructuring pattern expected." },
141141
Array_element_destructuring_pattern_expected: { code: 1181, category: DiagnosticCategory.Error, key: "Array element destructuring pattern expected." },
142142
A_destructuring_declaration_must_have_an_initializer: { code: 1182, category: DiagnosticCategory.Error, key: "A destructuring declaration must have an initializer." },
143-
An_implementation_cannot_be_declared_in_ambient_contexts: { code: 1184, category: DiagnosticCategory.Error, key: "An implementation cannot be declared in ambient contexts." },
143+
An_implementation_cannot_be_declared_in_ambient_contexts: { code: 1183, category: DiagnosticCategory.Error, key: "An implementation cannot be declared in ambient contexts." },
144144
Modifiers_cannot_appear_here: { code: 1184, category: DiagnosticCategory.Error, key: "Modifiers cannot appear here." },
145145
Merge_conflict_marker_encountered: { code: 1185, category: DiagnosticCategory.Error, key: "Merge conflict marker encountered." },
146146
A_rest_element_cannot_have_an_initializer: { code: 1186, category: DiagnosticCategory.Error, key: "A rest element cannot have an initializer." },
@@ -190,10 +190,6 @@ namespace ts {
190190
An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: DiagnosticCategory.Error, key: "An export declaration can only be used in a module." },
191191
An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: DiagnosticCategory.Error, key: "An ambient module declaration is only allowed at the top level in a file." },
192192
A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: { code: 1235, category: DiagnosticCategory.Error, key: "A namespace declaration is only allowed in a namespace or module." },
193-
Experimental_support_for_async_functions_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalAsyncFunctions_to_remove_this_warning: { code: 1236, category: DiagnosticCategory.Error, key: "Experimental support for async functions is a feature that is subject to change in a future release. Specify '--experimentalAsyncFunctions' to remove this warning." },
194-
with_statements_are_not_allowed_in_an_async_function_block: { code: 1300, category: DiagnosticCategory.Error, key: "'with' statements are not allowed in an async function block." },
195-
await_expression_is_only_allowed_within_an_async_function: { code: 1308, category: DiagnosticCategory.Error, key: "'await' expression is only allowed within an async function." },
196-
Async_functions_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1311, category: DiagnosticCategory.Error, key: "Async functions are only available when targeting ECMAScript 6 and higher." },
197193
The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: { code: 1236, category: DiagnosticCategory.Error, key: "The return type of a property decorator function must be either 'void' or 'any'." },
198194
The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: { code: 1237, category: DiagnosticCategory.Error, key: "The return type of a parameter decorator function must be either 'void' or 'any'." },
199195
Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: { code: 1238, category: DiagnosticCategory.Error, key: "Unable to resolve signature of class decorator when called as an expression." },
@@ -204,6 +200,10 @@ namespace ts {
204200
_0_modifier_cannot_be_used_with_1_modifier: { code: 1243, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used with '{1}' modifier." },
205201
Abstract_methods_can_only_appear_within_an_abstract_class: { code: 1244, category: DiagnosticCategory.Error, key: "Abstract methods can only appear within an abstract class." },
206202
Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: { code: 1245, category: DiagnosticCategory.Error, key: "Method '{0}' cannot have an implementation because it is marked abstract." },
203+
Experimental_support_for_async_functions_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalAsyncFunctions_to_remove_this_warning: { code: 1246, category: DiagnosticCategory.Error, key: "Experimental support for async functions is a feature that is subject to change in a future release. Specify '--experimentalAsyncFunctions' to remove this warning." },
204+
with_statements_are_not_allowed_in_an_async_function_block: { code: 1300, category: DiagnosticCategory.Error, key: "'with' statements are not allowed in an async function block." },
205+
await_expression_is_only_allowed_within_an_async_function: { code: 1308, category: DiagnosticCategory.Error, key: "'await' expression is only allowed within an async function." },
206+
Async_functions_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1311, category: DiagnosticCategory.Error, key: "Async functions are only available when targeting ECMAScript 6 and higher." },
207207
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
208208
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
209209
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
@@ -516,7 +516,7 @@ namespace ts {
516516
Option_inlineSources_can_only_be_used_when_either_option_inlineSourceMap_or_option_sourceMap_is_provided: { code: 5051, category: DiagnosticCategory.Error, key: "Option 'inlineSources' can only be used when either option '--inlineSourceMap' or option '--sourceMap' is provided." },
517517
Option_0_cannot_be_specified_without_specifying_option_1: { code: 5052, category: DiagnosticCategory.Error, key: "Option '{0}' cannot be specified without specifying option '{1}'." },
518518
Option_0_cannot_be_specified_with_option_1: { code: 5053, category: DiagnosticCategory.Error, key: "Option '{0}' cannot be specified with option '{1}'." },
519-
A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5053, category: DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." },
519+
A_tsconfig_json_file_is_already_defined_at_Colon_0: { code: 5054, category: DiagnosticCategory.Error, key: "A 'tsconfig.json' file is already defined at: '{0}'." },
520520
Concatenate_and_emit_output_to_single_file: { code: 6001, category: DiagnosticCategory.Message, key: "Concatenate and emit output to single file." },
521521
Generates_corresponding_d_ts_file: { code: 6002, category: DiagnosticCategory.Message, key: "Generates corresponding '.d.ts' file." },
522522
Specifies_the_location_where_debugger_should_locate_map_files_instead_of_generated_locations: { code: 6003, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate map files instead of generated locations." },

src/compiler/diagnosticMessages.json

+23-24
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,7 @@
549549
},
550550
"An implementation cannot be declared in ambient contexts.": {
551551
"category": "Error",
552-
"code": 1184
552+
"code": 1183
553553
},
554554
"Modifiers cannot appear here.": {
555555
"category": "Error",
@@ -747,24 +747,6 @@
747747
"category": "Error",
748748
"code": 1235
749749
},
750-
"Experimental support for async functions is a feature that is subject to change in a future release. Specify '--experimentalAsyncFunctions' to remove this warning.": {
751-
"category": "Error",
752-
"code": 1236
753-
},
754-
755-
756-
"'with' statements are not allowed in an async function block.": {
757-
"category": "Error",
758-
"code": 1300
759-
},
760-
"'await' expression is only allowed within an async function.": {
761-
"category": "Error",
762-
"code": 1308
763-
},
764-
"Async functions are only available when targeting ECMAScript 6 and higher.": {
765-
"category": "Error",
766-
"code": 1311
767-
},
768750
"The return type of a property decorator function must be either 'void' or 'any'.": {
769751
"category": "Error",
770752
"code": 1236
@@ -805,6 +787,23 @@
805787
"category": "Error",
806788
"code": 1245
807789
},
790+
"Experimental support for async functions is a feature that is subject to change in a future release. Specify '--experimentalAsyncFunctions' to remove this warning.": {
791+
"category": "Error",
792+
"code": 1246
793+
},
794+
795+
"'with' statements are not allowed in an async function block.": {
796+
"category": "Error",
797+
"code": 1300
798+
},
799+
"'await' expression is only allowed within an async function.": {
800+
"category": "Error",
801+
"code": 1308
802+
},
803+
"Async functions are only available when targeting ECMAScript 6 and higher.": {
804+
"category": "Error",
805+
"code": 1311
806+
},
808807
"Duplicate identifier '{0}'.": {
809808
"category": "Error",
810809
"code": 2300
@@ -1700,23 +1699,23 @@
17001699
"Merged declaration '{0}' cannot include a default export declaration. Consider adding a separate 'export default {0}' declaration instead.": {
17011700
"category": "Error",
17021701
"code": 2652
1703-
},
1702+
},
17041703
"Non-abstract class expression does not implement inherited abstract member '{0}' from class '{1}'.": {
17051704
"category": "Error",
17061705
"code": 2653
1707-
},
1706+
},
17081707
"Exported external package typings file cannot contain tripleslash references. Please contact the package author to update the package definition.": {
17091708
"category": "Error",
17101709
"code": 2654
17111710
},
17121711
"Exported external package typings can only be in '.d.ts' files. Please contact the package author to update the package definition.": {
17131712
"category": "Error",
17141713
"code": 2655
1715-
},
1714+
},
17161715
"Exported external package typings file '{0}' is not a module. Please contact the package author to update the package definition.": {
17171716
"category": "Error",
17181717
"code": 2656
1719-
},
1718+
},
17201719
"Import declaration '{0}' is using private name '{1}'.": {
17211720
"category": "Error",
17221721
"code": 4000
@@ -2055,7 +2054,7 @@
20552054
},
20562055
"A 'tsconfig.json' file is already defined at: '{0}'.": {
20572056
"category": "Error",
2058-
"code": 5053
2057+
"code": 5054
20592058
},
20602059

20612060
"Concatenate and emit output to single file.": {

tests/baselines/reference/ambientErrors.errors.txt

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
tests/cases/conformance/ambient/ambientErrors.ts(2,15): error TS1039: Initializers are not allowed in ambient contexts.
22
tests/cases/conformance/ambient/ambientErrors.ts(6,18): error TS2382: Specialized overload signature is not assignable to any non-specialized signature.
33
tests/cases/conformance/ambient/ambientErrors.ts(17,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
4-
tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1184: An implementation cannot be declared in ambient contexts.
4+
tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1183: An implementation cannot be declared in ambient contexts.
55
tests/cases/conformance/ambient/ambientErrors.ts(24,5): error TS1066: Ambient enum elements can only have integer literal initializers.
66
tests/cases/conformance/ambient/ambientErrors.ts(29,5): error TS1066: Ambient enum elements can only have integer literal initializers.
77
tests/cases/conformance/ambient/ambientErrors.ts(34,11): error TS1039: Initializers are not allowed in ambient contexts.
8-
tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1184: An implementation cannot be declared in ambient contexts.
8+
tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1183: An implementation cannot be declared in ambient contexts.
99
tests/cases/conformance/ambient/ambientErrors.ts(37,20): error TS1039: Initializers are not allowed in ambient contexts.
1010
tests/cases/conformance/ambient/ambientErrors.ts(38,13): error TS1039: Initializers are not allowed in ambient contexts.
11-
tests/cases/conformance/ambient/ambientErrors.ts(39,23): error TS1184: An implementation cannot be declared in ambient contexts.
12-
tests/cases/conformance/ambient/ambientErrors.ts(40,14): error TS1184: An implementation cannot be declared in ambient contexts.
13-
tests/cases/conformance/ambient/ambientErrors.ts(41,22): error TS1184: An implementation cannot be declared in ambient contexts.
11+
tests/cases/conformance/ambient/ambientErrors.ts(39,23): error TS1183: An implementation cannot be declared in ambient contexts.
12+
tests/cases/conformance/ambient/ambientErrors.ts(40,14): error TS1183: An implementation cannot be declared in ambient contexts.
13+
tests/cases/conformance/ambient/ambientErrors.ts(41,22): error TS1183: An implementation cannot be declared in ambient contexts.
1414
tests/cases/conformance/ambient/ambientErrors.ts(47,20): error TS2435: Ambient modules cannot be nested in other modules.
1515
tests/cases/conformance/ambient/ambientErrors.ts(51,16): error TS2436: Ambient module declaration cannot specify relative module name.
1616
tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export assignment cannot be used in a module with other exported elements.
@@ -44,7 +44,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
4444
// Ambient function with function body
4545
declare function fn4() { };
4646
~
47-
!!! error TS1184: An implementation cannot be declared in ambient contexts.
47+
!!! error TS1183: An implementation cannot be declared in ambient contexts.
4848

4949
// Ambient enum with non - integer literal constant member
5050
declare enum E1 {
@@ -67,7 +67,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
6767
!!! error TS1039: Initializers are not allowed in ambient contexts.
6868
function fn() { }
6969
~
70-
!!! error TS1184: An implementation cannot be declared in ambient contexts.
70+
!!! error TS1183: An implementation cannot be declared in ambient contexts.
7171
class C {
7272
static x = 3;
7373
~
@@ -77,13 +77,13 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
7777
!!! error TS1039: Initializers are not allowed in ambient contexts.
7878
constructor() { }
7979
~
80-
!!! error TS1184: An implementation cannot be declared in ambient contexts.
80+
!!! error TS1183: An implementation cannot be declared in ambient contexts.
8181
fn() { }
8282
~
83-
!!! error TS1184: An implementation cannot be declared in ambient contexts.
83+
!!! error TS1183: An implementation cannot be declared in ambient contexts.
8484
static sfn() { }
8585
~
86-
!!! error TS1184: An implementation cannot be declared in ambient contexts.
86+
!!! error TS1183: An implementation cannot be declared in ambient contexts.
8787
}
8888
}
8989

tests/baselines/reference/classAbstractDeclarations.d.errors.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,5): error TS1242: 'abstract' modifier can only appear on a class or method declaration.
2-
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,28): error TS1184: An implementation cannot be declared in ambient contexts.
2+
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(2,28): error TS1183: An implementation cannot be declared in ambient contexts.
33
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(11,15): error TS2515: Non-abstract class 'CC' does not implement inherited abstract member 'foo' from class 'AA'.
44
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(13,15): error TS2515: Non-abstract class 'DD' does not implement inherited abstract member 'foo' from class 'BB'.
55
tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractDeclarations.d.ts(17,15): error TS2515: Non-abstract class 'FF' does not implement inherited abstract member 'foo' from class 'CC'.
@@ -11,7 +11,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
1111
~~~~~~~~
1212
!!! error TS1242: 'abstract' modifier can only appear on a class or method declaration.
1313
~
14-
!!! error TS1184: An implementation cannot be declared in ambient contexts.
14+
!!! error TS1183: An implementation cannot be declared in ambient contexts.
1515
}
1616

1717
declare abstract class AA {

0 commit comments

Comments
 (0)