public override SyntaxNode VisitBlock(BlockSyntax node) { node = (BlockSyntax)base.VisitBlock(node); SyntaxList <StatementSyntax> statements = node.Statements; var ifStatement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)) as IfStatementSyntax; if (ifStatement != null && IsFixable(ifStatement) && ((BlockSyntax)ifStatement.Parent).Statements.IsLastStatement(ifStatement, skipLocalFunction: true)) { var block = (BlockSyntax)ifStatement.Statement; ExpressionSyntax newCondition = Negator.LogicallyNegate(ifStatement.Condition); IfStatementSyntax newIfStatement = ifStatement .WithCondition(newCondition) .WithStatement(block.WithStatements(SingletonList(_jumpStatement))) .WithFormatterAnnotation(); int index = statements.IndexOf(ifStatement); SyntaxList <StatementSyntax> newStatements = statements .ReplaceAt(index, newIfStatement) .InsertRange(index + 1, block.Statements.Select(f => f.WithFormatterAnnotation())); node = node.WithStatements(newStatements); } return(node); }
private static SyntaxNode InsertStatement( SyntaxNode node, StatementSyntax statement) { var body = (BlockSyntax)GetBodyOrExpressionBody(node); SyntaxList <StatementSyntax> statements = body.Statements; StatementSyntax lastStatement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement, SyntaxKind.ReturnStatement)); int index = (lastStatement != null) ? statements.IndexOf(lastStatement) + 1 : 0; BlockSyntax newBody = body.WithStatements(statements.Insert(index, statement)); if (node.IsKind(SyntaxKind.MethodDeclaration)) { return(((MethodDeclarationSyntax)node).WithBody(newBody)); } else { return(((LocalFunctionStatementSyntax)node).WithBody(newBody)); } }
private static MemberDeclarationSyntax LastPropertyOrField( SyntaxList <MemberDeclarationSyntax> members) { var lastProperty = members.LastOrDefault(m => m is PropertyDeclarationSyntax); return(lastProperty ?? LastField(members)); }
private static MemberDeclarationSyntax AfterMember( SyntaxList <MemberDeclarationSyntax> members, MemberDeclarationSyntax eventDeclaration) { if (eventDeclaration.Kind() == SyntaxKind.EventFieldDeclaration) { // Field style events go after the last field event, or after the last field. var lastEvent = members.LastOrDefault(m => m is EventFieldDeclarationSyntax); return(lastEvent ?? LastField(members)); } if (eventDeclaration.Kind() == SyntaxKind.EventDeclaration) { // Property style events go after existing events, then after existing constructors. var lastEvent = members.LastOrDefault(m => m is EventDeclarationSyntax); return(lastEvent ?? LastConstructor(members)); } return(null); }
internal static bool TryGetCloseBraceNode(this SyntaxList <RazorSyntaxNode> children, [NotNullWhen(true)] out RazorMetaCodeSyntax?brace) { // If there is no whitespace between the directive and the brace then there will only be // three children and the brace should be the last child brace = null; if (children.LastOrDefault(c => c.Kind == Language.SyntaxKind.RazorMetaCode) is RazorMetaCodeSyntax metaCode) { var token = metaCode.MetaCode.SingleOrDefault(m => m.Kind == Language.SyntaxKind.RightBrace); if (token != null) { brace = metaCode; } } return(brace != null); }
static SyntaxList <StatementSyntax> CreateSectionStatements(StatementSyntax source) { var result = new SyntaxList <StatementSyntax>(); if (source is BlockSyntax) { var block = source as BlockSyntax; result = result.AddRange(block.Statements); } else { result = result.Add(source); } if (!(result.LastOrDefault() is ReturnStatementSyntax)) { result = result.Add(SyntaxFactory.BreakStatement()); } return(result); }
private static SyntaxNode InsertStatements( SyntaxNode node, IEnumerable <StatementSyntax> newStatements) { var body = (BlockSyntax)GetBodyOrExpressionBody(node); SyntaxList <StatementSyntax> statements = body.Statements; StatementSyntax lastStatement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement, SyntaxKind.ReturnStatement)); int index = (lastStatement != null) ? statements.IndexOf(lastStatement) + 1 : 0; BlockSyntax newBody = body.WithStatements(statements.InsertRange(index, newStatements)); if (node is MethodDeclarationSyntax methodDeclaration) { return(methodDeclaration.WithBody(newBody)); } return(((LocalFunctionStatementSyntax)node).WithBody(newBody)); }
protected static MemberDeclarationSyntax LastOperator(SyntaxList <MemberDeclarationSyntax> members) { return(members.LastOrDefault(m => m is OperatorDeclarationSyntax || m is ConversionOperatorDeclarationSyntax)); }
protected static MemberDeclarationSyntax LastMethod(SyntaxList <MemberDeclarationSyntax> members) { return(members.LastOrDefault(m => m is MethodDeclarationSyntax)); }
protected static MemberDeclarationSyntax LastConstructor(SyntaxList <MemberDeclarationSyntax> members) { return(members.LastOrDefault(m => m is ConstructorDeclarationSyntax)); }
private static XmlElementSyntax TrimWhitespaceContent(XmlElementSyntax paragraph, out SyntaxList <XmlNodeSyntax> leadingWhitespaceContent, out SyntaxList <XmlNodeSyntax> trailingWhitespaceContent) { SyntaxList <XmlNodeSyntax> completeContent = XmlSyntaxFactory.List(paragraph.Content.SelectMany(ExpandTextNodes).ToArray()); leadingWhitespaceContent = XmlSyntaxFactory.List(completeContent.TakeWhile(x => XmlCommentHelper.IsConsideredEmpty(x)).ToArray()); trailingWhitespaceContent = XmlSyntaxFactory.List(completeContent.Skip(leadingWhitespaceContent.Count).Reverse().TakeWhile(x => XmlCommentHelper.IsConsideredEmpty(x)).Reverse().ToArray()); SyntaxList <XmlNodeSyntax> trimmedContent = XmlSyntaxFactory.List(completeContent.Skip(leadingWhitespaceContent.Count).Take(completeContent.Count - leadingWhitespaceContent.Count - trailingWhitespaceContent.Count).ToArray()); SyntaxTriviaList leadingTrivia = SyntaxFactory.TriviaList(); SyntaxTriviaList trailingTrivia = SyntaxFactory.TriviaList(); if (trimmedContent.Any()) { leadingTrivia = trimmedContent[0].GetLeadingTrivia(); trailingTrivia = trimmedContent.Last().GetTrailingTrivia(); trimmedContent = trimmedContent.Replace(trimmedContent[0], trimmedContent[0].WithoutLeadingTrivia()); trimmedContent = trimmedContent.Replace(trimmedContent.Last(), trimmedContent.Last().WithoutTrailingTrivia()); } else { leadingTrivia = SyntaxFactory.TriviaList(); trailingTrivia = SyntaxFactory.TriviaList(); } XmlElementSyntax result = paragraph; if (leadingWhitespaceContent.Any()) { var first = leadingWhitespaceContent[0]; var newFirst = first.WithLeadingTrivia(first.GetLeadingTrivia().InsertRange(0, paragraph.GetLeadingTrivia())); leadingWhitespaceContent = leadingWhitespaceContent.Replace(first, newFirst); } else { leadingTrivia = leadingTrivia.InsertRange(0, result.GetLeadingTrivia()); } if (trailingWhitespaceContent.Any()) { var last = trailingWhitespaceContent.Last(); var newLast = last.WithLeadingTrivia(last.GetLeadingTrivia().AddRange(paragraph.GetTrailingTrivia())); trailingWhitespaceContent = trailingWhitespaceContent.Replace(last, newLast); } else { trailingTrivia = trailingTrivia.AddRange(result.GetTrailingTrivia()); } if (trimmedContent.FirstOrDefault() is XmlTextSyntax firstTextNode && firstTextNode.TextTokens.Any()) { SyntaxToken firstTextToken = firstTextNode.TextTokens[0]; string leadingWhitespace = new(firstTextToken.Text.Cast <char>().TakeWhile(char.IsWhiteSpace).ToArray()); if (leadingWhitespace.Length > 0) { SyntaxToken newFirstTextToken = XmlSyntaxFactory.TextLiteral(firstTextToken.Text.Substring(leadingWhitespace.Length)).WithTriviaFrom(firstTextToken); XmlTextSyntax newFirstTextNode = firstTextNode.WithTextTokens(firstTextNode.TextTokens.Replace(firstTextToken, newFirstTextToken)); trimmedContent = trimmedContent.Replace(firstTextNode, newFirstTextNode); leadingTrivia = leadingTrivia.Add(SyntaxFactory.Whitespace(leadingWhitespace)); } } if (trimmedContent.LastOrDefault() is XmlTextSyntax lastTextNode && lastTextNode.TextTokens.Any()) { SyntaxToken lastTextToken = lastTextNode.TextTokens.Last(); string trailingWhitespace = new(lastTextToken.Text.Cast <char>().Reverse().TakeWhile(char.IsWhiteSpace).Reverse().ToArray()); if (trailingWhitespace.Length > 0) { SyntaxToken newLastTextToken = XmlSyntaxFactory.TextLiteral(lastTextToken.Text.Substring(0, lastTextToken.Text.Length - trailingWhitespace.Length)).WithTriviaFrom(lastTextToken); XmlTextSyntax newLastTextNode = lastTextNode.WithTextTokens(lastTextNode.TextTokens.Replace(lastTextToken, newLastTextToken)); trimmedContent = trimmedContent.Replace(lastTextNode, newLastTextNode); trailingTrivia = trailingTrivia.Insert(0, SyntaxFactory.Whitespace(trailingWhitespace)); } } return(result.WithContent(trimmedContent) .WithLeadingTrivia(leadingTrivia) .WithTrailingTrivia(trailingTrivia)); }
public SyntaxToken WithDelegateToParentAnnotation <T>(SyntaxList <T> unvisitedSourceStatementList, SyntaxToken destinationToken) where T : SyntaxNode { return(WithDelegateToParentAnnotation(unvisitedSourceStatementList.LastOrDefault(), destinationToken)); }
public static MemberDeclarationSyntax?LastField(SyntaxList <MemberDeclarationSyntax> members) => members.LastOrDefault(m => m is FieldDeclarationSyntax);
public static MemberDeclarationSyntax LastField(SyntaxList <MemberDeclarationSyntax> members) { return(members.LastOrDefault(m => m is FieldDeclarationSyntax)); }
public static MemberDeclarationSyntax?LastMethod(SyntaxList <MemberDeclarationSyntax> members) => members.LastOrDefault(m => m is MethodDeclarationSyntax);
public static MemberDeclarationSyntax?LastConstructor(SyntaxList <MemberDeclarationSyntax> members) => members.LastOrDefault(m => m is ConstructorDeclarationSyntax);
protected static int GetInsertionIndex <TDeclaration>( SyntaxList <TDeclaration> declarationList, TDeclaration declaration, CodeGenerationOptions options, IList <bool> availableIndices, Func <SyntaxList <TDeclaration>, TDeclaration> after = null, Func <SyntaxList <TDeclaration>, TDeclaration> before = null) where TDeclaration : SyntaxNode { Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); if (options != null) { // Try to strictly obey the after option by inserting immediately after the member containing the location if (options.AfterThisLocation != null) { var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start); if (afterMember != null) { var index = declarationList.IndexOf(afterMember); index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } // Try to strictly obey the before option by inserting immediately before the member containing the location if (options.BeforeThisLocation != null) { var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End); if (beforeMember != null) { var index = declarationList.IndexOf(beforeMember); index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } if (options.AutoInsertionLocation) { if (declarationList.IsEmpty()) { return(0); } else if (declarationList.IsSorted(CSharpDeclarationComparer.Instance)) { var result = Array.BinarySearch(declarationList.ToArray(), declaration, CSharpDeclarationComparer.Instance); var index = GetPreferredIndex(result < 0 ? ~result : result, availableIndices, forward: true); if (index != -1) { return(index); } } if (after != null) { var member = after(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } } if (before != null) { var member = before(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } } } } // Otherwise, add the declaration to the end. { var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false); if (index != -1) { return(index); } } return(declarationList.Count); }
private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, SyntaxToken asyncKeyword, BlockSyntax body) { if (asyncKeyword.IsKind(SyntaxKind.AsyncKeyword) && body?.IsMissing == false && !node.SpanContainsDirectives()) { SyntaxList <StatementSyntax> statements = body.Statements; if (statements.Any()) { StatementSyntax statement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)); if (statement != null) { SyntaxKind kind = statement.Kind(); if (kind == SyntaxKind.ReturnStatement) { var returnStatement = (ReturnStatementSyntax)statement; AwaitExpressionSyntax awaitExpression = GetAwaitExpressionOrDefault(returnStatement); if (awaitExpression != null) { HashSet <AwaitExpressionSyntax> awaitExpressions = CollectAwaitExpressions(body, TextSpan.FromBounds(body.SpanStart, returnStatement.Span.End)); if (awaitExpressions != null) { if (awaitExpressions.Count == 1) { if (ReturnTypeAndAwaitTypeEquals(node, awaitExpression, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpression); } } else { int index = statements.IndexOf(returnStatement); if (index > 0) { StatementSyntax previousStatement = statements[index - 1]; SyntaxKind previousStatementKind = previousStatement.Kind(); if (previousStatementKind == SyntaxKind.IfStatement) { Analyze(context, node, asyncKeyword, awaitExpression, awaitExpressions, GetAwaitExpressionsFromIfStatement((IfStatementSyntax)previousStatement, endsWithElse: false)); } else if (previousStatementKind == SyntaxKind.SwitchStatement) { Analyze(context, node, asyncKeyword, awaitExpression, awaitExpressions, GetAwaitExpressionsFromSwitchStatement((SwitchStatementSyntax)previousStatement, containsDefaultSection: false)); } } } } } } else if (kind == SyntaxKind.IfStatement) { Analyze(context, node, body, asyncKeyword, GetAwaitExpressionsFromIfStatement((IfStatementSyntax)statement, endsWithElse: true)); } else if (kind == SyntaxKind.SwitchStatement) { Analyze(context, node, body, asyncKeyword, GetAwaitExpressionsFromSwitchStatement((SwitchStatementSyntax)statement, containsDefaultSection: true)); } } } } }
public static MemberDeclarationSyntax LastOperator( SyntaxList <MemberDeclarationSyntax> members ) => members.LastOrDefault( m => m is OperatorDeclarationSyntax || m is ConversionOperatorDeclarationSyntax );
public static int GetInsertionIndex <TDeclaration>( SyntaxList <TDeclaration> declarationList, TDeclaration declaration, CodeGenerationOptions options, IList <bool> availableIndices, IComparer <TDeclaration> comparerWithoutNameCheck, IComparer <TDeclaration> comparerWithNameCheck, Func <SyntaxList <TDeclaration>, TDeclaration> after = null, Func <SyntaxList <TDeclaration>, TDeclaration> before = null) where TDeclaration : SyntaxNode { Contract.ThrowIfTrue(availableIndices != null && availableIndices.Count != declarationList.Count + 1); if (options != null) { // Try to strictly obey the after option by inserting immediately after the member containing the location if (options.AfterThisLocation != null) { var afterMember = declarationList.LastOrDefault(m => m.SpanStart <= options.AfterThisLocation.SourceSpan.Start); if (afterMember != null) { var index = declarationList.IndexOf(afterMember); index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } // Try to strictly obey the before option by inserting immediately before the member containing the location if (options.BeforeThisLocation != null) { var beforeMember = declarationList.FirstOrDefault(m => m.Span.End >= options.BeforeThisLocation.SourceSpan.End); if (beforeMember != null) { var index = declarationList.IndexOf(beforeMember); index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } if (options.AutoInsertionLocation) { if (declarationList.IsEmpty()) { return(0); } var desiredIndex = TryGetDesiredIndexIfGrouped( declarationList, declaration, availableIndices, comparerWithoutNameCheck, comparerWithNameCheck); if (desiredIndex.HasValue) { return(desiredIndex.Value); } if (after != null) { var member = after(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index + 1, availableIndices, forward: true); if (index != -1) { return(index); } } } } if (before != null) { var member = before(declarationList); if (member != null) { var index = declarationList.IndexOf(member); if (index >= 0) { index = GetPreferredIndex(index, availableIndices, forward: false); if (index != -1) { return(index); } } } } } } // Otherwise, add the declaration to the end. { var index = GetPreferredIndex(declarationList.Count, availableIndices, forward: false); if (index != -1) { return(index); } } return(declarationList.Count); }
private static void Analyze(SyntaxNodeAnalysisContext context, SyntaxNode node, SyntaxToken asyncKeyword, BlockSyntax body) { SyntaxList <StatementSyntax> statements = body.Statements; StatementSyntax statement = statements.LastOrDefault(f => !f.IsKind(SyntaxKind.LocalFunctionStatement)); if (statement == null) { return; } switch (statement.Kind()) { case SyntaxKind.ReturnStatement: { var returnStatement = (ReturnStatementSyntax)statement; AwaitExpressionSyntax awaitExpression = GetAwaitExpression(returnStatement); if (awaitExpression == null) { return; } RemoveRedundantAsyncAwaitWalker walker = VisitStatements(); HashSet <AwaitExpressionSyntax> awaitExpressions = walker.AwaitExpressions; if (awaitExpressions.Count == 1) { if (VerifyTypes(node, awaitExpression, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpression); } } else if (awaitExpressions.Count > 1) { StatementSyntax prevStatement = statements[statements.IndexOf(returnStatement) - 1]; switch (prevStatement.Kind()) { case SyntaxKind.IfStatement: { if (VerifyIfStatement((IfStatementSyntax)prevStatement, awaitExpressions.Count - 1, endsWithElse: false) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } break; } case SyntaxKind.SwitchStatement: { if (VerifySwitchStatement((SwitchStatementSyntax)prevStatement, awaitExpressions.Count - 1, containsDefaultSection: false) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } break; } } } RemoveRedundantAsyncAwaitWalkerCache.Free(walker); break; } case SyntaxKind.IfStatement: { RemoveRedundantAsyncAwaitWalker walker = VisitStatements(); HashSet <AwaitExpressionSyntax> awaitExpressions = walker.AwaitExpressions; if (awaitExpressions.Count > 0 && VerifyIfStatement((IfStatementSyntax)statement, awaitExpressions.Count, endsWithElse: true) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } RemoveRedundantAsyncAwaitWalkerCache.Free(walker); break; } case SyntaxKind.SwitchStatement: { RemoveRedundantAsyncAwaitWalker walker = VisitStatements(); HashSet <AwaitExpressionSyntax> awaitExpressions = walker.AwaitExpressions; if (awaitExpressions.Count > 0 && VerifySwitchStatement((SwitchStatementSyntax)statement, awaitExpressions.Count, containsDefaultSection: true) && VerifyTypes(node, awaitExpressions, context.SemanticModel, context.CancellationToken)) { ReportDiagnostic(context, asyncKeyword, awaitExpressions); } RemoveRedundantAsyncAwaitWalkerCache.Free(walker); break; } } RemoveRedundantAsyncAwaitWalker VisitStatements() { RemoveRedundantAsyncAwaitWalker walker = RemoveRedundantAsyncAwaitWalkerCache.GetInstance(); foreach (StatementSyntax s in statements) { walker.Visit(s); if (walker.ShouldStop) { return(walker); } if (s == statement) { return(walker); } } return(walker); } }