Skip to content
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

Report errors for using yield/generators right now. #1268

Merged
merged 2 commits into from
Nov 25, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/compiler/diagnosticInformationMap.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,5 +414,7 @@ module ts {
_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." },
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
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." },
};
}
8 changes: 8 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1654,5 +1654,13 @@
"You cannot rename this element.": {
"category": "Error",
"code": 8000
},
"'yield' expressions are not currently supported.": {
"category": "Error",
"code": 9000
},
"'generators' are not currently supported.": {
"category": "Error",
"code": 9001
}
}
87 changes: 45 additions & 42 deletions src/compiler/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1155,6 +1155,15 @@ module ts {
return false;
}

function parseOptionalToken(t: SyntaxKind): Node {
if (token === t) {
var node = createNode(t);
nextToken();
return finishNode(node);
}
return undefined;
}

function canParseSemicolon() {
// If there's a real semicolon, then we can always parse it out.
if (token === SyntaxKind.SemicolonToken) {
Expand Down Expand Up @@ -2202,10 +2211,7 @@ module ts {

if (!scanner.hasPrecedingLineBreak() &&
(token === SyntaxKind.AsteriskToken || isStartOfExpression())) {
if (parseOptional(SyntaxKind.AsteriskToken)) {
node.flags = NodeFlags.YieldStar;
}

node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
node.expression = parseAssignmentExpression();
return finishNode(node);
}
Expand Down Expand Up @@ -2255,7 +2261,7 @@ module ts {
}
else {
// If not, we're probably better off bailing out and returning a bogus function expression.
return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /* name */ undefined, sig, createMissingNode());
return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /*asteriskToken:*/ undefined, /*name:*/ undefined, sig, createMissingNode());
}
}

Expand Down Expand Up @@ -2395,7 +2401,7 @@ module ts {
body = parseAssignmentExpression();
}

return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /* name */ undefined, sig, body);
return makeFunctionExpression(SyntaxKind.ArrowFunction, pos, /*asteriskToken:*/ undefined, /*name:*/ undefined, sig, body);
}

function parseConditionalExpression(): Expression {
Expand Down Expand Up @@ -2731,26 +2737,23 @@ module ts {

function parsePropertyAssignment(): Declaration {
var nodePos = scanner.getStartPos();
var isGenerator = parseOptional(SyntaxKind.AsteriskToken);
var asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
var tokenIsIdentifier = isIdentifier();
var nameToken = token;
var propertyName = parsePropertyName();
var node: Declaration;
if (isGenerator || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
if (asteriskToken || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
node = <PropertyDeclaration>createNode(SyntaxKind.PropertyAssignment, nodePos);
node.name = propertyName;
if (isGenerator) {
node.flags |= NodeFlags.Generator;
}
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ isGenerator);
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken);

var body = parseFunctionBlock(isGenerator, /* ignoreMissingOpenBrace */ false);
var body = parseFunctionBlock(!!asteriskToken, /* ignoreMissingOpenBrace */ false);
// do not propagate property name as name for function expression
// for scenarios like
// var x = 1;
// var y = { x() { } }
// otherwise this will bring y.x into the scope of x which is incorrect
(<PropertyDeclaration>node).initializer = makeFunctionExpression(SyntaxKind.FunctionExpression, node.pos, undefined, sig, body);
(<PropertyDeclaration>node).initializer = makeFunctionExpression(SyntaxKind.FunctionExpression, node.pos, asteriskToken, undefined, sig, body);
return finishNode(node);
}

Expand Down Expand Up @@ -2808,24 +2811,21 @@ module ts {

var pos = getNodePos();
parseExpected(SyntaxKind.FunctionKeyword);
var isGenerator = parseOptional(SyntaxKind.AsteriskToken);
var name = isGenerator ? doInYieldContext(parseOptionalIdentifier) : parseOptionalIdentifier();
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ isGenerator);
var asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
var name = asteriskToken ? doInYieldContext(parseOptionalIdentifier) : parseOptionalIdentifier();
var sig = parseSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken);

var body = parseFunctionBlock(/*allowYield:*/ isGenerator, /* ignoreMissingOpenBrace */ false);
return makeFunctionExpression(SyntaxKind.FunctionExpression, pos, name, sig, body, isGenerator ? NodeFlags.Generator : undefined);
var body = parseFunctionBlock(/*allowYield:*/ !!asteriskToken, /* ignoreMissingOpenBrace */ false);
return makeFunctionExpression(SyntaxKind.FunctionExpression, pos, asteriskToken, name, sig, body);
}

function parseOptionalIdentifier() {
return isIdentifier() ? parseIdentifier() : undefined;
}

function makeFunctionExpression(kind: SyntaxKind, pos: number, name: Identifier, sig: ParsedSignature, body: Node, flags?: NodeFlags): FunctionExpression {
function makeFunctionExpression(kind: SyntaxKind, pos: number, asteriskToken: Node, name: Identifier, sig: ParsedSignature, body: Node): FunctionExpression {
var node = <FunctionExpression>createNode(kind, pos);
if (flags) {
node.flags = flags;
}

node.asteriskToken = asteriskToken;
node.name = name;
node.typeParameters = sig.typeParameters;
node.parameters = sig.parameters;
Expand Down Expand Up @@ -3292,14 +3292,10 @@ module ts {
var node = <FunctionLikeDeclaration>createNode(SyntaxKind.FunctionDeclaration, fullStart);
setModifiers(node, modifiers);
parseExpected(SyntaxKind.FunctionKeyword);
var isGenerator = parseOptional(SyntaxKind.AsteriskToken);
if (isGenerator) {
node.flags |= NodeFlags.Generator;
}

node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
node.name = parseIdentifier();
fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ isGenerator, node);
node.body = parseFunctionBlockOrSemicolon(isGenerator);
fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!node.asteriskToken, node);
node.body = parseFunctionBlockOrSemicolon(!!node.asteriskToken);
return finishNode(node);
}

Expand All @@ -3314,27 +3310,24 @@ module ts {

function parsePropertyMemberDeclaration(fullStart: number, modifiers: ModifiersArray): Declaration {
var flags = modifiers ? modifiers.flags : 0;
var isGenerator = parseOptional(SyntaxKind.AsteriskToken);
if (isGenerator) {
flags |= NodeFlags.Generator;
}

var asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
var name = parsePropertyName();
if (parseOptional(SyntaxKind.QuestionToken)) {
// Note: this is not legal as per the grammar. But we allow it in the parser and
// report an error in the grammar checker.
flags |= NodeFlags.QuestionMark;
}

if (isGenerator || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
if (asteriskToken || token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
var method = <MethodDeclaration>createNode(SyntaxKind.Method, fullStart);
setModifiers(method, modifiers);
if (flags) {
method.flags = flags;
}
method.asteriskToken = asteriskToken;
method.name = name;
fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ isGenerator, method);
method.body = parseFunctionBlockOrSemicolon(isGenerator);
fillSignature(SyntaxKind.CallSignature, SyntaxKind.ColonToken, /* returnTokenRequired */ false, /*yieldAndGeneratorParameterContext:*/ !!asteriskToken, method);
method.body = parseFunctionBlockOrSemicolon(!!asteriskToken);
return finishNode(method);
}
else {
Expand Down Expand Up @@ -4302,12 +4295,20 @@ module ts {
function checkFunctionDeclaration(node: FunctionLikeDeclaration) {
return checkAnyParsedSignature(node) ||
checkFunctionName(node.name) ||
checkForBodyInAmbientContext(node.body, /*isConstructor:*/ false);
checkForBodyInAmbientContext(node.body, /*isConstructor:*/ false) ||
checkForGenerator(node);
}

function checkForGenerator(node: FunctionLikeDeclaration) {
if (node.asteriskToken) {
return grammarErrorOnNode(node.asteriskToken, Diagnostics.generators_are_not_currently_supported);
}
}

function checkFunctionExpression(node: FunctionExpression) {
return checkAnyParsedSignature(node) ||
checkFunctionName(node.name);
checkFunctionName(node.name) ||
checkForGenerator(node);
}

function checkFunctionName(name: Node) {
Expand Down Expand Up @@ -4386,7 +4387,8 @@ module ts {
function checkMethod(node: MethodDeclaration) {
return checkAnyParsedSignature(node) ||
checkForBodyInAmbientContext(node.body, /*isConstructor:*/ false) ||
(node.parent.kind === SyntaxKind.ClassDeclaration && checkForInvalidQuestionMark(node, Diagnostics.A_class_member_cannot_be_declared_optional));
(node.parent.kind === SyntaxKind.ClassDeclaration && checkForInvalidQuestionMark(node, Diagnostics.A_class_member_cannot_be_declared_optional)) ||
checkForGenerator(node);
}

function checkForBodyInAmbientContext(body: Block | Expression, isConstructor: boolean): boolean {
Expand Down Expand Up @@ -4963,6 +4965,7 @@ module ts {
if (!(node.parserContextFlags & ParserContextFlags.Yield)) {
return grammarErrorOnFirstToken(node, Diagnostics.yield_expression_must_be_contained_within_a_generator_declaration);
}
return grammarErrorOnFirstToken(node, Diagnostics.yield_expressions_are_not_currently_supported);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,6 @@ module ts {
Let = 0x00000800, // Variable declaration
Const = 0x00001000, // Variable declaration
OctalLiteral = 0x00002000,
Generator = 0x00004000,
YieldStar = 0x00008000,

Modifier = Export | Ambient | Public | Private | Protected | Static,
AccessibilityModifier = Public | Private | Protected,
Expand Down Expand Up @@ -377,6 +375,7 @@ module ts {
* FunctionExpression
*/
export interface FunctionLikeDeclaration extends Declaration, ParsedSignature {
asteriskToken?: Node;
body?: Block | Expression;
}

Expand Down Expand Up @@ -442,6 +441,7 @@ module ts {
}

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,10): error TS9001: 'generators' are not currently supported.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts (1 errors) ====
function * foo(a = yield => yield) {
~
!!! error TS9001: 'generators' are not currently supported.
}
8 changes: 0 additions & 8 deletions tests/baselines/reference/FunctionDeclaration10_es6.js

This file was deleted.

8 changes: 0 additions & 8 deletions tests/baselines/reference/FunctionDeclaration10_es6.types

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration11_es6.ts(1,10): error TS9001: 'generators' are not currently supported.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration11_es6.ts (1 errors) ====
function * yield() {
~
!!! error TS9001: 'generators' are not currently supported.
}
7 changes: 0 additions & 7 deletions tests/baselines/reference/FunctionDeclaration11_es6.js

This file was deleted.

4 changes: 0 additions & 4 deletions tests/baselines/reference/FunctionDeclaration11_es6.types

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration13_es6.ts(1,10): error TS9001: 'generators' are not currently supported.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration13_es6.ts(3,11): error TS2304: Cannot find name 'yield'.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration13_es6.ts (1 errors) ====
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration13_es6.ts (2 errors) ====
function * foo() {
~
!!! error TS9001: 'generators' are not currently supported.
// Legal to use 'yield' in a type context.
var v: yield;
~~~~~
Expand Down
12 changes: 0 additions & 12 deletions tests/baselines/reference/FunctionDeclaration13_es6.js

This file was deleted.

8 changes: 8 additions & 0 deletions tests/baselines/reference/FunctionDeclaration1_es6.errors.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration1_es6.ts(1,10): error TS9001: 'generators' are not currently supported.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration1_es6.ts (1 errors) ====
function * foo() {
~
!!! error TS9001: 'generators' are not currently supported.
}
7 changes: 0 additions & 7 deletions tests/baselines/reference/FunctionDeclaration1_es6.js

This file was deleted.

4 changes: 0 additions & 4 deletions tests/baselines/reference/FunctionDeclaration1_es6.types

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,9): error TS9001: 'generators' are not currently supported.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,18): error TS2304: Cannot find name 'yield'.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts (1 errors) ====
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts (2 errors) ====
function*foo(a = yield) {
~
!!! error TS9001: 'generators' are not currently supported.
~~~~~
!!! error TS2304: Cannot find name 'yield'.
}
8 changes: 0 additions & 8 deletions tests/baselines/reference/FunctionDeclaration6_es6.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(1,9): error TS9001: 'generators' are not currently supported.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(3,20): error TS2304: Cannot find name 'yield'.


==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts (1 errors) ====
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts (2 errors) ====
function*bar() {
~
!!! error TS9001: 'generators' are not currently supported.
// 'yield' here is an identifier, and not a yield expression.
function*foo(a = yield) {
~~~~~
Expand Down
Loading