예제 #1
0
 /// <summary>
 /// Gets a list of method or indexed property symbols for a syntax node.
 /// </summary>
 /// <param name="semanticModel"></param>
 /// <param name="node">The syntax node to get semantic information for.</param>
 /// <param name="cancellationToken">The cancellation token.</param>
 public static ImmutableArray <ISymbol> GetMemberGroup(
     this SemanticModel semanticModel,
     SyntaxNode node,
     CancellationToken cancellationToken = default(CancellationToken)
     )
 {
     return(semanticModel.GetMemberGroup(node, cancellationToken));
 }
        private bool TryGetComIndexers(SemanticModel semanticModel, ExpressionSyntax expression, CancellationToken cancellationToken, out IEnumerable<IPropertySymbol> indexers, out ITypeSymbol expressionType)
        {
            indexers = semanticModel.GetMemberGroup(expression, cancellationToken).OfType<IPropertySymbol>();

            if (indexers.Any() && expression is MemberAccessExpressionSyntax)
            {
                expressionType = semanticModel.GetTypeInfo(((MemberAccessExpressionSyntax)expression).Expression, cancellationToken).Type;
                return true;
            }

            expressionType = null;
            return false;
        }
        private bool TryGetTextForSymbol(SyntaxToken token, SemanticModel semanticModel, Document document, CancellationToken cancellationToken, out string text)
        {
            ISymbol symbol;
            if (token.Parent is TypeArgumentListSyntax)
            {
                var genericName = token.GetAncestor<GenericNameSyntax>();
                symbol = semanticModel.GetSymbolInfo(genericName, cancellationToken).Symbol ?? semanticModel.GetTypeInfo(genericName, cancellationToken).Type;
            }
            else if (token.Parent is NullableTypeSyntax && token.IsKind(SyntaxKind.QuestionToken))
            {
                text = "System.Nullable`1";
                return true;
            }
            else
            {
                var symbols = semanticModel.GetSymbols(token, document.Project.Solution.Workspace, bindLiteralsToUnderlyingType: true, cancellationToken: cancellationToken);
                symbol = symbols.FirstOrDefault();

                if (symbol == null)
                {
                    var bindableParent = document.GetLanguageService<ISyntaxFactsService>().GetBindableParent(token);
                    var overloads = semanticModel.GetMemberGroup(bindableParent);
                    symbol = overloads.FirstOrDefault();
                }
            }

            // Local: return the name if it's the declaration, otherwise the type
            if (symbol is ILocalSymbol && !symbol.DeclaringSyntaxReferences.Any(d => d.GetSyntax().DescendantTokens().Contains(token)))
            {
                symbol = ((ILocalSymbol)symbol).Type;
            }

            // Range variable: use the type
            if (symbol is IRangeVariableSymbol)
            {
                var info = semanticModel.GetTypeInfo(token.Parent, cancellationToken);
                symbol = info.Type;
            }

            // Just use syntaxfacts for operators
            if (symbol is IMethodSymbol && ((IMethodSymbol)symbol).MethodKind == MethodKind.BuiltinOperator)
            {
                text = null;
                return false;
            }

            text = symbol != null ? Format(symbol) : null;
            return symbol != null;
        }
            private static ITypeSymbol GetRegularExpressionType(SemanticModel semanticModel, SyntaxNode node)
            {
                // regular case. always use ConvertedType to get implicit conversion right.
                var expression = node.GetUnparenthesizedExpression();

                var info = semanticModel.GetTypeInfo(expression);
                var conv = semanticModel.GetConversion(expression);

                if (info.ConvertedType == null || info.ConvertedType.IsErrorType())
                {
                    // there is no implicit conversion involved. no need to go further
                    return info.Type;
                }

                // always use converted type if method group
                if ((!node.IsKind(SyntaxKind.ObjectCreationExpression) && semanticModel.GetMemberGroup(expression).Length > 0) ||
                    IsCoClassImplicitConversion(info, conv, semanticModel.Compilation.CoClassType()))
                {
                    return info.ConvertedType;
                }

                // check implicit conversion
                if (conv.IsImplicit && (conv.IsConstantExpression || conv.IsEnumeration))
                {
                    return info.ConvertedType;
                }

                // always try to use type that is more specific than object type if possible.
                return !info.Type.IsObjectType() ? info.Type : info.ConvertedType;
            }
            private bool CheckOverloadsContainUriParameters(SemanticModel model, IMethodSymbol method, SyntaxNode node, CancellationToken cancellationToken)
            {
                INamedTypeSymbol uriType = _uri;
                foreach (IMethodSymbol overload in model.GetMemberGroup(node, cancellationToken).OfType<IMethodSymbol>())
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    if (method.Equals(overload))
                    {
                        continue;
                    }

                    if (overload.Parameters.Any(p => p.Type?.Equals(uriType) == true))
                    {
                        return true;
                    }
                }

                return false;
            }