/// <summary> /// Recurrent function for removeing bagical number from last statement in given BlockSyntax. /// </summary> /// <param name="oldBlock">BlockSyntax in which a statement is defined</param> /// <param name="root">Root in which a statement was defind orignally</param> /// <returns>New BlockSyntax with removed magical number in a statement</returns> private BlockSyntax RemoveMagicalNumber(BlockSyntax oldBlock, SyntaxNode root) { StatementSyntax node = oldBlock.Statements.Last(); // Find all magical numbers in a statement var numericalNode = node.DescendantNodes() .FirstOrDefault(n => n.IsKind(SyntaxKind.NumericLiteralExpression)); if (numericalNode != null) { var expresion = (LocalDeclarationStatementSyntax)SyntaxFactory .ParseStatement($"var {FindFreeVariableName(root, oldBlock)} = {numericalNode.ToFullString()};") .WithLeadingTrivia(node.GetLeadingTrivia()) .WithTrailingTrivia(SyntaxFactory .ParseTrailingTrivia("\n")); return(RemoveMagicalNumber(oldBlock.RemoveNode(node, SyntaxRemoveOptions.KeepNoTrivia) .AddStatements(expresion) .AddStatements(node.ReplaceNode(numericalNode, SyntaxFactory.IdentifierName(expresion.Declaration .Variables[0] .Identifier))), root)); } else { return(oldBlock); } }
/// <summary> /// Check for any inline "out" variable declarations in this statement - i.e. MyFunc(out var result) - /// and declare those variables now. /// </summary> private string DeclareInlineOutVariables(StatementSyntax statement) { StringBuilder sb = new StringBuilder(); IEnumerable <SyntaxNode> declarationExpressionNodes = statement .DescendantNodes(x => !x.IsKind(SyntaxKind.Block)) // Don't descend into child blocks .Where(x => x.IsKind(SyntaxKind.DeclarationExpression)); foreach (DeclarationExpressionSyntax declarationExpressionNode in declarationExpressionNodes) { string varType = _compilation.GetSemanticModel(declarationExpressionNode.Type.SyntaxTree).GetFullTypeName(declarationExpressionNode.Type); string mappedType = _backend.CSharpToShaderType(varType); sb.Append(" "); sb.Append(mappedType); sb.Append(' '); switch (declarationExpressionNode.Designation) { case SingleVariableDesignationSyntax svds: string identifier = _backend.CorrectIdentifier(svds.Identifier.Text); sb.Append(identifier); sb.Append(';'); sb.AppendLine(); break; default: throw new NotImplementedException($"{declarationExpressionNode.Designation.GetType()} designations are not implemented."); } } return(sb.ToString()); }
public static StatementSyntax EventInitializer(string addMethod, string implementor) { return(_EventInitializer.ReplaceNodes(_EventInitializer.DescendantNodes().OfType <IdentifierNameSyntax>(), (oldNode, newNode) => { var id = oldNode.Identifier.ToString() == "__1" ? addMethod : implementor; return newNode.WithIdentifier(SyntaxFactory.Identifier(id)); })); }
private static async Task <Document> RefactorAsync( Document document, ForEachStatementSyntax forEachStatement, CancellationToken cancellationToken) { int position = forEachStatement.SpanStart; SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); string name = NameGenerator.Default.EnsureUniqueLocalName(DefaultNames.EnumeratorVariable, semanticModel, position, cancellationToken: cancellationToken); InvocationExpressionSyntax expression = SimpleMemberInvocationExpression(forEachStatement.Expression, IdentifierName(WellKnownMemberNames.GetEnumeratorMethodName)); VariableDeclarationSyntax variableDeclaration = VariableDeclaration(VarType(), Identifier(name).WithRenameAnnotation(), expression); MemberAccessExpressionSyntax currentExpression = SimpleMemberAccessExpression(IdentifierName(name), IdentifierName("Current")); ILocalSymbol localSymbol = semanticModel.GetDeclaredSymbol(forEachStatement, cancellationToken); StatementSyntax statement = forEachStatement.Statement; StatementSyntax newStatement = statement.ReplaceNodes( statement .DescendantNodes() .Where(node => node.Kind() == SyntaxKind.IdentifierName && localSymbol.Equals(semanticModel.GetSymbol(node, cancellationToken))), (node, _) => currentExpression.WithTriviaFrom(node)); WhileStatementSyntax whileStatement = WhileStatement( SimpleMemberInvocationExpression(IdentifierName(name), IdentifierName("MoveNext")), newStatement); if (semanticModel .GetSpeculativeMethodSymbol(position, expression)? .ReturnType .Implements(SpecialType.System_IDisposable, allInterfaces: true) == true) { UsingStatementSyntax usingStatement = UsingStatement( variableDeclaration, default(ExpressionSyntax), Block(whileStatement)); usingStatement = usingStatement .WithLeadingTrivia(forEachStatement.GetLeadingTrivia()) .WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(forEachStatement, usingStatement, cancellationToken).ConfigureAwait(false)); } else { LocalDeclarationStatementSyntax localDeclaration = LocalDeclarationStatement(variableDeclaration) .WithLeadingTrivia(forEachStatement.GetLeadingTrivia()) .WithFormatterAnnotation(); var newStatements = new StatementSyntax[] { localDeclaration, whileStatement.WithFormatterAnnotation() }; return(await document.ReplaceNodeAsync(forEachStatement, newStatements, cancellationToken).ConfigureAwait(false)); } }
private static Document MakeObjectInitializer(Document document, SyntaxNode root, StatementSyntax statement, ISymbol variableSymbol, SemanticModel semanticModel) { var blockParent = statement.FirstAncestorOrSelf<BlockSyntax>(); var objectCreationExpression = statement.DescendantNodes().OfType<ObjectCreationExpressionSyntax>().Single(); var newBlockParent = CreateNewBlockParent(statement, semanticModel, objectCreationExpression, variableSymbol); var newRoot = root.ReplaceNode(blockParent, newBlockParent); var newDocument = document.WithSyntaxRoot(newRoot); return newDocument; }
private static Document MakeObjectInitializer(Document document, SyntaxNode root, StatementSyntax statement, ISymbol variableSymbol, SemanticModel semanticModel) { var blockParent = statement.FirstAncestorOrSelf <BlockSyntax>(); var objectCreationExpression = statement.DescendantNodes().OfType <ObjectCreationExpressionSyntax>().First(); var newBlockParent = CreateNewBlockParent(statement, semanticModel, objectCreationExpression, variableSymbol); var newRoot = root.ReplaceNode(blockParent, newBlockParent); var newDocument = document.WithSyntaxRoot(newRoot); return(newDocument); }
static List <StatementSyntax> GenerateTcCall(Type t, TcCase test, MethodInfo m) { var stmts = new List <StatementSyntax> (); if (!m.IsStatic) { var newobj_template = @"class Foo { void Run () { var o = new #CLASS# (); }}"; // FIXME: Disposable stmts.Add(ParseText <LocalDeclarationStatementSyntax> (newobj_template.Replace("#CLASS#", t.FullName))); } if (!m.IsPublic) { // FIXME: nskipped++; return(stmts); } string callstr; StatementSyntax node = null; var tname = GetTypeName(t); if (test.MemberDataMethod != null) { callstr = $"class Foo {{ void Run () {{ foreach (var row in {tname}.{test.MemberDataMethod.Name} ()) typeof ({tname}).GetMethod (\"{m.Name}\").Invoke ({(m.IsStatic ? "null" : "o")}, (object []) row); }}"; node = ParseText <StatementSyntax> (callstr); } else { callstr = $"class Foo {{ void Run () {{ {(m.IsStatic ? tname : "o")}.{m.Name} (); }}"; node = ParseText <ExpressionStatementSyntax> (callstr); } if (test.Values != null && test.MemberDataMethod == null) { var parameters = m.GetParameters(); var arg_nodes = new List <ArgumentSyntax> (); for (var index = 0; index < test.Values.Length; index++) { var val_node = EncodeValue(test.Values [index], parameters [index].ParameterType); if (val_node == null) { nskipped++; return(stmts); } arg_nodes.Add(Argument(val_node)); } var args_node = node.DescendantNodes().OfType <ArgumentListSyntax> ().First(); node = node.ReplaceNode(args_node, ArgumentList(SeparatedList(arg_nodes.ToArray()))); } stmts.Add(node); return(stmts); }
private async Task <Document> MakeObjectInitializerAsync(Document document, StatementSyntax statement, ISymbol variableSymbol, SemanticModel semanticModel, CancellationToken cancellationToken) { var blockParent = statement.FirstAncestorOrSelf <BlockSyntax>(); var objectCreationExpression = statement.DescendantNodes().OfType <ObjectCreationExpressionSyntax>().Single(); var newBlockParent = CreateNewBlockParent(statement, semanticModel, objectCreationExpression, variableSymbol); var root = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = root.ReplaceNode(blockParent, newBlockParent); var newDocument = document.WithSyntaxRoot(newRoot); return(newDocument); }
public static bool TryGetAction( StatementSyntax statement, out Func <SyntaxNode, SyntaxNode> action) { ExpressionSyntax outer = null; foreach (var node in statement.DescendantNodes()) { if (node.IsKind(SyntaxKind.InvocationExpression) || node.IsKind(SyntaxKind.ConditionalAccessExpression)) { var expression = (ExpressionSyntax)node; int invocationsCount; bool isExpressionMatch = IsMatch(expression, 0, true, out invocationsCount); if (isExpressionMatch && invocationsCount >= 2) { outer = expression; break; } } } if (outer == null) { action = null; return(false); } var declarations = new List <LocalDeclarationStatementSyntax>(); while (outer.Parent.IsKind(SyntaxKind.ConditionalAccessExpression)) { var conditonalAccess = (ConditionalAccessExpressionSyntax)outer.Parent; if (outer == conditonalAccess.WhenNotNull) { outer = conditonalAccess; } else { break; } } action = syntaxRoot => UnchainMultipleMethodCalls(syntaxRoot, outer); return(true); }
public static bool ContainsAssignmentOf(this StatementSyntax statementSyntax, string variableName, SemanticModel semanticModel) { if (!statementSyntax.IsCycle()) { return(false); } var assignments = statementSyntax .DescendantNodes() .OfType <AssignmentExpressionSyntax>() .ToList(); var declarations = statementSyntax .DescendantNodes() .OfType <VariableDeclaratorSyntax>() .ToList(); foreach (var assignment in assignments) { var variable = assignment.Left; if (variable.HasName(variableName, semanticModel)) { return(true); } } foreach (var declaration in declarations) { var variable = declaration.Identifier; if (variable.Text == variableName) { return(true); } } return(false); }
private static bool ContainsBreakStatementThatBelongsToParentLoop(StatementSyntax statement) { if (ShouldCheckBreakStatement()) { foreach (SyntaxNode descendant in statement.DescendantNodes(statement.Span, f => !IsLoopOrNestedMethod(f.Kind()))) { if (descendant.IsKind(SyntaxKind.BreakStatement)) { return(true); } } } return(false); bool IsLoopOrNestedMethod(SyntaxKind kind) { return(kind.IsLoop() || kind.IsNestedMethod()); } bool ShouldCheckBreakStatement() { for (SyntaxNode node = statement.Parent; node != null; node = node.Parent) { if (node is MemberDeclarationSyntax) { break; } SyntaxKind kind = node.Kind(); if (kind.IsNestedMethod()) { break; } if (kind.IsLoop()) { return(true); } } return(false); } }
private static bool IsPassedAsArgument(StatementSyntax statement, SemanticModel semanticModel, ILocalSymbol identitySymbol) { if (statement == null) { return(false); } var args = statement.DescendantNodes().OfKind <ArgumentSyntax>(SyntaxKind.Argument); foreach (var arg in args) { var argSymbol = semanticModel.GetSymbolInfo(arg.Expression).Symbol; if (identitySymbol.Equals(argSymbol)) { return(true); } } return(false); }
private static async Task<Document> WrapAsync(Document document, StatementSyntax expressionStatement, CancellationToken token) { var identifierNameSyntax = expressionStatement.DescendantNodes().FirstOrDefault(x => x.IsKind(SyntaxKind.IdentifierName)) as IdentifierNameSyntax; if (identifierNameSyntax == null) return document; var loggerName = identifierNameSyntax.Identifier.Text; var expression = SyntaxFactory.ParseExpression(loggerName + ".IsDebugEnabled"); var ifStatement = SyntaxFactory.IfStatement(expression, expressionStatement); var root = await document.GetSyntaxRootAsync(token); root = root.ReplaceNode(expressionStatement, ifStatement); return document.WithSyntaxRoot(root); }
private static bool IsAssignmentOrDeclaration(StatementSyntax statement, AssignmentExpressionSyntax assignment) { if (statement.DescendantNodes().Contains(assignment)) { // it's our own assignment that we check return(true); } switch (statement) { case LocalDeclarationStatementSyntax _: return(true); // the statement is a variable declaration case ExpressionStatementSyntax e when e.Expression.IsKind(SyntaxKind.SimpleAssignmentExpression): return(true); // it is another assignment expression default: return(false); } }
private static bool IsInTryCatchWithMethodInvocation(StatementSyntax node, List <SyntaxNode> ancestors) { var tryAncestor = (TryStatementSyntax)ancestors.FirstOrDefault(n => n.IsKind(SyntaxKind.TryStatement)); if (tryAncestor == null || tryAncestor.Catches.Count == 0) { return(false); } if (node.IsKind(SyntaxKind.ReturnStatement) && node.DescendantNodes().Any(n => n.IsAnyKind(StatementsThatCanThrow))) { return(true); } return(tryAncestor.Block.Statements .TakeWhile(statement => !statement.Equals(node)) .SelectMany(statement => statement.DescendantNodes()) .Any(statement => statement.IsAnyKind(StatementsThatCanThrow))); }
private static async Task <Document> WrapAsync(Document document, StatementSyntax expressionStatement, CancellationToken token) { var identifierNameSyntax = expressionStatement.DescendantNodes().FirstOrDefault(x => x.IsKind(SyntaxKind.IdentifierName)) as IdentifierNameSyntax; if (identifierNameSyntax == null) { return(document); } var loggerName = identifierNameSyntax.Identifier.Text; var expression = SyntaxFactory.ParseExpression(loggerName + ".IsDebugEnabled"); var ifStatement = SyntaxFactory.IfStatement(expression, expressionStatement); var root = await document.GetSyntaxRootAsync(token); root = root.ReplaceNode(expressionStatement, ifStatement); return(document.WithSyntaxRoot(root)); }
private static Boolean AllTypeInStatementIsValid(StatementSyntax statement, SemanticModel semanticModel) { var listNodes = statement.DescendantNodes().ToList(); var member = listNodes.OfType <MemberAccessExpressionSyntax>().FirstOrDefault(); var typeList = member != null?member.Name.DescendantNodesAndSelf().OfType <TypeSyntax>() : listNodes.OfType <TypeSyntax>(); if (!AllTypeIsExist(typeList.ToList(), semanticModel)) { return(false); } if (typeList.First().GetLastToken().GetNextToken().Kind() != SyntaxKind.SemicolonToken) { return(false); } var beginTokenInType = member != null?member.GetFirstToken() : typeList.First().GetFirstToken(); if (statement.DescendantNodesAndTokens().Contains(beginTokenInType.GetPreviousToken())) { return(false); } return(true); }
private static bool HasDescendantCSharpStatement(this StatementSyntax c) { return(c.DescendantNodes().OfType <StatementSyntax>().Any()); }
private static IEnumerable <StatementSyntax> GetInnerStatements(StatementSyntax statement) => statement.DescendantNodes().OfType <StatementSyntax>();
public static bool IsLoopBodyReadsOnlyCurrentItem( StatementSyntax body, SemanticModel semanticModel, ExpressionSyntax collection, string counterName) { ISymbol collectionSymbol; string collectionPartName; if (!TryGetCollectionInfo(collection, semanticModel, out collectionPartName, out collectionSymbol)) { return(false); } // // Search for collection references within loop body // (check only identifiers and member access elements) // foreach (var node in body.DescendantNodes()) { if (node.IsKind(SyntaxKind.IdentifierName)) { var identifierNode = (IdentifierNameSyntax)node; if (identifierNode.Identifier.Text == collectionPartName) { // // If identifier name equals to collection part name // we check whether are they the same symbols. // var nodeSymbol = semanticModel.GetSymbolInfo(node).Symbol; if (collectionSymbol == nodeSymbol) { // // If it's is a reference then we check // wheter it's read only element access by counter // if (!IsReadOnlyCollectionAccess(identifierNode, counterName)) { return(false); } } } else if (identifierNode.Identifier.Text == counterName) { // // If identifier name equals to counter name // we check whether counter is used for element access // if (!node.Parent.IsKind(SyntaxKind.Argument) || !node.Parent.Parent.IsKind(SyntaxKind.BracketedArgumentList) || !node.Parent.Parent.Parent.IsKind(SyntaxKind.ElementAccessExpression)) { return(false); } // // Check whether accessed by counter name collection is our collection // var elementAccess = (ElementAccessExpressionSyntax)node.Parent.Parent.Parent; var accessedCollectionSymbol = semanticModel.GetSymbolInfo(elementAccess.Expression).Symbol; if (accessedCollectionSymbol != collectionSymbol) { return(false); } } } else if (node.IsKind(SyntaxKind.SimpleMemberAccessExpression)) { var memberAccessNode = (MemberAccessExpressionSyntax)node; if (memberAccessNode.Name.Identifier.Text == collectionPartName) { // // If identifier name equals to collection part name // we check whether are they the same symbols. // var nodeSymbol = semanticModel.GetSymbolInfo(node).Symbol; if (collectionSymbol == nodeSymbol) { // // If it's is a reference then we check // wheter it's read only element access by counter // if (!IsReadOnlyCollectionAccess(memberAccessNode, counterName)) { return(false); } } } } } return(true); }
private static bool IsPassedAsArgument(StatementSyntax statement, SemanticModel semanticModel, ILocalSymbol identitySymbol) { if (statement == null) return false; var args = statement.DescendantNodes().OfKind<ArgumentSyntax>(SyntaxKind.Argument); foreach (var arg in args) { var argSymbol = semanticModel.GetSymbolInfo(arg.Expression).Symbol; if (identitySymbol.Equals(argSymbol)) return true; } return false; }