/// <summary> /// Reads the argument list for a method invocation expression. /// </summary> /// <param name="closingSymbol"> /// The symbol that closes the argument list. /// </param> /// <param name="parentReference"> /// The parent code part. /// </param> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the list of arguments in the method invocation. /// </returns> private IList<Argument> GetArgumentList(SymbolType closingSymbol, Reference<ICodePart> parentReference, bool unsafeCode) { Param.AssertNotNull(closingSymbol, "closingSymbol"); Param.AssertNotNull(parentReference, "parentReference"); Param.Ignore(unsafeCode); List<Argument> arguments = new List<Argument>(); while (true) { // Save the current last token. Node<CsToken> previousTokenNode = this.tokens.Last; // Move to the next code token. Symbol firstSymbol = this.GetNextSymbol(parentReference); if (firstSymbol.SymbolType == closingSymbol) { break; } Reference<ICodePart> argumentReference = new Reference<ICodePart>(); if (firstSymbol.SymbolType != SymbolType.Comma) { // Gather the parameter name label if it exists. CsToken argumentName = null; if (firstSymbol.SymbolType == SymbolType.Other) { // Look at the next symbol after the label. int index = this.GetNextCodeSymbolIndex(2); if (index >= 0) { Symbol colon = this.symbols.Peek(index); if (colon != null && colon.SymbolType == SymbolType.Colon) { // This is an argument name label. Add the name label and the colon. argumentName = this.GetToken(CsTokenType.Other, SymbolType.Other, argumentReference); this.tokens.Add(argumentName); // The next symbol must be the colon. this.tokens.Add(this.GetToken(CsTokenType.LabelColon, SymbolType.Colon, argumentReference)); } } } // Gather the argument modifiers. ParameterModifiers modifiers = ParameterModifiers.None; int i = this.GetNextCodeSymbolIndex(1); if (i >= 0) { Symbol symbol = this.symbols.Peek(i); if (symbol.SymbolType == SymbolType.Ref) { this.tokens.Add(this.GetToken(CsTokenType.Ref, SymbolType.Ref, argumentReference)); modifiers = ParameterModifiers.Ref; } else if (symbol.SymbolType == SymbolType.Out) { this.tokens.Add(this.GetToken(CsTokenType.Out, SymbolType.Out, argumentReference)); modifiers = ParameterModifiers.Out; } else if (symbol.SymbolType == SymbolType.Params) { this.tokens.Add(this.GetToken(CsTokenType.Params, SymbolType.Params, argumentReference)); modifiers = ParameterModifiers.Params; } } // The argument body expression must come next. Expression argumentExpression = this.GetNextExpression(ExpressionPrecedence.None, argumentReference, unsafeCode); // Create the collection of tokens that form the argument, and strip off whitesace from the beginning and end. CsTokenList argumentTokenList = new CsTokenList(this.tokens, previousTokenNode.Next, this.tokens.Last); argumentTokenList.Trim(CsTokenType.EndOfLine, CsTokenType.WhiteSpace); // Create and add the argument. Argument argument = new Argument( argumentName, modifiers, argumentExpression, CodeLocation.Join(firstSymbol.Location, argumentExpression.Location), parentReference, argumentTokenList, this.symbols.Generated); argumentReference.Target = argument; arguments.Add(argument); } // If the next symbol is a comma, add the comma and proceed. int x = this.GetNextCodeSymbolIndex(1); if (x >= 0) { if (this.symbols.Peek(x).SymbolType == SymbolType.Comma) { this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, parentReference)); } } } // Trim the list down to a small array before returning it. return arguments.ToArray(); }
/// <summary> /// Determine whether the argument passed in is equivalent to "" /// </summary> /// <param name="argument"> /// The Argument to check. /// </param> /// <returns> /// True if equivalent to string.empty otherwise false. /// </returns> private static bool ArgumentTokensMatchStringEmpty(Argument argument) { CsToken firstToken = argument.Tokens.First.Value; if (firstToken.CsTokenType == CsTokenType.String && IsEmptyString(firstToken.Text)) { return true; } if (firstToken.CsTokenType == CsTokenType.Null) { return true; } if (argument.Tokens.MatchTokens(StringComparison.OrdinalIgnoreCase, "string", ".", "empty")) { return true; } if (argument.Tokens.MatchTokens(StringComparison.OrdinalIgnoreCase, "system", ".", "string", ".", "empty")) { return true; } if (argument.Tokens.MatchTokens(StringComparison.OrdinalIgnoreCase, "global", "::", "system", ".", "string", ".", "empty")) { return true; } return false; }
/// <summary> /// The save. /// </summary> /// <param name="argument"> /// The argument. /// </param> /// <param name="writer"> /// The writer. /// </param> private void Save(Argument argument) { if (argument.Modifiers != ParameterModifiers.None) { this.Save(argument.Modifiers, this.cppWriter); this.SaveModifiersAfter(argument.Modifiers, this.cppWriter); this.cppWriter.Write(' '); } @switch(argument.Expression); }