/// <summary> /// Implements a workaround for issue #936, force re-parsing to get the same sort of syntax tree as the original document. /// </summary> /// <param name="project">The project to update.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <returns>The updated <see cref="Project"/>.</returns> private async Task <Project> RecreateProjectDocumentsAsync(Project project, CancellationToken cancellationToken) { foreach (var documentId in project.DocumentIds) { var document = project.GetDocument(documentId); var initialTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); document = await RecreateDocumentAsync(document, cancellationToken).ConfigureAwait(false); var recreatedTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (CodeFixValidationMode != CodeFixValidationMode.None) { // We expect the tree produced by the code fix (initialTree) to match the form of the tree produced // by the compiler for the same text (recreatedTree). TreeEqualityVisitor.AssertNodesEqual( await recreatedTree.GetRootAsync(cancellationToken).ConfigureAwait(false), await initialTree.GetRootAsync(cancellationToken).ConfigureAwait(false), checkTrivia: CodeFixValidationMode == CodeFixValidationMode.Full); } project = document.Project; } return(project); }
/// <summary> /// Implements a workaround for issue #936, force re-parsing to get the same sort of syntax tree as the original document. /// </summary> /// <param name="project">The project to update.</param> /// <param name="verifier">The verifier to use for test assertions.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param> /// <returns>The updated <see cref="Project"/>.</returns> private async Task <Project> RecreateProjectDocumentsAsync(Project project, IVerifier verifier, CancellationToken cancellationToken) { foreach (var documentId in project.DocumentIds) { var document = project.GetDocument(documentId); var initialTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); document = await RecreateDocumentAsync(document, cancellationToken).ConfigureAwait(false); var recreatedTree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); if (CodeFixValidationMode != CodeFixValidationMode.None) { try { // We expect the tree produced by the code fix (initialTree) to match the form of the tree produced // by the compiler for the same text (recreatedTree). TreeEqualityVisitor.AssertNodesEqual( verifier, SyntaxKindType, await recreatedTree.GetRootAsync(cancellationToken).ConfigureAwait(false), await initialTree.GetRootAsync(cancellationToken).ConfigureAwait(false), checkTrivia: CodeFixValidationMode == CodeFixValidationMode.Full); } catch { // Try to revalidate the tree with a better message var renderedInitialTree = TreeToString(await initialTree.GetRootAsync(cancellationToken).ConfigureAwait(false), CodeFixValidationMode); var renderedRecreatedTree = TreeToString(await recreatedTree.GetRootAsync(cancellationToken).ConfigureAwait(false), CodeFixValidationMode); verifier.EqualOrDiff(renderedRecreatedTree, renderedInitialTree); // This is not expected to be hit, but it will be hit if the validation failure occurred in a // portion of the tree not captured by the rendered form from TreeToString. throw; } } project = document.Project; } return(project); }