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