internal void AddParameter(Parameter parameter) { if (this.parameters == null) { this.parameters = new List<Parameter>(); } this.parameters.Add(parameter); }
/// <summary> /// Adds a parameter to the expression. /// </summary> /// <param name="parameter">The parameter to add.</param> internal void AddParameter(Parameter parameter) { Param.AssertNotNull(parameter, "parameter"); if (this.parameters == null) { this.parameters = new List<Parameter>(); } this.parameters.Add(parameter); }
/// <summary> /// Fills in the details of the set accessor. /// </summary> /// <param name="parent">The parent of the accessor.</param> private void FillSetAccessorDetails(CsElement parent) { Param.AssertNotNull(parent, "parent"); var accessorReference = new Reference<ICodePart>(this); Property property = parent as Property; if (property != null) { // Set accessors on properties do not have a return type but have an // implied input parameter. this.returnType = CreateVoidTypeToken(accessorReference); this.parameters = new Parameter[] { new Parameter( property.ReturnType, "value", accessorReference, ParameterModifiers.None, null, CodeLocation.Empty, null, property.ReturnType.Generated) }; } else { // Set accessors on indexers do not have a return type but, but have the input // parameters of the parent indexer. Indexer indexer = (Indexer)parent as Indexer; this.returnType = CreateVoidTypeToken(accessorReference); Parameter[] tempParameters = new Parameter[indexer.Parameters.Count + 1]; int i = 0; foreach (Parameter parameter in indexer.Parameters) { tempParameters[i++] = parameter; } // Add the implicit value parameter since this is a set accessor. tempParameters[i] = new Parameter( indexer.ReturnType, "value", accessorReference, ParameterModifiers.None, null, CodeLocation.Empty, null, indexer.ReturnType.Generated); this.parameters = tempParameters; } }
/// <summary> /// Parses an element's parameter list. /// </summary> /// <param name="elementReference">A reference to the element being created.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="openingBracketType">The type of the bracket which opens the parameter list.</param> /// <param name="staticMethod">Indicates whether the parameters are part of a static method.</param> /// <returns>Returns the collection of parameters.</returns> private IList<Parameter> ParseParameterList( Reference<ICodePart> elementReference, bool unsafeCode, SymbolType openingBracketType, bool staticMethod) { Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); Param.Ignore(openingBracketType); Param.Ignore(staticMethod); CsTokenType openingBracketTokenType = CsTokenType.OpenParenthesis; CsTokenType closingBracketTokenType = CsTokenType.CloseParenthesis; SymbolType closingBracketType = SymbolType.CloseParenthesis; if (openingBracketType == SymbolType.OpenSquareBracket) { openingBracketTokenType = CsTokenType.OpenSquareBracket; closingBracketTokenType = CsTokenType.CloseSquareBracket; closingBracketType = SymbolType.CloseSquareBracket; } else { Debug.Assert( openingBracketType == SymbolType.OpenParenthesis, "The opening bracket type can only be a parenthesis or a square bracket."); } // Get the opening bracket. Bracket openingParenthesis = this.GetBracketToken(openingBracketTokenType, openingBracketType, elementReference); Node<CsToken> openingParenthesisNode = this.tokens.InsertLast(openingParenthesis); // Get each of the parameters. Symbol symbol = this.GetNextSymbol(elementReference); List<Parameter> parameters = new List<Parameter>(); while (symbol.SymbolType != closingBracketType) { var parameterReference = new Reference<ICodePart>(); Node<CsToken> previousToken = this.tokens.Last; // Collect attributes on the parameter. while (symbol.SymbolType == SymbolType.OpenSquareBracket) { Attribute attribute = this.GetAttribute(parameterReference, unsafeCode); if (attribute == null) { throw this.CreateSyntaxException(); } this.tokens.Add(attribute); symbol = this.GetNextSymbol(parameterReference); } ParameterModifiers modifiers = ParameterModifiers.None; // If there is a parameter modifier, get it. if (symbol.SymbolType == SymbolType.Ref) { this.tokens.Add(this.GetToken(CsTokenType.Ref, SymbolType.Ref, parameterReference)); modifiers |= ParameterModifiers.Ref; } else if (symbol.SymbolType == SymbolType.Out) { this.tokens.Add(this.GetToken(CsTokenType.Out, SymbolType.Out, parameterReference)); modifiers |= ParameterModifiers.Out; } else if (symbol.SymbolType == SymbolType.Params) { this.tokens.Add(this.GetToken(CsTokenType.Params, SymbolType.Params, parameterReference)); modifiers |= ParameterModifiers.Params; } else if (symbol.SymbolType == SymbolType.This) { // The this keyword indicates that this is an extension method. This is only allowed if // both of the following are true: // 1. This must be the first parameter. // 2. The element must be a static method. if (parameters.Count == 0 && staticMethod) { this.tokens.Add(this.GetToken(CsTokenType.This, SymbolType.This, parameterReference)); modifiers |= ParameterModifiers.This; } } // Get the parameter type. TypeToken parameterType = this.GetTypeToken(parameterReference, unsafeCode, true); CsToken parameterName = null; if (parameterType.Text.Equals("__arglist", StringComparison.Ordinal)) { // When the parameterType is __arglist, this means that there is actually no parameter type at // all, and the parameter name should be set to the __arglist token. parameterName = parameterType.ChildTokens.First.Value; parameterType = null; parameterName.ParentRef = parameterReference; this.tokens.Add(parameterName); } else { this.tokens.Add(parameterType); // Get the parameter name. parameterName = this.GetToken(CsTokenType.Other, SymbolType.Other, parameterReference); this.tokens.Add(parameterName); } // Get the optional default value for the parameter. Expression defaultArgument = null; symbol = this.GetNextSymbol(parameterReference); if (symbol.SymbolType == SymbolType.Equals) { this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, parameterReference)); // Get the default value expression. defaultArgument = this.GetNextExpression(ExpressionPrecedence.None, parameterReference, unsafeCode); } // Create the list of tokens comprising the parameter, and trim any whitespace off the beginning and end. var tokenList = new CsTokenList(this.tokens, previousToken.Next, this.tokens.Last); tokenList.Trim(); var parameter = new Parameter( parameterType, parameterName.Text, elementReference, modifiers, defaultArgument, parameterType == null ? parameterName.Location : CodeLocation.Join(parameterType.Location, parameterName.Location), tokenList, parameterType == null ? parameterName.Generated : parameterType.Generated || parameterName.Generated); parameterReference.Target = parameter; parameters.Add(parameter); // If the next symbol, is a comma, get the next parameter. symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType == SymbolType.Comma) { this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, elementReference)); symbol = this.GetNextSymbol(elementReference); } } // Get the closing bracket. Bracket closingParenthesis = this.GetBracketToken(closingBracketTokenType, closingBracketType, elementReference); Node<CsToken> closingParenthesisNode = this.tokens.InsertLast(closingParenthesis); openingParenthesis.MatchingBracketNode = closingParenthesisNode; closingParenthesis.MatchingBracketNode = openingParenthesisNode; // Return the parameters as a read-only collection. return parameters.ToArray(); }
/// <summary> /// Parses an anonymous method or lambda expression's parameter list. /// </summary> /// <param name="elementReference">A reference to the element being created.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <returns>Returns the collection of parameters.</returns> private ICollection<Parameter> ParseAnonymousMethodParameterList(Reference<ICodePart> elementReference, bool unsafeCode) { Param.AssertNotNull(elementReference, "elementReference"); Param.Ignore(unsafeCode); // Get the opening bracket. Bracket openingParenthesis = this.GetBracketToken(CsTokenType.OpenParenthesis, SymbolType.OpenParenthesis, elementReference); Node<CsToken> openingParenthesisNode = this.tokens.InsertLast(openingParenthesis); List<Parameter> parameters = new List<Parameter>(); // Get each of the parameters. Symbol symbol = this.GetNextSymbol(elementReference); while (symbol.SymbolType != SymbolType.CloseParenthesis) { var parameterReference = new Reference<ICodePart>(); Node<CsToken> previousToken = this.tokens.Last; ParameterModifiers modifiers = ParameterModifiers.None; // If there is a parameter modifier, get it. if (symbol.SymbolType == SymbolType.Ref) { this.tokens.Add(this.GetToken(CsTokenType.Ref, SymbolType.Ref, parameterReference)); modifiers |= ParameterModifiers.Ref; } else if (symbol.SymbolType == SymbolType.Out) { this.tokens.Add(this.GetToken(CsTokenType.Out, SymbolType.Out, parameterReference)); modifiers |= ParameterModifiers.Out; } else if (symbol.SymbolType == SymbolType.Params) { this.tokens.Add(this.GetToken(CsTokenType.Params, SymbolType.Params, parameterReference)); modifiers |= ParameterModifiers.Params; } // The first token is either the parameter type in an explicit parameter list, or the parameter name // in an implicit parameter list. TypeToken firstToken = this.GetTypeToken(parameterReference, unsafeCode, true); // Peek ahead and look at the type of the next token. int index = this.GetNextCodeSymbolIndex(1); if (index == -1) { throw this.CreateSyntaxException(); } symbol = this.symbols.Peek(index); if (symbol.SymbolType == SymbolType.Comma || symbol.SymbolType == SymbolType.CloseParenthesis) { // There is no type. if (firstToken.ChildTokens.Count > 1) { throw this.CreateSyntaxException(); } CsToken nameToken = firstToken.ChildTokens.First.Value; nameToken.ParentRef = parameterReference; this.tokens.Add(nameToken); var parameter = new Parameter( null, nameToken.Text, elementReference, modifiers, null, nameToken.Location, new CsTokenList(this.tokens, previousToken.Next, this.tokens.Last), nameToken.Generated); parameterReference.Target = parameter; parameters.Add(parameter); } else { // There is a type and a name. this.tokens.Add(firstToken); // Get the parameter name. CsToken nameToken = this.GetToken(CsTokenType.Other, SymbolType.Other, parameterReference); this.tokens.Add(nameToken); var parameter = new Parameter( firstToken, nameToken.Text, elementReference, modifiers, null, CodeLocation.Join(firstToken.Location, nameToken.Location), new CsTokenList(this.tokens, previousToken.Next, this.tokens.Last), firstToken.Generated || nameToken.Generated); parameterReference.Target = parameter; parameters.Add(parameter); } // If the next symbol is a comma, get the next parameter. symbol = this.GetNextSymbol(elementReference); if (symbol.SymbolType == SymbolType.Comma) { this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, elementReference)); symbol = this.GetNextSymbol(elementReference); } } // Get the closing bracket. Bracket closingParenthesis = this.GetBracketToken(CsTokenType.CloseParenthesis, SymbolType.CloseParenthesis, elementReference); Node<CsToken> closingParenthesisNode = this.tokens.InsertLast(closingParenthesis); openingParenthesis.MatchingBracketNode = closingParenthesisNode; closingParenthesis.MatchingBracketNode = openingParenthesisNode; return parameters; }
private void FillSetAccessorDetails(CsElement parent) { Property property = parent as Property; if (property != null) { this.returnType = CreateVoidTypeToken(); this.parameters = new Parameter[] { new Parameter(property.ReturnType, "value", ParameterModifiers.None, new CodeLocation(), null, property.ReturnType.Generated) }; } else { Indexer indexer = (Indexer) parent; this.returnType = CreateVoidTypeToken(); Parameter[] parameterArray = new Parameter[indexer.Parameters.Count + 1]; int index = 0; foreach (Parameter parameter in indexer.Parameters) { parameterArray[index++] = parameter; } parameterArray[index] = new Parameter(indexer.ReturnType, "value", ParameterModifiers.None, new CodeLocation(), null, indexer.ReturnType.Generated); this.parameters = parameterArray; } }