CrefSyntaxExtensions.cs 4.0 KB
Newer Older
1
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2 3 4 5

using System.Threading;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Options;
6
using Microsoft.CodeAnalysis.Simplification;
P
Pilchie 已提交
7 8 9 10 11 12 13 14 15 16 17
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.CSharp.Extensions
{
    internal static class CrefSyntaxExtensions
    {
        public static bool TryReduceOrSimplifyExplicitName(
            this CrefSyntax crefSyntax,
            SemanticModel semanticModel,
            out CrefSyntax replacementNode,
            out TextSpan issueSpan,
18
            OptionSet optionSet,
P
Pilchie 已提交
19 20 21 22 23 24
            CancellationToken cancellationToken)
        {
            replacementNode = null;
            issueSpan = default(TextSpan);

            // Currently Qualified Cref is the only CrefSyntax We are handling separately
25
            if (crefSyntax.Kind() != SyntaxKind.QualifiedCref)
P
Pilchie 已提交
26 27 28 29 30 31 32 33
            {
                return false;
            }

            var qualifiedCrefSyntax = (QualifiedCrefSyntax)crefSyntax;
            var memberCref = qualifiedCrefSyntax.Member;

            // Currently we are dealing with only the NameMemberCrefs
34
            if (optionSet.GetOption(SimplificationOptions.PreferIntrinsicPredefinedTypeKeywordInMemberAccess, LanguageNames.CSharp) &&
35
                (memberCref.Kind() == SyntaxKind.NameMemberCref))
P
Pilchie 已提交
36 37
            {
                var nameMemberCref = ((NameMemberCrefSyntax)memberCref).Name;
38
                var symbolInfo = semanticModel.GetSymbolInfo(nameMemberCref, cancellationToken);
P
Pilchie 已提交
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
                var symbol = symbolInfo.Symbol;

                if (symbol == null)
                {
                    return false;
                }

                if (symbol is INamespaceOrTypeSymbol)
                {
                    var namespaceOrTypeSymbol = (INamespaceOrTypeSymbol)symbol;

                    // 1. Check for Predefined Types
                    if (symbol is INamedTypeSymbol)
                    {
                        var namedSymbol = (INamedTypeSymbol)symbol;
                        var keywordKind = ExpressionSyntaxExtensions.GetPredefinedKeywordKind(namedSymbol.SpecialType);

                        if (keywordKind != SyntaxKind.None)
                        {
                            replacementNode = SyntaxFactory.TypeCref(
                                                SyntaxFactory.PredefinedType(
                                                    SyntaxFactory.Token(crefSyntax.GetLeadingTrivia(), keywordKind, crefSyntax.GetTrailingTrivia())));
B
Basoundr_ms 已提交
61
                            replacementNode = crefSyntax.CopyAnnotationsTo(replacementNode);
P
Pilchie 已提交
62

B
Basoundr_ms 已提交
63
                            // we want to show the whole name expression as unnecessary
64
                            issueSpan = crefSyntax.Span;
P
Pilchie 已提交
65 66 67 68 69 70 71

                            return true;
                        }
                    }
                }
            }

B
Basoundr_ms 已提交
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
            var oldSymbol = semanticModel.GetSymbolInfo(crefSyntax, cancellationToken).Symbol;
            if (oldSymbol != null)
            {
                var speculativeBindingOption = SpeculativeBindingOption.BindAsExpression;
                if (oldSymbol is INamespaceOrTypeSymbol)
                {
                    speculativeBindingOption = SpeculativeBindingOption.BindAsTypeOrNamespace;
                }

                var newSymbol = semanticModel.GetSpeculativeSymbolInfo(crefSyntax.SpanStart, memberCref, speculativeBindingOption).Symbol;

                if (newSymbol == oldSymbol)
                {
                    // Copy Trivia and Annotations
                    memberCref = memberCref.WithLeadingTrivia(crefSyntax.GetLeadingTrivia());
                    memberCref = crefSyntax.CopyAnnotationsTo(memberCref);
                    issueSpan = qualifiedCrefSyntax.Container.Span;
                    replacementNode = memberCref;
                    return true;
                }
            }

P
Pilchie 已提交
94 95 96 97
            return false;
        }
    }
}