private bool TryInitializeIdentifierName( TService service, SemanticDocument semanticDocument, TSimpleNameSyntax identifierName, CancellationToken cancellationToken) { this.SimpleName = identifierName; if (!service.TryInitializeIdentifierNameState(semanticDocument, identifierName, cancellationToken, out var identifierToken, out var simpleNameOrMemberAccessExpression)) { return(false); } this.IdentifierToken = identifierToken; this.SimpleNameOrMemberAccessExpression = simpleNameOrMemberAccessExpression; var semanticModel = semanticDocument.SemanticModel; var semanticFacts = semanticDocument.Document.GetLanguageService <ISemanticFactsService>(); var syntaxFacts = semanticDocument.Document.GetLanguageService <ISyntaxFactsService>(); if (semanticFacts.IsWrittenTo(semanticModel, this.SimpleNameOrMemberAccessExpression, cancellationToken) || syntaxFacts.IsInNamespaceOrTypeContext(this.SimpleNameOrMemberAccessExpression)) { return(false); } // 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(); var containingType = semanticModel.GetEnclosingNamedType(identifierToken.SpanStart, cancellationToken); if (containingType == null) { return(false); } var semanticInfo = semanticModel.GetSymbolInfo(this.SimpleNameOrMemberAccessExpression, cancellationToken); if (cancellationToken.IsCancellationRequested) { return(false); } if (semanticInfo.Symbol != null) { 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. if (!service.TryDetermineTypeToGenerateIn( semanticDocument, containingType, simpleNameOrMemberAccessExpression, cancellationToken, out var typeToGenerateIn, out var isStatic)) { return(false); } if (!isStatic) { return(false); } this.TypeToGenerateIn = typeToGenerateIn; return(true); }
private bool TryInitializeSimpleName( TService service, SemanticDocument document, TSimpleNameSyntax simpleName, CancellationToken cancellationToken) { if (!service.TryInitializeIdentifierNameState( document, simpleName, cancellationToken, out var identifierToken, out var simpleNameOrMemberAccessExpression, out var isInExecutableBlock, out var isInConditionalAccessExpression)) { return(false); } if (string.IsNullOrWhiteSpace(identifierToken.ValueText)) { return(false); } this.SimpleNameOpt = simpleName; this.IdentifierToken = identifierToken; this.SimpleNameOrMemberAccessExpressionOpt = simpleNameOrMemberAccessExpression; this.IsInExecutableBlock = isInExecutableBlock; this.IsInConditionalAccessExpression = isInConditionalAccessExpression; // If we're in a type context then we shouldn't offer to generate a field or // property. var syntaxFacts = document.Project.LanguageServices.GetService <ISyntaxFactsService>(); if (syntaxFacts.IsInNamespaceOrTypeContext(this.SimpleNameOrMemberAccessExpressionOpt)) { return(false); } this.IsConstant = syntaxFacts.IsInConstantContext(this.SimpleNameOrMemberAccessExpressionOpt); // 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 = document.SemanticModel; this.ContainingType = semanticModel.GetEnclosingNamedType(this.IdentifierToken.SpanStart, cancellationToken); if (this.ContainingType == null) { return(false); } // 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(); var semanticInfo = semanticModel.GetSymbolInfo(this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); if (semanticInfo.Symbol != null) { 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 (!service.TryDetermineTypeToGenerateIn(document, this.ContainingType, this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken, out var typeToGenerateIn, out var isStatic)) { return(false); } this.TypeToGenerateIn = typeToGenerateIn; this.IsStatic = isStatic; DetermineFieldType(document, cancellationToken); var semanticFacts = document.Project.LanguageServices.GetService <ISemanticFactsService>(); this.IsInRefContext = semanticFacts.IsInRefContext(semanticModel, this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken); this.IsInInContext = semanticFacts.IsInInContext(semanticModel, this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken); this.IsInOutContext = semanticFacts.IsInOutContext(semanticModel, this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken); this.IsWrittenTo = semanticFacts.IsWrittenTo(semanticModel, this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken); this.IsOnlyWrittenTo = semanticFacts.IsOnlyWrittenTo(semanticModel, this.SimpleNameOrMemberAccessExpressionOpt, cancellationToken); this.IsInConstructor = DetermineIsInConstructor(document); this.IsInMemberContext = this.SimpleNameOpt != this.SimpleNameOrMemberAccessExpressionOpt || syntaxFacts.IsObjectInitializerNamedAssignmentIdentifier(this.SimpleNameOrMemberAccessExpressionOpt); CheckSurroundingContext(document, SymbolKind.Field, cancellationToken); CheckSurroundingContext(document, SymbolKind.Property, cancellationToken); return(true); }