/// <summary> /// Determines whether the given expression is the left-hand-side literal in any of the assignment expressions within an object initialize expression. /// </summary> /// <param name="expression"> /// The expression to check. /// </param> /// <returns> /// Returns true if the expression is the left-hand-side literal in any of the assignment expressions within an object initializer expression. /// </returns> /// <remarks> /// This method checks for the following situation: /// <code> /// class MyClass { public bool Member { get { return true; } } public void SomeMethod() { MyObjectType someObject = new MyObjectType { Member = this.Member }; } } /// </code> /// In this case, StyleCop will raise a violation since it looks like the Member token should be prefixed by 'this.', however, it is actually referring to a property on the MyObjectType type. /// </remarks> private static bool IsObjectInitializerLeftHandSideExpression(Expression expression) { Param.AssertNotNull(expression, "expression"); // The expression should be a literal expression if it represents the keyword being checked. if (expression.ExpressionType == ExpressionType.Literal) { // The literal should be a child-expression of an assignment expression. AssignmentExpression assignmentExpression = expression.Parent as AssignmentExpression; if (assignmentExpression != null) { // The left-hand-side of the assignment expression should be the literal expression. if (assignmentExpression.LeftHandSide == expression) { // The assignment expression should be the child of an object initializer expression. ObjectInitializerExpression objectInitializeExpression = assignmentExpression.Parent as ObjectInitializerExpression; if (objectInitializeExpression != null) { return(true); } } } } return(false); }
/// <summary> /// Gets an object initializer expression. /// </summary> /// <param name="unsafeCode"> /// Indicates whether the code being parsed resides in an unsafe code block. /// </param> /// <returns> /// Returns the expression. /// </returns> private ObjectInitializerExpression GetObjectInitializerExpression(bool unsafeCode) { Param.Ignore(unsafeCode); Reference<ICodePart> expressionReference = new Reference<ICodePart>(); List<AssignmentExpression> initializerExpressions = new List<AssignmentExpression>(); // Add and move past the opening curly bracket. Bracket openingBracket = this.GetBracketToken(CsTokenType.OpenCurlyBracket, SymbolType.OpenCurlyBracket, expressionReference); Node<CsToken> openingBracketNode = this.tokens.InsertLast(openingBracket); while (true) { // If the next symbol is the closing curly bracket, then we are done. Symbol symbol = this.GetNextSymbol(expressionReference); if (symbol.SymbolType == SymbolType.CloseCurlyBracket) { break; } Reference<ICodePart> initializerExpressionReference = new Reference<ICodePart>(); // Get the identifier. LiteralExpression identifier = this.GetLiteralExpression(initializerExpressionReference, unsafeCode); // Get the equals sign. symbol = this.GetNextSymbol(initializerExpressionReference); if (symbol.SymbolType != SymbolType.Equals) { throw this.CreateSyntaxException(); } this.tokens.Add(this.GetOperatorToken(OperatorType.Equals, initializerExpressionReference)); // Get the initializer value. If this begins with an opening curly bracket, // this is an embedded object or collection initializer. Otherwise, it is // some other kind of expression. Expression initializerValue = null; symbol = this.GetNextSymbol(initializerExpressionReference); if (symbol.SymbolType == SymbolType.OpenCurlyBracket) { initializerValue = this.GetObjectOrCollectionInitializerExpression(initializerExpressionReference, unsafeCode); } else { initializerValue = this.GetNextExpression(ExpressionPrecedence.None, initializerExpressionReference, unsafeCode); } // Create and add this initializer. CsTokenList initializerTokens = new CsTokenList(this.tokens, identifier.Tokens.First, initializerValue.Tokens.Last); AssignmentExpression initializerExpression = new AssignmentExpression( initializerTokens, AssignmentExpression.Operator.Equals, identifier, initializerValue); initializerExpressionReference.Target = initializerExpression; initializerExpressions.Add(initializerExpression); // Check whether we're done. symbol = this.GetNextSymbol(expressionReference); if (symbol.SymbolType == SymbolType.Comma) { this.tokens.Add(this.GetToken(CsTokenType.Comma, SymbolType.Comma, expressionReference)); // If the next symbol after this is the closing curly bracket, then we are done. symbol = this.GetNextSymbol(expressionReference); if (symbol.SymbolType == SymbolType.CloseCurlyBracket) { break; } } else { break; } } // Add and move past the closing curly bracket. Bracket closingBracket = this.GetBracketToken(CsTokenType.CloseCurlyBracket, SymbolType.CloseCurlyBracket, expressionReference); Node<CsToken> closingBracketNode = this.tokens.InsertLast(closingBracket); openingBracket.MatchingBracketNode = closingBracketNode; closingBracket.MatchingBracketNode = openingBracketNode; // Create the token list for the overall expression. CsTokenList expressionTokens = new CsTokenList(this.tokens, openingBracketNode, closingBracketNode); // Create and return the expression. ObjectInitializerExpression expression = new ObjectInitializerExpression(expressionTokens, initializerExpressions.ToArray()); expressionReference.Target = expression; return expression; }