/// <summary> /// Block statements must not contain embedded regions. /// </summary> /// <param name="node"> /// The node to process. /// </param> private void BlockStatementsMustNotContainEmbeddedRegions(ITreeNode node) { for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode tokenNode = currentNode as ITokenNode; if (tokenNode.GetTokenType() == CSharpTokenType.LBRACE) { ITokenNode previousTokenNode = Utils.GetFirstNonWhitespaceTokenToLeft(tokenNode); ITokenNode previousTokenNode2 = previousTokenNode.GetPrevToken(); if (previousTokenNode.GetTokenType() == CSharpTokenType.PP_MESSAGE && previousTokenNode2.GetTokenType() == CSharpTokenType.PP_START_REGION) { IStartRegion startRegionNode = previousTokenNode.GetContainingNode <IStartRegion>(true); if (startRegionNode != null) { MoveRegionInsideNextOpenCurlyBracket(startRegionNode); } } } } if (currentNode.FirstChild != null) { this.BlockStatementsMustNotContainEmbeddedRegions(currentNode.FirstChild); } } }
/// <summary> /// The code must not contain multiple whitespace in a row. /// </summary> /// <param name="node"> /// The node. /// </param> public static void CodeMustNotContainMultipleWhitespaceInARow(ITreeNode node) { for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode currentToken = currentNode as ITokenNode; ITokenNode previousToken = currentToken.GetPrevToken(); if (previousToken != null) { if (currentToken.GetTokenType() == CSharpTokenType.WHITE_SPACE && previousToken.GetTokenType() == CSharpTokenType.WHITE_SPACE) { using (WriteLockCookie.Create(true)) { LowLevelModificationUtil.DeleteChild(currentToken); } } } } if (currentNode.FirstChild != null) { CodeMustNotContainMultipleWhitespaceInARow(currentNode.FirstChild); } } }
/// <summary> /// Element documentation headers must be preceded by blank line. /// </summary> /// <param name="node"> /// The node. /// </param> private void ElementDocumentationHeadersMustBePrecededByBlankLine(ITreeNode node) { // go back to first new line to the left // thisnew line must be immeidately preceded by a new line and if not insert one for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is IDocCommentNode) { ITokenNode token = currentNode as ITokenNode; ITokenNode firstNewLineToLeft = Utils.GetFirstNewLineTokenToLeft(token); if (firstNewLineToLeft != null) { ITokenNode tokenBeforeNewLine = firstNewLineToLeft.GetPrevToken(); // if we're the start of a code block then don't insert a new line. if (!tokenBeforeNewLine.IsNewLine() && tokenBeforeNewLine.GetTokenType() != CSharpTokenType.LBRACE && tokenBeforeNewLine.GetTokenType() != CSharpTokenType.END_OF_LINE_COMMENT) { firstNewLineToLeft.GetNextToken().InsertNewLineBefore(); } } } if (currentNode.FirstChild != null) { this.ElementDocumentationHeadersMustBePrecededByBlankLine(currentNode.FirstChild); } } }
/// <summary> /// Commas must be spaced correctly. /// </summary> /// <param name="node"> /// The node to use. /// </param> public void EqualsMustBeSpacedCorrectly(ITreeNode node) { List <TokenNodeType> tokensThatCanBeLeftSideOfEquals = new List <TokenNodeType> { CSharpTokenType.WHITE_SPACE, CSharpTokenType.NE, CSharpTokenType.LT, CSharpTokenType.GT }; const string WhiteSpace = " "; for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode tokenNode = currentNode as ITokenNode; if (tokenNode.GetTokenType() == CSharpTokenType.EQ) { ITokenNode nextToken = tokenNode.GetNextToken(); ITokenNode previousToken = tokenNode.GetPrevToken(); if (!nextToken.IsWhitespace()) { using (WriteLockCookie.Create(true)) { // insert a space LeafElementBase leafElement = TreeElementFactory.CreateLeafElement( CSharpTokenType.WHITE_SPACE, new JetBrains.Text.StringBuffer(WhiteSpace), 0, WhiteSpace.Length); LowLevelModificationUtil.AddChildBefore(nextToken, new ITreeNode[] { leafElement }); } } if (!tokensThatCanBeLeftSideOfEquals.Contains(previousToken.GetTokenType())) { using (WriteLockCookie.Create(true)) { // insert a space LeafElementBase leafElement = TreeElementFactory.CreateLeafElement( CSharpTokenType.WHITE_SPACE, new JetBrains.Text.StringBuffer(WhiteSpace), 0, WhiteSpace.Length); LowLevelModificationUtil.AddChildBefore(tokenNode, new ITreeNode[] { leafElement }); } } } } if (currentNode.FirstChild != null) { this.EqualsMustBeSpacedCorrectly(currentNode.FirstChild); } } }
/// <summary> /// Remove line if previous tokens are new lines. /// </summary> /// <param name="tokenNode"> /// The token node. /// </param> private static void RemoveLineIfPreviousTokensAreNewLines(ITokenNode tokenNode) { // first prev token will be whitespace padding out the line ITokenNode prevToken1 = tokenNode.GetPrevToken(); ITokenNode prevToken2 = prevToken1.GetPrevToken(); ITokenNode prevToken3 = prevToken2.GetPrevToken(); IWhitespaceNode prevToken2WhiteSpaceNode = prevToken2 as IWhitespaceNode; IWhitespaceNode prevToken3WhiteSpaceNode = prevToken3 as IWhitespaceNode; if (prevToken2WhiteSpaceNode != null && prevToken2WhiteSpaceNode.IsNewLine && prevToken3WhiteSpaceNode != null && prevToken3WhiteSpaceNode.IsNewLine) { Utils.RemoveNewLineBefore(tokenNode); } }
/// <summary> /// Moves the IStartRegion specified inside the next open curly bracket and moves the corresponding end region inside too. /// </summary> /// <param name="startRegionNode"> /// The node to move. /// </param> public static void MoveRegionInsideNextOpenCurlyBracket(IStartRegion startRegionNode) { using (WriteLockCookie.Create(true)) { ITokenNode newLocationTokenNode = Utils.GetFirstNonWhitespaceTokenToRight(startRegionNode.Message); // if its a start region there is probably a corresponding end region // find it, and move it inside the block // find the position to delete from ITokenNode startOfTokensToDelete = Utils.GetFirstNewLineTokenToLeft(startRegionNode.NumberSign); ITokenNode endOfTokensToDelete = Utils.GetFirstNewLineTokenToRight(startRegionNode.Message); ITokenNode startOfTokensToFormat = startOfTokensToDelete.GetPrevToken(); IEndRegion endRegionNode = startRegionNode.EndRegion; IStartRegion newStartRegion = startRegionNode.Copy(null); ITokenNode firstNonWhitespaceAfterBracket = Utils.GetFirstNonWhitespaceTokenToRight(newLocationTokenNode); LowLevelModificationUtil.AddChildBefore(firstNonWhitespaceAfterBracket, new[] { newStartRegion }); newStartRegion.InsertNewLineAfter(); LowLevelModificationUtil.DeleteChildRange(startOfTokensToDelete, endOfTokensToDelete); IStartRegion endOfTokensToFormat = newStartRegion; if (endRegionNode != null) { startOfTokensToDelete = Utils.GetFirstNewLineTokenToLeft(endRegionNode.NumberSign); endOfTokensToDelete = Utils.GetFirstNewLineTokenToRight(endRegionNode.NumberSign); IEndRegion newEndRegionNode = endRegionNode.Copy(null); ITokenNode newLineToken = Utils.GetFirstNonWhitespaceTokenToLeft(endRegionNode.NumberSign); LowLevelModificationUtil.AddChildBefore(newLineToken, new[] { newEndRegionNode }); newEndRegionNode.InsertNewLineAfter(); LowLevelModificationUtil.DeleteChildRange(startOfTokensToDelete, endOfTokensToDelete); endOfTokensToFormat = (IStartRegion)newLineToken; } ////CSharpFormatterHelper.FormatterInstance.Format(startOfTokensToFormat, endOfTokensToFormat); ICSharpCodeFormatter codeFormatter = (ICSharpCodeFormatter)CSharpLanguage.Instance.LanguageService().CodeFormatter; codeFormatter.Format(startOfTokensToFormat, endOfTokensToFormat); } }
/// <summary> /// Moves the comment token specified after the next available non whitespace char (normally an open curly bracket). /// </summary> /// <param name="commentTokenNode"> /// The comment token to move. /// </param> public static void MoveCommentInsideNextOpenCurlyBracket(ITokenNode commentTokenNode) { using (WriteLockCookie.Create(true)) { // move comment inside block curly bracket here // we copy it, then insert it and then delete the copied one ITokenNode startOfTokensToDelete = Utils.GetFirstNonWhitespaceTokenToLeft(commentTokenNode).GetNextToken(); ITokenNode endOfTokensToDelete = Utils.GetFirstNewLineTokenToRight(commentTokenNode); ITokenNode startOfTokensToFormat = startOfTokensToDelete.GetPrevToken(); ITokenNode openCurlyBracketTokenNode = Utils.GetFirstNonWhitespaceTokenToRight(commentTokenNode); ITokenNode newCommentTokenNode = commentTokenNode.Copy(null); ITokenNode tokenNodeToInsertAfter = Utils.GetFirstNewLineTokenToRight(openCurlyBracketTokenNode); LowLevelModificationUtil.AddChildAfter(tokenNodeToInsertAfter, new[] { newCommentTokenNode }); LowLevelModificationUtil.AddChildAfter(newCommentTokenNode, newCommentTokenNode.InsertNewLineAfter()); DeleteChildRange(startOfTokensToDelete, endOfTokensToDelete); ITokenNode endOfTokensToFormat = newCommentTokenNode; CSharpFormatterHelper.FormatterInstance.Format(startOfTokensToFormat, endOfTokensToFormat); } }
/// <summary> /// Gets the first non-whitespace token that occurs before the token passed in. /// </summary> /// <param name="tokenNode"> /// The TokenNode to start at. /// </param> /// <returns> /// The first non-whitespace token. /// </returns> public static ITokenNode GetFirstNonWhitespaceTokenToLeft(ITokenNode tokenNode) { ITokenNode currentToken = tokenNode.GetPrevToken(); while (currentToken != null && currentToken.IsWhitespace()) { currentToken = currentToken.GetPrevToken(); } return currentToken; }
/// <summary> /// Gets the first non-whitespace token that occurs before the token passed in. /// </summary> /// <param name="tokenNode"> /// The TokenNode to start at. /// </param> /// <returns> /// The first non-whitespace token. /// </returns> public static ITokenNode GetFirstNewLineTokenToLeft(ITokenNode tokenNode) { ITokenNode currentToken = tokenNode.GetPrevToken(); while (!currentToken.IsNewLine() && currentToken != null) { currentToken = currentToken.GetPrevToken(); } return currentToken; }
/// <summary> /// True if the token is preceded on the same line by a non-whitespace token. /// </summary> /// <param name="tokenNode"> /// THe token to start at. /// </param> /// <returns> /// True or false. /// </returns> public static bool TokenHasNonWhitespaceTokenToLeftOnSameLine(ITokenNode tokenNode) { ITokenNode currentToken = tokenNode.GetPrevToken(); if (currentToken == null) { return false; } while (currentToken.IsWhitespace() && !currentToken.IsNewLine() && currentToken != null) { currentToken = currentToken.GetPrevToken(); } return currentToken != null && !currentToken.IsNewLine(); }