/// <summary> /// Executes QuickFix or ContextAction. Returns post-execute method. /// </summary> /// <returns> /// Action to execute after document and PSI transaction finish. Use to open TextControls, navigate caret, etc. /// </returns> protected override Action <ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress) { MissingTokenErrorElement errorElement = _highlighting.AssociatedNode; IFile file = errorElement.GetContainingFile(); Assertion.AssertNotNull(file, "file != null"); TreeTextRange modifiedRange; TextRange hotspotRange; // replace the error token by the missing text using (WriteLockCookie.Create(file.IsPhysical())) { modifiedRange = errorElement.GetTreeTextRange(); ITokenNode previousToken = errorElement.GetPreviousToken(); if (previousToken != null && previousToken.GetTokenType() == T4TokenNodeTypes.NewLine) { modifiedRange = modifiedRange.Join(previousToken.GetTreeTextRange()); } Assertion.AssertNotNull(file, "file != null"); Pair <string, TextRange> textWithHotspotRange = GetMissingTextWithHotspotRange(errorElement); hotspotRange = textWithHotspotRange.Second; file.ReParse(modifiedRange, textWithHotspotRange.First); } if (!hotspotRange.IsValid) { return(null); } // create a hotspot around a directive name or value, with basic completion invoked return(textControl => { DocumentRange initialRange = file.GetDocumentRange(modifiedRange); int startOffset = initialRange.TextRange.StartOffset; var finalRange = new TextRange(startOffset + hotspotRange.StartOffset, startOffset + hotspotRange.EndOffset); string fieldName = textControl.Document.GetText(finalRange); Shell.Instance .GetComponent <LiveTemplatesManager>() .CreateHotspotSessionAtopExistingText( solution, TextRange.InvalidRange, textControl, LiveTemplatesManager.EscapeAction.LeaveTextAndCaret, HotspotHelper.CreateBasicCompletionHotspotInfo(fieldName, new DocumentRange(initialRange.Document, finalRange))) .Execute(); }); }
public override ITokenNode GetMinimalSeparator(ITokenNode leftToken, ITokenNode rightToken) { if (leftToken is IWhitespaceNode || leftToken.GetTokenType() == PsiTokenType.WHITE_SPACE) { return(null); } if (leftToken.GetTokenType() == PsiTokenType.END_OF_LINE_COMMENT && rightToken.GetTokenType() != PsiTokenType.NEW_LINE) { return(PsiFormatterHelper.CreateNewLine("\r\n")); } if (rightToken is IWhitespaceNode || rightToken.GetTokenType() == PsiTokenType.WHITE_SPACE) { return(null); } if (leftToken.GetTokenType() == PsiTokenType.LBRACE || leftToken.GetTokenType() == PsiTokenType.RBRACE || leftToken.GetTokenType() == PsiTokenType.RBRACE || leftToken.GetTokenType() == PsiTokenType.RBRACKET || leftToken.GetTokenType() == PsiTokenType.LPARENTH || leftToken.GetTokenType() == PsiTokenType.RPARENTH || leftToken.GetTokenType() == PsiTokenType.LT || leftToken.GetTokenType() == PsiTokenType.GT) { return(null); } if (rightToken.GetTokenType() == PsiTokenType.LBRACE || rightToken.GetTokenType() == PsiTokenType.RBRACE || rightToken.GetTokenType() == PsiTokenType.RBRACE || rightToken.GetTokenType() == PsiTokenType.RBRACKET || rightToken.GetTokenType() == PsiTokenType.LPARENTH || rightToken.GetTokenType() == PsiTokenType.RPARENTH || rightToken.GetTokenType() == PsiTokenType.LT || rightToken.GetTokenType() == PsiTokenType.GT) { return(null); } if (rightToken.GetTokenType() == PsiTokenType.ASTERISK || rightToken.GetTokenType() == PsiTokenType.QUEST) { return(null); } if ((leftToken.GetTokenType() == PsiTokenType.COLON || leftToken.GetTokenType() == PsiTokenType.SEMICOLON) && (!(rightToken.GetTokenType() == PsiTokenType.C_STYLE_COMMENT || rightToken.GetTokenType() == PsiTokenType.END_OF_LINE_COMMENT))) { return(PsiFormatterHelper.CreateNewLine("\r\n")); } TokenNodeType tokenType1 = leftToken.GetTokenType(); TokenNodeType tokenType2 = rightToken.GetTokenType(); if (myGlueingCache.Get(new TokenTypePair(tokenType1, tokenType2))) { return (tokenType1 == PsiTokenType.END_OF_LINE_COMMENT ? PsiFormatterHelper.CreateNewLine("\r\n") : PsiFormatterHelper.CreateSpace(" ")); } return(null); }
public static AccessRights GetAccessRights([CanBeNull] ITokenNode accessModifier) { var modifierTokenType = accessModifier?.GetTokenType(); if (modifierTokenType == FSharpTokenType.PRIVATE) { return(AccessRights.PRIVATE); } if (modifierTokenType == FSharpTokenType.INTERNAL) { return(AccessRights.INTERNAL); } return(AccessRights.PUBLIC); }
/// <summary> /// Commas must be spaced correctly. /// </summary> /// <param name="node"> /// The node to use. /// </param> public static void CommasMustBeSpacedCorrectly(ITreeNode node) { List <TokenNodeType> tokensThatCanBeRightSideOfComma = new List <TokenNodeType> { CSharpTokenType.NEW_LINE, CSharpTokenType.WHITE_SPACE, CSharpTokenType.RBRACKET, CSharpTokenType.GT, CSharpTokenType.COMMA, CSharpTokenType.RPARENTH }; 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.COMMA) { ITokenNode nextToken = tokenNode.GetNextToken(); if (!tokensThatCanBeRightSideOfComma.Contains(nextToken.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(nextToken, new ITreeNode[] { leafElement }); } } } } if (currentNode.FirstChild != null) { CommasMustBeSpacedCorrectly(currentNode.FirstChild); } } }
/// <summary>Analyzes the specified statement.</summary> /// <param name="node">The node.</param> /// <returns>Returns the suggestion base.</returns> public SuggestionBase[] Analyze(ITokenNode node) { var type = node.GetTokenType(); if (!type.IsStringLiteral) { return null; } if (node.Language.Name != "CSHARP") { return null; } if (node.GetText() != "\"\"") { return null; } var parent = node.Parent; if (parent == null) { return null; } if (parent.Parent is ISwitchLabelStatement) { return null; } var attribute = node.GetContainingElement(typeof(IAttribute), true) as IAttribute; if (attribute != null) { return null; } var suggestions = new List<SuggestionBase> { new StringEmptySuggestion(this.solution, node) }; return suggestions.ToArray(); }
/// <summary> /// Opening curly brackets must not be preceded by blank line. /// </summary> /// <param name="node"> /// The node. /// </param> private void OpeningCurlyBracketsMustNotBePrecededByBlankLine(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) { RemoveLineIfPreviousTokensAreNewLines(tokenNode); } } if (currentNode.FirstChild != null) { this.OpeningCurlyBracketsMustNotBePrecededByBlankLine(currentNode.FirstChild); } } }
/// <summary> /// Replace empty strings with string dot empty. /// </summary> /// <param name="node"> /// The node to process. /// </param> public static void ReplaceEmptyStringsWithStringDotEmpty(ITreeNode node) { for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode tokenNode = currentNode as ITokenNode; if (tokenNode.GetTokenType().IsStringLiteral) { IAttribute attribute = tokenNode.GetContainingNode <IAttribute>(true); ISwitchLabelStatement switchLabelStatement = tokenNode.GetContainingNode <ISwitchLabelStatement>(true); IConstantDeclaration constantDeclaration = tokenNode.GetContainingNode <IConstantDeclaration>(true); IRegularParameterDeclaration parameterDeclaration = tokenNode.GetContainingNode <IRegularParameterDeclaration>(true); // Not for attributes, switch labels, constant declarations, or parameter declarations if (attribute == null && switchLabelStatement == null && constantDeclaration == null && parameterDeclaration == null) { string text = currentNode.GetText(); if (text == "\"\"" || text == "@\"\"") { const string NewText = "string.Empty"; ITokenNode newLiteral = (ITokenNode) CSharpTokenType.STRING_LITERAL_REGULAR.Create(new JetBrains.Text.StringBuffer(NewText), new TreeOffset(0), new TreeOffset(NewText.Length)); using (WriteLockCookie.Create(true)) { LowLevelModificationUtil.ReplaceChildRange(currentNode, currentNode, new ITreeNode[] { newLiteral }); } } } } } if (currentNode.FirstChild != null) { ReadabilityRules.ReplaceEmptyStringsWithStringDotEmpty(currentNode.FirstChild); } } }
private static PostfixTemplateContext TryCreateFromReferenceExpression( [NotNull] PostfixTemplateExecutionContext executionContext, [NotNull] ICSharpExpression qualifierExpression, [NotNull] IReferenceExpression referenceExpression) { // protect from 'o.M(.var)' var invocation = qualifierExpression as IInvocationExpression; if (invocation != null && invocation.LPar != null && invocation.RPar == null) { var argument = invocation.Arguments.LastOrDefault(); if (argument != null && argument.Expression == null) { return(null); } } // protect from 'smth.var\n(someCode).InBraces()' invocation = referenceExpression.Parent as IInvocationExpression; if (invocation != null) { for (ITokenNode lpar = invocation.LPar, token = invocation.InvokedExpression.NextSibling as ITokenNode; token != null && token != lpar && token.IsFiltered(); token = token.NextSibling as ITokenNode) { if (token.GetTokenType() == CSharpTokenType.NEW_LINE) { return(null); } } } // protect from 'doubleDot..var' var qualifierReference = qualifierExpression as IReferenceExpression; if (qualifierReference != null && qualifierReference.NameIdentifier == null) { return(null); } return(new CSharpReferenceExpressionPostfixTemplateContext(referenceExpression, qualifierExpression, executionContext)); }
public void CheckString( ICSharpLiteralExpression literalExpression, IHighlightingConsumer highlightingConsumer, StringSettings settings) { //ConstantValue val = literalExpression.ConstantValue; // Ignore it unless it's something we're re-evalutating if (!this._daemonProcess.IsRangeInvalidated(literalExpression.GetDocumentRange())) { return; } // Ignore verbatim strings. if (settings.IgnoreVerbatimStrings && LiteralService.Get(CSharpLanguage.Instance).IsVerbatimStringLiteral(literalExpression)) { return; } ITokenNode tokenNode = literalExpression.Literal; if (tokenNode == null) { return; } if (tokenNode.GetTokenType() == CSharpTokenType.STRING_LITERAL) { ISpellChecker spellChecker = SpellCheckManager.GetSpellChecker(this._settingsStore, this._solution, settings.DictionaryNames); StringSpellChecker.SpellCheck( literalExpression.GetDocumentRange().Document, tokenNode, spellChecker, this._solution, highlightingConsumer, this._settingsStore, settings); } }
public static MemberDecoration GetDecoration([CanBeNull] ITokenNode accessModifier, TreeNodeCollection <IAttribute> attributes) { var decoration = MemberDecoration.DefaultValue; if (accessModifier != null) { var tokenType = accessModifier.GetTokenType(); if (tokenType == FSharpTokenType.INTERNAL) { decoration.Modifiers |= Modifiers.INTERNAL; } else if (tokenType == FSharpTokenType.PRIVATE) { decoration.Modifiers |= Modifiers.PRIVATE; } else if (tokenType == FSharpTokenType.PUBLIC) { decoration.Modifiers |= Modifiers.PUBLIC; } } foreach (var attr in attributes) { switch (attr.GetShortName()) { case FSharpImplUtil.AbstractClass: decoration.Modifiers |= Modifiers.ABSTRACT; break; case FSharpImplUtil.Sealed: decoration.Modifiers |= Modifiers.SEALED; break; } } return(Normalize(decoration)); }
private void CodeMustNotContainEmptyRegions(ITreeNode node) { for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode tokenNode = currentNode as ITokenNode; if (tokenNode.GetTokenType() == CSharpTokenType.PP_START_REGION) { IStartRegion startRegionNode = tokenNode.GetContainingNode <IStartRegion>(true); IEndRegion endRegion = startRegionNode.EndRegion; if (endRegion != null) { ITokenNode previousTokenNode = Utils.GetFirstNonWhitespaceTokenToLeft(endRegion.NumberSign); IStartRegion a = previousTokenNode.GetContainingNode <IStartRegion>(true); if (a != null && a.Equals(startRegionNode)) { using (WriteLockCookie.Create(true)) { ModificationUtil.DeleteChild(startRegionNode); ModificationUtil.DeleteChild(endRegion); } } } } } if (currentNode.FirstChild != null) { this.CodeMustNotContainEmptyRegions(currentNode.FirstChild); } } }
/// <summary> /// While do footer must not be preceded by blank line. /// </summary> /// <param name="node"> /// The node. /// </param> private void WhileDoFooterMustNotBePrecededByBlankLine(ITreeNode node) { for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode tokenNode = currentNode as ITokenNode; if (tokenNode.GetTokenType() == CSharpTokenType.WHILE_KEYWORD) { if (currentNode.Parent is IDoStatement) { RemoveLineIfPreviousTokensAreNewLines(tokenNode); } } } if (currentNode.FirstChild != null) { this.WhileDoFooterMustNotBePrecededByBlankLine(currentNode.FirstChild); } } }
/// <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); } } }
// We have right brace. We'll find all left braces. // 'RBRACE[caret]' protected override void TryHighlightToLeft(MatchingHighlightingsConsumer consumer, ITokenNode selectedToken, TreeOffset treeOffset) { if (selectedToken.GetTokenType() != CSharpTokenType.STRING_LITERAL) { return; } if (ExistingTreeNodes.ExistingTrees.Count == 0) { return; } DocumentRange rBraceRange = myProvider.DocumentCaret.ExtendLeft(1); ITreeNode node = GetNodeFromRange(rBraceRange); string lang = GetLanguageFromNode(node); if (String.IsNullOrEmpty(lang)) { return; } string rBrother = node.UserData.GetData(Constants.YcTokenName); string lbrother = LanguageHelper.GetBrother(lang, rBrother, Brother.Left); if (String.IsNullOrEmpty(lbrother)) { return; } int leftNumber = LanguageHelper.GetNumberFromYcName(lang, lbrother); int rightNumber = Int32.Parse(node.UserData.GetData(Constants.YcTokNumber)); var helper = Helper.ReSharperHelper <DocumentRange, ITreeNode> .Instance; IEnumerable <DocumentRange> ranges = helper.GetPairedRanges(lang, leftNumber, rightNumber, rBraceRange, false); foreach (DocumentRange range in ranges) { MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, range, rBraceRange); } /* * need for measurement * List<ITreeNode> forest = Helper.ReSharperHelper<DocumentRange, ITreeNode>.Instance.GetForestWithToken(lang, rBraceRange); * * var lBraceTextRange = new TreeTextRange(treeOffset.Shift(-1), 1); * * var leftRanges = new List<DocumentRange>(); * * foreach (ITreeNode tree in forest) * { * var rBraceNode = tree.FindNodeAt(lBraceTextRange); * //if (rBraceNode == null) * // //in general, this should not be. But while such a situation occurs * // continue; * * var lbraceNode = rBraceNode.PrevSibling; * while (lbraceNode != null * && lbraceNode.UserData.GetData(Constants.YcTokenName) != lbrother) * { * lbraceNode = lbraceNode.PrevSibling; * } * if (lbraceNode != null) * leftRanges.Add(lbraceNode.GetNavigationRange()); * } * * foreach (DocumentRange range in leftRanges) * { * MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, range, rBraceRange); * } */ }
private static void HandleElement(ITextControl editor, ITreeNode element, int offset) { string stringToInsert = Clipboard.GetText(); if (string.IsNullOrEmpty(stringToInsert)) { return; } IDocCommentNode docCommentNode = element as IDocCommentNode; if (docCommentNode != null) { JetBrains.Util.dataStructures.TypedIntrinsics.Int32 <DocLine> currentLineNumber = editor.Document.GetCoordsByOffset(editor.Caret.Offset()).Line; string currentLine = editor.Document.GetLineText(currentLineNumber); int index = currentLine.IndexOf("///", StringComparison.Ordinal); if (index < 0) { return; } string prefix = currentLine.Substring(0, index); if (ShallEscape(docCommentNode, editor.Caret.Offset()) && JetBrains.UI.RichText.RichTextBlockToHtml.HtmlEncode(stringToInsert) != stringToInsert && MessageBox.ShowYesNo("Do you want the text to be escaped?")) { stringToInsert = JetBrains.UI.RichText.RichTextBlockToHtml.HtmlEncode(stringToInsert); } stringToInsert = stringToInsert.Replace("\n", "\n" + prefix + "///"); } ITokenNode token = element as ITokenNode; if (token != null) { if (token.GetTokenType() == CSharpTokenType.STRING_LITERAL && offset < token.GetTreeTextRange().EndOffset.Offset) { string text = token.GetText(); if (text.StartsWith("@") && offset > token.GetTreeTextRange().StartOffset.Offset + 1) { stringToInsert = stringToInsert.Replace("\"", "\"\""); } else if (!text.StartsWith("@")) { stringToInsert = stringToInsert. Replace("\\", "\\\\"). Replace("\a", "\\a"). Replace("\b", "\\b"). Replace("\f", "\\f"). Replace("\n", "\\n"). Replace("\r", "\\r"). Replace("\t", "\\t"). Replace("\v", "\\v"). Replace("\'", "\\'"). Replace("\"", "\\\""); } } } editor.Document.InsertText(editor.Caret.Offset(), stringToInsert); }
// We have left brace. We'll find all right braces. // '[caret]LBRACE' protected override void TryHighlightToRight(MatchingHighlightingsConsumer consumer, ITokenNode selectedToken, TreeOffset treeOffset) { if (selectedToken.GetTokenType() != CSharpTokenType.STRING_LITERAL) { return; } if (ExistingTreeNodes.ExistingTrees.Count == 0) { return; } DocumentRange lBraceRange = myProvider.DocumentCaret.ExtendRight(1); ITreeNode node = GetNodeFromRange(lBraceRange); string lang = GetLanguageFromNode(node); if (String.IsNullOrEmpty(lang)) { return; } string lBrother = node.UserData.GetData(Constants.YcTokenName); string rBrother = LanguageHelper.GetBrother(lang, lBrother, Brother.Right); if (String.IsNullOrEmpty(rBrother)) { return; } int leftNumber = Int32.Parse(node.UserData.GetData(Constants.YcTokNumber)); int rightNumber = LanguageHelper.GetNumberFromYcName(lang, rBrother); var helper = Helper.ReSharperHelper <DocumentRange, ITreeNode> .Instance; IEnumerable <DocumentRange> ranges = helper.GetPairedRanges(lang, leftNumber, rightNumber, lBraceRange, true); foreach (DocumentRange range in ranges) { MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, lBraceRange, range); } /* * need for measurement * Console.WriteLine(); * Stopwatch timer = new Stopwatch(); * timer.Start(); * List<ITreeNode> forest = Helper.ReSharperHelper<DocumentRange, ITreeNode>.Instance.GetForestWithToken(lang, lBraceRange); * * var lBraceTextRange = new TreeTextRange(treeOffset, 1); * * var rightRanges = new List<DocumentRange>(); * * foreach (ITreeNode tree in forest) * { * var lbraceNode = tree.FindNodeAt(lBraceTextRange); * //if (lbraceNode == null) * ////in general, this should not be. But while such a situation occurs * // continue; * var rBraceNode = lbraceNode.NextSibling; * while (rBraceNode != null * && rBraceNode.UserData.GetData(Constants.YcTokenName) != rBrother) * { * var text = rBraceNode.UserData.GetData(Constants.YcTokenName); * if (string.IsNullOrEmpty(text)) * Console.WriteLine(); * rBraceNode = rBraceNode.NextSibling; * } * if (rBraceNode != null) * rightRanges.Add(rBraceNode.GetNavigationRange()); * } * timer.Stop(); * measure.Add(timer.Elapsed); * if (measure.Count == 10) * { * using (var str = new StreamWriter(String.Format(newName, measure.Count))) * { * foreach (TimeSpan span in measure) * { * str.WriteLine(span); * } * } * } * * foreach (DocumentRange range in rightRanges) * { * MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, lBraceRange, range); * } */ }
/// <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); } } }
public override ITokenNode GetMinimalSeparator(ITokenNode leftToken, ITokenNode rightToken) { if (leftToken is IWhitespaceNode || leftToken.GetTokenType() == PsiTokenType.WHITE_SPACE) { return null; } if (leftToken.GetTokenType() == PsiTokenType.END_OF_LINE_COMMENT && rightToken.GetTokenType() != PsiTokenType.NEW_LINE) { return PsiFormatterHelper.CreateNewLine("\r\n"); } if (rightToken is IWhitespaceNode || rightToken.GetTokenType() == PsiTokenType.WHITE_SPACE) { return null; } if (leftToken.GetTokenType() == PsiTokenType.LBRACE || leftToken.GetTokenType() == PsiTokenType.RBRACE || leftToken.GetTokenType() == PsiTokenType.RBRACE || leftToken.GetTokenType() == PsiTokenType.RBRACKET || leftToken.GetTokenType() == PsiTokenType.LPARENTH || leftToken.GetTokenType() == PsiTokenType.RPARENTH || leftToken.GetTokenType() == PsiTokenType.LT || leftToken.GetTokenType() == PsiTokenType.GT) { return null; } if (rightToken.GetTokenType() == PsiTokenType.LBRACE || rightToken.GetTokenType() == PsiTokenType.RBRACE || rightToken.GetTokenType() == PsiTokenType.RBRACE || rightToken.GetTokenType() == PsiTokenType.RBRACKET || rightToken.GetTokenType() == PsiTokenType.LPARENTH || rightToken.GetTokenType() == PsiTokenType.RPARENTH || rightToken.GetTokenType() == PsiTokenType.LT || rightToken.GetTokenType() == PsiTokenType.GT) { return null; } if (rightToken.GetTokenType() == PsiTokenType.ASTERISK || rightToken.GetTokenType() == PsiTokenType.QUEST) { return null; } if ((leftToken.GetTokenType() == PsiTokenType.COLON || leftToken.GetTokenType() == PsiTokenType.SEMICOLON) && (!(rightToken.GetTokenType() == PsiTokenType.C_STYLE_COMMENT || rightToken.GetTokenType() == PsiTokenType.END_OF_LINE_COMMENT))) { return PsiFormatterHelper.CreateNewLine("\r\n"); } TokenNodeType tokenType1 = leftToken.GetTokenType(); TokenNodeType tokenType2 = rightToken.GetTokenType(); if (myGlueingCache.Get(new TokenTypePair(tokenType1, tokenType2))) { return tokenType1 == PsiTokenType.END_OF_LINE_COMMENT ? PsiFormatterHelper.CreateNewLine("\r\n") : PsiFormatterHelper.CreateSpace(" "); } return null; }
/// <summary> /// Closing curly bracket must be followed by blank line. /// </summary> /// <param name="node"> /// The node to use. /// </param> public static void ClosingCurlyBracketMustBeFollowedByBlankLine(ITreeNode node) { // Closing curly brackets must be followed by a newline unless they are closing an object initializer or // followed by one of the endtokens defined here. // catch // finally // else // rbrace // dowhile // preprocessor directives List <TokenNodeType> tokensThatFollowClosingCurlyBracketWithoutNewLine = new List <TokenNodeType> { CSharpTokenType.RBRACE, CSharpTokenType.DO_KEYWORD, CSharpTokenType.ELSE_KEYWORD, CSharpTokenType.CATCH_KEYWORD, CSharpTokenType.FINALLY_KEYWORD }; List <TokenNodeType> objectInitializerFollowers = new List <TokenNodeType> { CSharpTokenType.AS_KEYWORD, CSharpTokenType.IS_KEYWORD, CSharpTokenType.COMMA, CSharpTokenType.SEMICOLON, CSharpTokenType.DOT, CSharpTokenType.QUEST, CSharpTokenType.COLON, CSharpTokenType.RPARENTH, CSharpTokenType.EQEQ, CSharpTokenType.GE, CSharpTokenType.GT, CSharpTokenType.LE, CSharpTokenType.LT, CSharpTokenType.NE, CSharpTokenType.MINUS, CSharpTokenType.PLUS, CSharpTokenType.DIV, CSharpTokenType.ASTERISK, CSharpTokenType.PERC, CSharpTokenType.MINUSMINUS, CSharpTokenType.PLUSPLUS }; for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ITokenNode) { ITokenNode tokenNode = currentNode as ITokenNode; if (tokenNode.GetTokenType() == CSharpTokenType.RBRACE) { IBlock blockNode = tokenNode.Parent as IBlock; if (blockNode != null) { JB::JetBrains.Util.dataStructures.TypedIntrinsics.Int32 <DocLine> lineNumberForLBrace = Utils.GetLineNumberForElement(blockNode.LBrace); JB::JetBrains.Util.dataStructures.TypedIntrinsics.Int32 <DocLine> lineNumberForRBrace = Utils.GetLineNumberForElement(blockNode.RBrace); if (lineNumberForLBrace != lineNumberForRBrace) { ITokenNode currentToken = tokenNode.GetNextToken(); int newLineCount = 0; while (currentToken != null) { if (currentToken.IsWhitespace()) { if (currentToken.IsNewLine()) { newLineCount++; if (newLineCount == 2) { // if we get 2 new lines we've already got a blank line after the closing curly bracket so jog on. break; } } } else { if ((!tokensThatFollowClosingCurlyBracketWithoutNewLine.Contains(currentToken.GetTokenType()) && !objectInitializerFollowers.Contains(currentToken.GetTokenType())) || (objectInitializerFollowers.Contains(currentToken.GetTokenType()) && newLineCount == 1)) { tokenNode.GetNextToken().InsertNewLineBefore(); } break; } currentToken = currentToken.GetNextToken(); } } } } } if (currentNode.FirstChild != null) { ClosingCurlyBracketMustBeFollowedByBlankLine(currentNode.FirstChild); } } }
/// <summary> /// Comments must be preceded by blank line. /// </summary> /// <param name="node"> /// The node. /// </param> private static void CommentsMustBePreceededByBlankLine(ITreeNode node) { for (ITreeNode currentNode = node; currentNode != null; currentNode = currentNode.NextSibling) { if (currentNode is ICommentNode && !(currentNode is IDocCommentNode)) { if (Utils.IsFirstNodeOnLine(currentNode) && !(currentNode.Parent is ICSharpFile)) { ITreeNode siblingMinus1 = currentNode.PrevSibling; if (siblingMinus1 != null) { ITreeNode siblingMinus2 = siblingMinus1.PrevSibling; if (siblingMinus2 != null) { ITreeNode siblingMinus3 = siblingMinus2.PrevSibling; ITokenNode siblingMinus3Token = siblingMinus3 as ITokenNode; IWhitespaceNode siblingMinus2WhitespaceNode = siblingMinus2 as IWhitespaceNode; IWhitespaceNode siblingMinus3WhitespaceNode = siblingMinus3 as IWhitespaceNode; ICommentNode siblingMinus3CommentNode = siblingMinus3 as ICommentNode; if (siblingMinus3CommentNode != null) { // if the previous sibling is a comment then it doesn't need a new line. continue; } if (siblingMinus3 is ISwitchLabelStatement) { //�if�we're�the�start�of�a�switch�block�then�don't�insert�a�new�line. continue; } if (siblingMinus3Token != null && siblingMinus3Token.GetTokenType() == CSharpTokenType.LBRACE) { // if we're the start of a code block then don't insert a new line. continue; } if (siblingMinus2WhitespaceNode == null || siblingMinus3WhitespaceNode == null || !siblingMinus2WhitespaceNode.IsNewLine || !(siblingMinus3WhitespaceNode.IsNewLine || siblingMinus3WhitespaceNode.IsWhitespace())) { currentNode.InsertNewLineBefore(); ////CSharpFormatterHelper.FormatterInstance.Format(currentNode.Parent); LanguageService languageService = CSharpLanguage.Instance.LanguageService(); if (languageService != null) { ICSharpCodeFormatter codeFormatter = (ICSharpCodeFormatter)languageService.CodeFormatter; if (codeFormatter != null) { codeFormatter.Format(currentNode.Parent); } } } } } } } if (currentNode.FirstChild != null) { CommentsMustBePreceededByBlankLine(currentNode.FirstChild); } } }
// We have left brace. We'll find all right braces. // '[caret]LBRACE' protected override void TryHighlightToRight(MatchingHighlightingsConsumer consumer, ITokenNode selectedToken, TreeOffset treeOffset) { if (selectedToken.GetTokenType() != CSharpTokenType.STRING_LITERAL) return; if (ExistingTreeNodes.ExistingTrees.Count == 0) return; DocumentRange lBraceRange = myProvider.DocumentCaret.ExtendRight(1); ITreeNode node = GetNodeFromRange(lBraceRange); string lang = GetLanguageFromNode(node); if (String.IsNullOrEmpty(lang)) return; string lBrother = node.UserData.GetData(Constants.YcTokenName); string rBrother = LanguageHelper.GetBrother(lang, lBrother, Brother.Right); if (String.IsNullOrEmpty(rBrother)) return; int leftNumber = Int32.Parse(node.UserData.GetData(Constants.YcTokNumber)); int rightNumber = LanguageHelper.GetNumberFromYcName(lang, rBrother); var helper = Helper.ReSharperHelper<DocumentRange, ITreeNode>.Instance; IEnumerable<DocumentRange> ranges = helper.GetPairedRanges(lang, leftNumber, rightNumber, lBraceRange, true); foreach (DocumentRange range in ranges) { MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, lBraceRange, range); } /* * need for measurement Console.WriteLine(); Stopwatch timer = new Stopwatch(); timer.Start(); List<ITreeNode> forest = Helper.ReSharperHelper<DocumentRange, ITreeNode>.Instance.GetForestWithToken(lang, lBraceRange); var lBraceTextRange = new TreeTextRange(treeOffset, 1); var rightRanges = new List<DocumentRange>(); foreach (ITreeNode tree in forest) { var lbraceNode = tree.FindNodeAt(lBraceTextRange); //if (lbraceNode == null) ////in general, this should not be. But while such a situation occurs // continue; var rBraceNode = lbraceNode.NextSibling; while (rBraceNode != null && rBraceNode.UserData.GetData(Constants.YcTokenName) != rBrother) { var text = rBraceNode.UserData.GetData(Constants.YcTokenName); if (string.IsNullOrEmpty(text)) Console.WriteLine(); rBraceNode = rBraceNode.NextSibling; } if (rBraceNode != null) rightRanges.Add(rBraceNode.GetNavigationRange()); } timer.Stop(); measure.Add(timer.Elapsed); if (measure.Count == 10) { using (var str = new StreamWriter(String.Format(newName, measure.Count))) { foreach (TimeSpan span in measure) { str.WriteLine(span); } } } foreach (DocumentRange range in rightRanges) { MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, lBraceRange, range); } */ }
public PostfixTemplateContext IsAvailable([CanBeNull] ITreeNode position, [NotNull] PostfixExecutionContext context) { if (!(position is ICSharpIdentifier)) { return(null); } // expr.__ var referenceExpression = position.Parent as IReferenceExpression; if (referenceExpression != null && referenceExpression.Delimiter != null) { var expression = referenceExpression.QualifierExpression; if (expression != null) { // protect from 'o.M(.var)' var invocation = expression as IInvocationExpression; if (invocation != null && invocation.LPar != null && invocation.RPar == null) { var argument = invocation.Arguments.LastOrDefault(); if (argument != null && argument.Expression == null) { return(null); } } // protect from 'smth.var\n(someCode).InBraces()' invocation = referenceExpression.Parent as IInvocationExpression; if (invocation != null) { for (ITokenNode lpar = invocation.LPar, token = invocation.InvokedExpression.NextSibling as ITokenNode; token != null && token != lpar && token.IsFiltered(); token = token.NextSibling as ITokenNode) { if (token.GetTokenType() == CSharpTokenType.NEW_LINE) { return(null); } } } // protect from 'doubleDot..var' var qualifierReference = expression as IReferenceExpression; if (qualifierReference != null && qualifierReference.NameIdentifier == null) { return(null); } return(new ReferenceExpressionPostfixTemplateContext(referenceExpression, expression, context)); } } // String.__ var referenceName = position.Parent as IReferenceName; if (referenceName != null && referenceName.Qualifier != null && referenceName.Delimiter != null) { var typeUsage = referenceName.Parent as ITypeUsage; if (typeUsage != null) { var expression = typeUsage.Parent as ICSharpExpression; if (expression != null) { return(new ReferenceNamePostfixTemplateContext(referenceName, expression, context)); } } } // string.__ var brokenStatement = FindBrokenStatement(position); if (brokenStatement != null) { var expressionStatement = brokenStatement.PrevSibling as IExpressionStatement; if (expressionStatement != null) { var expression = FindExpressionBrokenByKeyword(expressionStatement); if (expression != null) { return(new BrokenStatementPostfixTemplateContext(brokenStatement, expression, context)); } } } return(null); }
protected override void TryHighlightToRight(MatchingHighlightingsConsumer consumer, ITokenNode selectedToken, TreeOffset treeOffset) { TokenNodeType tokenType = selectedToken.GetTokenType(); if (this.IsLeftBracket(tokenType)) { ITokenNode matchedToken; if (this.FindMatchingRightBracket(selectedToken, out matchedToken)) { consumer.ConsumeMatchingBracesHighlighting(selectedToken.GetDocumentRange(), matchedToken.GetDocumentRange()); } else { consumer.ConsumeHighlighting( "ReSharper Unmatched Brace", selectedToken.GetDocumentRange().StartOffsetRange().ExtendRight(1)); if (matchedToken == null) { return; } consumer.ConsumeHighlighting( "ReSharper Unmatched Brace", matchedToken.GetDocumentRange().EndOffsetRange().ExtendLeft(1)); } } else { if (tokenType != NTriplesTokenType.STRING_LITERAL) { return; } if (selectedToken.GetText()[0] == 64) { if (treeOffset != selectedToken.GetTreeTextRange().StartOffset.Shift(1)) { return; } consumer.ConsumeMatchingBracesHighlighting( selectedToken.GetDocumentRange().StartOffsetRange().ExtendRight(1).Shift(1), selectedToken.GetDocumentRange().EndOffsetRange().ExtendLeft(1)); } else { if (treeOffset != selectedToken.GetTreeTextRange().StartOffset) { return; } consumer.ConsumeMatchingBracesHighlighting( selectedToken.GetDocumentRange().StartOffsetRange().ExtendRight(1), selectedToken.GetDocumentRange().EndOffsetRange().ExtendLeft(1)); } } }
public TextRange GetBlockComment(ITokenNode tokenNode) { return(tokenNode.GetTokenType() == ShaderLabTokenType.MULTI_LINE_COMMENT ? new TextRange(tokenNode.GetDocumentStartOffset().Offset, tokenNode.GetDocumentEndOffset().Offset) : TextRange.InvalidRange); }
private static void SwapFileHeaderNode(ICSharpFile file, string newHeader) { ITreeRange existingHeaderRange = Utils.GetFileHeaderTreeRange(file); using (WriteLockCookie.Create(file.IsPhysical())) { ICommentNode newCommentNode; if (existingHeaderRange.IsEmpty) { // existing header missing so add on a new line for our new header newHeader += Environment.NewLine; IWhitespaceNode node = file.FirstChild as IWhitespaceNode; bool insertNewLine = true; while (node != null) { if (node.IsNewLine) { insertNewLine = false; break; } node = node.NextSibling as IWhitespaceNode; } if (insertNewLine) { newHeader += Environment.NewLine; } newCommentNode = (ICommentNode) CSharpTokenType.END_OF_LINE_COMMENT.Create(new JB::JetBrains.Text.StringBuffer(newHeader), new TreeOffset(0), new TreeOffset(newHeader.Length)); LowLevelModificationUtil.AddChildBefore(file.FirstChild, new ITreeNode[] { newCommentNode }); } else { ITokenNode lastToken = (ITokenNode)existingHeaderRange.Last; ITokenNode nextToken = lastToken.GetNextToken(); if (nextToken != null) { ITokenNode nextNextToken = nextToken.GetNextToken(); if (nextNextToken != null) { ITokenNode nextNextNextToken = nextNextToken.GetNextToken(); if (!nextToken.IsNewLine() || !nextNextToken.IsNewLine()) { newHeader += Environment.NewLine; } if (nextNextNextToken.GetTokenType() == CSharpTokenType.PP_SHARP && nextToken.IsNewLine() && nextNextToken.IsNewLine()) { newHeader += Environment.NewLine; } newCommentNode = (ICommentNode) CSharpTokenType.END_OF_LINE_COMMENT.Create( new JB::JetBrains.Text.StringBuffer(newHeader), new TreeOffset(0), new TreeOffset(newHeader.Length)); LowLevelModificationUtil.ReplaceChildRange(existingHeaderRange.First, existingHeaderRange.Last, new ITreeNode[] { newCommentNode }); } } } } }
// We have right brace. We'll find all left braces. // 'RBRACE[caret]' protected override void TryHighlightToLeft(MatchingHighlightingsConsumer consumer, ITokenNode selectedToken, TreeOffset treeOffset) { if (selectedToken.GetTokenType() != CSharpTokenType.STRING_LITERAL) return; if (ExistingTreeNodes.ExistingTrees.Count == 0) return; DocumentRange rBraceRange = myProvider.DocumentCaret.ExtendLeft(1); ITreeNode node = GetNodeFromRange(rBraceRange); string lang = GetLanguageFromNode(node); if (String.IsNullOrEmpty(lang)) return; string rBrother = node.UserData.GetData(Constants.YcTokenName); string lbrother = LanguageHelper.GetBrother(lang, rBrother, Brother.Left); if (String.IsNullOrEmpty(lbrother)) return; int leftNumber = LanguageHelper.GetNumberFromYcName(lang, lbrother); int rightNumber = Int32.Parse(node.UserData.GetData(Constants.YcTokNumber)); var helper = Helper.ReSharperHelper<DocumentRange, ITreeNode>.Instance; IEnumerable<DocumentRange> ranges = helper.GetPairedRanges(lang, leftNumber, rightNumber, rBraceRange, false); foreach (DocumentRange range in ranges) { MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, range, rBraceRange); } /* * need for measurement List<ITreeNode> forest = Helper.ReSharperHelper<DocumentRange, ITreeNode>.Instance.GetForestWithToken(lang, rBraceRange); var lBraceTextRange = new TreeTextRange(treeOffset.Shift(-1), 1); var leftRanges = new List<DocumentRange>(); foreach (ITreeNode tree in forest) { var rBraceNode = tree.FindNodeAt(lBraceTextRange); //if (rBraceNode == null) // //in general, this should not be. But while such a situation occurs // continue; var lbraceNode = rBraceNode.PrevSibling; while (lbraceNode != null && lbraceNode.UserData.GetData(Constants.YcTokenName) != lbrother) { lbraceNode = lbraceNode.PrevSibling; } if (lbraceNode != null) leftRanges.Add(lbraceNode.GetNavigationRange()); } foreach (DocumentRange range in leftRanges) { MatchingBracesContextHighlightersUtil.ConsumeMatchingBracesHighlighting(consumer, range, rBraceRange); } */ }