private void NodeToJson(JsonWriter jw, SyntaxNodeOrToken node, Dictionary <SyntaxNodeOrToken, int> nodeToIdx) { jw.WriteStartObject(); jw.WritePropertyName("id"); jw.WriteValue(nodeToIdx[node]); jw.WritePropertyName("type"); jw.WriteValue(node.Kind().ToString()); if (node.IsKind(SyntaxKind.IdentifierName) || node.IsKind(SyntaxKind.PredefinedType) || RoslynUtils.IsSimpleLiteral(node) || node.IsToken || node.AsNode().ChildNodes().Count() == 0) { jw.WritePropertyName("value"); jw.WriteValue(node.ToString()); } else { jw.WritePropertyName("children"); jw.WriteStartArray(); foreach (var child in node.AsNode().ChildNodesAndTokens()) { if (!nodeToIdx.TryGetValue(child, out int idx)) { idx = int.MaxValue; } jw.WriteValue(idx); } jw.WriteEndArray(); } jw.WriteEndObject(); }
public static bool HasOutKeywordForArgument(SyntaxNodeOrToken nodeOrToken) { var isArgument = nodeOrToken.IsKind(SyntaxKind.Argument); var hasOutKeyword = isArgument && ((ArgumentSyntax)nodeOrToken).RefOrOutKeyword.IsKind(SyntaxKind.OutKeyword); return(hasOutKeyword); }
private static bool TryFindNodeOrToken( SyntaxNodeOrToken node, SyntaxKind kind, ref int occurrence, ref SyntaxNodeOrToken foundNode ) { if (node.IsKind(kind)) { occurrence--; if (occurrence == 0) { foundNode = node; return(true); } } // we should probably did into trivia if this is a Token, but we won't foreach (var child in node.ChildNodesAndTokens()) { if (TryFindNodeOrToken(child, kind, ref occurrence, ref foundNode)) { return(true); } } return(false); }
public static bool IsSimpleLiteral(SyntaxNodeOrToken node) => node.IsKind(SyntaxKind.FalseKeyword) || node.IsKind(SyntaxKind.TrueKeyword) || node.IsKind(SyntaxKind.NullKeyword) || node.IsKind(SyntaxKind.NumericLiteralExpression) || node.IsKind(SyntaxKind.CharacterLiteralExpression) || node.IsKind(SyntaxKind.StringLiteralExpression);
public TNode InsertModifier(TNode node, SyntaxToken modifier, IModifierComparer comparer = null) { if (node == null) { throw new ArgumentNullException(nameof(node)); } SyntaxTokenList modifiers = GetModifiers(node); Debug.Assert(modifiers.Any() || modifiers == default(SyntaxTokenList), node.ToString()); if (!modifiers.Any()) { SyntaxNodeOrToken nodeOrToken = FindNodeOrTokenAfterModifiers(node); if (!nodeOrToken.IsKind(SyntaxKind.None)) { SyntaxTriviaList trivia = nodeOrToken.GetLeadingTrivia(); if (trivia.Any()) { SyntaxTriviaList leadingTrivia = modifier.LeadingTrivia; if (!leadingTrivia.IsSingleElasticMarker()) { trivia = trivia.AddRange(leadingTrivia); } if (nodeOrToken.IsNode) { SyntaxNode node2 = nodeOrToken.AsNode(); node = node.ReplaceNode(node2, node2.WithoutLeadingTrivia()); } else { SyntaxToken token = nodeOrToken.AsToken(); node = node.ReplaceToken(token, token.WithoutLeadingTrivia()); } return(WithModifiers(node, TokenList(modifier.WithLeadingTrivia(trivia)))); } } } return(WithModifiers(node, modifiers.InsertModifier(modifier, comparer ?? ModifierComparer.Instance))); }
void UpdateWordAdornments() { SnapshotPoint currentRequest = RequestedPoint; var document = View.TextSnapshot.TextBuffer.GetRelatedDocuments().FirstOrDefault(); if (document == null) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } var syntaxTree = document.GetSyntaxTreeAsync().ConfigureAwait(false).GetAwaiter().GetResult(); var root = syntaxTree.GetRoot(); SyntaxNodeOrToken token = root.FindToken(currentRequest.Position); var line = View.TextSnapshot.GetLineFromPosition(currentRequest.Position); SyntaxNodeOrToken lineSyntax = root.FindNode(TextSpan.FromBounds(line.Start, line.End)); var nodes = lineSyntax.ChildNodesAndTokens(); var methods = new List <SyntaxNodeOrToken>(); TraversideNodes(nodes, methods); if (!methods.Any()) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } var idx = -1; TextSpan currentArgSpan = TextSpan.FromBounds(0, 0); SyntaxNodeOrToken _sqlSyntax = null; foreach (var method in methods) { var _argsSyntax = ((SyntaxNodeOrToken)method.Parent).GetNextSibling().ChildNodesAndTokens().Where(p => p.IsKind(SyntaxKind.Argument)); foreach (var _arg in _argsSyntax) { idx++; if (_arg.Span.Start <= currentRequest.Position && currentRequest.Position <= _arg.Span.End) { currentArgSpan = _arg.Span; var dot = method.GetPreviousSibling(); //如果方法名签名不是一个点(.),终止 if (!dot.IsKind(SyntaxKind.DotToken)) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } _sqlSyntax = dot.GetPreviousSibling(); break; } } } //如果没有选择参数,并且Splice方法前不是字符串 if (idx == -1 || !_sqlSyntax.IsKind(SyntaxKind.StringLiteralExpression)) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } //SyntaxNodeOrToken argsSyntax = null; //if (token.Parent.IsKind(SyntaxKind.ArgumentList)) // argsSyntax = token.Parent; //else // argsSyntax = ((SyntaxNodeOrToken)token.Parent?.Parent).GetPreviousSibling().Parent;//此情况是光标在具体某个参数上 //if (argsSyntax.RawKind == 0) // argsSyntax = ((SyntaxNodeOrToken)token.Parent?.Parent?.Parent).GetPreviousSibling().Parent; //if (argsSyntax == null || !argsSyntax.IsKind(SyntaxKind.ArgumentList)) //{ // SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); // return; //} //var expression = argsSyntax.GetPreviousSibling(); //#region 判断是不是拼接sql的方法(Splice) //var syntax = expression.ChildNodesAndTokens(); //if (syntax.Count != 3) //{ // SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); // return; //} //if (!syntax.First().IsKind(SyntaxKind.StringLiteralExpression) || !syntax.Last().IsKind(SyntaxKind.IdentifierName) || !syntax.Last().ToFullString().Equals("Splice", StringComparison.Ordinal)) //{ // SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); // return; //} //#endregion //var args = argsSyntax.ChildNodesAndTokens().Where(p => p.IsKind(SyntaxKind.Argument)).ToList(); //var pointer = token.Span.Start; ////获取当前焦点在第几个参数 //foreach (var arg in args) //{ // idx++; // if (arg.Span.Start >= pointer && pointer <= arg.Span.End) // break; //} //var sqlSyntax = syntax.First(); var sql = _sqlSyntax.ToString(); var startIdx = -1; var endIdx = -1; var currentIdx = 0; for (var i = 0; i <= idx; i++) { startIdx = sql.IndexOf("{", currentIdx); if (startIdx == -1) { break; } endIdx = sql.IndexOf("}", startIdx); if (endIdx == -1) { break; } currentIdx = endIdx; } if (startIdx == -1 || endIdx == -1) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(), null); return; } List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); //添加当前选中的参数高亮 //wordSpans.Add(new SnapshotSpan(View.TextSnapshot, currentArgSpan.Start, currentArgSpan.End - currentArgSpan.Start)); //添加对应的拼接sql部分高亮 wordSpans.Add(new SnapshotSpan(View.TextSnapshot, _sqlSyntax.Span.Start + startIdx, endIdx - startIdx + 1)); //Find all words in the buffer like the one the caret is on TextExtent word = TextStructureNavigator.GetExtentOfWord(currentRequest); SnapshotSpan currentWord = word.Span; //If this is the current word, and the caret moved within a word, we're done. if (CurrentWord.HasValue && currentWord == CurrentWord) { return; } //If another change hasn't happened, do a real update if (currentRequest == RequestedPoint) { SynchronousUpdate(currentRequest, new NormalizedSnapshotSpanCollection(wordSpans), currentWord); } }