public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) { var document = context.Document; var textSpan = context.Span; var cancellationToken = context.CancellationToken; var syntaxFacts = document.GetLanguageService <ISyntaxFactsService>(); var sourceText = await document.GetTextAsync(cancellationToken).ConfigureAwait(false); var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); // We offer the refactoring when the user is either on the header of a class/struct, // or if they're between any members of a class/struct and are on a blank line. if (!syntaxFacts.IsOnTypeHeader(root, textSpan.Start) && !syntaxFacts.IsBetweenTypeMembers(sourceText, root, textSpan.Start)) { return; } var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); // Only supported on classes/structs. var containingType = AbstractGenerateFromMembersCodeRefactoringProvider.GetEnclosingNamedType( semanticModel, root, textSpan.Start, cancellationToken); var overridableMembers = containingType.GetOverridableMembers(cancellationToken); if (overridableMembers.Length == 0) { return; } context.RegisterRefactoring(new GenerateOverridesWithDialogCodeAction( this, document, textSpan, containingType, overridableMembers)); }
protected override bool TryInitializeState( SemanticDocument document, TextSpan textSpan, CancellationToken cancellationToken, out INamedTypeSymbol classType) { cancellationToken.ThrowIfCancellationRequested(); // Offer the feature if we're on the header for the class/struct, or if we're on the // first base-type of a class. var syntaxFacts = document.Document.GetLanguageService <ISyntaxFactsService>(); if (syntaxFacts.IsOnTypeHeader(document.Root, textSpan.Start)) { classType = AbstractGenerateFromMembersCodeRefactoringProvider.GetEnclosingNamedType( document.SemanticModel, document.Root, textSpan.Start, cancellationToken); return(classType?.TypeKind == TypeKind.Class); } var syntaxTree = document.SyntaxTree; var node = document.Root.FindToken(textSpan.Start).GetAncestor <TypeSyntax>(); if (node != null) { if (node.Parent is BaseTypeSyntax && node.Parent.IsParentKind(SyntaxKind.BaseList)) { var baseList = (BaseListSyntax)node.Parent.Parent; if (baseList.Types.Count > 0 && baseList.Types[0].Type == node && baseList.IsParentKind(SyntaxKind.ClassDeclaration)) { var semanticModel = document.SemanticModel; classType = semanticModel.GetDeclaredSymbol(baseList.Parent, cancellationToken) as INamedTypeSymbol; return(classType != null); } } } classType = null; return(false); }