protected override Task <ISymbol> GenerateMemberAsync(ISymbol newOverriddenMember, INamedTypeSymbol newContainingType, Document newDocument, CompletionItem completionItem, CancellationToken cancellationToken)
        {
            // Special case: if you are overriding object.ToString(), we will make the return value as non-nullable. The return was made nullable because
            // are implementations out there that will return null, but that's not something we really want new implementations doing. We may need to consider
            // expanding this behavior to other methods in the future; if that is the case then we would want there to be an attribute on the return type
            // rather than updating this list, but for now there is no such attribute until we find more cases for it. See
            // https://github.com/dotnet/roslyn/issues/30317 for some additional conversation about this design decision.
            //
            // We don't check if methodSymbol.ContainingType is object, in case you're overriding something that is itself an override
            if (newOverriddenMember is IMethodSymbol methodSymbol &&
                methodSymbol.Name == "ToString" &&
                methodSymbol.Parameters.Length == 0)
            {
                newOverriddenMember = CodeGenerationSymbolFactory.CreateMethodSymbol(methodSymbol, returnType: methodSymbol.ReturnType.WithNullableAnnotation(NullableAnnotation.NotAnnotated));
            }

            // Figure out what to insert, and do it. Throw if we've somehow managed to get this far and can't.
            var syntaxFactory = newDocument.GetLanguageService <SyntaxGenerator>();

            var itemModifiers = MemberInsertionCompletionItem.GetModifiers(completionItem);
            var modifiers     = itemModifiers.WithIsUnsafe(itemModifiers.IsUnsafe | newOverriddenMember.RequiresUnsafeModifier());

            return(syntaxFactory.OverrideAsync(
                       newOverriddenMember, newContainingType, newDocument, modifiers, cancellationToken));
        }
        private async Task <Document> DetermineNewDocumentAsync(CompletionItem completionItem, SourceText sourceText, CancellationToken cancellationToken)
        {
            // The span we're going to replace
            var line = sourceText.Lines[MemberInsertionCompletionItem.GetLine(completionItem)];
            //var line = textSnapshot.GetLineFromLineNumber(MemberInsertionCompletionItem.GetLine(completionItem));

            //var sourceText = textSnapshot.AsText();
            var document = sourceText.GetOpenDocumentInCurrentContextWithChanges();

            Contract.ThrowIfNull(document);

            // Annotate the line we care about so we can find it after adding usings
            var tree          = document.GetSyntaxTreeAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var token         = GetToken(completionItem, tree, cancellationToken);
            var annotatedRoot = tree.GetRoot(cancellationToken).ReplaceToken(token, token.WithAdditionalAnnotations(_otherAnnotation));

            document = document.WithSyntaxRoot(annotatedRoot);

            var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false);

            var insertionRoot = PrepareTreeForMemberInsertion(memberContainingDocument, cancellationToken);
            var insertionText = GenerateInsertionText(memberContainingDocument, cancellationToken);

            var destinationSpan = ComputeDestinationSpan(insertionRoot, insertionText);

            var finalText = insertionRoot.GetText(sourceText.Encoding).Replace(destinationSpan, insertionText.Trim());

            document = document.WithText(finalText);
            var newRoot     = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End));

            document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation)));
            return(Formatter.FormatAsync(document, _annotation, cancellationToken: cancellationToken).WaitAndGetResult(cancellationToken));
        }
Beispiel #3
0
        protected override async Task <ISymbol> GenerateMemberAsync(ISymbol newOverriddenMember, INamedTypeSymbol newContainingType, Document newDocument, CompletionItem completionItem, CancellationToken cancellationToken)
        {
            // Figure out what to insert, and do it. Throw if we've somehow managed to get this far and can't.
            var syntaxFactory  = newDocument.GetLanguageService <SyntaxGenerator>();
            var codeGenService = newDocument.GetLanguageService <ICodeGenerationService>();

            var itemModifiers = MemberInsertionCompletionItem.GetModifiers(completionItem);
            var modifiers     = itemModifiers.WithIsUnsafe(itemModifiers.IsUnsafe | newOverriddenMember.IsUnsafe());

            if (newOverriddenMember.Kind == SymbolKind.Method)
            {
                return(await syntaxFactory.OverrideMethodAsync((IMethodSymbol)newOverriddenMember,
                                                               modifiers, newContainingType, newDocument, cancellationToken).ConfigureAwait(false));
            }
            else if (newOverriddenMember.Kind == SymbolKind.Property)
            {
                return(await syntaxFactory.OverridePropertyAsync((IPropertySymbol)newOverriddenMember,
                                                                 modifiers, newContainingType, newDocument, cancellationToken).ConfigureAwait(false));
            }
            else
            {
                return(syntaxFactory.OverrideEvent((IEventSymbol)newOverriddenMember,
                                                   modifiers, newContainingType));
            }
        }
        protected override Task <ISymbol> GenerateMemberAsync(ISymbol newOverriddenMember, INamedTypeSymbol newContainingType, Document newDocument, CompletionItem completionItem, CancellationToken cancellationToken)
        {
            // Figure out what to insert, and do it. Throw if we've somehow managed to get this far and can't.
            var syntaxFactory = newDocument.GetLanguageService <SyntaxGenerator>();

            var itemModifiers = MemberInsertionCompletionItem.GetModifiers(completionItem);
            var modifiers     = itemModifiers.WithIsUnsafe(itemModifiers.IsUnsafe | newOverriddenMember.IsUnsafe());

            return(syntaxFactory.OverrideAsync(
                       newOverriddenMember, newContainingType, newDocument, modifiers, cancellationToken));
        }
Beispiel #5
0
        protected override async Task <ISymbol> GenerateMemberAsync(ISymbol member, INamedTypeSymbol containingType, Document document, CompletionItem item, CancellationToken cancellationToken)
        {
            var syntaxFactory = document.GetLanguageService <SyntaxGenerator>();
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            var method = (IMethodSymbol)member;

            return(CodeGenerationSymbolFactory.CreateMethodSymbol(
                       attributes: ImmutableArray <AttributeData> .Empty,
                       accessibility: Accessibility.NotApplicable,
                       modifiers: MemberInsertionCompletionItem.GetModifiers(item),
                       returnType: semanticModel.Compilation.GetSpecialType(SpecialType.System_Void),
                       returnsByRef: method.ReturnsByRef,
                       explicitInterfaceImplementations: default,
        private CompletionItem CreateItem(IMethodSymbol method, int line, TextSpan lineSpan, TextSpan span, SemanticModel semanticModel, DeclarationModifiers modifiers, Document document, SyntaxToken token)
        {
            modifiers = new DeclarationModifiers(method.IsStatic, isUnsafe: method.IsUnsafe(), isPartial: true, isAsync: modifiers.IsAsync);
            var displayText = GetDisplayText(method, semanticModel, span.Start);

            return(MemberInsertionCompletionItem.Create(
                       displayText,
                       modifiers,
                       line,
                       method,
                       token,
                       span.Start,
                       rules: this.GetRules()));
        }
        protected override async Task <ISymbol> GenerateMemberAsync(ISymbol member, INamedTypeSymbol containingType, Document document, CompletionItem item, CancellationToken cancellationToken)
        {
            var syntaxFactory = document.GetLanguageService <SyntaxGenerator>();
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            return(CodeGenerationSymbolFactory.CreateMethodSymbol(attributes: new List <AttributeData>(),
                                                                  accessibility: Accessibility.NotApplicable,
                                                                  modifiers: MemberInsertionCompletionItem.GetModifiers(item),
                                                                  returnType: semanticModel.Compilation.GetSpecialType(SpecialType.System_Void),
                                                                  explicitInterfaceSymbol: null,
                                                                  name: member.Name,
                                                                  typeParameters: ((IMethodSymbol)member).TypeParameters,
                                                                  parameters: member.GetParameters().Select(p => CodeGenerationSymbolFactory.CreateParameterSymbol(p.GetAttributes(), p.RefKind, p.IsParams, p.Type, p.Name)).ToList(),
                                                                  statements: syntaxFactory.CreateThrowNotImplementedStatementBlock(semanticModel.Compilation)));
        }
            private CompletionItem CreateItem(
                ISymbol symbol, ISymbolDisplayService symbolDisplayService,
                SemanticModel semanticModel, SyntaxToken startToken, DeclarationModifiers modifiers)
            {
                var position = startToken.SpanStart;

                var displayString = symbolDisplayService.ToMinimalDisplayString(semanticModel, position, symbol, _overrideNameFormat);

                return(MemberInsertionCompletionItem.Create(
                           displayString,
                           modifiers,
                           _startLineNumber,
                           symbol,
                           startToken,
                           position,
                           rules: _provider.GetRules()));
            }
Beispiel #9
0
        private async Task <Document> DetermineNewDocumentAsync(Document document, CompletionItem completionItem, CancellationToken cancellationToken)
        {
            var text = await document.GetTextAsync(cancellationToken).ConfigureAwait(false);

            // The span we're going to replace
            var line = text.Lines[MemberInsertionCompletionItem.GetLine(completionItem)];

            // Annotate the line we care about so we can find it after adding usings
            var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);

            var token         = GetToken(completionItem, tree, cancellationToken);
            var annotatedRoot = tree.GetRoot(cancellationToken).ReplaceToken(token, token.WithAdditionalAnnotations(_otherAnnotation));

            document = document.WithSyntaxRoot(annotatedRoot);

            var memberContainingDocument = await GenerateMemberAndUsingsAsync(document, completionItem, line, cancellationToken).ConfigureAwait(false);

            if (memberContainingDocument == null)
            {
                // Generating the new document failed because we somehow couldn't resolve
                // the underlying symbol's SymbolKey. At this point, we won't be able to
                // make any changes, so just return the document we started with.
                return(document);
            }

            var insertionRoot = await GetTreeWithAddedSyntaxNodeRemovedAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false);

            var insertionText = await GenerateInsertionTextAsync(memberContainingDocument, cancellationToken).ConfigureAwait(false);

            var destinationSpan = ComputeDestinationSpan(insertionRoot);

            var finalText = insertionRoot.GetText(text.Encoding)
                            .Replace(destinationSpan, insertionText.Trim());

            document = document.WithText(finalText);
            var newRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            var declaration = GetSyntax(newRoot.FindToken(destinationSpan.End));

            document = document.WithSyntaxRoot(newRoot.ReplaceNode(declaration, declaration.WithAdditionalAnnotations(_annotation)));
            return(await Formatter.FormatAsync(document, _annotation, cancellationToken : cancellationToken).ConfigureAwait(false));
        }
        private async Task <Document> GenerateMemberAndUsingsAsync(
            Document document,
            CompletionItem completionItem,
            TextLine line,
            CancellationToken cancellationToken)
        {
            var syntaxFactory  = document.GetLanguageService <SyntaxGenerator>();
            var codeGenService = document.GetLanguageService <ICodeGenerationService>();

            // Resolve member and type in our new, forked, solution
            var semanticModel    = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);
            var containingType   = semanticModel.GetEnclosingSymbol <INamedTypeSymbol>(line.Start, cancellationToken);
            var symbols          = MemberInsertionCompletionItem.GetSymbolsAsync(completionItem, document, cancellationToken).WaitAndGetResult(cancellationToken);
            var overriddenMember = symbols.First();

            // CodeGenerationOptions containing before and after
            var options = new CodeGenerationOptions(contextLocation: semanticModel.SyntaxTree.GetLocation(TextSpan.FromBounds(line.Start, line.Start)));

            var generatedMember = await GenerateMemberAsync(overriddenMember, containingType, document, completionItem, cancellationToken).ConfigureAwait(false);

            generatedMember = _annotation.AddAnnotationToSymbol(generatedMember);

            Document memberContainingDocument = null;

            if (generatedMember.Kind == SymbolKind.Method)
            {
                memberContainingDocument = codeGenService.AddMethodAsync(document.Project.Solution, containingType, (IMethodSymbol)generatedMember, options, cancellationToken).WaitAndGetResult(cancellationToken);
            }
            else if (generatedMember.Kind == SymbolKind.Property)
            {
                memberContainingDocument = codeGenService.AddPropertyAsync(document.Project.Solution, containingType, (IPropertySymbol)generatedMember, options, cancellationToken).WaitAndGetResult(cancellationToken);
            }
            else if (generatedMember.Kind == SymbolKind.Event)
            {
                memberContainingDocument = codeGenService.AddEventAsync(document.Project.Solution, containingType, (IEventSymbol)generatedMember, options, cancellationToken).WaitAndGetResult(cancellationToken);
            }

            return(memberContainingDocument);
        }
Beispiel #11
0
 protected override Task<CompletionDescription> GetDescriptionWorkerAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
     => MemberInsertionCompletionItem.GetDescriptionAsync(item, document, cancellationToken);
 public override Task <CompletionDescription> GetDescriptionAsync(Document document, CompletionItem item, CancellationToken cancellationToken)
 {
     return(MemberInsertionCompletionItem.GetDescriptionAsync(item, document, cancellationToken));
 }