/// <summary> /// Gets the name of the element. /// </summary> /// <returns>The name of the element.</returns> protected override string GetElementName() { // For a field, the name of the first variable declarator is the name of the field. VariableDeclaratorExpression declarator = this.FindFirstDescendent <VariableDeclaratorExpression>(); if (declarator != null) { return(declarator.Identifier.Text); } throw new SyntaxException(this.Document, this.LineNumber); }
/// <summary> /// Reads an expression beginning with two unknown words. /// </summary> /// <param name="expressionProxy">Proxy object for the expression being created.</param> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="type">The type of the variable.</param> /// <param name="previousPrecedence">The precedence of the previous expression.</param> /// <param name="unsafeCode">Indicates whether the code being parsed resides in an unsafe code block.</param> /// <returns>Returns the expression.</returns> private VariableDeclarationExpression GetVariableDeclarationExpression( CodeUnitProxy expressionProxy, CodeUnitProxy parentProxy, Expression type, ExpressionPrecedence previousPrecedence, bool unsafeCode) { Param.AssertNotNull(expressionProxy, "expressionProxy"); Param.AssertNotNull(parentProxy, "parentProxy"); Param.AssertNotNull(type, "type"); Param.Ignore(previousPrecedence); Param.Ignore(unsafeCode); CsLanguageService.Debug.Assert( type.ExpressionType == ExpressionType.Literal || type.ExpressionType == ExpressionType.MemberAccess || type.ExpressionType == ExpressionType.QualifiedAlias, "The left side of a variable declaration must either be a literal or a member access."); VariableDeclarationExpression expression = null; if (CheckPrecedence(previousPrecedence, ExpressionPrecedence.None)) { // Move past whitespace, etc, and add it to the expression proxy if we've already started the expression, // otherwise add it to the parent. this.AdvanceToNextCodeSymbol(expressionProxy.Children.Count > 0 ? expressionProxy : parentProxy); // Convert the type expression to a literal type token expression. LiteralExpression literalType = null; if (type.ExpressionType == ExpressionType.Literal) { literalType = (LiteralExpression)type; if (!literalType.Token.Is(TokenType.Type)) { literalType = null; } } if (literalType == null) { literalType = this.ConvertTypeExpression(type); } // Get each declarator. while (true) { var variableDeclaratorExpressionProxy = new CodeUnitProxy(this.document); // Get the next word. Symbol symbol = this.PeekNextSymbol(); if (symbol.SymbolType != SymbolType.Other) { throw this.CreateSyntaxException(); } // Get the identifier. LiteralExpression identifier = this.GetLiteralExpression(variableDeclaratorExpressionProxy, unsafeCode); if (identifier == null || identifier.Children.Count == 0) { throw new SyntaxException(this.document, symbol.LineNumber); } // Get the initializer if it exists. Expression initializer = null; symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Equals) { // Add the equals token. this.GetOperatorSymbolToken(variableDeclaratorExpressionProxy, OperatorType.Equals); // Check whether this is an array initializer. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.OpenCurlyBracket) { initializer = this.GetArrayInitializerExpression(variableDeclaratorExpressionProxy, unsafeCode); } else { initializer = this.GetNextExpression(variableDeclaratorExpressionProxy, ExpressionPrecedence.None, unsafeCode); } } // Create and add the declarator. var declarator = new VariableDeclaratorExpression(variableDeclaratorExpressionProxy, identifier, initializer); expressionProxy.Children.Add(declarator); // Now check if the next character is a comma. If so there is another declarator. symbol = this.PeekNextSymbol(); if (symbol.SymbolType != SymbolType.Comma) { // There are no more declarators. break; } // Add the comma. this.GetToken(expressionProxy, TokenType.Comma, SymbolType.Comma); } // Create the expression. expression = new VariableDeclarationExpression(expressionProxy, literalType); parentProxy.Children.Add(expression); } return expression; }
/// <summary> /// Parses and returns the declarators for a field. /// </summary> /// <param name="parentProxy">Represents the parent item.</param> /// <param name="unsafeCode">Indicates whether the code is marked as unsafe.</param> /// <param name="fieldType">The field type.</param> /// <returns>Returns the name of the first field.</returns> private string GetFieldDeclarators(CodeUnitProxy parentProxy, bool unsafeCode, TypeToken fieldType) { Param.AssertNotNull(parentProxy, "parentProxy"); Param.Ignore(unsafeCode); Param.AssertNotNull(fieldType, "fieldType"); string firstFieldName = null; Symbol symbol = this.PeekNextSymbol(); while (symbol.SymbolType != SymbolType.Semicolon) { this.AdvanceToNextCodeSymbol(parentProxy); var declaratorProxy = new CodeUnitProxy(this.document); // Get the identifier. var identifierExpressionProxy = new CodeUnitProxy(this.document); Token identifier = this.GetElementNameToken(identifierExpressionProxy, unsafeCode, true); var identifierExpression = new LiteralExpression(identifierExpressionProxy, identifier); declaratorProxy.Children.Add(identifierExpression); if (firstFieldName == null) { firstFieldName = identifier.Text; } Expression initialization = null; // Check whether there is an equals sign. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Equals) { this.GetOperatorSymbolToken(declaratorProxy, OperatorType.Equals); // Get the expression after the equals sign. If the expression starts with an // opening curly bracket, then this is an initialization expression or an // anonymous type initialization expression. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.OpenCurlyBracket) { // Determine whether this is an array or an anonymous type. if (fieldType.Text == "var" || ( fieldType.Text != "Array" && fieldType.Text != "System.Array" && !fieldType.Text.Contains("["))) { initialization = this.GetAnonymousTypeInitializerExpression(declaratorProxy, unsafeCode); } else { initialization = this.GetArrayInitializerExpression(declaratorProxy, unsafeCode); } } else { initialization = this.GetNextExpression(declaratorProxy, ExpressionPrecedence.None, unsafeCode); } if (initialization == null) { throw this.CreateSyntaxException(); } } var declaratorExpression = new VariableDeclaratorExpression(declaratorProxy, identifierExpression, initialization); parentProxy.Children.Add(declaratorExpression); // If the next symbol is a comma, continue. symbol = this.PeekNextSymbol(); if (symbol.SymbolType == SymbolType.Comma) { this.GetToken(parentProxy, TokenType.Comma, SymbolType.Comma); symbol = this.PeekNextSymbol(); } } // Return the declarators as a read-only collection. return firstFieldName; }