Esempio n. 1
0
        public BindClauseProducer(
            NewBindingInfo newBindingInfo
            )
        {
            if (newBindingInfo is null)
            {
                throw new ArgumentNullException(nameof(newBindingInfo));
            }

            _newBindingInfo = newBindingInfo;
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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
                    );
            }
        }