private Expression ParseLambdaHelperEnd(FunctionDefinition func, Expression expr, string whitespace, string colonWhiteSpace, List<string> commaWhiteSpace, bool ateTerminator) { // Pep 342 in Python 2.5 allows Yield Expressions, which can occur inside a Lambda body. // In this case, the lambda is a generator and will yield it's final result instead of just return it. Statement body; if (func.IsGenerator) { YieldExpression y = new YieldExpression(expr); y.SetLoc(expr.IndexSpan); body = new ExpressionStatement(y); } else { body = new ReturnStatement(expr); } body.SetLoc(expr.StartIndex, expr.EndIndex); FunctionDefinition func2 = PopFunction(); System.Diagnostics.Debug.Assert(func == func2); func.SetBody(body); func.EndIndex = GetEnd(); LambdaExpression ret = new LambdaExpression(func); func.SetLoc(func.IndexSpan); ret.SetLoc(func.IndexSpan); if (_verbatim) { AddPreceedingWhiteSpace(ret, whitespace); AddSecondPreceedingWhiteSpace(ret, colonWhiteSpace); AddListWhiteSpace(ret, commaWhiteSpace.ToArray()); if (!ateTerminator) { AddErrorIsIncompleteNode(ret); } } return ret; }
// funcdef: [decorators] 'def' NAME parameters ':' suite // parameters: '(' [varargslist] ')' // this gets called with "def" as the look-ahead private FunctionDefinition ParseFuncDef(bool isCoroutine) { string preWhitespace = null, afterAsyncWhitespace = null; var start = isCoroutine ? GetStart() : 0; if (isCoroutine) { preWhitespace = _tokenWhiteSpace; } Eat(TokenKind.KeywordDef); if (isCoroutine) { afterAsyncWhitespace = _tokenWhiteSpace; } else { preWhitespace = _tokenWhiteSpace; start = GetStart(); } var name = ReadName(); var nameExpr = MakeName(name); nameExpr.SetLoc(GetStart(), GetEnd()); string nameWhiteSpace = _tokenWhiteSpace; bool ateLeftParen = name.HasName && Eat(TokenKind.LeftParenthesis); string parenWhiteSpace = _tokenWhiteSpace; var lStart = GetStart(); var lEnd = GetEnd(); int grouping = _tokenizer.GroupingLevel; List<string> commaWhiteSpace = null; bool ateTerminator = false; Parameter[] parameters = ateLeftParen ? ParseVarArgsList(TokenKind.RightParenthesis, out commaWhiteSpace, out ateTerminator, true) : null; string closeParenWhiteSpace = _tokenWhiteSpace; FunctionDefinition ret; if (parameters == null) { // error in parameters ret = new FunctionDefinition(nameExpr, new Parameter[0]); ret.IsCoroutine = isCoroutine; if (_verbatim) { AddVerbatimName(name, ret); AddPreceedingWhiteSpace(ret, preWhitespace); if (afterAsyncWhitespace != null) { GetNodeAttributes(ret)[FunctionDefinition.WhitespaceAfterAsync] = afterAsyncWhitespace; } AddSecondPreceedingWhiteSpace(ret, nameWhiteSpace); AddThirdPreceedingWhiteSpace(ret, parenWhiteSpace); AddFourthPreceedingWhiteSpace(ret, closeParenWhiteSpace); if (!ateTerminator) { AddErrorMissingCloseGrouping(ret); } if (!ateLeftParen) { AddErrorIsIncompleteNode(ret); } } ret.SetLoc(start, lEnd); return ret; } string arrowWhiteSpace = null; Expression returnAnnotation = null; if (MaybeEat(TokenKind.Arrow)) { arrowWhiteSpace = _tokenWhiteSpace; returnAnnotation = ParseExpression(); } var rStart = GetStart(); var rEnd = GetEnd(); ret = new FunctionDefinition(nameExpr, parameters); AddVerbatimName(name, ret); PushFunction(ret); // set IsCoroutine before parsing the body to enable use of 'await' ret.IsCoroutine = isCoroutine; Statement body = ParseClassOrFuncBody(); FunctionDefinition ret2 = PopFunction(); System.Diagnostics.Debug.Assert(ret == ret2); ret.SetBody(body); ret.ReturnAnnotation = returnAnnotation; ret.HeaderIndex = rEnd; if (_verbatim) { AddPreceedingWhiteSpace(ret, preWhitespace); if (afterAsyncWhitespace != null) { GetNodeAttributes(ret)[FunctionDefinition.WhitespaceAfterAsync] = afterAsyncWhitespace; } AddSecondPreceedingWhiteSpace(ret, nameWhiteSpace); AddThirdPreceedingWhiteSpace(ret, parenWhiteSpace); AddFourthPreceedingWhiteSpace(ret, closeParenWhiteSpace); AddListWhiteSpace(ret, commaWhiteSpace.ToArray()); if (arrowWhiteSpace != null) { AddFifthPreceedingWhiteSpace(ret, arrowWhiteSpace); } if (!ateTerminator) { AddErrorMissingCloseGrouping(ret); } } ret.SetLoc(start, body.EndIndex); return ret; }