private static string CreateCompilationErrorMessage([NotNull] EmitResult emitResult, [NotNull] SyntaxTree syntaxTree)
        {
            if (emitResult == null)
            {
                throw new ArgumentNullException(nameof(emitResult));
            }
            if (syntaxTree == null)
            {
                throw new ArgumentNullException(nameof(syntaxTree));
            }
            if (emitResult.Success)
            {
                throw new ArgumentException("EmitResult should contain failed compilation result.", nameof(emitResult));
            }

            var message = new StringBuilder()
                          .AppendLine("Compilation failed:");

            foreach (var diagnostic in emitResult.Diagnostics.Where(item => item.Severity == DiagnosticSeverity.Error))
            {
                message
                .Append(diagnostic.Id)
                .Append(": ")
                .AppendLine(diagnostic.GetMessage(CultureInfo.InvariantCulture));
            }

            var code = Formatter.Format(syntaxTree.GetRoot(), new AdhocWorkspace()).ToString();

            message.AppendLine()
            .AppendLine("Generated code:")
            .AppendLine()
            .AppendLine(code);

            return(message.ToString());
        }
Exemple #2
0
        /// <summary>
        /// Save generated code as a string.
        /// </summary>
        /// <param name="cu">Generated code.</param>
        /// <returns>Generated code as a string.</returns>
        public string SaveCodeAsString(CompilationUnitSyntax cu)
        {
            if (cu == null)
            {
                throw new ArgumentNullException(nameof(cu));
            }

            var workspace     = CreateWorkspace();
            var formattedCode = Formatter.Format(cu, workspace);

            return(formattedCode.ToFullString());
        }
Exemple #3
0
        /// <summary>
        /// Save generated code to a file.
        /// </summary>
        /// <param name="cu">Generated code.</param>
        /// <param name="path">Full output path.</param>
        public void SaveCodeToFile(CompilationUnitSyntax cu, string path)
        {
            if (cu == null)
            {
                throw new ArgumentNullException(nameof(cu));
            }

            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentException("Value cannot be null or empty.", nameof(path));
            }

            var workspace     = CreateWorkspace();
            var formattedCode = Formatter.Format(cu, workspace);

            using (var sourceWriter = new StreamWriter(path))
            {
                formattedCode.WriteTo(sourceWriter);
            }
        }
Exemple #4
0
        protected override async Task <Solution> ProcessAsync(Document document, SyntaxNode syntaxNode, CancellationToken cancellationToken)
        {
            var root = syntaxNode as CompilationUnitSyntax;

            if (root == null)
            {
                return(document.Project.Solution);
            }

            if (!LoadMSTestNamespaces())
            {
                return(document.Project.Solution);
            }

            var originalRoot = root;

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            List <UsingDirectiveSyntax> newUsings = new List <UsingDirectiveSyntax>();
            bool needsChanges = false;

            foreach (var usingSyntax in root.Usings)
            {
                var symbolInfo = semanticModel.GetSymbolInfo(usingSyntax.Name);
                if (symbolInfo.Symbol != null)
                {
                    string namespaceDocID = symbolInfo.Symbol.GetDocumentationCommentId();
                    if (s_mstestNamespaces.Contains(namespaceDocID))
                    {
                        needsChanges = true;
                    }
                    else
                    {
                        newUsings.Add(RemoveLeadingAndTrailingCompilerDirectives(usingSyntax));
                    }
                }
                else
                {
                    newUsings.Add(RemoveLeadingAndTrailingCompilerDirectives(usingSyntax));
                }
            }

            if (!needsChanges)
            {
                return(document.Project.Solution);
            }

            TransformationTracker transformationTracker = new TransformationTracker();

            RemoveTestClassAttributes(root, semanticModel, transformationTracker);
            RemoveContractsRequiredAttributes(root, semanticModel, transformationTracker);
            ChangeTestInitializeAttributesToCtor(root, semanticModel, transformationTracker);
            ChangeTestCleanupAttributesToDispose(root, semanticModel, transformationTracker);
            ChangeTestMethodAttributesToFact(root, semanticModel, transformationTracker);
            ChangeAssertCalls(root, semanticModel, transformationTracker);
            root = transformationTracker.TransformRoot(root);


            //  Remove compiler directives before the first member of the file (e.g. an #endif after the using statements)
            var firstMember = root.Members.FirstOrDefault();

            if (firstMember != null)
            {
                if (firstMember.HasLeadingTrivia)
                {
                    var newLeadingTrivia = RemoveCompilerDirectives(firstMember.GetLeadingTrivia());
                    root = root.ReplaceNode(firstMember, firstMember.WithLeadingTrivia(newLeadingTrivia));
                }
            }

            var xUnitUsing = SyntaxFactory.UsingDirective(SyntaxFactory.ParseName("Xunit")).NormalizeWhitespace();

            newUsings.Add(xUnitUsing);

            //  Apply trailing trivia from original last using statement to new last using statement
            SyntaxTriviaList usingTrailingTrivia = RemoveCompilerDirectives(originalRoot.Usings.Last().GetTrailingTrivia());

            newUsings[newUsings.Count - 1] = newUsings.Last().WithTrailingTrivia(usingTrailingTrivia);

            root     = root.WithUsings(SyntaxFactory.List <UsingDirectiveSyntax>(newUsings));
            document = document.WithSyntaxRoot(root);

            document = await Formatter.FormatAsync(document, cancellationToken : cancellationToken);

            var solution = document.Project.Solution;

            return(solution);
        }