Exemple #1
0
            private bool TryInitializeExplicitInterface(
                TService service,
                SemanticDocument document,
                SyntaxNode methodDeclaration,
                CancellationToken cancellationToken)
            {
                MethodKind = MethodKind.Ordinary;
                if (!service.TryInitializeExplicitInterfaceState(
                        document, methodDeclaration, cancellationToken,
                        out var identifierToken, out var methodSymbol, out var typeToGenerateIn))
                {
                    return(false);
                }

                if (methodSymbol.ExplicitInterfaceImplementations.Any())
                {
                    return(false);
                }

                IdentifierToken  = identifierToken;
                TypeToGenerateIn = typeToGenerateIn;

                cancellationToken.ThrowIfCancellationRequested();
                var semanticModel = document.SemanticModel;

                ContainingType = semanticModel.GetEnclosingNamedType(methodDeclaration.SpanStart, cancellationToken);
                if (ContainingType == null)
                {
                    return(false);
                }

                if (!ContainingType.Interfaces.Contains(TypeToGenerateIn))
                {
                    return(false);
                }

                SignatureInfo = new MethodSignatureInfo(document, this, methodSymbol);
                return(true);
            }
            private bool TryInitializeImplicitConversion(TService service, SemanticDocument document, SyntaxNode node, CancellationToken cancellationToken)
            {
                MethodKind = MethodKind.Conversion;
                if (!service.TryInitializeImplicitConversionState(
                        document, node, ClassInterfaceModuleStructTypes, cancellationToken,
                        out var identifierToken, out var methodSymbol, out var typeToGenerateIn))
                {
                    return(false);
                }

                ContainingType = document.SemanticModel.GetEnclosingNamedType(node.SpanStart, cancellationToken);
                if (ContainingType == null)
                {
                    return(false);
                }

                IdentifierToken      = identifierToken;
                TypeToGenerateIn     = typeToGenerateIn;
                SignatureInfo        = new MethodSignatureInfo(document, this, methodSymbol);
                MethodGenerationKind = MethodGenerationKind.ImplicitConversion;
                return(true);
            }
Exemple #3
0
            private bool TryInitializeSimpleName(
                TService service,
                SemanticDocument semanticDocument,
                TSimpleNameSyntax simpleName,
                CancellationToken cancellationToken)
            {
                MethodKind    = MethodKind.Ordinary;
                SimpleNameOpt = simpleName;
                if (!service.TryInitializeSimpleNameState(
                        semanticDocument, simpleName, cancellationToken,
                        out var identifierToken, out var simpleNameOrMemberAccessExpression,
                        out var invocationExpressionOpt, out var isInConditionalExpression))
                {
                    return(false);
                }

                IdentifierToken = identifierToken;
                SimpleNameOrMemberAccessExpression = simpleNameOrMemberAccessExpression;
                InvocationExpressionOpt            = invocationExpressionOpt;
                IsInConditionalAccessExpression    = isInConditionalExpression;

                if (string.IsNullOrWhiteSpace(IdentifierToken.ValueText))
                {
                    return(false);
                }

                // If we're not in a type, don't even bother.  NOTE(cyrusn): We'll have to rethink this
                // for C# Script.
                cancellationToken.ThrowIfCancellationRequested();
                var semanticModel = semanticDocument.SemanticModel;

                ContainingType = semanticModel.GetEnclosingNamedType(SimpleNameOpt.SpanStart, cancellationToken);
                if (ContainingType == null)
                {
                    return(false);
                }

                if (InvocationExpressionOpt != null)
                {
                    SignatureInfo = service.CreateInvocationMethodInfo(semanticDocument, this);
                }
                else
                {
                    var typeInference = semanticDocument.Document.GetLanguageService <ITypeInferenceService>();
                    var delegateType  = typeInference.InferDelegateType(semanticModel, SimpleNameOrMemberAccessExpression, cancellationToken);
                    if (delegateType != null && delegateType.DelegateInvokeMethod != null)
                    {
                        SignatureInfo = new MethodSignatureInfo(semanticDocument, this, delegateType.DelegateInvokeMethod);
                    }
                    else
                    {
                        // We don't have and invocation expression or a delegate, but we may have a special expression without parenthesis.  Lets see
                        // if the type inference service can directly infer the type for our expression.
                        var expressionType = service.DetermineReturnTypeForSimpleNameOrMemberAccessExpression(typeInference, semanticModel, SimpleNameOrMemberAccessExpression, cancellationToken);
                        if (expressionType == null)
                        {
                            return(false);
                        }

                        SignatureInfo = new MethodSignatureInfo(semanticDocument, this, CreateMethodSymbolWithReturnType(expressionType));
                    }
                }

                // Now, try to bind the invocation and see if it succeeds or not.  if it succeeds and
                // binds uniquely, then we don't need to offer this quick fix.
                cancellationToken.ThrowIfCancellationRequested();

                // If the name bound with errors, then this is a candidate for generate method.
                var semanticInfo = semanticModel.GetSymbolInfo(SimpleNameOrMemberAccessExpression, cancellationToken);

                if (semanticInfo.GetAllSymbols().Any(s => s.Kind == SymbolKind.Local || s.Kind == SymbolKind.Parameter) &&
                    !service.AreSpecialOptionsActive(semanticModel))
                {
                    // if the name bound to something in scope then we don't want to generate the
                    // method because it will be shadowed by what's in scope. Unless we are in a
                    // special state such as Option Strict On where we want to generate fixes even
                    // if we shadow types.
                    return(false);
                }

                // Check if the symbol is on the list of valid symbols for this language.
                cancellationToken.ThrowIfCancellationRequested();
                if (semanticInfo.Symbol != null && !service.IsValidSymbol(semanticInfo.Symbol, semanticModel))
                {
                    return(false);
                }

                // Either we found no matches, or this was ambiguous. Either way, we might be able
                // to generate a method here.  Determine where the user wants to generate the method
                // into, and if it's valid then proceed.
                cancellationToken.ThrowIfCancellationRequested();
                if (!TryDetermineTypeToGenerateIn(
                        semanticDocument, ContainingType, SimpleNameOrMemberAccessExpression, cancellationToken,
                        out var typeToGenerateIn, out var isStatic))
                {
                    return(false);
                }

                var semanticFacts = semanticDocument.Document.GetLanguageService <ISemanticFactsService>();

                IsWrittenTo          = semanticFacts.IsWrittenTo(semanticModel, InvocationExpressionOpt ?? SimpleNameOrMemberAccessExpression, cancellationToken);
                TypeToGenerateIn     = typeToGenerateIn;
                IsStatic             = isStatic;
                MethodGenerationKind = MethodGenerationKind.Member;
                return(true);
            }
            private bool TryInitializeSimpleName(
                TService service,
                SemanticDocument semanticDocument,
                TSimpleNameSyntax simpleName,
                CancellationToken cancellationToken)
            {
                MethodKind    = MethodKind.Ordinary;
                SimpleNameOpt = simpleName;
                if (!service.TryInitializeSimpleNameState(
                        semanticDocument, simpleName, cancellationToken,
                        out var identifierToken, out var simpleNameOrMemberAccessExpression,
                        out var invocationExpressionOpt, out var isInConditionalExpression))
                {
                    return(false);
                }

                var syntaxFacts = semanticDocument.Document.GetRequiredLanguageService <ISyntaxFactsService>();

                if (syntaxFacts.IsLeftSideOfAnyAssignment(simpleNameOrMemberAccessExpression))
                {
                    return(false);
                }

                IdentifierToken = identifierToken;
                SimpleNameOrMemberAccessExpression = simpleNameOrMemberAccessExpression;
                InvocationExpressionOpt            = invocationExpressionOpt;
                IsInConditionalAccessExpression    = isInConditionalExpression;

                if (string.IsNullOrWhiteSpace(IdentifierToken.ValueText))
                {
                    return(false);
                }

                // If we're not in a type, don't even bother.  NOTE(cyrusn): We'll have to rethink this
                // for C# Script.
                cancellationToken.ThrowIfCancellationRequested();
                var semanticModel = semanticDocument.SemanticModel;

                ContainingType = semanticModel.GetEnclosingNamedType(SimpleNameOpt.SpanStart, cancellationToken);
                if (ContainingType == null)
                {
                    return(false);
                }

                if (InvocationExpressionOpt != null)
                {
                    SignatureInfo = service.CreateInvocationMethodInfo(semanticDocument, this);
                }
                else
                {
                    var typeInference = semanticDocument.Document.GetLanguageService <ITypeInferenceService>();
                    var delegateType  = typeInference.InferDelegateType(semanticModel, SimpleNameOrMemberAccessExpression, cancellationToken);
                    if (delegateType != null && delegateType.DelegateInvokeMethod != null)
                    {
                        SignatureInfo = new MethodSignatureInfo(semanticDocument, this, delegateType.DelegateInvokeMethod);
                    }
                    else
                    {
                        // We don't have and invocation expression or a delegate, but we may have a special expression without parenthesis.  Lets see
                        // if the type inference service can directly infer the type for our expression.
                        var expressionType = service.DetermineReturnTypeForSimpleNameOrMemberAccessExpression(typeInference, semanticModel, SimpleNameOrMemberAccessExpression, cancellationToken);
                        if (expressionType == null)
                        {
                            return(false);
                        }

                        SignatureInfo = new MethodSignatureInfo(semanticDocument, this, CreateMethodSymbolWithReturnType(expressionType));
                    }
                }

                // Now, try to bind the invocation and see if it succeeds or not.  if it succeeds and
                // binds uniquely, then we don't need to offer this quick fix.
                cancellationToken.ThrowIfCancellationRequested();

                // If the name bound with errors, then this is a candidate for generate method.
                var semanticInfo = semanticModel.GetSymbolInfo(SimpleNameOrMemberAccessExpression, cancellationToken);

                if (semanticInfo.GetAllSymbols().Any(static s => s.Kind is SymbolKind.Local or SymbolKind.Parameter) &&