예제 #1
0
        private static bool FindMatchingBrace(SourceLocation position, int direction, SyntaxNode parent, SyntaxKind syntaxKind, out TextSpan right)
        {
            var tokens = parent.ChildNodes.Where(t => t.Kind == syntaxKind);
            var relevantTokens = (direction < 0)
                ? from t in tokens
                    where t.SourceRange.End <= position
                    select t
                : from t in tokens
                    where position < t.SourceRange.Start
                    select t;

            right = new TextSpan();
            var found = false;

            foreach (var token in relevantTokens.Cast<SyntaxToken>())
            {
                if (!found)
                {
                    right = token.Span;
                    found = true;
                }
                else
                    return false;
            }

            return found;
        }
예제 #2
0
        private static BraceMatchingResult MatchBraces(SyntaxToken token, SourceLocation position, SyntaxKind leftKind, SyntaxKind rightKind)
        {
            var isLeft = token.Kind == leftKind &&
                         position == token.SourceRange.Start;

            var isRight = token.Kind == rightKind &&
                          position == token.SourceRange.End;

            if (isLeft)
            {
                var left = token.Span;
                TextSpan right;
                if (FindMatchingBrace(position, 1, token.Parent, rightKind, out right))
                    return MapResultToFile(left, right);
            }
            else if (isRight)
            {
                TextSpan left;
                var right = token.Span;
                if (FindMatchingBrace(position, -1, token.Parent, leftKind, out left))
                    return MapResultToFile(left, right);
            }

            return BraceMatchingResult.None;
        }
        public IEnumerable<CompletionItem> GetItems(SemanticModel semanticModel, SourceLocation position)
        {
            var syntaxTree = semanticModel.Compilation.SyntaxTree;

            return GetAvailableKeywords(syntaxTree, position)
                .Select(k => k.GetText())
                .Select(t => new CompletionItem(t, t, t + " Keyword", Glyph.Keyword));
        }
예제 #4
0
 private static BraceMatchingResult MatchBraces(SyntaxTree syntaxTree, SourceLocation position, SyntaxKind leftKind, SyntaxKind rightKind)
 {
     return syntaxTree.Root.FindStartTokens(position)
         .Select(t => MatchBraces(t, position, leftKind, rightKind))
         .Where(r => r.IsValid)
         .DefaultIfEmpty(BraceMatchingResult.None)
         .First();
 }
예제 #5
0
 public BraceMatchingResult MatchBraces(SyntaxTree syntaxTree, SourceLocation position)
 {
     return _matchingKinds
         .Select(k => MatchBraces(syntaxTree, position, k.Item1, k.Item2))
         .Where(r => r.IsValid)
         .DefaultIfEmpty(BraceMatchingResult.None)
         .First();
 }
        private static bool IsInPropertyAccess(SyntaxNode root, SourceLocation position)
        {
            var token = root.FindTokenOnLeft(position);
            if (token == null || !token.SourceRange.ContainsOrTouches(position))
                return false;

            var propertyAccess = token.Parent.AncestorsAndSelf().OfType<FieldAccessExpressionSyntax>().FirstOrDefault();
            return propertyAccess != null && (propertyAccess.DotToken == token || propertyAccess.Name == token);
        }
        public IEnumerable<HighlightSpan> GetHighlights(SemanticModel semanticModel, SourceLocation position)
        {
            var symbolAtPosition = semanticModel.FindSymbol(position);
            if (symbolAtPosition == null)
                return Enumerable.Empty<HighlightSpan>();

            return semanticModel.FindUsages(symbolAtPosition.Value.Symbol)
                .Select(s => new HighlightSpan(s.Span, s.Kind == SymbolSpanKind.Definition));
        }
        private static IEnumerable<SyntaxKind> GetAvailableKeywords(SyntaxTree syntaxTree, SourceLocation position)
        {
            var isInNonUserCode = syntaxTree.Root.InNonUserCode(position);
            if (isInNonUserCode)
                yield break;

            var isPreprocessorDirectiveContext = syntaxTree.DefinitelyInMacro(position);

            var leftToken = syntaxTree.Root.FindTokenOnLeft(position);

            var targetToken = leftToken.GetPreviousTokenIfTouchingWord(position);
            if (targetToken == null)
                yield break;

            var isPreprocessorKeywordContext = isPreprocessorDirectiveContext && syntaxTree.IsPreprocessorKeywordContext(position, leftToken);

            var isStatementContext = !isPreprocessorDirectiveContext && targetToken.IsBeginningOfStatementContext();

            var isSemanticContext = !isPreprocessorDirectiveContext && leftToken.HasAncestor<SemanticSyntax>();

            var isTypeDeclarationContext = syntaxTree.IsTypeDeclarationContext(targetToken);

            if (IsValidBreakKeywordContext(isStatementContext, leftToken))
                yield return SyntaxKind.BreakKeyword;

            if (targetToken.IsSwitchLabelContext())
                yield return SyntaxKind.CaseKeyword;

            if (IsValidContinueKeywordContext(isStatementContext, leftToken))
                yield return SyntaxKind.ContinueKeyword;

            if (isPreprocessorDirectiveContext || IsValidElseKeywordContext(targetToken))
                yield return SyntaxKind.ElseKeyword;

            if (isPreprocessorKeywordContext || isStatementContext)
                yield return SyntaxKind.IfKeyword;

            if (isSemanticContext)
                yield return SyntaxKind.PackoffsetKeyword;

            if (isStatementContext)
                yield return SyntaxKind.ReturnKeyword;

            if (isSemanticContext)
                yield return SyntaxKind.RegisterKeyword;

            if (isTypeDeclarationContext)
                yield return SyntaxKind.StructKeyword;

            if (isStatementContext)
                yield return SyntaxKind.SwitchKeyword;

            if (isStatementContext || IsValidWhileKeywordContext(targetToken))
                yield return SyntaxKind.WhileKeyword;
        }
예제 #9
0
        public static SymbolSpan? FindSymbol(this SemanticModel semanticModel, SourceLocation position)
        {
            if (semanticModel == null)
                throw new ArgumentNullException(nameof(semanticModel));

            var syntaxTree = semanticModel.SyntaxTree;
            return syntaxTree.Root.FindNodes(position)
                .SelectMany(n => GetSymbolSpans(semanticModel, n))
                .Where(s => s.Span.IsInRootFile && s.SourceRange.ContainsOrTouches(position))
                .Select(s => s).Cast<SymbolSpan?>().FirstOrDefault();
        }
예제 #10
0
        private static IEnumerable<CompletionItem> GetGlobalCompletions(SemanticModel semanticModel, SourceLocation position)
        {
            var symbols = semanticModel.LookupSymbols(position)
                .Where(x => !(x is SemanticSymbol))
                .Where(x => !(x is AttributeSymbol));

            if (!semanticModel.SyntaxTree.PossiblyInTypeName(position))
                symbols = symbols.Where(x => !(x is TypeSymbol));

            return CreateSymbolCompletions(symbols);
        }
예제 #11
0
        public static IEnumerable<HighlightSpan> GetHighlights(this SemanticModel semanticModel, SourceLocation position, IEnumerable<IHighlighter> highlighters)
        {
            var result = new List<HighlightSpan>();

            foreach (var highlighter in highlighters)
            {
                result.AddRange(highlighter
                    .GetHighlights(semanticModel, position)
                    .Where(x => x.Span.IsInRootFile));
            }

            return result;
        }
예제 #12
0
        public static bool IsPreprocessorKeywordContext(this SyntaxTree syntaxTree, SourceLocation position, SyntaxToken preProcessorTokenOnLeftOfPosition)
        {
            // cases:
            //  #|
            //  #d|
            //  # |
            //  # d|

            // note: comments are not allowed between the # and item.
            var token = preProcessorTokenOnLeftOfPosition;
            token = token.GetPreviousTokenIfTouchingWord(position);

            if (token.IsKind(SyntaxKind.HashToken))
                return true;

            return false;
        }
예제 #13
0
        private static FieldAccessExpressionSyntax GetPropertyAccessExpression(SyntaxNode root, SourceLocation position)
        {
            var token = root.FindTokenOnLeft(position);
            var previous = token.GetPreviousToken(false, true);
            var dot = previous != null && previous.Kind == SyntaxKind.DotToken
                          ? previous
                          : token;

            var p = dot.Parent.AncestorsAndSelf().OfType<FieldAccessExpressionSyntax>().FirstOrDefault();

            if (p != null)
            {
                var afterDot = p.DotToken.SourceRange.End <= position && position <= p.Name.SourceRange.End;
                if (afterDot)
                    return p;
            }

            return null;
        }
예제 #14
0
        public IEnumerable<CompletionItem> GetItems(SemanticModel semanticModel, SourceLocation position)
        {
            var root = semanticModel.SyntaxTree.Root;

            // We don't want to show a completions for these cases.
            if (semanticModel.SyntaxTree.PossiblyInUserGivenName(position))
                return Enumerable.Empty<CompletionItem>();
            if (semanticModel.SyntaxTree.DefinitelyInMacro(position))
                return Enumerable.Empty<CompletionItem>();
            if (semanticModel.SyntaxTree.DefinitelyInVariableDeclaratorQualifier(position))
                return Enumerable.Empty<CompletionItem>();

            // Comments and literals don't get completion information
            if (root.InComment(position) || root.InLiteral(position))
                return Enumerable.Empty<CompletionItem>();

            if (semanticModel.SyntaxTree.DefinitelyInTypeName(position))
                return GetTypeCompletions(semanticModel, position);

            var propertyAccessExpression = GetPropertyAccessExpression(root, position);
            return propertyAccessExpression == null
                ? GetGlobalCompletions(semanticModel, position)
                : GetMemberCompletions(semanticModel, propertyAccessExpression);
        }
예제 #15
0
 public IEnumerable<Symbol> LookupSymbols(SourceLocation position)
 {
     var node = FindClosestNodeWithBinder(_bindingResult.Root, position);
     var binder = node == null ? null : _bindingResult.GetBinder(node);
     return binder == null
         ? Enumerable.Empty<Symbol>()
         : LookupSymbols(binder);
 }
예제 #16
0
 private SyntaxNode FindClosestNodeWithBinder(SyntaxNode root, SourceLocation position)
 {
     var token = root.FindTokenContext(position);
     return (from n in token.Parent.AncestorsAndSelf()
         let bc = _bindingResult.GetBinder(n)
         where bc != null
         select n).FirstOrDefault();
 }
예제 #17
0
 private static IEnumerable<CompletionItem> GetTypeCompletions(SemanticModel semanticModel, SourceLocation position)
 {
     var symbols = semanticModel.LookupSymbols(position).OfType<TypeSymbol>();
     return CreateSymbolCompletions(symbols);
 }