예제 #1
0
        /// <summary>
        /// Processes the given expression.
        /// </summary>
        /// <param name="expression">
        /// The expression to process.
        /// </param>
        /// <param name="element">
        /// The parent element.
        /// </param>
        /// <param name="validPrefixes">
        /// The list of acceptable Hungarian-type prefixes.
        /// </param>
        private void ProcessExpression(Expression expression, CsElement element, Dictionary <string, string> validPrefixes)
        {
            Param.AssertNotNull(expression, "expression");
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(validPrefixes, "validPrefixes");

            // Check the type of the expression.
            if (expression.ExpressionType == ExpressionType.AnonymousMethod)
            {
                AnonymousMethodExpression anonymousMethod = (AnonymousMethodExpression)expression;

                // Check the anonymous method's variables.
                if (anonymousMethod.Variables != null)
                {
                    foreach (Variable variable in anonymousMethod.Variables)
                    {
                        this.CheckMethodVariablePrefix(variable, element, validPrefixes);
                    }

                    // Check the statements under the anonymous method.
                    foreach (Statement statement in anonymousMethod.ChildStatements)
                    {
                        this.ProcessStatement(statement, element, validPrefixes);
                    }
                }
            }

            // Check the child expressions under this expression.
            foreach (Expression childExpression in expression.ChildExpressions)
            {
                this.ProcessExpression(childExpression, element, validPrefixes);
            }
        }
        /// <summary>
        /// Checks the given list of expressions.
        /// </summary>
        /// <param name="element">
        /// The element containing the expressions.
        /// </param>
        /// <param name="expressions">
        /// The list of expressions.
        /// </param>
        private void CheckStatementFormattingRulesForExpressions(CsElement element, ICollection <Expression> expressions)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expressions, "expressions");

            foreach (Expression expression in expressions)
            {
                if (expression.ExpressionType == ExpressionType.AnonymousMethod)
                {
                    // Check the statements within this anonymous method expression.
                    AnonymousMethodExpression anonymousMethod = expression as AnonymousMethodExpression;
                    this.CheckStatementFormattingRulesForStatements(element, anonymousMethod.ChildStatements);
                }
                else
                {
                    // Check the child expressions under this expression.
                    this.CheckStatementFormattingRulesForExpressions(element, expression.ChildExpressions);
                }
            }
        }
        /// <summary>
        /// Checks that parenthesis are used correctly within an anonymous method.
        /// </summary>
        /// <param name="element">
        /// The parent element.
        /// </param>
        /// <param name="expression">
        /// The expression to check.
        /// </param>
        private void CheckAnonymousMethodParenthesis(CsElement element, AnonymousMethodExpression expression)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expression, "expression");

            if (expression.Parameters == null || expression.Parameters.Count == 0)
            {
                // Check for parenthesis.
                for (Node<CsToken> tokenNode = expression.Tokens.First; tokenNode != expression.Tokens.Last; tokenNode = tokenNode.Next)
                {
                    if (tokenNode.Value.CsTokenType == CsTokenType.OpenCurlyBracket)
                    {
                        break;
                    }

                    if (tokenNode.Value.CsTokenType == CsTokenType.OpenParenthesis)
                    {
                        // If we're inside a MethodInvocation and the method being called is a method on our class
                        // with at least 2 signatures then the parens are required.
                        if (expression.Parent is MethodInvocationExpression)
                        {
                            MethodInvocationExpression parentExpression = expression.Parent as MethodInvocationExpression;

                            CsToken classMemberName = Utils.ExtractBaseClassMemberName(parentExpression, parentExpression.Tokens.First);

                            if (classMemberName == null)
                            {
                                break;
                            }

                            ClassBase classBase = Utils.GetClassBase(element);

                            Dictionary<string, List<CsElement>> allClassMembers = Utils.CollectClassMembers(classBase);

                            ICollection<CsElement> classMembers = Utils.FindClassMember(classMemberName.Text, classBase, allClassMembers, false);

                            if (classMembers != null && classMembers.Count > 1)
                            {
                                break;
                            }
                        }

                        this.AddViolation(element, tokenNode.Value.LineNumber, Rules.RemoveDelegateParenthesisWhenPossible);
                        break;
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Reads an anonymous method from the code.
        /// </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 AnonymousMethodExpression GetAnonymousMethodExpression(Reference<ICodePart> parentReference, bool unsafeCode)
        {
            Param.AssertNotNull(parentReference, "parentReference");
            Param.Ignore(unsafeCode);

            Reference<ICodePart> expressionReference = new Reference<ICodePart>();

            // Create the anonymous method object now.
            AnonymousMethodExpression anonymousMethod = new AnonymousMethodExpression();

            Node<CsToken> previousTokenNode = this.tokens.Last;

            // First symbol could be 'async' for asynchronous delegates.
            Symbol nextSymbol = this.symbols.Peek(1);
            if (nextSymbol.SymbolType == SymbolType.Other && nextSymbol.Text == "async")
            {
                this.tokens.Add(this.GetToken(CsTokenType.Async, SymbolType.Other, expressionReference));
                anonymousMethod.Async = true;
            }

            // Get the delegate keyword.
            this.tokens.Add(this.GetToken(CsTokenType.Delegate, SymbolType.Delegate, parentReference, expressionReference));

            // Check whether the next symbol is an opening parenthesis.
            Symbol symbol = this.GetNextSymbol(expressionReference);

            ICollection<Parameter> parameters = null;
            if (symbol.SymbolType == SymbolType.OpenParenthesis)
            {
                parameters = this.ParseAnonymousMethodParameterList(expressionReference, unsafeCode);
            }

            // The next symbol must be an opening curly bracket.
            Bracket openingBracket = this.GetBracketToken(CsTokenType.OpenCurlyBracket, SymbolType.OpenCurlyBracket, expressionReference);
            Node<CsToken> openingBracketNode = this.tokens.InsertLast(openingBracket);

            // Read the child statements.
            Node<CsToken> closingBracketNode = this.ParseStatementScope(anonymousMethod, expressionReference, unsafeCode);

            if (closingBracketNode == null)
            {
                // If we failed to get a closing bracket back, then there is a syntax
                // error in the document since there is an opening bracket with no matching
                // closing bracket.
                throw this.CreateSyntaxException();
            }

            openingBracket.MatchingBracketNode = closingBracketNode;
            ((Bracket)closingBracketNode.Value).MatchingBracketNode = openingBracketNode;

            // Create the token list for the anonymous method expression.
            Node<CsToken> firstNode = previousTokenNode == null ? this.tokens.First : previousTokenNode.Next;

            anonymousMethod.Tokens = new CsTokenList(this.tokens, firstNode, this.tokens.Last);

            // Get the item's argument list if necessary.
            if (parameters != null && parameters.Count > 0)
            {
                anonymousMethod.AddParameters(parameters);
            }

            // Add a variable for each of the parameters.
            if (anonymousMethod.Parameters != null && anonymousMethod.Parameters.Count > 0)
            {
                // Add a variable for each of the parameters.
                foreach (Parameter parameter in anonymousMethod.Parameters)
                {
                    anonymousMethod.Variables.Add(
                        new Variable(parameter.Type, parameter.Name, VariableModifiers.None, parameter.Location, expressionReference, parameter.Generated));
                }
            }

            // Return the expression.
            expressionReference.Target = anonymousMethod;
            return anonymousMethod;
        }
 /// <summary>
 /// The save.
 /// </summary>
 /// <param name="anonymousMethodExpression">
 /// The anonymous method expression.
 /// </param>
 private void Save(AnonymousMethodExpression anonymousMethodExpression)
 {
     this.cppWriter.Write("[=]");
     this.Save(anonymousMethodExpression.Parameters, this.cppWriter, SavingOptions.None /* SavingOptions.ApplyReference */);
     this.Save(anonymousMethodExpression, SaveICodeUnit.NoNewLine);
     this.SetMarkBeginOfBlock();
 }