public BindClauseProducer( NewBindingInfo newBindingInfo ) { if (newBindingInfo is null) { throw new ArgumentNullException(nameof(newBindingInfo)); } _newBindingInfo = newBindingInfo; }
public async Task <(Document?, SyntaxNode?)> SurgeAsync( Document document, NewBindingInfo newBindingInfo ) { if (document is null) { throw new ArgumentNullException(nameof(document)); } if (newBindingInfo is null) { throw new ArgumentNullException(nameof(newBindingInfo)); } var documentEditor = await DocumentEditor.CreateAsync( document ); #region add new namespaces var existingUsings = documentEditor.OriginalRoot .DescendantNodes() .OfType <UsingDirectiveSyntax>() .ToList() ; var additionalNamespaces = newBindingInfo.GetUniqueUsings(existingUsings).ToList(); if (existingUsings.Count > 0) { documentEditor.InsertAfter(existingUsings.Last(), additionalNamespaces); } else { documentEditor.InsertAfter( documentEditor.OriginalRoot.DescendantNodes().First(), additionalNamespaces ); } #endregion #region add new binding var methodSyntax = documentEditor.OriginalRoot .DescendantNodes() .OfType <MethodDeclarationSyntax>() .FirstOrDefault(m => m.Identifier.Text == _targetMethod.MethodDeclaration.MethodName) ; if (methodSyntax == null) { return(null, null); } if (methodSyntax.Body == null) { return(null, null); } var leadingTrivia = methodSyntax.Body.GetLeadingTrivia().ToString(); var syntaxAnnotation = new SyntaxAnnotation(); var bcp = new BindClauseProducer(newBindingInfo); var producedBinding = bcp.ProduceBinding(leadingTrivia) .WithAdditionalAnnotations(syntaxAnnotation); var modifiedMethodSyntax = methodSyntax.WithBody( methodSyntax.Body.AddStatements(new[] { producedBinding }) ); documentEditor.ReplaceNode( methodSyntax, modifiedMethodSyntax ); #endregion var changedDocument = documentEditor.GetChangedDocument(); var changedRoot = await changedDocument.GetSyntaxRootAsync(); var opts = GeneralOptions.Instance; if (changedRoot != null && opts.EnableWhitespaceNormalization) { var changedSyntaxRoot = changedRoot.NormalizeWhitespace(); changedDocument = changedDocument.WithSyntaxRoot(changedSyntaxRoot); changedRoot = await changedDocument.GetSyntaxRootAsync(); } var addedBinding = changedRoot ?.DescendantNodes() .Where(n => n.HasAnnotation(syntaxAnnotation)) .FirstOrDefault() ?? null; return(changedDocument, addedBinding); }
public async Task DoSurgeryAsync( NewBindingInfo newBindingInfo ) { if (newBindingInfo is null) { throw new ArgumentNullException(nameof(newBindingInfo)); } if (string.IsNullOrEmpty(_targetMethod.MethodDeclaration.Position.FilePath)) { return; } await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); var dte = Package.GetGlobalService(typeof(EnvDTE.DTE)) as DTE2; if (dte == null) { return; } var componentModel = Package.GetGlobalService(typeof(SComponentModel)) as IComponentModel; if (componentModel == null) { return; } var textManager = Package.GetGlobalService(typeof(SVsTextManager)) as IVsTextManager; if (textManager == null) { return; } var workspace = (Workspace)componentModel.GetService <VisualStudioWorkspace>(); if (workspace == null) { return; } ErrorHandler.ThrowOnFailure(textManager.GetActiveView(1, null, out var currentActiveView)); var currentDocumentFilePath = System.IO.Path.Combine(dte.ActiveDocument.Path, dte.ActiveDocument.Name); currentActiveView.GetCaretPos(out var currentLine, out var currentColumn); #region open modified document var modifiedDocumentHelper = new VisualStudioDocumentHelper( _targetMethod.MethodDeclaration.Position.FilePath ); modifiedDocumentHelper.OpenAndNavigate( _targetMethod.MethodDeclaration.Position.StartLine, _targetMethod.MethodDeclaration.Position.StartColumn, _targetMethod.MethodDeclaration.Position.EndLine, _targetMethod.MethodDeclaration.Position.EndColumn ); #endregion #region switch back to source document if needed if (newBindingInfo.IsBindingComplete) { var sourceDocumentHelper = new VisualStudioDocumentHelper( currentDocumentFilePath ); sourceDocumentHelper.OpenAndNavigate( currentLine, currentColumn, currentLine, currentColumn ); } #endregion var document = workspace.GetDocument( _targetMethod.MethodDeclaration.Position.FilePath ); if (document == null) { return; } var surgeon = new SyntaxSurgeon( _targetMethod ); var(surgedDocument, addedBinding) = await surgeon.SurgeAsync( document, newBindingInfo ); if (surgedDocument == null) { return; } if (!workspace.TryApplyChanges(surgedDocument.Project.Solution)) { DpdtPackage.ShowMessageBox( "Error", "Error happened while additing a new binding clause. Please try again." ); return; } if (!newBindingInfo.IsBindingComplete && addedBinding != null) { var addedBindingLineSpan = addedBinding.GetLocation().GetLineSpan(); modifiedDocumentHelper.OpenAndNavigate( addedBindingLineSpan.StartLinePosition.Line, addedBindingLineSpan.StartLinePosition.Character, addedBindingLineSpan.EndLinePosition.Line, addedBindingLineSpan.EndLinePosition.Character ); } }