public async Task ApplyRefactoring(Solution solution) { try { ReadUserInput(); documentsRegistry = await InitializeDocumentRegistry(solution); invokedMethodDocument = await GetInvokationMethodType(solution); documentsToCopy.Add(invokedMethodDocument); await RecursiveMethod(invokedMethodDocument); var invokedMethodProjectName = invokedMethodDocument.DocumentTypeFullName.Split('.').FirstOrDefault(); startup = documentsRegistry.FirstOrDefault(x => x.DocumentTypeFullName.Contains(invokedMethodProjectName + ".Startup")); CreateMicroserviceDirectory(); BeginWriting(); } catch (Exception) { Console.WriteLine("There was an error applying the refactoring."); Environment.Exit(0); } }
private async Task RecursiveMethod(DocumentAnalyzerAggregate document) { var treeRoot = await document.SyntaxTree.GetRootAsync(); // We're assuming only one class per file. var isClass = treeRoot.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault() != null; var isInterface = treeRoot.DescendantNodes().OfType <InterfaceDeclarationSyntax>().FirstOrDefault() != null; if (isClass) { await FindTypeDependenciesForType(document); } else if (isInterface) { var interfaceImplementations = await GetInterfaceImplementations(document); foreach (var interfaceImplementation in interfaceImplementations) { if (!documentsToCopy.Contains(interfaceImplementation)) { documentsToCopy.Add(interfaceImplementation); await FindTypeDependenciesForType(interfaceImplementation); } } } }
private async Task FindTypeDependenciesForType(DocumentAnalyzerAggregate document) { var root = await document.SyntaxTree.GetRootAsync(); var classDeclaration = root.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault(); foreach (var item in classDeclaration.DescendantNodes()) { string typeName = null; if (classDeclaration != null) { switch (item) { case SimpleBaseTypeSyntax simpleBaseTypeSyntax: typeName = simpleBaseTypeSyntax.Type.ToString(); break; case ParameterSyntax parameterSyntax: typeName = parameterSyntax.Type.ToString(); break; case IdentifierNameSyntax identifierNameSyntax: typeName = identifierNameSyntax.ToString(); break; case SimpleNameSyntax simpleNameSyntax: typeName = simpleNameSyntax.ToString(); break; case TypeSyntax typeSyntax: typeName = typeSyntax.ToString(); break; } if (typeName != null) { var documentToCopy = documentsRegistry.FirstOrDefault(x => x.DocumentTypeFullName.Contains(typeName)); if (documentToCopy != null && !documentsToCopy.Contains(documentToCopy)) { documentsToCopy.Add(documentToCopy); await RecursiveMethod(documentToCopy); } } } } }
private async Task <HashSet <DocumentAnalyzerAggregate> > GetInterfaceImplementations(DocumentAnalyzerAggregate interfaceDocument) { var implementations = new HashSet <DocumentAnalyzerAggregate>(); foreach (var document in documentsRegistry) { var root = await document.SyntaxTree.GetRootAsync(); // We only care about classes implementing interfaces and not interfaces implementing interfaces. var classDeclaration = root.DescendantNodes().OfType <ClassDeclarationSyntax>().FirstOrDefault(); if (classDeclaration != null) { var name = interfaceDocument.Document.Name.Split('.')[0]; var documentLines = classDeclaration.ToString().Split('\n'); var classDeclarationLine = documentLines.FirstOrDefault(x => x.Contains(name)); if (classDeclarationLine != null) { var classExtensions = classDeclarationLine.Split(':'); if (classExtensions.Length > 1) { var classExtensionsList = classExtensions[1].Split(','); if (classExtensionsList.FirstOrDefault(x => x.Contains(name)) != null) { implementations.Add(document); } } } } } return(implementations); }