Skip to content

Basic support for generators as iterators #3031

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 46 commits into from
May 30, 2015
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
d47f3be
Make expression optional in YieldExpression
JsonFreeman Apr 22, 2015
8aa62b4
Improve yield context error message
JsonFreeman Apr 23, 2015
8dac1bf
Add some tests for yield*
JsonFreeman Apr 23, 2015
124fdb6
Allow yield expressions, and allow generators only in ES6 and higher
JsonFreeman Apr 22, 2015
d52c224
Disallow generators in an ambient context
JsonFreeman Apr 22, 2015
7f5a89a
Disallow * token on overload signatures
JsonFreeman Apr 23, 2015
be5557a
Formatting for generators
JsonFreeman Apr 23, 2015
5c48620
Move getIteratedType out of checkIteratedType
JsonFreeman Apr 24, 2015
a9e1d48
Simplify global generic type instantiation constructors
JsonFreeman Apr 25, 2015
65222d6
Check that generator return type is assignable from its IterableItera…
JsonFreeman Apr 25, 2015
eada0cd
Yield and yield* have type any
JsonFreeman Apr 27, 2015
21415af
Rebaseline error codes
JsonFreeman Apr 27, 2015
623507c
Disallow return expressions in a generator
JsonFreeman Apr 27, 2015
95bfd7c
Assignability checking for yield and yield* expressions
JsonFreeman Apr 28, 2015
44777b9
Contextual typing for yield expressions
JsonFreeman Apr 28, 2015
7fce775
Infer return types from yield and yield* expressions
JsonFreeman Apr 29, 2015
48a91b0
Fix some crashes in the checker
JsonFreeman Apr 29, 2015
d163f83
Accept baselines
JsonFreeman Apr 30, 2015
a9055b8
Fix contextual typing of object literal methods
JsonFreeman Apr 30, 2015
ba1ed04
Improve error for void generator
JsonFreeman Apr 30, 2015
9f01952
Add implicit any error for generator with no type annotation and no y…
JsonFreeman May 1, 2015
37f5e41
Remove error for having return expressions in a generator
JsonFreeman May 1, 2015
9133ab6
Adjust symbol baselines after rebase
JsonFreeman May 4, 2015
fbce0a5
Cache element types of iterable and iterator
JsonFreeman May 4, 2015
6183c81
Formatting for yield and yield* expressions
JsonFreeman May 4, 2015
28d9c6c
Add tests for generators
JsonFreeman May 4, 2015
5fcc4e9
Remove Generator interface from ES6 lib. We may need to add a better …
JsonFreeman May 4, 2015
ce9dc32
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 5, 2015
8c1f5da
Always call getReturnTypeOfSignature on a generator from checkFunctio…
JsonFreeman May 5, 2015
cf4ca1f
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 6, 2015
170bc5c
Initial PR feedback
JsonFreeman May 6, 2015
a14ec69
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 8, 2015
1a14725
Fix up two comments
JsonFreeman May 8, 2015
7c6eed7
Accept baselines after merge
JsonFreeman May 8, 2015
670ad05
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 11, 2015
cb198aa
Disallow yield expressions inside a class
JsonFreeman May 12, 2015
63d2313
Clarify error message
JsonFreeman May 12, 2015
7e798e9
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 12, 2015
6037780
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 19, 2015
67c88a2
Initial PR feedback
JsonFreeman May 20, 2015
0a49128
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 27, 2015
33f8e56
Fix CRLF issue
JsonFreeman May 28, 2015
faac853
Address PR feedback for generators
JsonFreeman May 30, 2015
059bb18
Merge branch 'master' of https://github.com/Microsoft/TypeScript into…
JsonFreeman May 30, 2015
1e7c774
Update symbol baselines because of things in lib.d.ts moving around
JsonFreeman May 30, 2015
171b385
Fix CRLF issue in baselines
JsonFreeman May 30, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
572 changes: 354 additions & 218 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

10 changes: 7 additions & 3 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ module ts {
Unterminated_template_literal: { code: 1160, category: DiagnosticCategory.Error, key: "Unterminated template literal." },
Unterminated_regular_expression_literal: { code: 1161, category: DiagnosticCategory.Error, key: "Unterminated regular expression literal." },
An_object_member_cannot_be_declared_optional: { code: 1162, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." },
yield_expression_must_be_contained_within_a_generator_declaration: { code: 1163, category: DiagnosticCategory.Error, key: "'yield' expression must be contained_within a generator declaration." },
A_yield_expression_is_only_allowed_in_a_generator_body: { code: 1163, category: DiagnosticCategory.Error, key: "A 'yield' expression is only allowed in a generator body." },
Computed_property_names_are_not_allowed_in_enums: { code: 1164, category: DiagnosticCategory.Error, key: "Computed property names are not allowed in enums." },
A_computed_property_name_in_an_ambient_context_must_directly_refer_to_a_built_in_symbol: { code: 1165, category: DiagnosticCategory.Error, key: "A computed property name in an ambient context must directly refer to a built-in symbol." },
A_computed_property_name_in_a_class_property_declaration_must_directly_refer_to_a_built_in_symbol: { code: 1166, category: DiagnosticCategory.Error, key: "A computed property name in a class property declaration must directly refer to a built-in symbol." },
Expand Down Expand Up @@ -174,6 +174,9 @@ module ts {
Type_expected_0_is_a_reserved_word_in_strict_mode: { code: 1215, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode" },
Type_expected_0_is_a_reserved_word_in_strict_mode_Class_definitions_are_automatically_in_strict_mode: { code: 1216, category: DiagnosticCategory.Error, key: "Type expected. '{0}' is a reserved word in strict mode. Class definitions are automatically in strict mode." },
Export_assignment_is_not_supported_when_module_flag_is_system: { code: 1218, category: DiagnosticCategory.Error, key: "Export assignment is not supported when '--module' flag is 'system'." },
Generators_are_only_available_when_targeting_ECMAScript_6_or_higher: { code: 1219, category: DiagnosticCategory.Error, key: "Generators are only available when targeting ECMAScript 6 or higher." },
Generators_are_not_allowed_in_an_ambient_context: { code: 1220, category: DiagnosticCategory.Error, key: "Generators are not allowed in an ambient context." },
An_overload_signature_cannot_be_declared_as_a_generator: { code: 1221, category: DiagnosticCategory.Error, key: "An overload signature cannot be declared as a generator." },
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
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." },
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
Expand Down Expand Up @@ -365,6 +368,8 @@ module ts {
A_rest_element_cannot_contain_a_binding_pattern: { code: 2501, category: DiagnosticCategory.Error, key: "A rest element cannot contain a binding pattern." },
_0_is_referenced_directly_or_indirectly_in_its_own_type_annotation: { code: 2502, category: DiagnosticCategory.Error, key: "'{0}' is referenced directly or indirectly in its own type annotation." },
Cannot_find_namespace_0: { code: 2503, category: DiagnosticCategory.Error, key: "Cannot find namespace '{0}'." },
No_best_common_type_exists_among_yield_expressions: { code: 2504, category: DiagnosticCategory.Error, key: "No best common type exists among yield expressions." },
A_generator_cannot_have_a_void_type_annotation: { code: 2505, 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}'." },
Expand Down Expand Up @@ -522,6 +527,7 @@ module ts {
_0_implicitly_has_type_any_because_it_is_does_not_have_a_type_annotation_and_is_referenced_directly_or_indirectly_in_its_own_initializer: { code: 7022, category: DiagnosticCategory.Error, key: "'{0}' implicitly has type 'any' because it is does not have a type annotation and is referenced directly or indirectly in its own initializer." },
_0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7023, category: DiagnosticCategory.Error, key: "'{0}' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
Function_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions: { code: 7024, category: DiagnosticCategory.Error, key: "Function implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions." },
Generator_implicitly_has_type_0_because_it_does_not_yield_any_values_Consider_supplying_a_return_type: { code: 7025, category: DiagnosticCategory.Error, key: "Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type." },
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
You_cannot_rename_elements_that_are_defined_in_the_standard_TypeScript_library: { code: 8001, category: DiagnosticCategory.Error, key: "You cannot rename elements that are defined in the standard TypeScript library." },
import_can_only_be_used_in_a_ts_file: { code: 8002, category: DiagnosticCategory.Error, key: "'import ... =' can only be used in a .ts file." },
Expand All @@ -540,8 +546,6 @@ module ts {
enum_declarations_can_only_be_used_in_a_ts_file: { code: 8015, category: DiagnosticCategory.Error, key: "'enum declarations' can only be used in a .ts file." },
type_assertion_expressions_can_only_be_used_in_a_ts_file: { code: 8016, category: DiagnosticCategory.Error, key: "'type assertion expressions' can only be used in a .ts file." },
decorators_can_only_be_used_in_a_ts_file: { code: 8017, category: DiagnosticCategory.Error, key: "'decorators' can only be used in a .ts file." },
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported." },
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported." },
Only_identifiers_Slashqualified_names_with_optional_type_arguments_are_currently_supported_in_a_class_extends_clauses: { code: 9002, category: DiagnosticCategory.Error, key: "Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses." },
class_expressions_are_not_currently_supported: { code: 9003, category: DiagnosticCategory.Error, key: "'class' expressions are not currently supported." },
class_declarations_are_only_supported_directly_inside_a_module_or_as_a_top_level_declaration: { code: 9004, category: DiagnosticCategory.Error, key: "'class' declarations are only supported directly inside a module or as a top level declaration." },
Expand Down
39 changes: 28 additions & 11 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@
"category": "Error",
"code": 1162
},
"'yield' expression must be contained_within a generator declaration.": {
"A 'yield' expression is only allowed in a generator body.": {
"category": "Error",
"code": 1163
},
Expand Down Expand Up @@ -682,8 +682,21 @@
"Export assignment is not supported when '--module' flag is 'system'.": {
"category": "Error",
"code": 1218
},
"Generators are only available when targeting ECMAScript 6 or higher.": {
"category": "Error",
"code": 1219
},
"Generators are not allowed in an ambient context.": {
"category": "Error",
"code": 1220
},
"An overload signature cannot be declared as a generator.": {
"category": "Error",
"code": 1221
},


"Duplicate identifier '{0}'.": {
"category": "Error",
"code": 2300
Expand Down Expand Up @@ -1439,15 +1452,23 @@
"A rest element cannot contain a binding pattern.": {
"category": "Error",
"code": 2501
},
},
"'{0}' is referenced directly or indirectly in its own type annotation.": {
"category": "Error",
"code": 2502
},
},
"Cannot find namespace '{0}'.": {
"category": "Error",
"code": 2503
},
"No best common type exists among yield expressions.": {
"category": "Error",
"code": 2504
},
"A generator cannot have a 'void' type annotation.": {
"category": "Error",
"code": 2505
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down Expand Up @@ -2080,6 +2101,10 @@
"category": "Error",
"code": 7024
},
"Generator implicitly has type '{0}' because it does not yield any values. Consider supplying a return type.": {
"category": "Error",
"code": 7025
},
"You cannot rename this element.": {
"category": "Error",
"code": 8000
Expand Down Expand Up @@ -2153,14 +2178,6 @@
"code": 8017
},

"'yield' expressions are not currently supported.": {
"category": "Error",
"code": 9000
},
"Generators are not currently supported.": {
"category": "Error",
"code": 9001
},
"Only identifiers/qualified-names with optional type arguments are currently supported in a class 'extends' clauses.": {
"category": "Error",
"code": 9002
Expand Down
15 changes: 14 additions & 1 deletion src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4010,7 +4010,20 @@ module ts {
property.name = name;
property.questionToken = questionToken;
property.type = parseTypeAnnotation();
property.initializer = allowInAnd(parseNonParameterInitializer);

// For initializers, we always want to allow 'in' expressions. For instance properties specifically,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I read this, I feel like the second sentence is going to be counter in some way to the first. It is not, and it confuses me as I expect there to be some contradiction. Maybe we can work on the wording offline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can remove the first sentence, or I can have the second sentence start on a new line. Would that help? The first sentence is not very interesting anyway.

// since they are evaluated inside the constructor, we do *not* want to parse yield expressions,
// so we specifically turn the yield context off. The grammar would look something like this:
//
// MemberVariableDeclaration[Yield]:
// AccessibilityModifier_opt PropertyName TypeAnnotation_opt Initialiser_opt[In];
// AccessibilityModifier_opt static_opt PropertyName TypeAnnotation_opt Initialiser_opt[In, ?Yield];
//
// The checker may still error in the static case to explicitly disallow the yield expression.
property.initializer = modifiers && modifiers.flags & NodeFlags.Static
? allowInAnd(parseNonParameterInitializer)
: doOutsideOfContext(ParserContextFlags.Yield | ParserContextFlags.DisallowIn, parseNonParameterInitializer);

parseSemicolon();
return finishNode(property);
}
Expand Down
9 changes: 8 additions & 1 deletion src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,7 +660,7 @@ module ts {

export interface YieldExpression extends Expression {
asteriskToken?: Node;
expression: Expression;
expression?: Expression;
}

export interface BinaryExpression extends Expression {
Expand Down Expand Up @@ -1543,6 +1543,13 @@ module ts {
numberIndexType: Type; // Numeric index type
}

/* @internal */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this actually work if another comment follows it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, how do I tell? Should I move it before?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seeing as @internal is a pseudo-modifier, yeah, let's move it a little closer.

// Just a place to cache element types of iterables and iterators
export interface IterableOrIteratorType extends ObjectType, UnionType {
iterableElementType?: Type;
iteratorElementType?: Type;
}

// Type parameters (TypeFlags.TypeParameter)
export interface TypeParameter extends Type {
constraint: Type; // Constraint
Expand Down
Loading