Example #1
0
        protected override bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken)
        {
            var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression) ?? syntaxFacts.GetExpressionOfConditionalMemberAccessExpression(expression);

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

            var semanticInfo       = semanticModel.GetTypeInfo(leftExpression, cancellationToken);
            var leftExpressionType = semanticInfo.Type;

            return(leftExpressionType != null && method.ReduceExtensionMethod(leftExpressionType) != null);
        }
        protected override bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken)
        {
            var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression) ?? syntaxFacts.GetExpressionOfConditionalMemberAccessExpression(expression);

            if (leftExpression == null)
            {
                if (expression.IsKind(SyntaxKind.CollectionInitializerExpression))
                {
                    leftExpression = expression.GetAncestor <ObjectCreationExpressionSyntax>();
                }
                else
                {
                    return(false);
                }
            }

            var semanticInfo       = semanticModel.GetTypeInfo(leftExpression, cancellationToken);
            var leftExpressionType = semanticInfo.Type;

            return(leftExpressionType != null && method.ReduceExtensionMethod(leftExpressionType) != null);
        }
        protected bool IsViableExtensionMethod(IMethodSymbol method, ITypeSymbol receiver)
        {
            if (receiver == null || method == null)
            {
                return(false);
            }

            // It's possible that the 'method' we're looking at is from a different language than
            // the language we're currently in.  For example, we might find the extension method
            // in an unreferenced VB project while we're in C#.  However, in order to 'reduce'
            // the extension method, the compiler requires both the method and receiver to be
            // from the same language.
            //
            // So, if they're not from the same language, we simply can't proceed.  Now in this
            // case we decide that the method is not viable.  But we could, in the future, decide
            // to just always consider such methods viable.

            if (receiver.Language != method.Language)
            {
                return(false);
            }

            return(method.ReduceExtensionMethod(receiver) != null);
        }
 public IMethodSymbol ReduceExtensionMethod(ITypeSymbol receiverType)
 {
     // This implementation feels incorrect!
     return(_symbol.ReduceExtensionMethod(receiverType));
 }
 private bool IsViableExtensionMethod(
     ITypeSymbol typeSymbol,
     IMethodSymbol method)
 {
     return typeSymbol != null && method.ReduceExtensionMethod(typeSymbol) != null;
 }
 private bool IsViableExtensionMethod(
     ITypeSymbol typeSymbol,
     IMethodSymbol method)
 {
     return(typeSymbol != null && method.ReduceExtensionMethod(typeSymbol) != null);
 }
        public override void VisitMethod(IMethodSymbol symbol)
        {
            if (symbol.MethodKind == MethodKind.AnonymousFunction)
            {
                // TODO(cyrusn): Why is this a literal?  Why don't we give the appropriate signature
                // of the method as asked?
                builder.Add(CreatePart(SymbolDisplayPartKind.NumericLiteral, symbol, "lambda expression"));
                return;
            }
            else if (symbol is SynthesizedGlobalMethodSymbol) // It would be nice to handle VB symbols too, but it's not worth the effort.
            {
                // Represents a compiler generated synthesized method symbol with a null containing
                // type.

                // TODO(cyrusn); Why is this a literal?
                builder.Add(CreatePart(SymbolDisplayPartKind.NumericLiteral, symbol, symbol.Name));
                return;
            }

            if (symbol.IsExtensionMethod && format.ExtensionMethodStyle != SymbolDisplayExtensionMethodStyle.Default)
            {
                if (symbol.MethodKind == MethodKind.ReducedExtension && format.ExtensionMethodStyle == SymbolDisplayExtensionMethodStyle.StaticMethod)
                {
                    symbol = symbol.GetConstructedReducedFrom();
                }
                else if (symbol.MethodKind != MethodKind.ReducedExtension && format.ExtensionMethodStyle == SymbolDisplayExtensionMethodStyle.InstanceMethod)
                {
                    // If we cannot reduce this to an instance form then display in the static form
                    symbol = symbol.ReduceExtensionMethod(symbol.Parameters.First().Type) ?? symbol;
                }
            }

            // Method members always have a type unless (1) this is a lambda method symbol, which we
            // have dealt with already, or (2) this is an error method symbol. If we have an error method
            // symbol then we do not know its accessibility, modifiers, etc, all of which require knowing
            // the containing type, so we'll skip them.

            if ((object)symbol.ContainingType != null || (symbol.ContainingSymbol is ITypeSymbol))
            {
                AddAccessibilityIfRequired(symbol);
                AddMemberModifiersIfRequired(symbol);

                if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeType))
                {
                    switch (symbol.MethodKind)
                    {
                    case MethodKind.Constructor:
                    case MethodKind.StaticConstructor:
                        break;

                    case MethodKind.Destructor:
                    case MethodKind.Conversion:
                        // If we're using the metadata format, then include the return type.
                        // Otherwise we eschew it since it is redundant in an conversion
                        // signature.
                        if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames))
                        {
                            goto default;
                        }

                        break;

                    default:
                        // The display code is called by the debugger; if a developer is debugging Roslyn and attempts
                        // to visualize a symbol *during its construction*, the parameters and return type might
                        // still be null.

                        if (symbol.ReturnsByRef)
                        {
                            AddRefIfRequired();
                        }
                        else if (symbol.ReturnsByRefReadonly)
                        {
                            AddRefReadonlyIfRequired();
                        }

                        AddCustomModifiersIfRequired(symbol.RefCustomModifiers);

                        if (symbol.ReturnsVoid)
                        {
                            AddKeyword(SyntaxKind.VoidKeyword);
                        }
                        else if (symbol.ReturnType != null)
                        {
                            AddReturnType(symbol);
                        }

                        AddSpace();
                        AddCustomModifiersIfRequired(symbol.ReturnTypeCustomModifiers);
                        break;
                    }
                }

                if (format.MemberOptions.IncludesOption(SymbolDisplayMemberOptions.IncludeContainingType))
                {
                    ITypeSymbol containingType;
                    bool        includeType;

                    if (symbol.MethodKind == MethodKind.LocalFunction)
                    {
                        includeType    = false;
                        containingType = null;
                    }
                    else if (symbol.MethodKind == MethodKind.ReducedExtension)
                    {
                        containingType = symbol.ReceiverType;
                        includeType    = true;
                        Debug.Assert(containingType != null);
                    }
                    else
                    {
                        containingType = symbol.ContainingType;

                        if ((object)containingType != null)
                        {
                            includeType = IncludeNamedType(symbol.ContainingType);
                        }
                        else
                        {
                            containingType = (ITypeSymbol)symbol.ContainingSymbol;
                            includeType    = true;
                        }
                    }

                    if (includeType)
                    {
                        containingType.Accept(this.NotFirstVisitor);
                        AddPunctuation(SyntaxKind.DotToken);
                    }
                }
            }

            bool isAccessor = false;

            switch (symbol.MethodKind)
            {
            case MethodKind.Ordinary:
            case MethodKind.DelegateInvoke:
            case MethodKind.LocalFunction:
                //containing type will be the delegate type, name will be Invoke
                builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.Name));
                break;

            case MethodKind.ReducedExtension:
                // Note: Extension methods invoked off of their static class will be tagged as methods.
                //       This behavior matches the semantic classification done in NameSyntaxClassifier.
                builder.Add(CreatePart(SymbolDisplayPartKind.ExtensionMethodName, symbol, symbol.Name));
                break;

            case MethodKind.PropertyGet:
            case MethodKind.PropertySet:
                isAccessor = true;
                var associatedProperty = (IPropertySymbol)symbol.AssociatedSymbol;
                if (associatedProperty == null)
                {
                    goto case MethodKind.Ordinary;
                }
                AddPropertyNameAndParameters(associatedProperty);
                AddPunctuation(SyntaxKind.DotToken);
                AddKeyword(symbol.MethodKind == MethodKind.PropertyGet ? SyntaxKind.GetKeyword : SyntaxKind.SetKeyword);
                break;

            case MethodKind.EventAdd:
            case MethodKind.EventRemove:
                isAccessor = true;
                var associatedEvent = (IEventSymbol)symbol.AssociatedSymbol;
                if (associatedEvent == null)
                {
                    goto case MethodKind.Ordinary;
                }
                AddEventName(associatedEvent);
                AddPunctuation(SyntaxKind.DotToken);
                AddKeyword(symbol.MethodKind == MethodKind.EventAdd ? SyntaxKind.AddKeyword : SyntaxKind.RemoveKeyword);
                break;

            case MethodKind.Constructor:
            case MethodKind.StaticConstructor:
                // Note: we are using the metadata name also in the case that
                // symbol.containingType is null (which should never be the case here) or is an
                //       anonymous type (which 'does not have a name').
                var name = format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames) || symbol.ContainingType == null || symbol.ContainingType.IsAnonymousType
                        ? symbol.Name
                        : symbol.ContainingType.Name;
                builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, name));
                break;

            case MethodKind.Destructor:
                // Note: we are using the metadata name also in the case that symbol.containingType is null, which should never be the case here.
                if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames) || symbol.ContainingType == null)
                {
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.Name));
                }
                else
                {
                    AddPunctuation(SyntaxKind.TildeToken);
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.ContainingType.Name));
                }
                break;

            case MethodKind.ExplicitInterfaceImplementation:
                AddExplicitInterfaceIfRequired(symbol.ExplicitInterfaceImplementations);
                builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol,
                                       ExplicitInterfaceHelpers.GetMemberNameWithoutInterfaceName(symbol.Name)));
                break;

            case MethodKind.UserDefinedOperator:
            case MethodKind.BuiltinOperator:
                if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames))
                {
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.MetadataName));
                }
                else
                {
                    AddKeyword(SyntaxKind.OperatorKeyword);
                    AddSpace();
                    if (symbol.MetadataName == WellKnownMemberNames.TrueOperatorName)
                    {
                        AddKeyword(SyntaxKind.TrueKeyword);
                    }
                    else if (symbol.MetadataName == WellKnownMemberNames.FalseOperatorName)
                    {
                        AddKeyword(SyntaxKind.FalseKeyword);
                    }
                    else
                    {
                        builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol,
                                               SyntaxFacts.GetText(SyntaxFacts.GetOperatorKind(symbol.MetadataName))));
                    }
                }
                break;

            case MethodKind.Conversion:
                if (format.CompilerInternalOptions.IncludesOption(SymbolDisplayCompilerInternalOptions.UseMetadataMethodNames))
                {
                    builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol, symbol.MetadataName));
                }
                else
                {
                    // "System.IntPtr.explicit operator System.IntPtr(int)"

                    // TODO: rewrite this part
                    AddSpace();
                    AddKeyword(SyntaxKind.OperatorKeyword);

                    if (symbol.MetadataName == WellKnownMemberNames.ImplicitConversionName)
                    {
                        AddSpace();
                        AddKeyword(SyntaxKind.ImplicitKeyword);
                    }
                    else
                    {
                        builder.Add(CreatePart(SymbolDisplayPartKind.MethodName, symbol,
                                               SyntaxFacts.GetText(SyntaxFacts.GetOperatorKind(symbol.MetadataName))));
                    }
                    AddSpace();
                    AddKeyword(SyntaxKind.AsKeyword);

                    AddSpace();
                    AddReturnType(symbol);
                }
                break;

            default:
                throw ExceptionUtilities.UnexpectedValue(symbol.MethodKind);
            }

            if (!isAccessor)
            {
                AddTypeArguments(symbol, default(ImmutableArray <ImmutableArray <CustomModifier> >));
                AddParameters(symbol);
                AddTypeParameterConstraints(symbol);
            }
        }
        protected override bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken)
        {
            var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression) ?? syntaxFacts.GetExpressionOfConditionalMemberAccessExpression(expression);
            if (leftExpression == null)
            {
                if (expression.IsKind(SyntaxKind.CollectionInitializerExpression))
                {
                    leftExpression = expression.GetAncestor<ObjectCreationExpressionSyntax>();
                }
                else
                {
                    return false;
                }
            }

            var semanticInfo = semanticModel.GetTypeInfo(leftExpression, cancellationToken);
            var leftExpressionType = semanticInfo.Type;

            return leftExpressionType != null && method.ReduceExtensionMethod(leftExpressionType) != null;
        }
        protected override bool IsViableExtensionMethod(IMethodSymbol method, SyntaxNode expression, SemanticModel semanticModel, ISyntaxFactsService syntaxFacts, CancellationToken cancellationToken)
        {
            var leftExpression = syntaxFacts.GetExpressionOfMemberAccessExpression(expression) ?? syntaxFacts.GetExpressionOfConditionalMemberAccessExpression(expression);
            if (leftExpression == null)
            {
                return false;
            }

            var semanticInfo = semanticModel.GetTypeInfo(leftExpression, cancellationToken);
            var leftExpressionType = semanticInfo.Type;

            return leftExpressionType != null && method.ReduceExtensionMethod(leftExpressionType) != null;
        }