public void UpdatePresentationControllerConstructor()
        {
            ConstructorDeclarationSyntax constructor = TestHelpers.GetConstructors(ast).FirstOrDefault();
            // if we false negative on whitespace it'll be here, but I think that'll be a rare enough issue to not hurt performance running multiple passes or regex
            var methodArguments = constructor.ParameterList.Parameters.FirstOrDefault(p => p.Type.ToString().Contains("ILogger<PresentationsController>"));

            Assert.True(methodArguments != null, "`PresentationsController`'s constructor should accept a third parameter of type `ILogger<PresentationsController>` with the name `logger`.");
            var setLogger = constructor.DescendantNodes().OfType <AssignmentExpressionSyntax>().FirstOrDefault(a => a.ToString().Contains("_logger"));

            Assert.True(setLogger != null, "`PresentationsController`'s constructor should set `_logger` to the provided `logger` parameter.");
        }
예제 #2
0
        public static IEnumerable <ClassMethodInfo> GetCallingMethods(ConstructorDeclarationSyntax constructorBlock, SemanticModel model,
                                                                      string thisNameSpace, string thisClassName)
        {
            var calling = from node in constructorBlock.DescendantNodes()
                          where node is InvocationExpressionSyntax ||
                          node is ObjectCreationExpressionSyntax ||
                          node is IdentifierNameSyntax
                          select node;

            return(GetCallingMethods(calling, model, thisNameSpace, thisClassName));
        }
예제 #3
0
        static (ConstructorSyntaxLink, bool IsCompleted) _StartingFromRec(ConstructorDeclarationSyntax ctorDeclarationSyntax, ClassDeclarationSyntax owingType, SemanticModel semanticModel)
        {
            var syntaxTree = ctorDeclarationSyntax.SyntaxTree;

            var nextCtorPath = (ConstructorInitializerSyntax)ctorDeclarationSyntax
                               .DescendantNodes()
                               .Where(x => x.Kind() == SyntaxKind.BaseConstructorInitializer || x.Kind() == SyntaxKind.ThisConstructorInitializer)
                               .SingleOrDefault();

            if (nextCtorPath == null)
            {
                return(_CreateFinalLink(owingType, ctorDeclarationSyntax), IsCompleted : true);
            }


            switch (nextCtorPath.Kind())
            {
            case SyntaxKind.ThisConstructorInitializer:
            {
                var nextCtor = _GetConstructor(owingType, nextCtorPath, semanticModel);

                if (!nextCtor.Exists)
                {
                    var incompleteLink = _CreateIncompleteIntermediateLink(owingClass: owingType, thisCtorDeclarationSyntax: ctorDeclarationSyntax, pathToNextCtor: nextCtorPath);
                    return(incompleteLink, IsCompleted : false);
                }

                var(nextLink, isComplete) = _StartingFromRec(nextCtor.Value, owingType, semanticModel: semanticModel);
                var link = _CreateIntermediateLink(nextLink, owingClass: owingType, thisCtorDeclarationSyntax: ctorDeclarationSyntax, pathToNextCtor: nextCtorPath);
                return(link, isComplete);
            }

            case SyntaxKind.BaseConstructorInitializer:
            {
                var baseTypeSyntax = SyntaxOperations.GetBaseTypeOf(owingType, syntaxTree, semanticModel).Value;
                var nextCtor       = _GetConstructor(baseTypeSyntax, nextCtorPath, semanticModel);

                if (!nextCtor.Exists)
                {
                    var incompleteLink = _CreateIncompleteIntermediateLink(owingClass: owingType, thisCtorDeclarationSyntax: ctorDeclarationSyntax, pathToNextCtor: nextCtorPath);
                    return(incompleteLink, IsCompleted : false);
                }

                var(nextLink, isCompleted) = _StartingFromRec(nextCtor.Value, owingType: baseTypeSyntax, semanticModel: semanticModel);
                var link = _CreateIntermediateLink(nextLink, owingClass: owingType, thisCtorDeclarationSyntax: ctorDeclarationSyntax, pathToNextCtor: nextCtorPath);
                return(link, isCompleted);
            }


            default:
                throw NotPreparedForThatCase.CannotHappenException;
            }
        }
예제 #4
0
        /// <summary>
        /// IsInitializeComponentInConstructor
        /// </summary>
        /// <param name="context"></param>
        /// <param name="constructor"></param>
        /// <returns></returns>
        private int IsInitializeComponentInConstructor(SyntaxNodeAnalysisContext context, ConstructorDeclarationSyntax constructor)
        {
            int count = 0;

            foreach (InvocationExpressionSyntax invocation in constructor.DescendantNodes().OfType <InvocationExpressionSyntax>())
            {
                IdentifierNameSyntax name = invocation.Expression as IdentifierNameSyntax;
                if (name == null)
                {
                    continue;
                }
                if (string.Equals(@"InitializeComponent", name.Identifier.ValueText))
                {
                    count++;
                }
            }
            return(count);
        }
        private static bool CheckIfAlreadyInitialized(SemanticModel model, ParameterSyntax parameter,
                                                      ConstructorDeclarationSyntax constructor, CancellationToken cancellationToken)
        {
            var parameterName = parameter.Identifier.ValueText;
            var assignments   = (constructor.DescendantNodes().OfType <AssignmentExpressionSyntax>()
                                 .Where(exp => exp.Right.DescendantTokens().Any(token => token.ValueText == parameterName))).ToList();

            if (!assignments.Any())
            {
                return(false);
            }

            var currentType = model.GetDeclaredSymbol(constructor.Parent, cancellationToken) as INamedTypeSymbol;

            return(assignments.Any(assignment =>
            {
                var targetType = model.GetSymbolInfo(assignment.Left, cancellationToken).Symbol?.ContainingType;
                return currentType == targetType;
            }));
        }
예제 #6
0
        private static ParameterSyntax FindExistingParameter(SemanticModel model, IFieldSymbol fieldSymbol,
                                                             ConstructorDeclarationSyntax constructor, CancellationToken cancellationToken)
        {
            foreach (var parameter in constructor.ParameterList.Parameters)
            {
                var parameterSymbol = model.GetDeclaredSymbol(parameter, cancellationToken) as IParameterSymbol;
                if (fieldSymbol != null && parameterSymbol != null && fieldSymbol.Type == parameterSymbol.Type)
                {
                    var assignments = constructor.DescendantNodes().OfType <AssignmentExpressionSyntax>().ToList();
                    foreach (var assignment in assignments)
                    {
                        var rightSymbol = model.GetSymbolInfo(assignment.Right, cancellationToken).Symbol;
                        if (rightSymbol != null && rightSymbol == parameterSymbol)
                        {
                            return(null);
                        }
                    }

                    return(parameter);
                }
            }

            return(null);
        }
예제 #7
0
        /// <summary>
        /// Get summary.
        /// </summary>
        /// <param name="theSyntaxNode">The syntax node to add the summary.</param>
        /// <returns>The syntax list.</returns>
        private static DocumentationCommentTriviaSyntax GetSummary(ConstructorDeclarationSyntax theSyntaxNode)
        {
            string summaryComment;

            if (theSyntaxNode.Modifiers.Any(SyntaxKind.StaticKeyword))
            {
                summaryComment = $" Initializes static members of the <see cref=\"{theSyntaxNode.Identifier.ValueText}\"/> class.";
            }
            else
            {
                summaryComment = $" Initializes a new instance of the <see cref=\"{theSyntaxNode.Identifier.ValueText}\"/> class.";
            }

            var summaryStart = XmlElementStartTag(XmlName(Identifier(Constants.Summary)))
                               .WithLessThanToken(Token(SyntaxKind.LessThanToken))
                               .WithGreaterThanToken(Token(SyntaxKind.GreaterThanToken)).NormalizeWhitespace();

            var summaryEnd = XmlElementEndTag(XmlName(Identifier(Constants.Summary))).NormalizeWhitespace()
                             .WithLessThanSlashToken(Token(SyntaxKind.LessThanSlashToken))
                             .WithGreaterThanToken(Token(SyntaxKind.GreaterThanToken));

            var summaryText = SingletonList <XmlNodeSyntax>(
                XmlText().NormalizeWhitespace()
                .WithTextTokens(
                    TokenList(
                        XmlTextNewLine(TriviaList(), Environment.NewLine, Environment.NewLine, TriviaList()).NormalizeWhitespace(),
                        XmlTextLiteral(
                            TriviaList(DocumentationCommentExterior("///")),
                            summaryComment,
                            summaryComment,
                            TriviaList()).NormalizeWhitespace(),
                        XmlTextNewLine(TriviaList(), Environment.NewLine, Environment.NewLine, TriviaList()).NormalizeWhitespace(),
                        XmlTextLiteral(
                            TriviaList(DocumentationCommentExterior("///")),
                            " ",
                            " ",
                            TriviaList()))).NormalizeWhitespace());

            var xmlComment = XmlText()
                             .WithTextTokens(
                TokenList(
                    XmlTextLiteral(
                        TriviaList(DocumentationCommentExterior("///")),
                        " ",
                        " ",
                        TriviaList()))).NormalizeWhitespace();

            var newLine = XmlText().WithTextTokens(TokenList(XmlTextNewLine(TriviaList(), Environment.NewLine, Environment.NewLine, TriviaList()))).NormalizeWhitespace();

            var summaryElement = XmlElement(summaryStart, summaryEnd).WithContent(summaryText);

            var list = List(new XmlNodeSyntax[] { xmlComment, summaryElement, newLine });

            // Add parameter comments
            if (theSyntaxNode.ParameterList.Parameters.Any())
            {
                foreach (var parameter in theSyntaxNode.ParameterList.Parameters)
                {
                    list = list.AddRange(
                        List(
                            new XmlNodeSyntax[]
                    {
                        xmlComment,

                        XmlElement(
                            XmlElementStartTag(XmlName(Identifier("param")))
                            .WithAttributes(
                                SingletonList <XmlAttributeSyntax>(
                                    XmlNameAttribute(
                                        XmlName(Identifier(TriviaList(Space), "name", TriviaList())),
                                        Token(SyntaxKind.DoubleQuoteToken),
                                        IdentifierName(parameter.Identifier.ValueText),
                                        Token(SyntaxKind.DoubleQuoteToken)))),
                            XmlElementEndTag(XmlName(Identifier("param"))))
                        .WithContent(
                            SingletonList <XmlNodeSyntax>(
                                XmlText()
                                .WithTextTokens(
                                    TokenList(
                                        XmlTextLiteral(
                                            TriviaList(),
                                            Convert.Parameter(parameter.Identifier.ValueText, parameter.Type.ToString()),
                                            "comment",
                                            TriviaList()))))),

                        newLine
                    }));
                }
            }

            // Add exceptions comments
            var throws = theSyntaxNode.DescendantNodes().OfType <ThrowStatementSyntax>();

            foreach (var syntax in throws)
            {
                if (syntax.ChildNodes().OfType <ObjectCreationExpressionSyntax>().Any())
                {
                    var identifier   = syntax.DescendantNodes().OfType <IdentifierNameSyntax>().FirstOrDefault();
                    var argumentList = syntax.DescendantNodes().OfType <ArgumentListSyntax>().FirstOrDefault();
                    var parms        = argumentList.DescendantTokens().Where(x => x.IsKind(SyntaxKind.StringLiteralToken)).ToList();
                    var parmText     = string.Empty;

                    if (parms.Any())
                    {
                        parmText = parms.Last().ValueText;
                    }

                    list = list.AddRange(
                        List(
                            new XmlNodeSyntax[]
                    {
                        xmlComment,

                        XmlElement(
                            XmlElementStartTag(XmlName(Identifier("exception")))
                            .WithAttributes(
                                SingletonList <XmlAttributeSyntax>(
                                    XmlNameAttribute(
                                        XmlName(Identifier(TriviaList(Space), "cref", TriviaList())),
                                        Token(SyntaxKind.DoubleQuoteToken),
                                        IdentifierName(identifier.Identifier.ValueText),
                                        Token(SyntaxKind.DoubleQuoteToken)))),
                            XmlElementEndTag(XmlName(Identifier("exception"))))
                        .WithContent(
                            SingletonList <XmlNodeSyntax>(
                                XmlText()
                                .WithTextTokens(
                                    TokenList(
                                        XmlTextLiteral(
                                            TriviaList(),
                                            parmText,
                                            "comment",
                                            TriviaList()))))),

                        newLine
                    }));
                }
            }

            return(DocumentationCommentTrivia(SyntaxKind.SingleLineDocumentationCommentTrivia, list));
        }
예제 #8
0
 private static void _Assert_IsIntermadiateLink(ConstructorSyntaxLink link, ClassDeclarationSyntax classDeclarationSyntax, ConstructorDeclarationSyntax ctorDeclarationSyntax)
 {
     Assert.AreEqual(link.CtorSyntax, ctorDeclarationSyntax);
     Assert.AreEqual(link.OwingClassSyntax, classDeclarationSyntax);
     Assert.AreEqual(link.PathToNextCtorSyntax.Value, ctorDeclarationSyntax.DescendantNodes().OfType <ConstructorInitializerSyntax>().Single());
 }