private static CompilationUnitSyntax ImportNeededNamespace(CompilationUnitSyntax root, SemanticModel semanticModel, MemberAccessExpressionSyntax callerMethod)
 {
     var symbolInfo = semanticModel.GetSymbolInfo(callerMethod.Name);
     var methodSymbol = symbolInfo.Symbol as IMethodSymbol;
     if (methodSymbol == null) return root;
     var namespaceDisplayString = methodSymbol.ContainingNamespace.ToDisplayString();
     var hasNamespaceImported = root
         .DescendantNodes()
         .OfType<UsingDirectiveSyntax>()
         .Select(s => s.Name.ToString())
         .Any(n => n == namespaceDisplayString);
     if (!hasNamespaceImported)
     {
         var namespaceQualifiedName = methodSymbol.ContainingNamespace.ToNameSyntax();
         root = root.AddUsings(SyntaxFactory.UsingDirective(namespaceQualifiedName));
     }
     return root;
 }
        private void ChangeAssertCalls(CompilationUnitSyntax root, SemanticModel semanticModel, TransformationTracker transformationTracker)
        {
            Dictionary<string, string> assertMethodsToRename = new Dictionary<string, string>()
            {
                { "AreEqual", "Equal" },
                { "AreNotEqual", "NotEqual" },
                { "IsNull", "Null" },
                { "IsNotNull", "NotNull" },
                { "AreSame", "Same" },
                { "AreNotSame", "NotSame" },
                { "IsTrue", "True" },
                { "IsFalse", "False" },
                { "IsInstanceOfType", "IsAssignableFrom" },
            };

            Dictionary<SimpleNameSyntax, string> nameReplacementsForNodes = new Dictionary<SimpleNameSyntax, string>();
            List<InvocationExpressionSyntax> methodCallsToReverseArguments = new List<InvocationExpressionSyntax>();

            foreach (var methodCallSyntax in root.DescendantNodes().OfType<MemberAccessExpressionSyntax>())
            {
                var expressionSyntax = methodCallSyntax.Expression;
                var expressionTypeInfo = semanticModel.GetTypeInfo(expressionSyntax);
                if (expressionTypeInfo.Type != null)
                {
                    string expressionDocID = expressionTypeInfo.Type.GetDocumentationCommentId();
                    if (IsTestNamespaceType(expressionDocID, "Assert"))
                    {
                        string newMethodName;
                        if (assertMethodsToRename.TryGetValue(methodCallSyntax.Name.Identifier.Text, out newMethodName))
                        {
                            nameReplacementsForNodes.Add(methodCallSyntax.Name, newMethodName);

                            if (newMethodName == "IsAssignableFrom" && methodCallSyntax.Parent is InvocationExpressionSyntax)
                            {
                                //  Parameter order is reversed between MSTest Assert.IsInstanceOfType and xUnit Assert.IsAssignableFrom
                                methodCallsToReverseArguments.Add((InvocationExpressionSyntax)methodCallSyntax.Parent);
                            }
                        }
                    }
                }
            }

            if (nameReplacementsForNodes.Any())
            {
                transformationTracker.AddTransformation(nameReplacementsForNodes.Keys, (transformationRoot, rewrittenNodes, originalNodeMap) =>
                {
                    return transformationRoot.ReplaceNodes(rewrittenNodes, (originalNode, rewrittenNode) =>
                    {
                        var realOriginalNode = (SimpleNameSyntax)originalNodeMap[originalNode];
                        string newName = nameReplacementsForNodes[realOriginalNode];
                        return SyntaxFactory.ParseName(newName);
                    });
                });

                transformationTracker.AddTransformation(methodCallsToReverseArguments, (transformationRoot, rewrittenNodes, originalNodeMap) =>
                {
                    return transformationRoot.ReplaceNodes(rewrittenNodes, (originalNode, rewrittenNode) =>
                    {
                        var invocationExpression = (InvocationExpressionSyntax)rewrittenNode;
                        var oldArguments = invocationExpression.ArgumentList.Arguments;
                        var newArguments = new SeparatedSyntaxList<ArgumentSyntax>().AddRange(new[] { oldArguments[1], oldArguments[0] });

                        return invocationExpression.WithArgumentList(invocationExpression.ArgumentList.WithArguments(newArguments));
                    });
                });
            }
        }
        private void ChangeTestMethodAttributesToFact(CompilationUnitSyntax root, SemanticModel semanticModel, TransformationTracker transformationTracker)
        {
            List<AttributeSyntax> nodesToReplace = new List<AttributeSyntax>();

            foreach (var attributeSyntax in root.DescendantNodes().OfType<AttributeSyntax>())
            {
                var typeInfo = semanticModel.GetTypeInfo(attributeSyntax);
                if (typeInfo.Type != null)
                {
                    string attributeTypeDocID = typeInfo.Type.GetDocumentationCommentId();
                    if (IsTestNamespaceType(attributeTypeDocID, "TestMethodAttribute"))
                    {
                        nodesToReplace.Add(attributeSyntax);
                    }
                }
            }

            transformationTracker.AddTransformation(nodesToReplace, (transformationRoot, rewrittenNodes, originalNodeMap) =>
            {
                return transformationRoot.ReplaceNodes(rewrittenNodes, (originalNode, rewrittenNode) =>
                {
                    return ((AttributeSyntax)rewrittenNode).WithName(SyntaxFactory.ParseName("Fact")).NormalizeWhitespace();
                });
            });
        }
        private void RemoveTestAttributes(CompilationUnitSyntax root, SemanticModel semanticModel, TransformationTracker transformationTracker, string attributeName)
        {
            List<AttributeSyntax> nodesToRemove = new List<AttributeSyntax>();

            foreach (var attributeListSyntax in root.DescendantNodes().OfType<AttributeListSyntax>())
            {
                var attributesToRemove = attributeListSyntax.Attributes.Where(attributeSyntax =>
                {
                    var typeInfo = semanticModel.GetTypeInfo(attributeSyntax);
                    if (typeInfo.Type != null)
                    {
                        string attributeTypeDocID = typeInfo.Type.GetDocumentationCommentId();
                        if (IsTestNamespaceType(attributeTypeDocID, attributeName))
                        {
                            return true;
                        }
                    }
                    return false;
                }).ToList();

                nodesToRemove.AddRange(attributesToRemove);
            }

            transformationTracker.AddTransformation(nodesToRemove, (transformationRoot, rewrittenNodes, originalNodeMap) =>
            {
                foreach (AttributeSyntax rewrittenNode in rewrittenNodes)
                {
                    var attributeListSyntax = (AttributeListSyntax)rewrittenNode.Parent;
                    var newSyntaxList = attributeListSyntax.Attributes.Remove(rewrittenNode);
                    if (newSyntaxList.Any())
                    {
                        transformationRoot = transformationRoot.ReplaceNode(attributeListSyntax, attributeListSyntax.WithAttributes(newSyntaxList));
                    }
                    else
                    {
                        transformationRoot = transformationRoot.RemoveNode(attributeListSyntax, SyntaxRemoveOptions.KeepLeadingTrivia);
                    }
                }
                return transformationRoot;
            });
        }
 private static bool ShouldAddExternAlias(ImmutableArray<string> aliases, CompilationUnitSyntax root)
 {
     var identifiers = root.DescendantNodes().OfType<ExternAliasDirectiveSyntax>().Select(e => e.Identifier.ToString());
     var externAliases = aliases.Where(a => identifiers.Contains(a));
     return !externAliases.Any();
 }
Ejemplo n.º 6
0
        /// <summary>
        /// Applies merge sort on Span.Start to obtain ordered stream of namespace decls and documentation
        /// syntax nodes.
        /// </summary>
        /// <param name="root">root of the syntax tree</param>
        /// <returns>stream ordered by span.start</returns>
        private static IEnumerable <SyntaxNode> NamespaceDeclsAndDocumentations(CompilationUnitSyntax root)
        {
            using var namespaceDecls =
                      root
                      .DescendantNodes()
                      .OfType <Syntax.NamespaceDeclarationSyntax>()
                      .GetEnumerator();

            using var documentations =
                      root
                      .DescendantNodes(descendIntoTrivia: true)
                      .OfType <Syntax.DocumentationCommentTriviaSyntax>()
                      .GetEnumerator();

            bool doneWithNamespaceDecls = !namespaceDecls.MoveNext();
            bool doneWithDocumentations = !documentations.MoveNext();

            SyntaxNode?prevWhat = null;   // previous yield return

            while (!doneWithNamespaceDecls || !doneWithDocumentations)
            {
                SyntaxNode?what;   // what to yield return

                if (doneWithNamespaceDecls && !doneWithDocumentations)
                {
                    what = documentations.Current;
                    doneWithDocumentations = !documentations.MoveNext();
                }
                else if (!doneWithNamespaceDecls && doneWithDocumentations)
                {
                    what = namespaceDecls.Current;
                    doneWithNamespaceDecls = !namespaceDecls.MoveNext();
                }
                else
                {
                    if (namespaceDecls.Current.SpanStart < documentations.Current.SpanStart)
                    {
                        what = namespaceDecls.Current;
                        doneWithNamespaceDecls = !namespaceDecls.MoveNext();
                    }
                    else
                    {
                        what = documentations.Current;
                        doneWithDocumentations = !documentations.MoveNext();
                    }
                }

                // Loop invariant
                if (what == null)
                {
                    throw new InvalidOperationException("Unexpected null what");
                }

                if (prevWhat != null && what.SpanStart <= prevWhat.SpanStart)
                {
                    throw new InvalidOperationException(
                              $"Unexpected {nameof(what)}.SpanStart (== {what.SpanStart}) " +
                              $"before {nameof(prevWhat)}.SpanStart (== {prevWhat.SpanStart})");
                }
                yield return(what);
            }
        }
Ejemplo n.º 7
0
        static CompilationUnitSyntax RemovePrivateMethods(CompilationUnitSyntax root)
        {
            List<SyntaxNode> removes = new List<SyntaxNode>();

            var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();

            foreach (var @class in classes)
            {
                var methods = @class.Members.OfType<MethodDeclarationSyntax>();
                foreach (var method in methods)
                {
                    SyntaxTokenList modifiers = method.Modifiers;
                    bool result = false;
                    foreach (SyntaxToken m in modifiers)
                    {
                        if (m.Text.Equals("private"))
                        {
                            result = true;
                            removes.Add(method);
                            break;
                        }
                    }
                        
                }
            }

            root = root.RemoveNodes(removes,SyntaxRemoveOptions.KeepDirectives);

            return root;
        }
Ejemplo n.º 8
0
        static CompilationUnitSyntax DumpEvents(CompilationUnitSyntax root)
        {
            Dictionary<SyntaxNode, SyntaxNode> changes = new Dictionary<SyntaxNode, SyntaxNode>();

            var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
            foreach (var @class in classes)
            {
                var events = @class.Members.OfType<EventDeclarationSyntax>();
                foreach (var @event in events)
                {
                    AccessorDeclarationSyntax add, remove;
                    BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();"));
                    AccessorDeclarationSyntax adder = SyntaxFactory.AccessorDeclaration(SyntaxKind.AddAccessorDeclaration,newBody);
                    AccessorDeclarationSyntax remover = SyntaxFactory.AccessorDeclaration(SyntaxKind.RemoveAccessorDeclaration, newBody);
                    SyntaxList<AccessorDeclarationSyntax> syntaxes = new SyntaxList<AccessorDeclarationSyntax>();
                    syntaxes = syntaxes.Add(adder);
                    syntaxes = syntaxes.Add(remover);
                    AccessorListSyntax accessors = SyntaxFactory.AccessorList(syntaxes);
                    
                    EventDeclarationSyntax modifiedEvent = @event.WithAccessorList(accessors);
                    changes.Add(@event, modifiedEvent);
                }

            }

            root = root.ReplaceNodes(changes.Keys, (n1, n2) => changes[n1]);
            return root;
        }
Ejemplo n.º 9
0
        static CompilationUnitSyntax DumpProperties(CompilationUnitSyntax root)
        {
            Dictionary<SyntaxNode, SyntaxNode> changes = new Dictionary<SyntaxNode, SyntaxNode>();

            var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
            foreach (var @class in classes)
            {
                var properties = @class.Members.OfType<PropertyDeclarationSyntax>();
                foreach (var property in properties)
                {
                    AccessorDeclarationSyntax getter, setter;
                    TryGetAccessors(property, out getter, out setter);

                    BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();"));
                    BlockSyntax getterBody = null;
                    BlockSyntax setterBody = null;
                    PropertyDeclarationSyntax modifiedProperty = null;
                    if (getter != null)
                    {
                        getterBody = getter.Body;
                        if (getterBody == null) continue;
                        changes.Add(getterBody, newBody);
                    }

                    if (setter != null)
                    {
                        setterBody = setter.Body;
                        if (setterBody == null) continue;
                        changes.Add(setterBody, newBody);
                    }
                }
                
            }

            root = root.ReplaceNodes(changes.Keys, (n1, n2) => changes[n1]);
            return root;
        }
Ejemplo n.º 10
0
        static CompilationUnitSyntax DumpConstructors(CompilationUnitSyntax root)
        {
            Dictionary<SyntaxNode, SyntaxNode> changes = new Dictionary<SyntaxNode, SyntaxNode>();

            var classes = root.DescendantNodes().OfType<ClassDeclarationSyntax>();
            foreach (var @class in classes)
            {
                var constructors = @class.Members.OfType<ConstructorDeclarationSyntax>();
                var destructors = @class.Members.OfType<DestructorDeclarationSyntax>();
                
                foreach (var c in constructors)
                {
                    BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();"));
                    BlockSyntax body = c.Body;
                    if (body == null) continue;
                    var modifiedMethod = c.ReplaceNode(body, newBody);
                    changes.Add(c, modifiedMethod);
                }

                foreach (var c in destructors)
                {
                    BlockSyntax newBody = SyntaxFactory.Block(SyntaxFactory.ParseStatement("throw new NotImplementedException();"));
                    BlockSyntax body = c.Body;
                    if (body == null) continue;
                    var modifiedMethod = c.ReplaceNode(body, newBody);
                    changes.Add(c, modifiedMethod);
                }
            }

            root = root.ReplaceNodes(changes.Keys, (n1, n2) => changes[n1]);
            return root;
        }