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."); }
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)); }
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; } }
/// <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; })); }
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); }
/// <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)); }
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()); }