/// <summary>
        /// Measures the number of lines taken up by comments between two tokens.
        /// </summary>
        /// <param name="start">The start token.</param>
        /// <param name="end">The end token.</param>
        /// <param name="includeAttributes">Indicates whether to also count attributes.</param>
        /// <returns>Returns the number of lines takes up by comments.</returns>
        private static int MeasureCommentLinesBetween(CodeUnit start, CodeUnit end, bool includeAttributes)
        {
            Param.AssertNotNull(start, "start");
            Param.AssertNotNull(end, "end");
            Param.Ignore(includeAttributes);

            int lineSpan = 0;

            int previousLineSpan      = -1;
            int previousEndLineNumber = -1;

            for (CodeUnit next = start.FindNext(); next != null && next != end; next = next.FindNext())
            {
                if (next.Is(LexicalElementType.Comment) || (next.Is(CodeUnitType.Attribute) && includeAttributes))
                {
                    int itemLineSpan = ParameterPrewordOffset(next);

                    if (previousEndLineNumber > 0 && next.LineNumber == previousEndLineNumber && previousLineSpan > 0)
                    {
                        --itemLineSpan;
                    }

                    lineSpan             += itemLineSpan;
                    previousLineSpan      = itemLineSpan;
                    previousEndLineNumber = next.Location.EndPoint.LineNumber;
                }
            }

            return(lineSpan);
        }
            /// <summary>
            /// Gets the location of one of the arguments in the list.
            /// </summary>
            /// <param name="index">The index of an argument in the list.</param>
            /// <returns>Returns the location of the arguments.</returns>
            public CodeLocation Location(int index)
            {
                Param.AssertValueBetween(index, 0, this.argumentList.Count - 1, "index");

                Argument argument = this.argumentList[index];

                // The location must be calculated by finding the first and last items
                // in the argument and joining their locations.
                CodeUnit firstItem = null;

                for (CodeUnit item = argument.FindFirstChild(); item != null; item = item.FindNextSibling())
                {
                    if (!item.Is(LexicalElementType.WhiteSpace) &&
                        !item.Is(LexicalElementType.EndOfLine) &&
                        !item.Is(CommentType.SingleLineComment) &&
                        !item.Is(CommentType.MultilineComment))
                    {
                        firstItem = item;
                        break;
                    }
                }

                if (firstItem != null)
                {
                    return(CodeLocation.Join(firstItem.Location, argument.FindLast().Location));
                }

                return(argument.Location);
            }
        /// <summary>
        /// Checks the placement and formatting of parameters to a method invocation or a method declaration.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="methodArguments">The arguments or parameters to the method.</param>
        /// <param name="methodStartLineNumber">The line number on which the method begins.</param>
        /// <param name="openBracketType">The type of the argument list opening bracket.</param>
        /// <param name="closeBracketType">The type of the argument list closing bracket.</param>
        private void CheckParameters(
            Element element,
            CodeUnit parameterList,
            IArgumentList methodArguments,
            int methodStartLineNumber,
            TokenType openBracketType,
            TokenType closeBracketType)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(methodArguments, "methodArguments");
            Param.AssertGreaterThanZero(methodStartLineNumber, "methodStartLineNumber");
            Param.Ignore(openBracketType);
            Param.Ignore(closeBracketType);

            OpenBracketToken openingBracket = this.CheckMethodOpeningBracket(element, parameterList, openBracketType);

            if (openingBracket != null)
            {
                this.CheckMethodClosingBracket(element, parameterList, openingBracket, closeBracketType, methodArguments);

                if (methodArguments.Count > 0)
                {
                    this.CheckMethodArgumentList(element, parameterList, methodArguments, openingBracket, methodStartLineNumber);
                }
            }
        }
        /// <summary>
        /// Parses the list of expressions.
        /// </summary>
        /// <param name="expressionParent">The direct parent of the expressions to check.</param>
        /// <param name="parentExpression">The parent expression, if there is one.</param>
        /// <param name="parentElement">The element that contains the expressions.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForExpressions(
            CodeUnit expressionParent,
            Expression parentExpression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary <string, List <Element> > members)
        {
            Param.AssertNotNull(expressionParent, "expressionParent");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentExpression);
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Loop through each of the expressions in the list.
            for (Expression expression = expressionParent.FindFirstChildExpression(); expression != null; expression = expression.FindNextSiblingExpression())
            {
                // If the expression is a variable declarator expression, we don't
                // want to match against the identifier tokens.
                if (expression.ExpressionType == ExpressionType.VariableDeclarator)
                {
                    VariableDeclaratorExpression declarator = (VariableDeclaratorExpression)expression;
                    if (declarator.Initializer != null)
                    {
                        this.CheckClassMemberRulesForExpression(declarator.Initializer, parentExpression, parentElement, parentClass, members);
                    }
                }
                else
                {
                    this.CheckClassMemberRulesForExpression(expression, parentExpression, parentElement, parentClass, members);
                }
            }
        }
        /// <summary>
        /// Fixes the error.
        /// </summary>
        /// <param name="violationContext">Context for the violation.</param>
        /// <param name="token">The token that is missing a prefix.</param>
        private void FixPrefixLocalCallsWithThisViolation(ViolationContext violationContext, Token token)
        {
            Param.Ignore(violationContext);
            Param.AssertNotNull(token, "token");

            CsDocument document = token.Document;

            // Find the item that is going to get replaced.
            CodeUnit          itemToReplace = token;
            LiteralExpression parent        = token.Parent as LiteralExpression;

            if (parent != null)
            {
                itemToReplace = parent;
            }

            // Record the location of this item.
            CodeUnitLocationMarker marker = document.GetCodeUnitLocationMarker(itemToReplace);

            // If the token is not already wrapped by a literal expression, create one.
            LiteralExpression rightHandSide = parent;

            if (rightHandSide == null)
            {
                rightHandSide = document.CreateLiteralExpression(token);
            }

            // Create the left-hand side and the expression.
            LiteralExpression      leftHandSide = document.CreateLiteralExpression(document.CreateThisToken());
            MemberAccessExpression expression   = document.CreateMemberAccessExpression(leftHandSide, rightHandSide);

            // Insert the member access expression in the same location as the previous literal.
            document.Insert(expression, marker);
        }
Beispiel #6
0
        /// <summary>
        /// Visits one code unit in the document.
        /// </summary>
        /// <param name="codeUnit">The item being visited.</param>
        /// <param name="parentElement">The parent element, if any.</param>
        /// <param name="parentStatement">The parent statement, if any.</param>
        /// <param name="parentExpression">The parent expression, if any.</param>
        /// <param name="parentClause">The parent query clause, if any.</param>
        /// <param name="parentToken">The parent token, if any.</param>
        /// <param name="context">The context.</param>
        /// <returns>Returns true to continue, or false to stop the walker.</returns>
        private bool VisitCodeUnit(
            CodeUnit codeUnit,
            Element parentElement,
            Statement parentStatement,
            Expression parentExpression,
            QueryClause parentClause,
            Token parentToken,
            object context)
        {
            Param.AssertNotNull(codeUnit, "codeUnit");
            Param.Ignore(parentElement, parentStatement, parentExpression, parentClause, parentToken);
            Param.Ignore(context);

            if (codeUnit.CodeUnitType == CodeUnitType.Element)
            {
                return(this.VisitElement((Element)codeUnit, parentElement));
            }
            else if (codeUnit.CodeUnitType == CodeUnitType.Statement)
            {
                return(this.VisitStatement((Statement)codeUnit, parentExpression, parentStatement, parentElement));
            }
            else if (codeUnit.CodeUnitType == CodeUnitType.Expression)
            {
                return(this.VisitExpression((Expression)codeUnit, parentExpression, parentStatement, parentElement));
            }

            return(!this.Cancel);
        }
        /// <summary>
        /// Determines whether the given word is the name of a local variable.
        /// </summary>
        /// <param name="word">The name to check.</param>
        /// <param name="item">The token containing the word.</param>
        /// <param name="parent">The expression that the word appears in.</param>
        /// <returns>True if the word is the name of a local variable, false if not.</returns>
        private static bool IsLocalMember(string word, Token item, Expression parent)
        {
            Param.AssertValidString(word, "word");
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parent, "parent");

            CodeUnit p = parent;

            while (p != null)
            {
                // Check to see if the name matches a local variable.
                if (ReadabilityRules.ContainsVariable(p.Variables, word, item))
                {
                    return(true);
                }

                // If the parent is an element (other than an accessor), do not look any higher up the stack than this.
                if (p.CodeUnitType == CodeUnitType.Element && !p.Is(ElementType.Accessor))
                {
                    break;
                }

                // Check to see whether the variable is defined within the parent.
                p = p.Parent;
            }

            return(false);
        }
Beispiel #8
0
        private void ProcessCodeUnit(CodeUnit item, XmlNode parentNode)
        {
            XmlNode elementNode = RecordItem(item, parentNode);

            for (CodeUnit child = item.Children.First; child != null; child = child.LinkNode.Next)
            {
                ProcessCodeUnit(child, elementNode);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Determines whether the given item is a preprocessor directive or an item within a preprocessor directive.
        /// </summary>
        /// <param name="item">The item to check.</param>
        /// <returns>Returns true if so; false otherwise.</returns>
        private static bool IsPreprocessorDirective(CodeUnit item)
        {
            Param.AssertNotNull(item, "item");

            if (item.Is(LexicalElementType.PreprocessorDirective))
            {
                return true;
            }

            return item.FindParent<PreprocessorDirective>() != null;
        }
Beispiel #10
0
        /// <summary>
        /// Determines whether the given item is a preprocessor directive or an item within a preprocessor directive.
        /// </summary>
        /// <param name="item">The item to check.</param>
        /// <returns>Returns true if so; false otherwise.</returns>
        private static bool IsPreprocessorDirective(CodeUnit item)
        {
            Param.AssertNotNull(item, "item");

            if (item.Is(LexicalElementType.PreprocessorDirective))
            {
                return(true);
            }

            return(item.FindParent <PreprocessorDirective>() != null);
        }
        /// <summary>
        /// Checks a method or method invocation to ensure that the closing bracket is
        /// on the same line as the last argument.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="openingBracket">The opening bracket.</param>
        /// <param name="closingBracketType">The type of the closing bracket.</param>
        /// <param name="arguments">The arguments to the method.</param>
        private void CheckMethodClosingBracket(
            Element element, CodeUnit parameterList, OpenBracketToken openingBracket, TokenType closingBracketType, IArgumentList arguments)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(openingBracket, "openingBracket");
            Param.Ignore(closingBracketType);
            Param.AssertNotNull(arguments, "arguments");

            // Find the closing bracket.
            CloseBracketToken closingBracket = null;

            Token next = parameterList.FindNextSiblingToken();

            if (next != null && next.Is(closingBracketType))
            {
                closingBracket = (CloseBracketToken)next;
            }

            if (closingBracket != null)
            {
                if (arguments.Count == 0)
                {
                    // The closing bracket must be on the same line as the opening bracket.
                    if (openingBracket.LineNumber != closingBracket.LineNumber)
                    {
                        // If the brackets are not on the same line, determine if this is because there are comments
                        // between the brackets.
                        int commentLineSpan = MeasureCommentLinesBetween(openingBracket, closingBracket, false);

                        if (openingBracket.LineNumber + commentLineSpan != closingBracket.LineNumber)
                        {
                            this.AddViolation(element, closingBracket.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfOpeningParenthesis);
                        }
                    }
                }
                else
                {
                    // The closing bracket must be on the same line as the end of the last method argument.
                    int lastArgumentEndLine = arguments.Location(arguments.Count - 1).EndPoint.LineNumber;
                    if (lastArgumentEndLine != closingBracket.LineNumber)
                    {
                        int commentLineSpan = MeasureCommentLinesBetween(arguments.Argument(arguments.Count - 1).FindLastDescendentToken(), closingBracket, false);

                        if (lastArgumentEndLine + commentLineSpan != closingBracket.LineNumber)
                        {
                            this.AddViolation(element, closingBracket.LineNumber, Rules.ClosingParenthesisMustBeOnLineOfLastParameter);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the CodeUnitLocationMarker class.
        /// </summary>
        /// <param name="codeUnit">The code unit.</param>
        internal CodeUnitLocationMarker(CodeUnit codeUnit)
        {
            Param.AssertNotNull(codeUnit, "codeUnit");

            this.Parent = codeUnit.Parent;
            this.NextSibling = codeUnit.LinkNode.Next;
            this.PreviousSibling = codeUnit.LinkNode.Previous;

            if (this.Parent == null && this.NextSibling == null && this.PreviousSibling == null)
            {
                throw new ArgumentException("codeUnit");
            }
        }
Beispiel #13
0
        private void BuildRootUnit()
        {
            OnProgress("Building root unit");
            _rootUnit = new CodeUnit
                        (
                _options.RootDependency,
                _namespaceDependency,
                _options.DependencyParser
                        );

            OnProgress("Resolving dependencies");
            _rootUnit.ResolveDependencies();
        }
        /// <summary>
        /// Gets the non-whitespace item that appears after the given item.
        /// </summary>
        /// <param name="item">The original item.</param>
        /// <returns>Returns the next item.</returns>
        private static CodeUnit GetNextNonWhitespaceItem(CodeUnit item)
        {
            Param.AssertNotNull(item, "item");

            for (CodeUnit next = item.FindNext(); next != null; next = next.FindNext())
            {
                if (!next.Is(LexicalElementType.EndOfLine) && !next.Is(LexicalElementType.WhiteSpace))
                {
                    return next;
                }
            }

            return null;
        }
        /// <summary>
        /// Gets the non-whitespace item that appears before the given item.
        /// </summary>
        /// <param name="item">The original item.</param>
        /// <returns>Returns the previous item.</returns>
        private static LexicalElement GetPreviousNonWhitespaceItem(CodeUnit item)
        {
            Param.AssertNotNull(item, "item");

            for (LexicalElement previous = item.FindPreviousLexicalElement(); previous != null; previous = previous.FindPreviousLexicalElement())
            {
                if (!previous.Is(LexicalElementType.EndOfLine) && !previous.Is(LexicalElementType.WhiteSpace))
                {
                    return previous;
                }
            }

            return null;
        }
        /// <summary>
        /// Gets the non-whitespace item that appears after the given item.
        /// </summary>
        /// <param name="item">The original item.</param>
        /// <returns>Returns the next item.</returns>
        private static CodeUnit GetNextNonWhitespaceItem(CodeUnit item)
        {
            Param.AssertNotNull(item, "item");

            for (CodeUnit next = item.FindNext(); next != null; next = next.FindNext())
            {
                if (!next.Is(LexicalElementType.EndOfLine) && !next.Is(LexicalElementType.WhiteSpace))
                {
                    return(next);
                }
            }

            return(null);
        }
        /// <summary>
        /// Checks the item that follows or precedes a curly bracket in a blocked statement to verify
        /// that there is no comment or region embedded within the statement.
        /// </summary>
        /// <param name="element">The element containing the statement.</param>
        /// <param name="previousOrNextItem">The previous or next item.</param>
        private void CheckTokenPrecedingOrFollowingCurlyBracket(Element element, CodeUnit previousOrNextItem)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(previousOrNextItem, "previousOrNextItem");

            if (previousOrNextItem.Is(LexicalElementType.Comment) || previousOrNextItem.Is(CodeUnitType.ElementHeader))
            {
                this.AddViolation(element, previousOrNextItem.LineNumber, Rules.BlockStatementsMustNotContainEmbeddedComments);
            }
            else if (previousOrNextItem.Is(PreprocessorType.Region) || previousOrNextItem.Is(PreprocessorType.EndRegion))
            {
                this.AddViolation(element, previousOrNextItem.LineNumber, Rules.BlockStatementsMustNotContainEmbeddedRegions);
            }
        }
        /// <summary>
        /// Gets the non-whitespace item that appears before the given item.
        /// </summary>
        /// <param name="item">The original item.</param>
        /// <returns>Returns the previous item.</returns>
        private static LexicalElement GetPreviousNonWhitespaceItem(CodeUnit item)
        {
            Param.AssertNotNull(item, "item");

            for (LexicalElement previous = item.FindPreviousLexicalElement(); previous != null; previous = previous.FindPreviousLexicalElement())
            {
                if (!previous.Is(LexicalElementType.EndOfLine) && !previous.Is(LexicalElementType.WhiteSpace))
                {
                    return(previous);
                }
            }

            return(null);
        }
        /// <summary>
        /// Checks the given list of statements.
        /// </summary>
        /// <param name="element">The element containing the statements.</param>
        /// <param name="statementParent">The parent of the statement to check.</param>
        private void CheckStatementFormattingRulesForStatements(Element element, CodeUnit statementParent)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(statementParent, "statementParent");

            Statement previousStatement = null;

            // Check each statement in the list.
            for (Statement statement = statementParent.FindFirstChildStatement(); statement != null; statement = statement.FindNextSiblingStatement())
            {
                this.CheckStatementFormattingRulesForStatement(element, statement, previousStatement);
                previousStatement = statement;
            }
        }
Beispiel #20
0
        public Token(string text, TokenType tokenType, bool wasEscaped, bool inDocComment, int lineNumber, int columnNumber, int newLines, string leadingWhitespace)
#endif
        {
            Text              = text;
            TokenType         = tokenType;
            WasEscaped        = wasEscaped;
            _inDocComment     = inDocComment;
            LineNumber        = lineNumber;
            ColumnNumber      = (ushort)columnNumber;
            NewLines          = (ushort)newLines;
            LeadingWhitespace = leadingWhitespace;
#if DEBUG
            CodeUnit = codeUnit;
#endif
        }
        /// <summary>
        /// Checks the argument list to a method or method invocation to ensure that the arguments are
        /// positioned correctly.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The element's argument list.</param>
        /// <param name="arguments">The arguments to the method.</param>
        /// <param name="openingBracket">The opening bracket token.</param>
        /// <param name="methodLineNumber">The line number on which the method begins.</param>
        private void CheckMethodArgumentList(Element element, CodeUnit parameterList, IArgumentList arguments, OpenBracketToken openingBracket, int methodLineNumber)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.AssertNotNull(arguments, "arguments");
            Param.AssertNotNull(openingBracket, "openingBracket");
            Param.AssertGreaterThanZero(methodLineNumber, "methodLineNumber");

            // Determine whether all of the parameters are on the same line as one another.
            bool someParametersShareLine;
            bool someParameterOnDifferentLines;

            DetermineMethodParameterPlacementScheme(
                arguments, out someParametersShareLine, out someParameterOnDifferentLines);

            // All parameters must either be on the same line, or each argument must begin on its own line.
            if (someParametersShareLine && someParameterOnDifferentLines)
            {
                this.AddViolation(
                    element,
                    methodLineNumber,
                    Rules.ParametersMustBeOnSameLineOrSeparateLines,
                    element.FriendlyTypeText);
            }

            // Determine whether all of the parameters are on the same line as one another.
            if (someParameterOnDifferentLines)
            {
                this.CheckSplitMethodArgumentList(element, parameterList, arguments, openingBracket);
            }
            else if (arguments.Count > 0)
            {
                // The first argument must start on the same line as the opening bracket, or
                // on the line after it.
                int firstArgumentStartLine = arguments.Location(0).LineNumber;

                if (firstArgumentStartLine != openingBracket.LineNumber &&
                    firstArgumentStartLine != openingBracket.LineNumber + 1)
                {
                    int commentLineSpan = MeasureCommentLinesAfter(openingBracket);

                    if (firstArgumentStartLine != openingBracket.LineNumber + commentLineSpan + 1)
                    {
                        this.AddViolation(element, firstArgumentStartLine, Rules.ParameterListMustFollowDeclaration);
                    }
                }
            }
        }
Beispiel #22
0
        /// <summary>
        /// Visits one code unit in the document.
        /// </summary>
        /// <param name="codeUnit">The item being visited.</param>
        /// <param name="parentElement">The parent element, if any.</param>
        /// <param name="parentStatement">The parent statement, if any.</param>
        /// <param name="parentExpression">The parent expression, if any.</param>
        /// <param name="parentClause">The parent query clause, if any.</param>
        /// <param name="parentToken">The parent token, if any.</param>
        /// <param name="settings">The settings.</param>
        /// <returns>Returns true to continue, or false to stop the walker.</returns>
        private bool VisitCodeUnit(
            CodeUnit codeUnit,
            Element parentElement,
            Statement parentStatement,
            Expression parentExpression,
            QueryClause parentClause,
            Token parentToken,
            Settings settings)
        {
            Param.AssertNotNull(codeUnit, "codeUnit");
            Param.Ignore(parentElement, parentStatement, parentExpression, parentClause, parentToken);
            Param.AssertNotNull(settings, "settings");

            if (codeUnit.CodeUnitType == CodeUnitType.Element)
            {
                return(this.VisitElement((Element)codeUnit, settings));
            }
            else if (codeUnit.CodeUnitType == CodeUnitType.Expression)
            {
                return(this.VisitExpression((Expression)codeUnit, parentElement));
            }
            else if (codeUnit.Is(LexicalElementType.Token))
            {
                Token token = (Token)codeUnit;
                if (token.TokenType == TokenType.Type && !token.Parent.Is(TokenType.Type))
                {
                    // Check that the type is using the built-in types, if applicable.
                    this.CheckBuiltInType((TypeToken)token, parentElement);
                }
                else if (token.TokenType == TokenType.String)
                {
                    // Check that the string is not using the empty string "" syntax.
                    this.CheckEmptyString(token, parentElement);
                }
            }
            else if (codeUnit.Is(PreprocessorType.Region))
            {
                this.CheckRegion((RegionDirective)codeUnit, parentElement, settings);
            }
            else if (codeUnit.Is(LexicalElementType.Comment))
            {
                this.CheckForEmptyComments((Comment)codeUnit, parentElement);
            }

            return(!this.Cancel);
        }
Beispiel #23
0
        private string GetName(CodeUnit codeUnit, string line)
        {
            int start;
            int end;

            if (codeUnit == CodeUnit.Class)
            {
                start = 22; // "\tpublic partial class ".Length
                end   = line.IndexOf(':', start) - 1;
            }
            else // if (codeUnit == CodeUnit.Enum)
            {
                start = 13; // "\tpublic enum ".Length
                end   = line.Length;
            }

            return(line.Substring(start, end - start));
        }
        CodeUnit CheckForPartialTypes(CodeUnit codeUnit)
        {
            CodeTypeDeclarationCollection types;
            CompileUnitPartialType        partialType;
            string partialTypeName;
            List <CompileUnitPartialType> tmp;
            Dictionary <string, List <CompileUnitPartialType> > partialTypes = PartialTypes;

            foreach (CodeNamespace ns in codeUnit.Unit.Namespaces)
            {
                if (ns == null)
                {
                    continue;
                }
                types = ns.Types;
                if (types == null || types.Count == 0)
                {
                    continue;
                }

                foreach (CodeTypeDeclaration type in types)
                {
                    if (type == null)
                    {
                        continue;
                    }

                    if (type.IsPartial)
                    {
                        partialType     = new CompileUnitPartialType(codeUnit.Unit, ns, type);
                        partialTypeName = partialType.TypeName;

                        if (!partialTypes.TryGetValue(partialTypeName, out tmp))
                        {
                            tmp = new List <CompileUnitPartialType> (1);
                            partialTypes.Add(partialTypeName, tmp);
                        }
                        tmp.Add(partialType);
                    }
                }
            }

            return(codeUnit);
        }
        /// <summary>
        /// Parses the given query clause.
        /// </summary>
        /// <param name="clause">The query clause.</param>
        /// <param name="parentExpression">The parent expression, if there is one.</param>
        /// <param name="parentElement">The element that contains the expressions.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForQueryClause(
            QueryClause clause,
            Expression parentExpression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary <string, List <Element> > members)
        {
            Param.AssertNotNull(clause, "clause");
            Param.Ignore(parentExpression);
            Param.AssertNotNull(parentElement, "parentElement");
            Param.AssertNotNull(parentClass, "parentClass");
            Param.AssertNotNull(members, "members");

            for (CodeUnit child = clause.FindFirstChild(); child != null; child = child.FindNextSibling())
            {
                if (child.Is(CodeUnitType.QueryClause))
                {
                    this.CheckClassMemberRulesForQueryClause((QueryClause)child, parentExpression, parentElement, parentClass, members);
                }
                else if (child.Is(CodeUnitType.Expression))
                {
                    this.CheckClassMemberRulesForExpression((Expression)child, parentExpression, parentElement, parentClass, members);
                }
                else if (child.Is(TokenType.Literal))
                {
                    Token token = (Token)child;

                    // Check to see whether this literal is preceded by a member access symbol. If not
                    // then we want to check whether this is a reference to one of our class members.
                    if (!IsLiteralTokenPrecededByMemberAccessSymbol(token))
                    {
                        // Process the literal.
                        this.CheckClassMemberRulesForLiteralToken(
                            token,
                            parentExpression,
                            parentExpression,
                            parentElement,
                            parentClass,
                            members);
                    }
                }
            }
        }
        /// <summary>
        /// Checks the given list of expressions.
        /// </summary>
        /// <param name="element">The element containing the expressions.</param>
        /// <param name="expressionParent">The parent of the expressions to check.</param>
        private void CheckStatementFormattingRulesForExpressions(Element element, CodeUnit expressionParent)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expressionParent, "expressionParent");

            for (Expression expression = expressionParent.FindFirstChildExpression(); expression != null; expression = expression.FindNextSiblingExpression())
            {
                if (expression.ExpressionType == ExpressionType.AnonymousMethod)
                {
                    // Check the statements within this anonymous method expression.
                    AnonymousMethodExpression anonymousMethod = expression as AnonymousMethodExpression;
                    this.CheckStatementFormattingRulesForStatements(element, anonymousMethod);
                }
                else
                {
                    // Check the child expressions under this expression.
                    this.CheckStatementFormattingRulesForExpressions(element, expression);
                }
            }
        }
        /// <summary>
        /// Measures the number of lines taken up by comments after the start item before the first word.
        /// </summary>
        /// <param name="start">The start item.</param>
        /// <returns>Returns the number of lines takes up by comments.</returns>
        private static int MeasureCommentLinesAfter(CodeUnit start)
        {
            Param.AssertNotNull(start, "start");

            int lineSpan = 0;

            int previousLineSpan      = -1;
            int previousEndLineNumber = -1;

            for (CodeUnit next = start.FindNext(); next != null; next = next.FindNext())
            {
                if (next.Is(LexicalElementType.Comment) || next.Is(CodeUnitType.Attribute))
                {
                    int itemLineSpan = ParameterPrewordOffset(next);

                    if (previousEndLineNumber > 0 && next.LineNumber == previousEndLineNumber && previousLineSpan > 0)
                    {
                        --itemLineSpan;
                    }

                    lineSpan             += itemLineSpan;
                    previousLineSpan      = itemLineSpan;
                    previousEndLineNumber = next.Location.EndPoint.LineNumber;
                    next = next.FindLast();
                }
                else if (!next.Is(LexicalElementType.WhiteSpace) &&
                         !next.Is(LexicalElementType.EndOfLine) &&
                         !next.Is(CodeUnitType.ParameterList) &&
                         !next.Is(CodeUnitType.ArgumentList) &&
                         !next.Is(CodeUnitType.Parameter) &&
                         !next.Is(CodeUnitType.Argument))
                {
                    break;
                }
            }

            return(lineSpan);
        }
        /// <summary>
        /// Determines the amount of offset to add to the line number of the next argument
        /// for a comment or attribute.
        /// </summary>
        /// <param name="item">The starting item.</param>
        /// <returns>Returns the amount of offset to add.</returns>
        private static int ParameterPrewordOffset(CodeUnit item)
        {
            Param.AssertNotNull(item, "tokenNode");

            Debug.Assert(item.Is(CodeUnitType.Attribute) || item.Is(LexicalElementType.Comment), "The item must be an attribute or a comment.");

            // Find the start of the next argument.
            for (CodeUnit next = item.FindLast().FindNext(); next != null; next = next.FindNext())
            {
                if (next.Is(LexicalElementType.EndOfLine))
                {
                    return(item.Location.LineSpan);
                }
                else if (!next.Is(LexicalElementType.WhiteSpace) &&
                         !next.Is(LexicalElementType.WhiteSpace) &&
                         !next.Is(CodeUnitType.Attribute))
                {
                    return(Math.Max(0, next.Location.StartPoint.LineNumber - item.Location.StartPoint.LineNumber));
                }
            }

            return(0);
        }
        /// <summary>
        /// Checks a method or method invocation to ensure that the opening bracket is
        /// on the same line as the method declaration.
        /// </summary>
        /// <param name="element">The element containing the expression.</param>
        /// <param name="parameterList">The argument list.</param>
        /// <param name="openingBracketType">The type of the bracket that opens the argument list.</param>
        /// <returns>Returns the opening bracket.</returns>
        private OpenBracketToken CheckMethodOpeningBracket(Element element, CodeUnit parameterList, TokenType openingBracketType)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(parameterList, "parameterList");
            Param.Ignore(openingBracketType);

            // Find the opening bracket.
            OpenBracketToken openingBracket = null;

            Token firstDeclarationToken = element.FirstDeclarationToken;

            if (firstDeclarationToken != null)
            {
                Token previous = parameterList.FindPreviousSiblingToken();
                if (previous != null && previous.Is(openingBracketType))
                {
                    openingBracket = (OpenBracketToken)previous;
                }

                if (openingBracket != null)
                {
                    // Find the last word before the opening bracket.
                    Token lastWord = openingBracket.FindPreviousToken();

                    if (lastWord != null && openingBracket.LineNumber != lastWord.LineNumber)
                    {
                        this.AddViolation(
                            element,
                            openingBracket.LineNumber,
                            Rules.OpeningParenthesisMustBeOnDeclarationLine,
                            element.FriendlyTypeText);
                    }
                }
            }

            return(openingBracket);
        }
Beispiel #30
0
        /// <summary>
        /// Records information about the given item, under the given node.
        /// </summary>
        /// <param name="item">The item to record.</param>
        /// <param name="parentNode">The Xml node to record this item beneath.</param>
        /// <returns>Returns the new Xml node describing this item.</returns>
        private static XmlNode RecordItem(CodeUnit item, XmlNode parentNode)
        {
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parentNode, "parentNode");

            // Create a new node for this item and add it to the parent.
            XmlNode codeUnitNode = parentNode.OwnerDocument.CreateElement("CodeUnit");

            parentNode.AppendChild(codeUnitNode);

            if (item.Is(CodeUnitType.LexicalElement))
            {
                XmlAttribute text = parentNode.OwnerDocument.CreateAttribute("Text");
                text.Value = ((LexicalElement)item).Text;
                codeUnitNode.Attributes.Append(text);
            }

            XmlAttribute type = parentNode.OwnerDocument.CreateAttribute("Type");

            type.Value = item.GetType().Name;
            codeUnitNode.Attributes.Append(type);

            return(codeUnitNode);
        }
        /// <summary>
        /// Parses the given statement list.
        /// </summary>
        /// <param name="statementParent">The direct parent of the statements to check.</param>
        /// <param name="parentElement">The element that contains the statements.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForStatements(
            CodeUnit statementParent,
            Element parentElement,
            ClassBase parentClass,
            Dictionary <string, List <Element> > members)
        {
            Param.AssertNotNull(statementParent, "statementParent");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Loop through each of the statements.
            for (Statement statement = statementParent.FindFirstChildStatement(); statement != null; statement = statement.FindNextSiblingStatement())
            {
                if (statement.Children.StatementCount > 0)
                {
                    // Parse the sub-statements.
                    this.CheckClassMemberRulesForStatements(statement, parentElement, parentClass, members);
                }

                // Parse the expressions in the statement.
                this.CheckClassMemberRulesForExpressions(statement, null, parentElement, parentClass, members);
            }
        }
Beispiel #32
0
        /// <summary>
        /// Finds the condition expression if there is one.
        /// </summary>
        /// <param name="start">The code unit in front of the expression.</param>
        /// <returns>Returns the condition expression or null.</returns>
        private Expression FindCondition(CodeUnit start)
        {
            Param.AssertNotNull(start, "start");

            for (CodeUnit c = start.FindNextSibling(); c != null; c = c.FindNextSibling())
            {
                if (!c.Is(CodeUnitType.LexicalElement) || c.Is(LexicalElementType.Token))
                {
                    if (c.Is(TokenType.Semicolon))
                    {
                        return null;
                    }

                    if (c.Is(CodeUnitType.Expression))
                    {
                        return (Expression)c;
                    }

                    break;
                }
            }

            throw new SyntaxException(this.Document, this.LineNumber);
        }
Beispiel #33
0
        /// <summary>
        /// Finds the end of a name, moving past member access operators.
        /// </summary>
        /// <param name="document">The document containing the tokens.</param>
        /// <param name="codeUnit">The code unit.</param>
        /// <param name="startToken">The first token of the name.</param>
        /// <param name="endToken">Returns the last token of the name.</param>
        /// <returns>Returns the full name.</returns>
        internal static string GetFullName(CsDocument document, CodeUnit codeUnit, Token startToken, out Token endToken)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(codeUnit, "codeUnit");
            Param.AssertNotNull(startToken, "start");

            endToken = CodeParser.FindEndOfName(document, codeUnit, startToken);
            CsLanguageService.Debug.Assert(endToken != null, "Did not find the end of the name");

            // Create the text string.
            var text = new StringBuilder();

            Token token = startToken;
            while (token != null)
            {
                text.Append(token.Text);

                if (token == endToken)
                {
                    break;
                }

                token = token.FindNextSiblingToken();
            }

            return text.ToString();
        }
Beispiel #34
0
        /// <summary>
        /// Checks the placement of curly brackets within the given item.
        /// </summary>
        /// <param name="item">The item containing the brackets to check.</param>
        /// <param name="parentElement">The element containing the brackets.</param>
        /// <param name="parentStatement">The statement containing the brackets, if any.</param>
        /// <param name="openBracket">The opening curly bracket within the token list.</param>
        /// <param name="allowAllOnOneLine">Indicates whether the brackets are allowed to be all on one line.</param>
        private void CheckBracketPlacement(
            CodeUnit item,
            Element parentElement,
            Statement parentStatement,
            OpenBracketToken openBracket,
            bool allowAllOnOneLine)
        {
            Param.AssertNotNull(item, "item");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentStatement);
            Param.AssertNotNull(openBracket, "openBracket");
            Param.Ignore(allowAllOnOneLine);

            if (openBracket.MatchingBracket != null &&
                !openBracket.Generated &&
                !openBracket.MatchingBracket.Generated)
            {
                // Check if the two brackets are on the same line as each other.
                if (openBracket.LineNumber == openBracket.MatchingBracket.LineNumber)
                {
                    // This is an error if the brackets are not allowed to be all on the same line.
                    if (!allowAllOnOneLine)
                    {
                        // Statements within constructor initializers are allowed to be all on the same line
                        // since sometimes this is the only way to write the statement.
                        if (parentStatement == null)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.ElementMustNotBeOnSingleLine, parentElement.FriendlyTypeText);
                        }
                        else if (parentStatement.StatementType != StatementType.ConstructorInitializer)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.StatementMustNotBeOnSingleLine);
                        }
                    }
                    else
                    {
                        // The brackets are only allowed to be on the same line if the entire statement is on the same line.
                        Token first = item.FindFirstDescendentToken();
                        Token last  = item.FindLastDescendentToken();

                        if (first != null && last != null && first.LineNumber != last.LineNumber)
                        {
                            this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket));
                        }
                    }
                }
                else
                {
                    // The brackets are on different lines. Both brackets must be on a line all by themselves.
                    if (LayoutRules.BracketSharesLine(openBracket, false))
                    {
                        this.AddViolation(parentElement, openBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket));
                    }

                    if (LayoutRules.BracketSharesLine(openBracket.MatchingBracket, true))
                    {
                        this.AddViolation(parentElement, openBracket.MatchingBracket.LineNumber, Rules.CurlyBracketsForMultiLineStatementsMustNotShareLine, GetOpeningOrClosingBracketText(openBracket.MatchingBracket));
                    }
                }
            }
        }
Beispiel #35
0
		CodeUnit CheckForPartialTypes (CodeUnit codeUnit)
		{
			CodeTypeDeclarationCollection types;
			CompileUnitPartialType partialType;
			string partialTypeName;
			List <CompileUnitPartialType> tmp;
			Dictionary <string, List <CompileUnitPartialType>> partialTypes = PartialTypes;
			
			foreach (CodeNamespace ns in codeUnit.Unit.Namespaces) {
				if (ns == null)
					continue;
				types = ns.Types;
				if (types == null || types.Count == 0)
					continue;

				foreach (CodeTypeDeclaration type in types) {
					if (type == null)
						continue;

					if (type.IsPartial) {
						partialType = new CompileUnitPartialType (codeUnit.Unit, ns, type);
						partialTypeName = partialType.TypeName;
						
						if (!partialTypes.TryGetValue (partialTypeName, out tmp)) {
							tmp = new List <CompileUnitPartialType> (1);
							partialTypes.Add (partialTypeName, tmp);
						}
						tmp.Add (partialType);
					}
				}
			}
						
			return codeUnit;
		}
        /// <summary>
        /// Parses the list of expressions.
        /// </summary>
        /// <param name="expressionParent">The direct parent of the expressions to check.</param>
        /// <param name="parentExpression">The parent expression, if there is one.</param>
        /// <param name="parentElement">The element that contains the expressions.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForExpressions(
            CodeUnit expressionParent,
            Expression parentExpression,
            Element parentElement,
            ClassBase parentClass,
            Dictionary<string, List<Element>> members)
        {
            Param.AssertNotNull(expressionParent, "expressionParent");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentExpression);
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Loop through each of the expressions in the list.
            for (Expression expression = expressionParent.FindFirstChildExpression(); expression != null; expression = expression.FindNextSiblingExpression())
            {
                // If the expression is a variable declarator expression, we don't 
                // want to match against the identifier tokens.
                if (expression.ExpressionType == ExpressionType.VariableDeclarator)
                {
                    VariableDeclaratorExpression declarator = (VariableDeclaratorExpression)expression;
                    if (declarator.Initializer != null)
                    {
                        this.CheckClassMemberRulesForExpression(declarator.Initializer, parentExpression, parentElement, parentClass, members);
                    }
                }
                else
                {
                    this.CheckClassMemberRulesForExpression(expression, parentExpression, parentElement, parentClass, members);
                }
            }
        }
Beispiel #37
0
        private void CheckCloseSquareBracket(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Close brackets should never be preceded by whitespace.
            LexicalElement previousItem = token.FindNextLexicalElement();
            if (previousItem != null &&
                (previousItem.LexicalElementType == LexicalElementType.WhiteSpace || previousItem.LexicalElementType == LexicalElementType.EndOfLine))
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingSquareBracketsMustBeSpacedCorrectly);
            }

            // Close brackets should be followed either by whitespace, a bracket,
            // a paren, a semicolon, a comma, a period, or an increment or decrement symbol.
            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null)
            {
                if (nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !nextItem.Is(TokenType.CloseParenthesis) &&
                    !nextItem.Is(TokenType.OpenParenthesis) &&      // someDictionary["Test"]();
                    !nextItem.Is(TokenType.CloseSquareBracket) &&   // someIndexer[someArray[1]] = 2;
                    !nextItem.Is(TokenType.OpenSquareBracket) &&    // someArray[1][2] = 2;
                    !nextItem.Is(TokenType.Semicolon) &&
                    !nextItem.Is(TokenType.Comma) &&
                    !nextItem.Is(TokenType.CloseGenericBracket) &&
                    nextItem.Text != "++" &&
                    nextItem.Text != "--" &&
                    !nextItem.Text.StartsWith(".", StringComparison.Ordinal))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingSquareBracketsMustBeSpacedCorrectly);
                }

                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    // If this is followed by whitespace, make sure that the character just
                    // after the whitespace is not a paren, bracket, comma, or semicolon.
                    for (LexicalElement item = nextItem.FindNextLexicalElement(); item != null; item = item.FindNextLexicalElement())
                    {
                        if (item.Is(TokenType.CloseParenthesis) ||
                            item.Is(TokenType.OpenParenthesis) ||
                            item.Is(TokenType.CloseSquareBracket) ||
                            item.Is(TokenType.OpenSquareBracket) ||
                            item.Is(TokenType.Semicolon) ||
                            item.Is(TokenType.Comma))
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingSquareBracketsMustBeSpacedCorrectly);
                        }
                        else if (item.LexicalElementType != LexicalElementType.WhiteSpace)
                        {
                            break;
                        }
                    }
                }
            }
        }
Beispiel #38
0
        private void CheckOpenParen(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            bool firstOnLine = false;
            bool lastOnLine = false;
            
            // Open parenthesis should never be preceded by whitespace unless it is the
            // first thing on the line or it follows a keyword or it follows a symbol or a number.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.LexicalElementType == LexicalElementType.WhiteSpace)
                        {
                            continue;
                        }
                        else if (item.LexicalElementType == LexicalElementType.EndOfLine)
                        {
                            firstOnLine = true;
                            break;
                        }
                        else if (
                            item.Is(TokenType.Case) ||
                            item.Is(TokenType.Catch) ||
                            item.Is(TokenType.CloseSquareBracket) ||
                            item.Is(TokenType.Comma) ||
                            item.Is(TokenType.Equals) ||
                            item.Is(TokenType.Fixed) ||
                            item.Is(TokenType.For) ||
                            item.Is(TokenType.Foreach) ||
                            item.Is(TokenType.From) ||
                            ////item.Is(TokenType.Goto) ||
                            item.Is(TokenType.Group) ||
                            item.Is(TokenType.If) ||
                            item.Is(TokenType.In) ||
                            item.Is(TokenType.Into) ||
                            item.Is(TokenType.Join) ||
                            item.Is(TokenType.Let) ||
                            item.Is(TokenType.Lock) ||
                            item.Is(CommentType.MultilineComment) ||
                            ////item.Is(TokenType.New) ||
                            item.Is(TokenType.Number) ||
                            item.Is(TokenType.OperatorSymbol) ||
                            item.Is(TokenType.OpenCurlyBracket) ||
                            item.Is(TokenType.OrderBy) ||
                            item.Is(TokenType.Return) ||
                            item.Is(TokenType.Select) ||
                            item.Is(TokenType.Semicolon) ||
                            ////item.Is(CommentType.SingleLineComment) ||
                            item.Is(TokenType.Switch) ||
                            item.Is(TokenType.Throw) ||
                            item.Is(TokenType.Using) ||
                            item.Is(TokenType.Where) ||
                            item.Is(TokenType.While) ||
                            item.Is(TokenType.WhileDo) ||
                            item.Is(TokenType.Yield))
                        {
                            break;
                        }
                        else
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningParenthesisMustBeSpacedCorrectly);
                        }
                    }
                }
            }

            // Open parens should never be followed by whitespace unless
            // it is the last thing on the line.
            LexicalElement next = token.FindPreviousLexicalElement();
            if (next != null &&
                (next.LexicalElementType == LexicalElementType.WhiteSpace || next.LexicalElementType == LexicalElementType.EndOfLine))
            {
                // Look to see if there is any non whitespace character
                // on this line other than a comment.
                for (LexicalElement item = next.FindNextLexicalElement(); item != null; item = item.FindNextLexicalElement())
                {
                    if (item.LexicalElementType == LexicalElementType.EndOfLine)
                    {
                        lastOnLine = true;
                        break;
                    }
                    else if (item.LexicalElementType != LexicalElementType.WhiteSpace &&
                        !item.Is(CommentType.SingleLineComment) &&
                        !item.Is(CommentType.MultilineComment))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningParenthesisMustBeSpacedCorrectly);
                        break;
                    }
                }
            }

            // Open parens cannot be the only thing on the line.
            if (firstOnLine && lastOnLine)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningParenthesisMustBeSpacedCorrectly);
            }
        }
Beispiel #39
0
        /// <summary>
        /// Finds the end of the given name, moving past member access operators.
        /// </summary>
        /// <param name="document">The document containing the name.</param>
        /// <param name="codeUnit">The code unit.</param>
        /// <param name="startToken">The first token of the name.</param>
        /// <returns>Returns the last token of the name within the token list.</returns>
        internal static Token FindEndOfName(CsDocument document, CodeUnit codeUnit, Token startToken)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(codeUnit, "codeUnit");
            Param.AssertNotNull(startToken, "startToken");

            Token endToken = startToken;

            bool accessSymbol = false;

            for (Token temp = startToken; temp != null; temp = temp.FindNextSiblingToken())
            {
                if (accessSymbol)
                {
                    if (temp.TokenType != TokenType.Literal)
                    {
                        throw new SyntaxException(document, temp.LineNumber);
                    }

                    endToken = temp;
                    accessSymbol = false;
                }
                else
                {
                    if (temp.Text == "." || temp.Text == "::")
                    {
                        accessSymbol = true;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            return endToken;
        }
Beispiel #40
0
        private static void ValidateCodeUnitReferences(CodeUnit root)
        {
            Param.AssertNotNull(root, "root");

            if (root != null)
            {
                root.ValidateCodeUnitReference(); 
                
                foreach (CodeUnit child in root.Children)
                {
                    ValidateCodeUnitReferences(child);
                }
            }
        }
        private void SplitFileByCodeUnit(CodeUnit codeUnit, string filePath, IEnumerable<string> lines)
        {
            var directory = Path.GetDirectoryName(filePath) ?? String.Empty;
            var currentStage = SplitStage.Header;
            var header = new List<string>();
            var code = new List<string>();
            var name = String.Empty;
            var proxyTypesAssemblyAttributeLine = string.Empty;
            var skipNext = false;
            var commandLine = String.Empty;
            var codeUnitStartsWith = codeUnit == CodeUnit.Class ? "public partial class" : "public enum";
            var files = new List<FileToCreate>(); // Delay this to the end to multithread the creation.  100's of small files takes a long time if checking with TFS sequentially

            foreach (var line in lines)
            {
                if (skipNext) { skipNext = false; continue; }

                switch (currentStage)
                {
                    case SplitStage.Header:
                        if (String.IsNullOrEmpty(line))
                        {
                            currentStage = SplitStage.Namespace;
                            header.Add(line);
                        }
                        else if (line.StartsWith(@"// Created via this command line:"))
                        {
                            // Since we are splitting the files, we don't want to put the command line in each file.  It would show every file as having been updated each time you change the path or user
                            commandLine = line;
                        }
                        else
                        {
                            header.Add(line);
                        }
                        break;

                    case SplitStage.Namespace:
                        if (header.Last().StartsWith("namespace "))
                        {
                            currentStage = SplitStage.CodeUnitHeader;
                            skipNext = true;
                        }
                        if (line.Contains("ProxyTypesAssemblyAttribute"))
                        {
                            proxyTypesAssemblyAttributeLine = line;
                            skipNext = true;
                            continue;
                        }
                        header.Add(line);
                        break;

                    case SplitStage.CodeUnitHeader:
                        if (line.TrimStart().StartsWith(codeUnitStartsWith))
                        {
                            name = GetName(codeUnit, line);
                            if (line.Contains(": Microsoft.Xrm.Sdk.Client.OrganizationServiceContext") || // Standard
                                line.Contains(": Microsoft.Xrm.Client.CrmOrganizationServiceContext")) // Xrm Client
                            {
                                // Put Created Via Command Line Back in
                                header.Insert(header.IndexOf(@"// </auto-generated>")+1, commandLine);
                                commandLine = string.Empty;
                                // Put Proxy Types Assembly Attribute Line back in
                                var i = header.IndexOf(String.Empty, 0) + 1;
                                header.Insert(i++, proxyTypesAssemblyAttributeLine);
                                header.Insert(i, String.Empty);
                                currentStage = SplitStage.ServiceContext;
                            }
                            else
                            {
                                currentStage = SplitStage.CodeUnit;
                            }
                        }
                        code.Add(line);
                        break;

                    case SplitStage.CodeUnit:
                        code.Add(line);
                        if (line == "\t}")
                        {
                            code.Add("}");
                            var fileName = Path.Combine(directory, name + ".cs");
                            files.Add(new FileToCreate(fileName, String.Join(Environment.NewLine, header.Concat(code))));
                            code.Clear();
                            currentStage = SplitStage.CodeUnitHeader;
                        }
                        break;

                    case SplitStage.ServiceContext:
                        code.Add(line);
                        break;

                    default:
                        throw new Exception("No Enum Defined");
                }
            }

            files.Add(new FileToCreate(filePath, String.IsNullOrWhiteSpace(commandLine) ? String.Join(Environment.NewLine, header.Concat(code)) : commandLine, true));

            WriteFilesAsync(files);
        }
        /// <summary>
        /// Checks the given list of expressions.
        /// </summary>
        /// <param name="element">The element containing the expressions.</param>
        /// <param name="expressionParent">The parent of the expressions to check.</param>
        private void CheckStatementFormattingRulesForExpressions(Element element, CodeUnit expressionParent)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(expressionParent, "expressionParent");

            for (Expression expression = expressionParent.FindFirstChildExpression(); expression != null; expression = expression.FindNextSiblingExpression())
            {
                if (expression.ExpressionType == ExpressionType.AnonymousMethod)
                {
                    // Check the statements within this anonymous method expression.
                    AnonymousMethodExpression anonymousMethod = expression as AnonymousMethodExpression;
                    this.CheckStatementFormattingRulesForStatements(element, anonymousMethod);
                }
                else
                {
                    // Check the child expressions under this expression.
                    this.CheckStatementFormattingRulesForExpressions(element, expression);
                }
            }
        }
Beispiel #43
0
        /// <summary>
        /// Checks a symbol for spacing.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckSymbol(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Symbols should have whitespace on both sides.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null &&
                previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                previousItem.LexicalElementType != LexicalElementType.EndOfLine)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, token.Text);
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null &&
                nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                nextItem.LexicalElementType != LexicalElementType.EndOfLine)
            {
                // Make sure the previous token is not operator.
                if (previousItem != null)
                {
                    for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.Is(TokenType.Operator))
                        {
                            return;
                        }
                        else if (item.LexicalElementType != LexicalElementType.WhiteSpace &&
                            item.LexicalElementType != LexicalElementType.EndOfLine &&
                            !item.Is(CommentType.SingleLineComment) &&
                            !item.Is(CommentType.MultilineComment) &&
                            item.LexicalElementType != LexicalElementType.PreprocessorDirective)
                        {
                            break;
                        }
                    }
                }

                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.SymbolsMustBeSpacedCorrectly, token.Text);
            }
        }
Beispiel #44
0
        /// <summary>
        /// Attaches this proxy to its code unit.
        /// </summary>
        /// <param name="codeUnit">The code unit to attach to.</param>
        public void Attach(CodeUnit codeUnit)
        {
            Param.AssertNotNull(codeUnit, "codeUnit");
            this.target = codeUnit;

            CsLanguageService.Debug.Assert(this.document != null || codeUnit.Is(ElementType.Document), "Only a document element can have a proxy with a null document property.");
        }
Beispiel #45
0
        /// <summary>
        /// Checks to make sure that the slashes in in the comment are followed by a space.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="comment">The comment.</param>
        private void CheckSingleLineComment(CodeUnit root, Comment comment)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(comment, "comment");

            // If the token length is less then two, this is not a valid comment so just ignore it.
            string text = comment.Text;
            if (text.Length > 2)
            {
                // The first character in the comment must be a space, except for the following four cases:
                // 1. The comment may start with three or more slashes: ///whatever
                // 2. The command may start with a backwards slash: //\whatever
                // 3. The comment may start with a dash if there are at last two dashes: //--
                // 4. The character after the second slash may be a newline character.
                if (text[2] != ' ' &&
                    text[2] != '\t' &&
                    text[2] != '/' &&
                    text[2] != '\\' &&
                    text[1] != '\n' &&
                    text[1] != '\r' &&
                    (text.Length < 4 || text[2] != '-' || text[3] != '-'))
                {
                    // The comment does not start with a single space.
                    this.AddViolation(comment.FindParentElement(), comment.LineNumber, Rules.SingleLineCommentsMustBeginWithSingleSpace);
                }
                else if (text.Length > 3 && (text[3] == ' ' || text[3] == '\t') && text[2] != '\\')
                {
                    // The comment starts with more than one space. This is only a violation if this is the first 
                    // single-line comment in a row. If there is another single-line comment directly above this one
                    // with no blank line between them, this is not a violation.
                    bool first = true;
                    int newLineCount = 0;

                    for (LexicalElement previousItem = comment.FindPreviousLexicalElement(); previousItem != null; previousItem = previousItem.FindPreviousLexicalElement())
                    {
                        if (previousItem.LexicalElementType == LexicalElementType.EndOfLine)
                        {
                            if (++newLineCount == 2)
                            {
                                break;
                            }
                        }
                        else if (previousItem.Is(CommentType.SingleLineComment))
                        {
                            first = false;
                            break;
                        }
                        else if (previousItem.LexicalElementType != LexicalElementType.WhiteSpace)
                        {
                            break;
                        }
                    }

                    if (first)
                    {
                        this.AddViolation(comment.FindParentElement(), comment.LineNumber, Rules.SingleLineCommentsMustBeginWithSingleSpace);
                    }
                }
            }
        }
Beispiel #46
0
        private void CheckSpacing(CodeUnit root, bool type)
        {
            Param.AssertNotNull(root, "root");
            Param.Ignore(type);

            // Make sure it contains at least one token.
            for (CodeUnit item = root.FindFirst(); item != null; item = item.FindNext(root))
            {
                if (this.Cancel)
                {
                    break;
                }

                if (!item.Generated)
                {
                    if (item.Is(TokenType.OperatorSymbol))
                    {
                        OperatorSymbolToken operatorSymbol = (OperatorSymbolToken)item;

                        switch (operatorSymbol.Category)
                        {
                            case OperatorCategory.Reference:
                                switch (operatorSymbol.SymbolType)
                                {
                                    case OperatorType.QualifiedAlias:
                                    case OperatorType.Pointer:
                                    case OperatorType.MemberAccess:
                                        this.CheckMemberAccessSymbol(root, operatorSymbol);
                                        break;

                                    case OperatorType.AddressOf:
                                    case OperatorType.Dereference:
                                        this.CheckUnsafeAccessSymbols(operatorSymbol, type);
                                        break;

                                    default:
                                        Debug.Fail("Unexpected operator category.");
                                        break;
                                }

                                break;

                            case OperatorCategory.Arithmetic:
                            case OperatorCategory.Assignment:
                            case OperatorCategory.Conditional:
                            case OperatorCategory.Logical:
                            case OperatorCategory.Relational:
                            case OperatorCategory.Shift:
                            case OperatorCategory.Lambda:
                                // Symbols should have whitespace on both sides
                                this.CheckSymbol(root, operatorSymbol);
                                break;

                            case OperatorCategory.IncrementDecrement:
                                this.CheckIncrementDecrement(operatorSymbol);
                                break;

                            case OperatorCategory.Unary:
                                if (operatorSymbol.SymbolType == OperatorType.Negative)
                                {
                                    this.CheckNegativeSign(operatorSymbol);
                                }
                                else if (operatorSymbol.SymbolType == OperatorType.Positive)
                                {
                                    this.CheckPositiveSign(operatorSymbol);
                                }
                                else
                                {
                                    this.CheckUnarySymbol(operatorSymbol);
                                }

                                break;
                        }
                    }
                    else if (item.Is(LexicalElementType.Token))
                    {
                        Token token = (Token)item;
                        switch (token.TokenType)
                        {
                            case TokenType.Catch:
                            case TokenType.Fixed:
                            case TokenType.For:
                            case TokenType.Foreach:
                            case TokenType.From:
                            case TokenType.Group:
                            case TokenType.If:
                            case TokenType.In:
                            case TokenType.Into:
                            case TokenType.Join:
                            case TokenType.Let:
                            case TokenType.Lock:
                            case TokenType.OrderBy:
                            case TokenType.Return:
                            case TokenType.Select:
                            case TokenType.Stackalloc:
                            case TokenType.Switch:
                            case TokenType.Throw:
                            case TokenType.Using:
                            case TokenType.Where:
                            case TokenType.While:
                            case TokenType.WhileDo:
                            case TokenType.Yield:
                                // These keywords must be followed by a space before the open parenthesis.
                                this.CheckKeywordWithSpace(token);
                                break;

                            case TokenType.New:
                                this.CheckNewKeywordSpacing(root, token);
                                break;

                            case TokenType.Checked:
                            case TokenType.Unchecked:
                            case TokenType.Sizeof:
                            case TokenType.Typeof:
                            case TokenType.DefaultValue:
                                // These keywords must not contain any space before the open parenthesis.
                                this.CheckKeywordWithoutSpace(root, token);
                                break;

                            case TokenType.Comma:
                            case TokenType.Semicolon:
                                this.CheckSemicolonAndComma(token);
                                break;

                            case TokenType.OpenParenthesis:
                                this.CheckOpenParen(root, token);
                                break;

                            case TokenType.CloseParenthesis:
                                this.CheckCloseParen(root, token);
                                break;

                            case TokenType.OpenSquareBracket:
                                this.CheckOpenSquareBracket(token);
                                break;

                            case TokenType.CloseSquareBracket:
                                this.CheckCloseSquareBracket(root, token);
                                break;

                            case TokenType.OpenCurlyBracket:
                                this.CheckOpenCurlyBracket(root, token);
                                break;

                            case TokenType.CloseCurlyBracket:
                                this.CheckCloseCurlyBracket(root, token);
                                break;

                            case TokenType.OpenAttributeBracket:
                                this.CheckAttributeTokenOpenBracket(token);
                                break;

                            case TokenType.CloseAttributeBracket:
                                this.CheckAttributeTokenCloseBracket(token);
                                break;

                            case TokenType.BaseColon:
                            case TokenType.WhereColon:
                                this.CheckSymbol(root, token);
                                break;

                            case TokenType.AttributeColon:
                            case TokenType.LabelColon:
                                this.CheckLabelColon(token);
                                break;

                            case TokenType.NullableTypeSymbol:
                                this.CheckNullableTypeSymbol(token);
                                break;

                            case TokenType.Operator:
                                this.CheckOperatorKeyword(token);
                                break;

                            case TokenType.OpenGenericBracket:
                                this.CheckGenericTokenOpenBracket(token);
                                break;

                            case TokenType.CloseGenericBracket:
                                this.CheckGenericTokenCloseBracket(token);
                                break;
                        }
                    }
                    else if (item.Is(CodeUnitType.LexicalElement))
                    {
                        LexicalElement lex = (LexicalElement)item;
                        switch (lex.LexicalElementType)
                        {
                            case LexicalElementType.WhiteSpace:
                                this.CheckWhitespace((Whitespace)item);
                                break;

                            case LexicalElementType.PreprocessorDirective:
                                this.CheckPreprocessorSpacing((PreprocessorDirective)item);
                                break;
                        }
                    }
                    else if (item.Is(LexicalElementType.Comment))
                    {
                        Comment comment = (Comment)item;
                        switch (comment.CommentType)
                        {
                            case CommentType.SingleLineComment:
                                // Look for tabs in the comment string.
                                this.CheckTabsInComment(comment);

                                // Check spacing in the comment.
                                this.CheckSingleLineComment(root, comment);
                                break;

                            case CommentType.MultilineComment:
                                // Look for tabs in the comment string.
                                this.CheckTabsInComment(comment);
                                break;
                        }
                    }
                    else
                    {
                        switch (item.CodeUnitType)
                        {
                            case CodeUnitType.ElementHeader:
                                ElementHeader header = (ElementHeader)item;
                                this.CheckXmlHeaderComment((ElementHeader)item);

                                // Look for tabs in the xml header string. Look at 
                                // each sub-token in the header individually to get the
                                // line numbers correct.
                                for (LexicalElement xmlHeaderItem = header.FindFirstDescendentLexicalElement(); xmlHeaderItem != null; xmlHeaderItem = xmlHeaderItem.FindNextDescendentLexicalElementOf(header))
                                {
                                    this.CheckTabsInComment(xmlHeaderItem);
                                }

                                break;
                        }
                    }
                }
            }
        }
Beispiel #47
0
        private void CheckCloseParen(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Close parens should never be preceded by whitespace.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null &&
                (previousItem.LexicalElementType == LexicalElementType.WhiteSpace || previousItem.LexicalElementType == LexicalElementType.EndOfLine))
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
            }

            // Find out what comes after the closing paren.
            LexicalElement nextItem = token.FindNextLexicalElement();
            LexicalElement nextNextItem = nextItem == null ? null : nextItem.FindNextLexicalElement();

            if (nextItem != null)
            {
                if (token.Parent is CastExpression)
                {
                    // There should not be any whitespace after the closing parenthesis in a cast expression.
                    if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                    }
                }
                else if (nextItem.Is(TokenType.LabelColon) || (nextNextItem != null && nextNextItem.Is(TokenType.LabelColon)))
                {
                    // If the next token is a colon, it's allowed to omit the whitespace only if we are in a switch\case statement.
                    bool followsCase = false;

                    for (LexicalElement item = token.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.LexicalElementType == LexicalElementType.EndOfLine)
                        {
                            break;
                        }
                        else if (item.Is(TokenType.Case))
                        {
                            followsCase = true;
                            break;
                        }
                    }

                    if ((followsCase && nextItem.LexicalElementType == LexicalElementType.WhiteSpace) ||
                        (!followsCase && nextItem.LexicalElementType != LexicalElementType.WhiteSpace))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                    }
                }
                else if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    if (nextNextItem != null)
                    {
                        // Make sure that the character just after the whitespace is not a paren, bracket, a comma, or a semicolon.
                        for (LexicalElement item = nextNextItem; item != null; item = item.FindNextLexicalElement())
                        {
                            if (IsAllowedAfterClosingParenthesis(item))
                            {
                                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                            }
                            else if (item.LexicalElementType != LexicalElementType.WhiteSpace)
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    // For all other types, the parenthesis must be followed by whitespace, unless the next character is a paren, bracket, comma, or a semicolon.
                    if (nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                        !IsAllowedAfterClosingParenthesis(nextItem))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingParenthesisMustBeSpacedCorrectly);
                    }
                }
            }
        }
Beispiel #48
0
        /// <summary>
        /// Checks a open bracket for spacing.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckOpenCurlyBracket(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Open curly brackets should be preceded either by whitespace, or an open paren.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null)
            {
                if (previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    previousItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !previousItem.Is(TokenType.OpenParenthesis))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningCurlyBracketsMustBeSpacedCorrectly);
                }

                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    // If this is preceded by whitespace, make sure that the character just
                    // before the whitespace is not an open paren.
                    for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                    {
                        if (item.Is(TokenType.OpenParenthesis))
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningCurlyBracketsMustBeSpacedCorrectly);
                        }
                        else if (item.LexicalElementType != LexicalElementType.WhiteSpace)
                        {
                            break;
                        }
                    }
                }
            }

            // Open curly brackets should always be followed by whitespace.
            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null &&
                nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                nextItem.LexicalElementType != LexicalElementType.EndOfLine)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.OpeningCurlyBracketsMustBeSpacedCorrectly);
            }
        }
        /// <summary>
        /// Parses the given statement list.
        /// </summary>
        /// <param name="statementParent">The direct parent of the statements to check.</param>
        /// <param name="parentElement">The element that contains the statements.</param>
        /// <param name="parentClass">The class that the element belongs to.</param>
        /// <param name="members">The collection of members of the parent class.</param>
        private void CheckClassMemberRulesForStatements(
            CodeUnit statementParent,
            Element parentElement,
            ClassBase parentClass,
            Dictionary<string, List<Element>> members)
        {
            Param.AssertNotNull(statementParent, "statementParent");
            Param.AssertNotNull(parentElement, "parentElement");
            Param.Ignore(parentClass);
            Param.Ignore(members);

            // Loop through each of the statements.
            for (Statement statement = statementParent.FindFirstChildStatement(); statement != null; statement = statement.FindNextSiblingStatement())
            {
                if (statement.Children.StatementCount > 0)
                {
                    // Parse the sub-statements.
                    this.CheckClassMemberRulesForStatements(statement, parentElement, parentClass, members);
                }

                // Parse the expressions in the statement.
                this.CheckClassMemberRulesForExpressions(statement, null, parentElement, parentClass, members);
            }
        }
Beispiel #50
0
        private void SplitFileByCodeUnit(CodeUnit codeUnit, string filePath, IEnumerable <string> lines)
        {
            var directory    = Path.GetDirectoryName(filePath) ?? string.Empty;
            var currentStage = SplitStage.Header;
            var header       = new List <string>();
            var code         = new List <string>();
            var name         = string.Empty;
            var proxyTypesAssemblyAttributeLine = string.Empty;
            var skipNext           = false;
            var commandLine        = string.Empty;
            var codeUnitStartsWith = codeUnit == CodeUnit.Class ? "public partial class" : "public enum";
            var files = new List <FileToWrite>(); // Delay this to the end to multithread the creation.  100's of small files takes a long time if checking with TFS sequentially

            foreach (var line in lines)
            {
                if (skipNext)
                {
                    skipNext = false; continue;
                }

                switch (currentStage)
                {
                case SplitStage.Header:
                    if (string.IsNullOrEmpty(line))
                    {
                        currentStage = SplitStage.Namespace;
                        header.Add(line);
                    }
                    else if (line.StartsWith(@"// Created via this command line:"))
                    {
                        // Since we are splitting the files, we don't want to put the command line in each file.  It would show every file as having been updated each time you change the path or user
                        commandLine = line;
                    }
                    else
                    {
                        header.Add(line);
                    }
                    break;

                case SplitStage.Namespace:
                    if (header.Last().StartsWith("namespace "))
                    {
                        currentStage = SplitStage.CodeUnitHeader;
                        skipNext     = true;
                    }
                    if (line.Contains("ProxyTypesAssemblyAttribute"))
                    {
                        proxyTypesAssemblyAttributeLine = line;
                        skipNext = true;
                        continue;
                    }
                    header.Add(line);
                    break;

                case SplitStage.CodeUnitHeader:
                    if (line.TrimStart().StartsWith(codeUnitStartsWith))
                    {
                        name = GetName(codeUnit, line);
                        if (line.Contains(": Microsoft.Xrm.Sdk.Client.OrganizationServiceContext") ||  // Standard
                            line.Contains(": Microsoft.Xrm.Client.CrmOrganizationServiceContext"))     // Xrm Client
                        {
                            // Put Created Via Command Line Back in
                            header.Insert(header.IndexOf(@"// </auto-generated>") + 1, commandLine);
                            commandLine = string.Empty;
                            // Put Proxy Types Assembly Attribute Line back in
                            var i = header.IndexOf(string.Empty, 0) + 1;
                            header.Insert(i++, proxyTypesAssemblyAttributeLine);
                            header.Insert(i, string.Empty);
                            currentStage = SplitStage.ServiceContext;
                        }
                        else
                        {
                            currentStage = SplitStage.CodeUnit;
                        }
                    }
                    code.Add(line);
                    break;

                case SplitStage.CodeUnit:
                    code.Add(line);
                    if (line == "\t}")
                    {
                        code.Add("}");
                        var fileName = Path.Combine(directory, name + ".cs");
                        files.Add(new FileToWrite(fileName, string.Join(Environment.NewLine, header.Concat(code))));
                        code.Clear();
                        currentStage = SplitStage.CodeUnitHeader;
                    }
                    break;

                case SplitStage.ServiceContext:
                    code.Add(line);
                    break;

                default:
                    throw new Exception("No Enum Defined");
                }
            }

            files.Add(new FileToWrite(filePath, string.IsNullOrWhiteSpace(commandLine) ? string.Join(Environment.NewLine, header.Concat(code)) : commandLine, true));

            WriteFilesAsync(files);
        }
Beispiel #51
0
		CodeUnit[] GetUnitsAsArray ()
		{
			CodeUnit[] result = new CodeUnit [units.Count];
			units.CopyTo (result, 0);
			return result;
		}
        /// <summary>
        /// Checks the item that follows or precedes a curly bracket in a blocked statement to verify
        /// that there is no comment or region embedded within the statement.
        /// </summary>
        /// <param name="element">The element containing the statement.</param>
        /// <param name="previousOrNextItem">The previous or next item.</param>
        private void CheckTokenPrecedingOrFollowingCurlyBracket(Element element, CodeUnit previousOrNextItem)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(previousOrNextItem, "previousOrNextItem");

            if (previousOrNextItem.Is(LexicalElementType.Comment) || previousOrNextItem.Is(CodeUnitType.ElementHeader))
            {
                this.AddViolation(element, previousOrNextItem.LineNumber, Rules.BlockStatementsMustNotContainEmbeddedComments);
            }
            else if (previousOrNextItem.Is(PreprocessorType.Region) || previousOrNextItem.Is(PreprocessorType.EndRegion))
            {
                this.AddViolation(element, previousOrNextItem.LineNumber, Rules.BlockStatementsMustNotContainEmbeddedRegions);
            }
        }
Beispiel #53
0
        /// <summary>
        /// Finds and gathers the initializer expressions for the for statement.
        /// </summary>
        /// <param name="start">The code unit in front of the initializers.</param>
        /// <returns>Returns the collection of initializers.</returns>
        private ICollection<Expression> FindIterators(CodeUnit start)
        {
            Param.AssertNotNull(start, "start");

            List<Expression> expressions = new List<Expression>();

            bool comma = true;
            for (CodeUnit c = start.FindNextSibling(); c != null; c = c.FindNextSibling())
            {
                if (!c.Is(CodeUnitType.LexicalElement) || c.Is(LexicalElementType.Token))
                {
                    if (c.Is(TokenType.CloseParenthesis))
                    {
                        return expressions.AsReadOnly();
                    }
                    else if (comma)
                    {
                        comma = false;
                        if (c.Is(CodeUnitType.Expression))
                        {
                            expressions.Add((Expression)c);
                        }
                        else
                        {
                            throw new SyntaxException(this.Document, this.LineNumber);
                        }
                    }
                    else
                    {
                        if (c.Is(TokenType.Comma))
                        {
                            comma = true;
                        }
                        else
                        {
                            throw new SyntaxException(this.Document, this.LineNumber);
                        }
                    }
                }
            }

            throw new SyntaxException(this.Document, this.LineNumber);
        }
Beispiel #54
0
        /// <summary>
        /// Checks a keyword that should not be followed by a space.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckKeywordWithoutSpace(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Keywords must not contain any space before the open parenthesis.
            LexicalElement temp = token.FindNextLexicalElement();
            if (temp != null &&
                (temp.LexicalElementType == LexicalElementType.WhiteSpace || temp.LexicalElementType == LexicalElementType.EndOfLine))
            {
                // Make sure the next non-whitespace character is not an open parenthesis.
                for (LexicalElement nextNonWhitespaceItem = temp.FindNextLexicalElement(); nextNonWhitespaceItem != null; nextNonWhitespaceItem = nextNonWhitespaceItem.FindNextLexicalElement())
                {
                    if (nextNonWhitespaceItem.Is(TokenType.OpenParenthesis))
                    {
                        this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.KeywordsMustBeSpacedCorrectly, token.Text);
                        break;
                    }
                    else if (nextNonWhitespaceItem.LexicalElementType != LexicalElementType.WhiteSpace && nextNonWhitespaceItem.LexicalElementType != LexicalElementType.EndOfLine)
                    {
                        break;
                    }
                }
            }
        }
Beispiel #55
0
 /// <summary>
 /// Determines whether the given item is an Xml header or an Xml header line.
 /// </summary>
 /// <param name="item">The item to check.</param>
 /// <returns>Returns true if so; false otherwise.</returns>
 private static bool IsXmlHeader(CodeUnit item)
 {
     Param.AssertNotNull(item, "item");
     return(item.Is(CodeUnitType.ElementHeader) || item.Is(CommentType.ElementHeaderLine));
 }
Beispiel #56
0
        /// <summary>
        /// Checks the spacing around a 'new' keyword.
        /// </summary>
        /// <param name="root">The token container list.</param>
        /// <param name="token">The token to check.</param>
        private void CheckNewKeywordSpacing(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // The keywords must be followed by a space, unless the next token is an opening square bracket, in which case
            // there should be no space.
            LexicalElement temp = token.FindNextLexicalElement();
            if (temp != null)
            {
                if (temp.LexicalElementType == LexicalElementType.WhiteSpace || temp.LexicalElementType == LexicalElementType.EndOfLine)
                {
                    // The keyword is followed by whitespace. Make sure the next non-whitespace character is not an opening bracket.
                    for (LexicalElement nextNonWhitespaceItem = temp.FindNextLexicalElement(); nextNonWhitespaceItem != null; nextNonWhitespaceItem = nextNonWhitespaceItem.FindNextLexicalElement())
                    {
                        if (nextNonWhitespaceItem.Is(TokenType.OpenSquareBracket))
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.CodeMustNotContainSpaceAfterNewKeywordInImplicitlyTypedArrayAllocation);
                            break;
                        }
                        else if (nextNonWhitespaceItem.LexicalElementType != LexicalElementType.WhiteSpace && nextNonWhitespaceItem.LexicalElementType != LexicalElementType.EndOfLine)
                        {
                            break;
                        }
                    }
                }
                else if (!temp.Is(TokenType.OpenSquareBracket))
                {
                    // The keyword is not followed by whitespace.
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.KeywordsMustBeSpacedCorrectly, token.Text);
                }
            }
        }
Beispiel #57
0
        /// <summary>
        /// Checks a close bracket for spacing.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckCloseCurlyBracket(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Close curly brackets should always be preceded by whitespace.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem != null &&
                previousItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                previousItem.LexicalElementType != LexicalElementType.EndOfLine)
            {
                this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly);
            }

            // Close curly brackets should be followed either by whitespace, a close paren,
            // a semicolon, or a comma.
            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem != null)
            {
                if (nextItem.LexicalElementType != LexicalElementType.WhiteSpace &&
                    nextItem.LexicalElementType != LexicalElementType.EndOfLine &&
                    !nextItem.Is(TokenType.CloseParenthesis) &&
                    !nextItem.Is(TokenType.Semicolon) &&
                    !nextItem.Is(TokenType.Comma))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly);
                }

                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace)
                {
                    // If this is followed by whitespace, make sure that the character just
                    // after the whitespace is not a close paren, semicolon, or comma.
                    for (LexicalElement item = nextItem.FindNextLexicalElement(); item != null; item = item.FindNextLexicalElement())
                    {
                        if (item.Is(TokenType.CloseParenthesis) ||
                            item.Is(TokenType.Semicolon) ||
                            item.Is(TokenType.Comma))
                        {
                            this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.ClosingCurlyBracketsMustBeSpacedCorrectly);
                        }
                        else if (item.LexicalElementType != LexicalElementType.WhiteSpace)
                        {
                            break;
                        }
                    }
                }
            }
        }
        private string GetName(CodeUnit codeUnit, string line)
        {
            int start;
            int end;
            if (codeUnit == CodeUnit.Class)
            {
                start = 22; // "\tpublic partial class ".Length
                end = line.IndexOf(':', start)-1;
            }
            else // if (codeUnit == CodeUnit.Enum)
            {
                start = 13; // "\tpublic enum ".Length
                end = line.Length;
            }

            return line.Substring(start, end - start);
        }
        /// <summary>
        /// Checks the given list of statements.
        /// </summary>
        /// <param name="element">The element containing the statements.</param>
        /// <param name="statementParent">The parent of the statement to check.</param>
        private void CheckStatementFormattingRulesForStatements(Element element, CodeUnit statementParent)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(statementParent, "statementParent");

            Statement previousStatement = null;

            // Check each statement in the list.
            for (Statement statement = statementParent.FindFirstChildStatement(); statement != null; statement = statement.FindNextSiblingStatement())
            {
                this.CheckStatementFormattingRulesForStatement(element, statement, previousStatement);
                previousStatement = statement;
            }
        }
Beispiel #60
0
        /// <summary>
        /// Checks a member access symbol for spacing.
        /// </summary>
        /// <param name="root">The container to parse.</param>
        /// <param name="token">The token to check.</param>
        private void CheckMemberAccessSymbol(CodeUnit root, Token token)
        {
            Param.AssertNotNull(root, "root");
            Param.AssertNotNull(token, "token");

            // Member access symbols should not have any whitespace on either side.
            LexicalElement previousItem = token.FindPreviousLexicalElement();
            if (previousItem == null)
            {
                if (previousItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    previousItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    previousItem.Is(CommentType.SingleLineComment) ||
                    previousItem.Is(CommentType.MultilineComment))
                {
                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.MemberAccessSymbolsMustBeSpacedCorrectly);
                }
            }

            LexicalElement nextItem = token.FindNextLexicalElement();
            if (nextItem == null)
            {
                if (nextItem.LexicalElementType == LexicalElementType.WhiteSpace ||
                    nextItem.LexicalElementType == LexicalElementType.EndOfLine ||
                    nextItem.Is(CommentType.SingleLineComment) ||
                    nextItem.Is(CommentType.MultilineComment))
                {
                    // Make sure the previous token is not the operator keyword.
                    if (previousItem != null)
                    {
                        for (LexicalElement item = previousItem.FindPreviousLexicalElement(); item != null; item = item.FindPreviousLexicalElement())
                        {
                            if (item.Is(TokenType.Operator))
                            {
                                return;
                            }
                            else if (item.LexicalElementType != LexicalElementType.WhiteSpace &&
                                item.LexicalElementType != LexicalElementType.EndOfLine &&
                                !item.Is(CommentType.SingleLineComment) &&
                                !item.Is(CommentType.MultilineComment))
                            {
                                break;
                            }
                        }
                    }

                    this.AddViolation(token.FindParentElement(), token.LineNumber, Rules.MemberAccessSymbolsMustBeSpacedCorrectly);
                }
            }
        }