private async Task<Document> DetermineNewDocumentAsync(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);

            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);
        }
Ejemplo n.º 2
0
        private async Task <Document> DetermineNewDocumentAsync(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);

            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));
        }
        protected override ISymbol GenerateMember(ISymbol member, INamedTypeSymbol containingType, Document document, MemberInsertionCompletionItem item, CancellationToken cancellationToken)
        {
            var syntaxFactory = document.GetLanguageService<SyntaxGenerator>();
            var semanticModel = document.GetSemanticModelAsync(cancellationToken).WaitAndGetResult(cancellationToken);

            return CodeGenerationSymbolFactory.CreateMethodSymbol(attributes: new List<AttributeData>(),
                accessibility: Accessibility.NotApplicable,
                modifiers: item.Modifiers,
                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));
        }
Ejemplo n.º 4
0
        private async Task <Document> GenerateMemberAndUsingsAsync(
            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 = 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);
        }
        protected override async Task<ISymbol> GenerateMemberAsync(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 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);
            }
        }
Ejemplo n.º 6
0
 protected abstract Task <ISymbol> GenerateMemberAsync(ISymbol member, INamedTypeSymbol containingType, Document document, MemberInsertionCompletionItem item, CancellationToken cancellationToken);
Ejemplo n.º 7
0
 protected abstract SyntaxToken GetToken(MemberInsertionCompletionItem completionItem, SyntaxTree tree, CancellationToken cancellationToken);
Ejemplo n.º 8
0
        protected override async Task <ISymbol> GenerateMemberAsync(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(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 async Task <ISymbol> GenerateMemberAsync(ISymbol member, INamedTypeSymbol containingType, Document document, MemberInsertionCompletionItem 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: item.Modifiers,
                                                                  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)));
        }
Ejemplo n.º 10
0
 protected override SyntaxToken GetToken(MemberInsertionCompletionItem completionItem, SyntaxTree tree, CancellationToken cancellationToken)
 {
     var token = completionItem.Token;
     return tree.FindTokenOnLeftOfPosition(token.Span.End, cancellationToken);
 }
 protected abstract Task<ISymbol> GenerateMemberAsync(ISymbol member, INamedTypeSymbol containingType, Document document, MemberInsertionCompletionItem item, CancellationToken cancellationToken);
 protected abstract SyntaxToken GetToken(MemberInsertionCompletionItem completionItem, SyntaxTree tree, CancellationToken cancellationToken);
        private async Task<Document> GenerateMemberAndUsingsAsync(
            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 = 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;
        }