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); }
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) &&