From ba1ed04ee207aec6250e7b41b094372f13a71815 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Thu, 30 Apr 2015 15:29:53 -0700 Subject: [PATCH] Improve error for void generator --- src/compiler/checker.ts | 23 +++++++++++-------- .../diagnosticInformationMap.generated.ts | 1 + src/compiler/diagnosticMessages.json | 4 ++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index be9047326c..4e4a6eab82 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8283,16 +8283,21 @@ module ts { if (node.type) { if (languageVersion >= ScriptTarget.ES6 && isSyntacticallyValidGenerator(node)) { let returnType = getTypeFromTypeNode(node.type); - let generatorElementType = getElementTypeFromIterableIterator(returnType, /*errorNode*/ undefined) || anyType; - let iterableIteratorInstantiation = createIterableIteratorType(generatorElementType); + if (returnType === voidType) { + error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation); + } + else { + let generatorElementType = getElementTypeFromIterableIterator(returnType, /*errorNode*/ undefined) || anyType; + let iterableIteratorInstantiation = createIterableIteratorType(generatorElementType); - // Naively, one could check that IterableIterator is assignable to the return type annotation. - // However, that would not catch the error in the following case. - // - // interface BadGenerator extends Iterable, Iterator { } - // function* g(): BadGenerator { } // Iterable and Iterator have different types! - // - checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + // Naively, one could check that IterableIterator is assignable to the return type annotation. + // However, that would not catch the error in the following case. + // + // interface BadGenerator extends Iterable, Iterator { } + // function* g(): BadGenerator { } // Iterable and Iterator have different types! + // + checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type); + } } } } diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 9c059aa248..05a963bd69 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -368,6 +368,7 @@ module ts { A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." }, A_return_statement_cannot_specify_a_value_in_a_generator_function: { code: 2502, category: DiagnosticCategory.Error, key: "A return statement cannot specify a value in a generator function." }, No_best_common_type_exists_among_yield_expressions: { code: 2503, category: DiagnosticCategory.Error, key: "No best common type exists among yield expressions." }, + A_generator_cannot_have_a_void_type_annotation: { code: 2504, category: DiagnosticCategory.Error, key: "A generator cannot have a 'void' type annotation." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: { code: 4004, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported interface has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 1a4d157b92..5539176406 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1461,6 +1461,10 @@ "category": "Error", "code": 2503 }, + "A generator cannot have a 'void' type annotation.": { + "category": "Error", + "code": 2504 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error",