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);
        }
示例#3
0
        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);
        }
示例#4
0
 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);
示例#5
0
        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)));
        }
示例#6
0
        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);
            }
        }