/// <summary> /// Reads a lambda expression. /// </summary> /// <param name="parentReference">The parent code unit.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the expression.</returns> private LambdaExpression GetLambdaExpression(Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(parentReference, "parentReference"); Param.Ignore(unsafeCode); // Create an empty lambda expression. var lambdaExpression = new LambdaExpression(); var expressionReference = new Reference<ICodePart>(); // Check whether the next symbol is an opening parenthesis. Symbol symbol = this.GetNextSymbol(parentReference); Node<CsToken> previousTokenNode = this.tokens.Last; ICollection<Parameter> parameters = null; if (symbol.SymbolType == SymbolType.OpenParenthesis) { parameters = this.ParseAnonymousMethodParameterList(expressionReference, unsafeCode); } else { // Since the statement did not begin with an opening parenthesis, // it must begin with a single unknown symbol. if (symbol.SymbolType != SymbolType.Other) { throw new SyntaxException(this.document.SourceCode, symbol.LineNumber); } CsToken token = this.GetToken(CsTokenType.Other, SymbolType.Other, expressionReference); this.tokens.Add(token); // Add the single parameter. lambdaExpression.AddParameter(new Parameter( null, token.Text, expressionReference, ParameterModifiers.None, null, token.Location, new CsTokenList(this.tokens, this.tokens.Last, this.tokens.Last), token.Generated)); } // Get the lambda operator. this.tokens.Add(this.GetOperatorToken(OperatorType.Lambda, expressionReference)); // Get the body of the expression. This can either be an expression or a statement. // If it starts with an opening curly bracket, it's a statement, otherwise it's an expression. symbol = this.GetNextSymbol(expressionReference); if (symbol.SymbolType == SymbolType.OpenCurlyBracket) { lambdaExpression.AnonymousFunctionBody = this.GetNextStatement(expressionReference, unsafeCode); } else { lambdaExpression.AnonymousFunctionBody = this.GetNextExpression(ExpressionPrecedence.None, expressionReference, unsafeCode); } // Create the overall token list for the expression. Node<CsToken> firstNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next; lambdaExpression.Tokens = new CsTokenList(this.tokens, firstNode, this.tokens.Last); // Get the item's argument list if necessary. if (parameters != null && parameters.Count > 0) { lambdaExpression.AddParameters(parameters); } // Add a variable for each of the parameters. if (lambdaExpression.Parameters != null && lambdaExpression.Parameters.Count > 0) { // Add a variable for each of the parameters. foreach (Parameter parameter in lambdaExpression.Parameters) { lambdaExpression.Variables.Add(new Variable( parameter.Type, parameter.Name, VariableModifiers.None, parameter.Location, expressionReference, parameter.Generated)); } } // Return the expression. expressionReference.Target = lambdaExpression; return lambdaExpression; }
private LambdaExpression GetLambdaExpression(bool unsafeCode) { LambdaExpression expression = new LambdaExpression(); Symbol nextSymbol = this.GetNextSymbol(); Microsoft.StyleCop.Node<CsToken> last = this.tokens.Last; ICollection<Parameter> items = null; if (nextSymbol.SymbolType == SymbolType.OpenParenthesis) { items = this.ParseAnonymousMethodParameterList(unsafeCode); } else { if (nextSymbol.SymbolType != SymbolType.Other) { throw new SyntaxException(this.document.SourceCode, nextSymbol.LineNumber); } CsToken item = this.GetToken(CsTokenType.Other, SymbolType.Other); this.tokens.Add(item); expression.AddParameter(new Parameter(null, item.Text, ParameterModifiers.None, item.Location, new CsTokenList(this.tokens, this.tokens.Last, this.tokens.Last), item.Generated)); } this.tokens.Add(this.GetOperatorToken(OperatorType.Lambda)); if (this.GetNextSymbol().SymbolType == SymbolType.OpenCurlyBracket) { expression.AnonymousFunctionBody = this.GetNextStatement(unsafeCode); } else { expression.AnonymousFunctionBody = this.GetNextExpression(ExpressionPrecedence.None, unsafeCode); } Microsoft.StyleCop.Node<CsToken> firstItemNode = (last == null) ? this.tokens.First : last.Next; expression.Tokens = new CsTokenList(this.tokens, firstItemNode, this.tokens.Last); if ((items != null) && (items.Count > 0)) { expression.AddParameters(items); } if ((expression.Parameters != null) && (expression.Parameters.Count > 0)) { foreach (Parameter parameter in expression.Parameters) { expression.Variables.Add(new Variable(parameter.Type, parameter.Name, VariableModifiers.None, parameter.Location.StartPoint, parameter.Generated)); } } return expression; }