Fixed regression in handling of yield statement with no expression.

This commit is contained in:
Eric Traut 2019-10-03 10:38:26 -07:00
parent e38ee60193
commit 574e0a5f1d
5 changed files with 29 additions and 14 deletions

View File

@ -221,7 +221,11 @@ export function printExpression(node: ExpressionNode, flags = PrintExpressionFla
}
return `(${ expressions.join(', ') })`;
} else if (node.nodeType === ParseNodeType.Yield) {
return 'yield ' + printExpression(node.expression, flags);
if (node.expression) {
return 'yield ' + printExpression(node.expression, flags);
} else {
return 'yield';
}
} else if (node.nodeType === ParseNodeType.YieldFrom) {
return 'yield from ' + printExpression(node.expression, flags);
} else if (node.nodeType === ParseNodeType.Ellipsis) {

View File

@ -828,9 +828,8 @@ export class TypeAnalyzer extends ParseTreeWalker {
}
visitYield(node: YieldExpressionNode) {
let yieldType = this._getTypeOfExpression(node.expression);
const typeSourceId = node.expression.id;
this._currentScope.getYieldType().addSource(yieldType, typeSourceId);
let yieldType = node.expression ? this._getTypeOfExpression(node.expression) : NoneType.create();
this._currentScope.getYieldType().addSource(yieldType, node.id);
// Wrap the yield type in an Iterator.
const iteratorType = ScopeUtils.getBuiltInType(this._currentScope, 'Iterator');
@ -847,8 +846,7 @@ export class TypeAnalyzer extends ParseTreeWalker {
visitYieldFrom(node: YieldFromExpressionNode) {
const yieldType = this._getTypeOfExpression(node.expression);
const typeSourceId = node.expression.id;
this._currentScope.getYieldType().addSource(yieldType, typeSourceId);
this._currentScope.getYieldType().addSource(yieldType, node.id);
this._validateYieldType(node, yieldType);
@ -2685,7 +2683,7 @@ export class TypeAnalyzer extends ParseTreeWalker {
this._addError(
`Expression of type '${ printType(yieldType) }' cannot be assigned ` +
`to yield type '${ printType(declaredYieldType) }'` + diagAddendum.getString(),
node.expression);
node.expression || node);
}
}
}

View File

@ -910,11 +910,11 @@ export namespace SliceExpressionNode {
export interface YieldExpressionNode extends ParseNodeBase {
readonly nodeType: ParseNodeType.Yield;
expression: ExpressionNode;
expression?: ExpressionNode;
}
export namespace YieldExpressionNode {
export function create(yieldToken: Token, expression: ExpressionNode) {
export function create(yieldToken: Token, expression?: ExpressionNode) {
const node: YieldExpressionNode = {
start: yieldToken.start,
length: yieldToken.length,
@ -923,7 +923,9 @@ export namespace YieldExpressionNode {
expression
};
extendRange(node, expression);
if (expression) {
extendRange(node, expression);
}
return node;
}

View File

@ -1223,10 +1223,13 @@ export class Parser {
return YieldFromExpressionNode.create(yieldToken, this._parseTestExpression());
}
const exprList = this._parseTestOrStarListAsExpression(
ErrorExpressionCategory.MissingExpression,
'Expected expression in yield statement');
this._reportConditionalErrorForStarTupleElement(exprList);
let exprList: ExpressionNode | undefined;
if (!this._isNextTokenNeverExpression()) {
exprList = this._parseTestOrStarListAsExpression(
ErrorExpressionCategory.MissingExpression,
'Expected expression in yield statement');
this._reportConditionalErrorForStarTupleElement(exprList);
}
return YieldExpressionNode.create(yieldToken, exprList);
}

View File

@ -70,3 +70,11 @@ s = generate()
# Verify that a call to a Generator method succeeds
s.close()
def generator6():
yield
def generator7() -> Generator[None]:
yield