public static IStatement FindStatement(IStatementContainer container, Func <IStatement, bool> filter) { // Climb through the statement tree if the container has a parent if (container is IStatement statement && statement.Parent != null) { var res = FindStatement(statement.Parent, filter); if (res != null) { return(res); } } // Loop through the container and see if any statements match against the filter foreach (var s in container.Statements) { if (filter(s)) { return(s); } // Search the statement if its an inner container if (!(s is IStatementContainer x)) { continue; } var res = FindStatement(x, filter); if (res != null) { return(res); } } return(null); }
public IfStatement(IStatementContainer parent) { Parent = parent; Statements = new ReadOnlyCollection <IStatement>(_statements); Expressions = new ReadOnlyCollection <IExpression>(_expressions); }
private static Task <Document> RefactorAsync( Document document, IfStatementSyntax ifStatement, ReturnStatementSyntax returnStatement, IStatementContainer container, CancellationToken cancellationToken) { SyntaxList <StatementSyntax> statements = container.Statements; IfStatement ifElse = IfStatement.Create(ifStatement); StatementSyntax statement = returnStatement; if (ifElse.Nodes.Any(f => f.Statement?.IsKind(SyntaxKind.Block) == true)) { statement = SyntaxFactory.Block(statement); } ElseClauseSyntax elseClause = SyntaxFactory.ElseClause(statement).WithFormatterAnnotation(); IfStatementSyntax lastIfStatement = ifElse.Nodes.Last(); IfStatementSyntax newIfStatement = ifStatement.ReplaceNode( lastIfStatement, lastIfStatement.WithElse(elseClause)); SyntaxList <StatementSyntax> newStatements = statements .Replace(ifStatement, newIfStatement) .RemoveAt(statements.IndexOf(returnStatement)); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
public override async Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken) { IStatementContainer container = StatementContainer.Create(IfStatement); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(IfStatement); ExpressionSyntax left = Left.WithoutTrivia(); ExpressionSyntax right = Right.WithoutTrivia(); SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); right = AddCastExpressionIfNecessary(right, semanticModel, IfStatement.SpanStart, cancellationToken); StatementSyntax newNode = CreateStatement( CoalesceExpression( left.Parenthesize().WithSimplifierAnnotation(), right.Parenthesize().WithSimplifierAnnotation())); newNode = newNode .WithLeadingTrivia(IfStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newNode); return(await document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken).ConfigureAwait(false)); }
public static bool TryCreate(StatementSyntax statement, out IStatementContainer container) { if (statement == null) { throw new ArgumentNullException(nameof(statement)); } SyntaxNode parent = statement.Parent; switch (parent?.Kind()) { case SyntaxKind.Block: { container = new BlockStatementContainer((BlockSyntax)parent); return(true); } case SyntaxKind.SwitchSection: { container = new SwitchSectionStatementContainer((SwitchSectionSyntax)parent); return(true); } default: { container = null; return(false); } } }
public static Task <Document> RefactorAsync( Document document, ObjectCreationExpressionSyntax objectCreation, SelectedStatementCollection selectedStatements, CancellationToken cancellationToken = default(CancellationToken)) { IStatementContainer container = selectedStatements.Container; ExpressionStatementSyntax[] expressionStatements = selectedStatements .Skip(1) .Cast <ExpressionStatementSyntax>() .ToArray(); StatementSyntax firstNode = selectedStatements.First; SyntaxList <StatementSyntax> newStatements = container.Statements.Replace( firstNode, firstNode.ReplaceNode( objectCreation, objectCreation.WithInitializer(CreateInitializer(objectCreation, expressionStatements)))); int count = expressionStatements.Length; int index = selectedStatements.FirstIndex + 1; while (count > 0) { newStatements = newStatements.RemoveAt(index); count--; } return(document.ReplaceNodeAsync( container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
public static Task <Document> RefactorAsync( Document document, IStatementContainer container, ImmutableArray <IfStatementSyntax> ifStatements, CancellationToken cancellationToken = default(CancellationToken)) { IfStatementSyntax newIfStatement = IfStatement( CreateCondition(ifStatements), Block(CreateStatements(ifStatements))); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(ifStatements[0]); SyntaxList <StatementSyntax> newStatements = statements.Replace( ifStatements[0], newIfStatement .WithLeadingTrivia(ifStatements[0].GetLeadingTrivia()) .WithTrailingTrivia(ifStatements[ifStatements.Length - 1].GetTrailingTrivia())); for (int i = 1; i < ifStatements.Length; i++) { newStatements = newStatements.RemoveAt(index + 1); } return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
internal static void ComputeRefactoring(RefactoringContext context, BinaryExpressionSpan binaryExpressionSpan) { BinaryExpressionSyntax binaryExpression = binaryExpressionSpan.BinaryExpression; SyntaxKind kind = binaryExpression.Kind(); if (kind == SyntaxKind.LogicalAndExpression || kind == SyntaxKind.LogicalOrExpression) { BinaryExpressionSyntax condition = GetCondition(binaryExpression); if (condition != null) { SyntaxNode parent = condition.Parent; switch (parent?.Kind()) { case SyntaxKind.IfStatement: { if (kind == SyntaxKind.LogicalAndExpression) { var refactoring = new ExtractConditionFromIfToNestedIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, (IfStatementSyntax)parent, condition, binaryExpressionSpan, cancellationToken)); } else if (kind == SyntaxKind.LogicalOrExpression) { IStatementContainer container = GetStatementContainer((StatementSyntax)parent); if (container != null) { var refactoring = new ExtractConditionFromIfToIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, container, condition, binaryExpressionSpan, cancellationToken)); } } break; } case SyntaxKind.WhileStatement: { if (kind == SyntaxKind.LogicalAndExpression) { var refactoring = new ExtractConditionFromWhileToNestedIfRefactoring(); context.RegisterRefactoring( refactoring.Title, cancellationToken => refactoring.RefactorAsync(context.Document, (WhileStatementSyntax)parent, condition, binaryExpressionSpan, cancellationToken)); } break; } } } } }
public static Task <Document> RefactorAsync( Document document, VariableDeclaratorSyntax declarator, CancellationToken cancellationToken) { var declaration = (VariableDeclarationSyntax)declarator.Parent; var localDeclaration = (LocalDeclarationStatementSyntax)declaration.Parent; IStatementContainer container = StatementContainer.Create(localDeclaration); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(localDeclaration); StatementSyntax nextStatement = statements[index + 1]; var expressionStatement = (ExpressionStatementSyntax)nextStatement; var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; ExpressionSyntax right = assignment.Right; EqualsValueClauseSyntax initializer = declarator.Initializer; ExpressionSyntax value = initializer?.Value; VariableDeclaratorSyntax newDeclarator = (value != null) ? declarator.ReplaceNode(value, right) : declarator.WithInitializer(EqualsValueClause(right)); LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration.ReplaceNode(declarator, newDeclarator); SyntaxTriviaList trailingTrivia = nextStatement.GetTrailingTrivia(); IEnumerable <SyntaxTrivia> trivia = container .Node .DescendantTrivia(TextSpan.FromBounds(localDeclaration.Span.End, right.SpanStart)); if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trivia.Concat(trailingTrivia)); } else { newLocalDeclaration = newLocalDeclaration.WithTrailingTrivia(trailingTrivia); } SyntaxList <StatementSyntax> newStatements = statements .Replace(localDeclaration, newLocalDeclaration) .RemoveAt(index + 1); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
/// <summary> /// visits a control token /// </summary> /// <param name="controltoken">control token to visit</param> public virtual void VisitControlToken(IStatementContainer controltoken) { if (controltoken is IParameterContainer parametercontrol) { VisitParameterContainer(parametercontrol); } VisitToken(controltoken.Body); if (controltoken is Try @try) { VisitToken(@try.Catch); } if (controltoken is If @if && @if.Else != null) { VisitToken(@if.Else); } }
public Task <Document> RefactorAsync( Document document, IStatementContainer container, BinaryExpressionSyntax condition, ExpressionSyntax expression, CancellationToken cancellationToken = default(CancellationToken)) { var ifStatement = (IfStatementSyntax)condition.Parent; IfStatementSyntax newIfStatement = RemoveExpressionFromCondition(ifStatement, condition, expression) .WithFormatterAnnotation(); SyntaxNode newNode = AddNextIf(container, ifStatement, newIfStatement, expression); return(document.ReplaceNodeAsync(container.Node, newNode, cancellationToken)); }
private static Task <Document> RefactorAsync( Document document, StatementSyntax statement, IfStatementSyntax ifStatement, int statementIndex, IStatementContainer container, ExpressionSyntax expression, CancellationToken cancellationToken) { var expressionStatement = (ExpressionStatementSyntax)ifStatement.GetSingleStatementOrDefault(); var assignment = (AssignmentExpressionSyntax)expressionStatement.Expression; ExpressionSyntax left = expression .WithoutTrailingTrivia() .Parenthesize(moveTrivia: true) .WithSimplifierAnnotation(); ExpressionSyntax right = assignment.Right .WithTrailingTrivia(expression.GetTrailingTrivia()) .Parenthesize(moveTrivia: true) .WithSimplifierAnnotation(); BinaryExpressionSyntax newNode = CSharpFactory.CoalesceExpression(left, right); StatementSyntax newStatement = statement.ReplaceNode(expression, newNode); IEnumerable <SyntaxTrivia> trivia = container.Node.DescendantTrivia(TextSpan.FromBounds(statement.Span.End, ifStatement.Span.End)); if (!trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia())) { newStatement = newStatement.WithTrailingTrivia(trivia); newStatement = newStatement.AppendToTrailingTrivia(ifStatement.GetTrailingTrivia()); } else { newStatement = newStatement.WithTrailingTrivia(ifStatement.GetTrailingTrivia()); } SyntaxList <StatementSyntax> newStatements = container.Statements .Remove(ifStatement) .ReplaceAt(statementIndex, newStatement); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
private void ReplaceOriginalMultipleVariableDeclarationStatement(MultipleVariableDeclarationStatement decl, IList stmts) { int index; // Replace the VariableDeclarationStatement node by a // (possible) sequence of SingleVariableDeclarationStatement IStatementContainer stmtContainer = decl.Parent as IStatementContainer; index = stmtContainer.Statements.IndexOf(decl); stmtContainer.Statements.RemoveAt(index); foreach (SingleVariableDeclarationStatement svDecl in stmts) { stmtContainer.Statements.Insert(index++, svDecl); } }
public override Task <Document> RefactorAsync( Document document, CancellationToken cancellationToken = default(CancellationToken)) { IStatementContainer container = StatementContainer.Create(IfStatement); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(IfStatement); TStatement newStatement = CreateNewStatement(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index - 1, newStatement); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
private static Task <Document> RefactorAsync( Document document, IStatementContainer statementContainer, StatementSyntax statement, InitializerExpressionSyntax initializer, ExpressionSyntax expression, CancellationToken cancellationToken) { ExpressionStatementSyntax[] expressions = Refactor(initializer, expression).ToArray(); expressions[expressions.Length - 1] = expressions[expressions.Length - 1] .WithTrailingTrivia(statement.GetTrailingTrivia()); SyntaxList <StatementSyntax> statements = statementContainer.Statements; int index = statements.IndexOf(statement); StatementSyntax newStatement = statement.RemoveNode(initializer, SyntaxRemoveOptions.KeepNoTrivia); SyntaxKind statementKind = statement.Kind(); if (statementKind == SyntaxKind.ExpressionStatement) { var expressionStatement = (ExpressionStatementSyntax)newStatement; newStatement = expressionStatement .WithExpression(expressionStatement.Expression.WithoutTrailingTrivia()); } else if (statementKind == SyntaxKind.LocalDeclarationStatement) { var localDeclaration = (LocalDeclarationStatementSyntax)newStatement; newStatement = localDeclaration .WithDeclaration(localDeclaration.Declaration.WithoutTrailingTrivia()); } SyntaxList <StatementSyntax> newStatements = statements.Replace(statement, newStatement); SyntaxNode newNode = statementContainer .NodeWithStatements(newStatements.InsertRange(index + 1, expressions)) .WithFormatterAnnotation(); return(document.ReplaceNodeAsync(statementContainer.Node, newNode, cancellationToken)); }
public override bool VisitAssignmentExpression(AssignmentExpression assignExp) { if (assignExp.Target.NodeType == NodeType.VariableRefExpression) { // Convert to declaration if not found on the scope VariableReferenceExpression varRef = (VariableReferenceExpression)assignExp.Target; ISymbolTable scope = varRef.SymbolTable; System.Diagnostics.Debug.Assert(scope != null); String name = varRef.Identifier.Name; if (!scope.IsDefined(name)) // TODO: The rules are slighly more complicated than that. { errorReport.Disable(); SingleVariableDeclarationStatement varDecl = new SingleVariableDeclarationStatement(varRef.Identifier); IStatement stmt = ASTUtils.GetParentStatement(varRef); System.Diagnostics.Debug.Assert(stmt != null); IStatementContainer stmts = stmt.Parent as IStatementContainer; int index = stmts.Statements.IndexOf(stmt); varDecl.InitExp = assignExp.Value; // stmts.Statements.Insert(index, varDecl); stmts.Statements.Replace(stmt, varDecl); if (!ApplyDeclarationRules(varRef.Identifier, scope, varDecl, stmt)) { stmts.Statements.Remove(varDecl); } errorReport.Enable(); } } return(base.VisitAssignmentExpression(assignExp)); }
private static SyntaxNode AddNextIf( IStatementContainer container, IfStatementSyntax ifStatement, IfStatementSyntax newIfStatement, ExpressionSyntax expression) { IfStatementSyntax nextIfStatement = ifStatement.WithCondition(expression) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(ifStatement); SyntaxList <StatementSyntax> newStatements = statements .Replace(ifStatement, newIfStatement) .Insert(index + 1, nextIfStatement); return(container.NodeWithStatements(newStatements)); }
public override Task <Document> RefactorAsync(Document document, CancellationToken cancellationToken = default(CancellationToken)) { IStatementContainer container = StatementContainer.Create(IfStatement); SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(IfStatement); ConditionalExpressionSyntax conditionalExpression = IfRefactoringHelper.CreateConditionalExpression(IfStatement.Condition, Expression1, Expression2); StatementSyntax newStatement = CreateStatement(conditionalExpression) .WithLeadingTrivia(IfStatement.GetLeadingTrivia()) .WithTrailingTrivia(statements[index + 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements .RemoveAt(index) .ReplaceAt(index, newStatement); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
public Task <Document> RefactorAsync( Document document, SelectedStatementCollection selectedStatements, CancellationToken cancellationToken = default(CancellationToken)) { IStatementContainer container = selectedStatements.Container; StatementSyntax[] statements = selectedStatements.ToArray(); int index = selectedStatements.FirstIndex; SyntaxTriviaList leadingTrivia = statements[0].GetLeadingTrivia(); SyntaxTriviaList trailingTrivia = statements[statements.Length - 1].GetTrailingTrivia(); statements[0] = statements[0].WithLeadingTrivia(); statements[statements.Length - 1] = statements[statements.Length - 1].WithTrailingTrivia(); SyntaxList <StatementSyntax> newStatements = container.Statements; int cnt = statements.Length; while (cnt > 0) { newStatements = newStatements.RemoveAt(index); cnt--; } TStatement statement = CreateStatement(statements.ToImmutableArray()); statement = statement .WithLeadingTrivia(leadingTrivia) .WithTrailingTrivia(trailingTrivia) .WithFormatterAnnotation(); newStatements = newStatements.Insert(index, statement); return(document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
private static Task <Document> RefactorAsync( Document document, IStatementContainer container, LocalDeclarationStatementSyntax[] localDeclarations, CancellationToken cancellationToken = default(CancellationToken)) { LocalDeclarationStatementSyntax localDeclaration = localDeclarations[0]; SyntaxList <StatementSyntax> statements = container.Statements; int index = statements.IndexOf(localDeclaration); VariableDeclaratorSyntax[] variables = localDeclarations .Skip(1) .Select(f => f.Declaration) .SelectMany(f => f.Variables) .ToArray(); LocalDeclarationStatementSyntax newLocalDeclaration = localDeclaration .AddDeclarationVariables(variables) .WithTrailingTrivia(localDeclarations[localDeclarations.Length - 1].GetTrailingTrivia()) .WithFormatterAnnotation(); SyntaxList <StatementSyntax> newStatements = statements.Replace( localDeclaration, newLocalDeclaration); for (int i = 1; i < localDeclarations.Length; i++) { newStatements = newStatements.RemoveAt(index + 1); } return(document.ReplaceNodeAsync( container.Node, container.NodeWithStatements(newStatements), cancellationToken)); }
private static Task<Document> RefactorAsync( Document document, ExpressionSyntax expression, SyntaxList<StatementSyntax> statements, IStatementContainer container, int statementIndex, int lastStatementIndex, CancellationToken cancellationToken) { IEnumerable<StatementSyntax> blockStatements = statements .Skip(statementIndex + 1) .Take(lastStatementIndex - statementIndex); IfStatementSyntax ifStatement = CreateNullCheck(expression, List(blockStatements)); if (lastStatementIndex < statements.Count - 1) ifStatement = ifStatement.AppendToTrailingTrivia(NewLineTrivia()); IEnumerable<StatementSyntax> newStatements = statements.Take(statementIndex + 1) .Concat(new IfStatementSyntax[] { ifStatement }) .Concat(statements.Skip(lastStatementIndex + 1)); return document.ReplaceNodeAsync(container.Node, container.NodeWithStatements(newStatements), cancellationToken); }
private bool ApplyDeclarationRules(Identifier ident, ISymbolTable namescope, SingleVariableDeclarationStatement typeDecl, IStatement statem) { // Second simple case: a local var and we are on the right place to // declare it if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { namescope.AddVariable(ident); return(true); } // More complex: a block or compound tries to redefine a variable if (ident.Type == IdentifierType.Local && (namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block)) { if (namescope.Parent.IsDefined(ident.Name)) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined in a parent scope.", ident.Name); return(false); } } // Local variables at class level? // We will support that as a type initializer, but not now. if (ident.Type == IdentifierType.Local && namescope.ScopeType == ScopeType.Type) { errorReport.Error("TODOFILENAME", typeDecl.Position, "At type level, just instance or static fields are allowed (yet)"); return(false); } // Static or instance in a method/block/compound are moved // to the parent class or source unit level if (ident.Type == IdentifierType.InstanceField || ident.Type == IdentifierType.StaticField) { if (namescope.ScopeType == ScopeType.SourceUnit || namescope.ScopeType == ScopeType.Type) { namescope.AddVariable(ident); } else if (namescope.ScopeType == ScopeType.Method || namescope.ScopeType == ScopeType.Compound || namescope.ScopeType == ScopeType.Block) { IASTNode node = statem.Parent; while (node != null && node.NodeType != NodeType.TypeDefinition && node.NodeType != NodeType.SourceUnit) { node = node.Parent; } if (node == null || node.SymbolTable == null) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Compiler error: The instance of static declaration '{0}' could not be mapped to a parent type", ident.Name); return(false); } ISymbolTable parentScope = node.SymbolTable; IStatementContainer typeStmtsContainer = node as IStatementContainer; System.Diagnostics.Debug.Assert(parentScope != null); System.Diagnostics.Debug.Assert(typeStmtsContainer != null); if (parentScope.IsDefined(ident.Name)) { errorReport.Error("TODOFILENAME", typeDecl.Position, "Sorry but '{0}' is already defined.", ident.Name); return(false); } else { parentScope.AddVariable(ident); // We can replace the declaration on the method // body with an assignment if and only if this type decl has // an init expression, so CreateAssignmentFromTypeDecl can return null AssignmentExpression assignExp = CreateAssignmentFromTypeDecl(typeDecl); ExpressionStatement assignExpStmt = new ExpressionStatement(assignExp); typeDecl.ConvertInitExpressionToDependency(); // Replace the declaration with an assignment (statem.Parent as IStatementContainer).Statements.Replace(typeDecl, assignExpStmt); // Add the member/field declaration to the parent typeStmtsContainer.Statements.Add(typeDecl); // TODO: Link assignment expression and typeDecl to help // find out the type of the field later return(true); } } } return(false); }
internal TypeStatement(string name, IStatementContainer parent) { Name = name; Parent = parent; }
private SelectedStatementCollection(IStatementContainer container, TextSpan span) : base(container.Statements, span) { Container = container; }
/// <inheritdoc /> public override void VisitControlToken(IStatementContainer controltoken) { base.VisitControlToken(controltoken); ++ControlTokens; }