Beispiel #1
0
        private bool TryClassifySymbol(
            NameSyntax name,
            ISymbol symbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken,
            out ClassifiedSpan classifiedSpan)
        {
            // For Namespace parts, we want don't want to classify the QualifiedNameSyntax
            // nodes, we instead wait for the each IdentifierNameSyntax node to avoid
            // creating overlapping ClassifiedSpans.
            if (symbol is INamespaceSymbol namespaceSymbol &&
                name is IdentifierNameSyntax identifierNameSyntax)
            {
                // Do not classify the global:: namespace. It is already syntactically classified as a keyword.
                var isGlobalNamespace = namespaceSymbol.IsGlobalNamespace &&
                                        identifierNameSyntax.Identifier.IsKind(SyntaxKind.GlobalKeyword);
                if (isGlobalNamespace)
                {
                    classifiedSpan = default;
                    return(false);
                }

                // Classifies both extern aliases and namespaces.
                classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.NamespaceName);
                return(true);
            }

            if (name.IsNullWithNoType() &&
                IsInVarContext(name))
            {
                var alias = semanticModel.GetAliasInfo(name, cancellationToken);
                if (alias == null || alias.Name != "var")
                {
                    if (!IsSymbolWithName(symbol, "var"))
                    {
                        // We bound to a symbol.  If we bound to a symbol called "var" then we want to
                        // classify this appropriately as a type.  Otherwise, we want to classify this as
                        // a keyword.
                        classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword);
                        return(true);
                    }
                }
            }

            if (name.IsUnmanaged && name.Parent.IsKind(SyntaxKind.ImplementsTypeConstraint))
            {
                var alias = semanticModel.GetAliasInfo(name, cancellationToken);
                if (alias == null || alias.Name != "unmanaged")
                {
                    if (!IsSymbolWithName(symbol, "unmanaged"))
                    {
                        // We bound to a symbol.  If we bound to a symbol called "unmanaged" then we want to
                        // classify this appropriately as a type.  Otherwise, we want to classify this as
                        // a keyword.
                        classifiedSpan = new ClassifiedSpan(name.Span, ClassificationTypeNames.Keyword);
                        return(true);
                    }
                }
            }

            // Use .Equals since we can't rely on object identity for constructed types.
            SyntaxToken token;

            switch (symbol)
            {
            case ITypeSymbol typeSymbol:
                var classification = GetClassificationForType(typeSymbol);
                if (classification != null)
                {
                    token          = name.GetNameToken();
                    classifiedSpan = new ClassifiedSpan(token.Span, classification);
                    return(true);
                }
                break;

            case IFieldSymbol fieldSymbol:
                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForField(fieldSymbol));
                return(true);

            case IMethodSymbol methodSymbol:
                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForMethod(methodSymbol));
                return(true);

            case IPropertySymbol propertySymbol:
                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.PropertyName);
                return(true);

            case IEventSymbol eventSymbol:
                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.EventName);
                return(true);

            case IParameterSymbol parameterSymbol:
                if (parameterSymbol.IsImplicitlyDeclared && parameterSymbol.Name == "value")
                {
                    break;
                }

                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.ParameterName);
                return(true);

            case ILocalSymbol localSymbol:
                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, GetClassificationForLocal(localSymbol));
                return(true);

            case ILabelSymbol labelSymbol:
                token          = name.GetNameToken();
                classifiedSpan = new ClassifiedSpan(token.Span, ClassificationTypeNames.LabelName);
                return(true);
            }

            classifiedSpan = default;
            return(false);
        }