private DocumentTransformationResult TransformDocument(IDocumentAnalyzationResult documentResult) { var rootNode = documentResult.Node; var result = new DocumentTransformationResult(rootNode); var rewrittenNodes = new List <TransformationResult>(); var namespaceNodes = new List <MemberDeclarationSyntax>(); var hasTaskUsing = rootNode.Usings.Any(o => o.Name.ToString() == "System.Threading.Tasks"); foreach (var namespaceResult in documentResult.Namespaces.OrderBy(o => o.Node.SpanStart)) { var namespaceNode = namespaceResult.Node; var typeNodes = new List <MemberDeclarationSyntax>(); foreach (var typeResult in namespaceResult.Types.Where(o => o.Conversion != TypeConversion.Ignore).OrderBy(o => o.Node.SpanStart)) { var transformResult = TransformType(typeResult); if (transformResult.TransformedNode == null) { continue; } typeNodes.Add(transformResult.TransformedNode); // We need to update the original file if it was modified if (transformResult.OriginalModifiedNode != null) { var typeSpanStart = typeResult.Node.SpanStart; var typeSpanLength = typeResult.Node.Span.Length; var typeNode = rootNode.DescendantNodesAndSelf().OfType <TypeDeclarationSyntax>() .First(o => o.SpanStart == typeSpanStart && o.Span.Length == typeSpanLength); var rewritenNode = new TransformationResult(typeNode) { TransformedNode = transformResult.OriginalModifiedNode }; rootNode = rootNode.ReplaceNode(typeNode, typeNode.WithAdditionalAnnotations(new SyntaxAnnotation(rewritenNode.Annotation))); rewrittenNodes.Add(rewritenNode); } // TODO: missing members //if (typeInfo.TypeTransformation == TypeTransformation.NewType && typeInfo.HasMissingMembers) //{ // transformResult = TransformType(typeInfo, true); // if (transformResult.Node == null) // { // continue; // } // typeNodes.Add(transformResult.Node); //} } if (typeNodes.Any()) { var leadingTrivia = namespaceResult.Types.First().Node.GetFirstToken().LeadingTrivia.First(o => o.IsKind(SyntaxKind.WhitespaceTrivia)); //TODO: check if Task is conflicted inside namespace if (!hasTaskUsing && namespaceNode.Usings.All(o => o.Name.ToString() != "System.Threading.Tasks")) { namespaceNode = namespaceNode.AddUsing("System.Threading.Tasks", TriviaList(leadingTrivia)); } // TODO: add locking namespaces namespaceNodes.Add(namespaceNode .WithMembers(List(typeNodes))); } } if (!namespaceNodes.Any()) { return(result); } // Update the original node var origRootNode = rootNode; foreach (var rewrittenNode in rewrittenNodes) { origRootNode = rootNode.ReplaceNode(rootNode.GetAnnotatedNodes(rewrittenNode.Annotation).First(), rewrittenNode.TransformedNode); } if (rootNode != origRootNode) { result.OriginalModifiedNode = origRootNode; } // Create the new node rootNode = rootNode .WithMembers(List(namespaceNodes)); // Add auto-generated comment var token = rootNode.DescendantTokens().First(); rootNode = rootNode.ReplaceToken(token, token.AddAutoGeneratedTrivia()); result.TransformedNode = rootNode; return(result); }
private DocumentTransformationResult TransformDocument(IDocumentAnalyzationResult documentResult) { var rootNode = documentResult.Node; var endOfLineTrivia = rootNode.DescendantTrivia().First(o => o.IsKind(SyntaxKind.EndOfLineTrivia)); var result = new DocumentTransformationResult(documentResult) { EndOfLineTrivia = endOfLineTrivia }; // Annotate so that the annotation exposed is valid rootNode = rootNode.WithAdditionalAnnotations(new SyntaxAnnotation(result.Annotation)); var globalNsTransformResult = new RootNamespaceTransformationResult(documentResult.GlobalNamespace); foreach (var typeResult in documentResult.GlobalNamespace.Types.Where(o => o.Conversion != TypeConversion.Ignore)) { var typeSpanStart = typeResult.Node.SpanStart; var typeSpanLength = typeResult.Node.Span.Length; var typeNode = rootNode.DescendantNodesAndSelf() .OfType <TypeDeclarationSyntax>() .First(o => o.SpanStart == typeSpanStart && o.Span.Length == typeSpanLength); var transformResult = TransformType(typeResult, globalNsTransformResult); result.TransformedTypes.Add(transformResult); rootNode = rootNode.ReplaceNode(typeNode, typeNode.WithAdditionalAnnotations(new SyntaxAnnotation(transformResult.Annotation))); } foreach (var namespaceResult in documentResult.GlobalNamespace.NestedNamespaces.OrderBy(o => o.Node.SpanStart)) { var namespaceSpanStart = namespaceResult.Node.SpanStart; var namespaceSpanLength = namespaceResult.Node.Span.Length; var namespaceNode = rootNode.DescendantNodesAndSelf() .OfType <NamespaceDeclarationSyntax>() .First(o => o.SpanStart == namespaceSpanStart && o.Span.Length == namespaceSpanLength); var transformResult = TransformNamespace(namespaceResult); result.TransformedNamespaces.Add(transformResult); rootNode = rootNode.ReplaceNode(namespaceNode, namespaceNode.WithAdditionalAnnotations(new SyntaxAnnotation(transformResult.Annotation))); } // Save the orignal node that was only annotated var originalAnnotatedNode = rootNode; // TODO: use the same pattern as in namespace and type transformation var transformResults = result.TransformedNamespaces .Cast <ITransformationResult>() .Union(result.TransformedTypes) .ToList(); var newMembers = transformResults .OrderBy(o => o.OriginalStartSpan) .SelectMany(o => o.GetTransformedNodes()) .ToList(); if (!newMembers.Any()) { return(result); // the document will not be created } rootNode = rootNode .WithMembers(List(newMembers)); // Update the original document if required foreach (var rewrittenNode in transformResults.Where(o => o.OriginalModified != null).OrderByDescending(o => o.OriginalStartSpan)) { if (result.OriginalModified == null) { result.OriginalModified = originalAnnotatedNode; } result.OriginalModified = result.OriginalModified .ReplaceNode(result.OriginalModified .GetAnnotatedNodes(rewrittenNode.Annotation).First(), rewrittenNode.OriginalModified); } // Add auto-generated comment rootNode = rootNode.WithLeadingTrivia( SyntaxNodeExtensions.AddAutoGeneratedTrivia(endOfLineTrivia).AddRange(rootNode.GetLeadingTrivia())); result.Transformed = rootNode; return(result); }
public DocumentTransformationResult(IDocumentAnalyzationResult analyzationResult) : base(analyzationResult.Node) { AnalyzationResult = analyzationResult; }