Exemple #1
0
        protected override SyntaxToken GetToken(
            CompletionItem completionItem,
            SyntaxTree tree,
            CancellationToken cancellationToken
            )
        {
            var tokenSpanEnd = MemberInsertionCompletionItem.GetTokenSpanEnd(completionItem);

            return(tree.FindTokenOnLeftOfPosition(tokenSpanEnd, cancellationToken));
        }
        protected override ISymbol GenerateMember(ISymbol newOverriddenMember, INamedTypeSymbol newContainingType, Document newDocument, MemberInsertionCompletionItem 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 modifiers = completionItem.Modifiers.WithIsUnsafe(completionItem.Modifiers.IsUnsafe | newOverriddenMember.IsUnsafe());
            if (newOverriddenMember.Kind == SymbolKind.Method)
            {
                return syntaxFactory.OverrideMethod((IMethodSymbol)newOverriddenMember,
                    modifiers, newContainingType, newDocument, cancellationToken);
            }
            else if (newOverriddenMember.Kind == SymbolKind.Property)
            {
                return syntaxFactory.OverrideProperty((IPropertySymbol)newOverriddenMember,
                    modifiers, newContainingType, newDocument, cancellationToken);
            }
            else
            {
                return syntaxFactory.OverrideEvent((IEventSymbol)newOverriddenMember,
                    modifiers, newContainingType);
            }
        }
 protected override SyntaxToken GetToken(MemberInsertionCompletionItem completionItem, SyntaxTree tree, CancellationToken cancellationToken)
 {
     var token = completionItem.Token;
     return tree.FindTokenOnLeftOfPosition(token.Span.End, cancellationToken);
 }
 protected abstract ISymbol GenerateMember(ISymbol member, INamedTypeSymbol containingType, Document document, MemberInsertionCompletionItem item, CancellationToken cancellationToken);
 protected abstract SyntaxToken GetToken(MemberInsertionCompletionItem completionItem, SyntaxTree tree, CancellationToken cancellationToken);
        private Document GenerateMemberAndUsings(
            Document document,
            MemberInsertionCompletionItem completionItem,
            ITextSnapshotLine 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 resolution = completionItem.SymbolId.Resolve(semanticModel.Compilation, cancellationToken: cancellationToken);
            var overriddenMember = GetResolvedSymbol(resolution, line.Extent.Span.ToTextSpan());

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

            var generatedMember = GenerateMember(overriddenMember, containingType, document, completionItem, cancellationToken);
            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;
        }
        private Document DetermineNewDocument(MemberInsertionCompletionItem completionItem, ITextSnapshot textSnapshot, CancellationToken cancellationToken)
        {
            // The span we're going to replace
            var line = textSnapshot.GetLineFromLineNumber(completionItem.Line);

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

            Document memberContainingDocument = GenerateMemberAndUsings(document, completionItem, line, cancellationToken);

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