public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { // e.g. int x, y = 0; if (node.Declaration.Variables.Count > 1) { return node; } // e.g. int x; if (node.Declaration.Variables[0].Initializer == null) { return node; } VariableDeclaratorSyntax declarator = node.Declaration.Variables.First(); TypeSyntax variableTypeName = node.Declaration.Type; TypeSymbol variableType = (TypeSymbol)semanticModel.GetSymbolInfo(variableTypeName).Symbol; TypeInfo initializerInfo = semanticModel.GetTypeInfo(declarator.Initializer.Value); // only when type is the same, (e.g. no base class casting) if (variableType == initializerInfo.Type) { TypeSyntax varTypeName = Syntax.IdentifierName("var") .WithLeadingTrivia(variableTypeName.GetLeadingTrivia()) .WithTrailingTrivia(variableTypeName.GetTrailingTrivia()); return node.ReplaceNode<LocalDeclarationStatementSyntax, TypeSyntax>(variableTypeName, varTypeName); } else { return node; } }
public static IEnumerable<ReplaceAction> GetSimplifications(LocalDeclarationStatementSyntax declaration, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken)) { var scope = declaration.Ancestors().OfType<BlockSyntax>().First(); var i = scope.Statements.IndexOf(declaration); foreach (var v in declaration.Declaration.Variables) { if (v.Initializer != null) { if (v.Initializer.Value.HasSideEffects(model, assume) != false) continue; var anyEffects = declaration.Declaration.Variables.Where(e => e.Initializer != null && e.Initializer.Value.HasSideEffects(model, assume) != false).Any(); if (v.Initializer.Value.IsConst(model) != true && anyEffects) continue; } var r = WithDeclarationMoved(scope, declaration, v, model, assume, cancellationToken); if (r == null) continue; var reducedDeclaration = declaration.Declaration.Variables.Count == 1 ? new LocalDeclarationStatementSyntax[0] : new[] { declaration.WithDeclaration(declaration.Declaration.WithVariables(declaration.Declaration.Variables.Without(v))) }; var newScopeWithReducedDeclaration = r.WithStatements(r.Statements.TakeSkipPutTake(i, 1, reducedDeclaration).List()); yield return new ReplaceAction("Reduce scope", scope, newScopeWithReducedDeclaration, v.Identifier.Span); } }
public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { if (node.Declaration.Variables.Count > 1) { return node; } if (node.Declaration.Variables[0].Initializer == null) { return node; } VariableDeclaratorSyntax declarator = node.Declaration.Variables.First(); TypeSyntax variableTypeName = node.Declaration.Type; TypeSymbol variableType = (TypeSymbol)SemanticModel.GetSymbolInfo(variableTypeName) .Symbol; TypeInfo initializerInfo = SemanticModel.GetTypeInfo(declarator.Initializer.Value); if (variableType == initializerInfo.Type) { TypeSyntax varTypeName = Syntax.IdentifierName("var") .WithLeadingTrivia( variableTypeName.GetLeadingTrivia()) .WithTrailingTrivia( variableTypeName.GetTrailingTrivia()); return node.ReplaceNode(variableTypeName, varTypeName); } else { return node; } }
public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { // Here, we collect expression expressions from any/all initialization expressions AddVariableExpressions(node.Declaration.Variables, _expressions); }
public static ArgumentType ArgumentDefinedAs(FieldDeclarationSyntax fieldDeclaration, LocalDeclarationStatementSyntax localDeclarationStatement, ExpressionSyntax expression) { if (fieldDeclaration != null) { return(ArgumentType.Field); } if (localDeclarationStatement != null) { return(ArgumentType.Local); } if (expression != null) { return(ArgumentType.Expression); } return(ArgumentType.Unknown); }
public static Task <Document> RefactorAsync(Document document, IfAnalysis ifAnalysis, CancellationToken cancellationToken = default) { switch (ifAnalysis.Kind) { case IfAnalysisKind.IfElseToAssignmentWithCoalesceExpression: { return(IfElseToAssignmentWithCoalesceExpressionAsync(document, (IfElseToAssignmentWithCoalesceExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToAssignmentWithConditionalExpression: { return(IfElseToAssignmentWithConditionalExpressionAsync(document, (IfElseToAssignmentWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.AssignmentAndIfToAssignmentWithConditionalExpression: { var analysis = (AssignmentAndIfToAssignmentWithConditionalExpressionAnalysis)ifAnalysis; ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(analysis.IfStatement.Condition, analysis.WhenTrue, analysis.WhenFalse); ExpressionStatementSyntax newStatement = analysis.Statement.ReplaceNode(analysis.Right, conditionalExpression); return(ToAssignmentWithConditionalExpressionAsync(document, analysis, newStatement, cancellationToken)); } case IfAnalysisKind.LocalDeclarationAndIfElseAssignmentWithConditionalExpression: { var analysis = (LocalDeclarationAndIfElseToAssignmentWithConditionalExpressionAnalysis)ifAnalysis; ConditionalExpressionSyntax conditionalExpression = CreateConditionalExpression(analysis.IfStatement.Condition, analysis.WhenTrue, analysis.WhenFalse); VariableDeclaratorSyntax declarator = analysis.Statement.Declaration.Variables[0]; EqualsValueClauseSyntax initializer = declarator.Initializer; EqualsValueClauseSyntax newInitializer = (initializer != null) ? initializer.WithValue(conditionalExpression) : EqualsValueClause(conditionalExpression); LocalDeclarationStatementSyntax newStatement = analysis.Statement.ReplaceNode(declarator, declarator.WithInitializer(newInitializer)); return(ToAssignmentWithConditionalExpressionAsync(document, analysis, newStatement, cancellationToken)); } case IfAnalysisKind.IfElseToAssignmentWithExpression: { return(IfElseToAssignmentWithExpressionAsync(document, (IfElseToAssignmentWithExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToAssignmentWithCondition: { return(IfElseToAssignmentWithConditionAsync(document, (IfElseToAssignmentWithConditionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToReturnWithCoalesceExpression: case IfAnalysisKind.IfElseToYieldReturnWithCoalesceExpression: case IfAnalysisKind.IfReturnToReturnWithCoalesceExpression: { return(IfToReturnWithCoalesceExpressionAsync(document, (IfToReturnWithCoalesceExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToReturnWithConditionalExpression: { return(IfElseToReturnWithConditionalExpressionAsync(document, (IfElseToReturnWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToReturnWithBooleanExpression: { return(IfElseToReturnWithBooleanExpressionAsync(document, (IfElseToReturnWithBooleanExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToReturnWithExpression: case IfAnalysisKind.IfElseToYieldReturnWithExpression: case IfAnalysisKind.IfReturnToReturnWithExpression: { return(IfToReturnWithExpressionAsync(document, (IfToReturnWithExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToYieldReturnWithConditionalExpression: { return(IfElseToYieldReturnWithConditionalExpressionAsync(document, (IfElseToYieldReturnWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfElseToYieldReturnWithBooleanExpression: { return(IfElseToYieldReturnWithBooleanExpressionAsync(document, (IfElseToYieldReturnWithBooleanExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfReturnToReturnWithConditionalExpression: { return(IfReturnToReturnWithConditionalExpressionAsync(document, (IfReturnToReturnWithConditionalExpressionAnalysis)ifAnalysis, cancellationToken)); } case IfAnalysisKind.IfReturnToReturnWithBooleanExpression: { return(IfReturnToReturnWithBooleanExpressionAsync(document, (IfReturnToReturnWithBooleanExpressionAnalysis)ifAnalysis, cancellationToken)); } default: { throw new InvalidOperationException(); } } }
public bool TryGetPatternPieces( BinaryExpressionSyntax isExpression, out IfStatementSyntax ifStatement, out LocalDeclarationStatementSyntax localDeclarationStatement, out VariableDeclaratorSyntax declarator, out CastExpressionSyntax castExpression) { ifStatement = null; localDeclarationStatement = null; declarator = null; castExpression = null; // The is check has to be in an if check: "if (x is Type) if (!isExpression.Parent.IsKind(SyntaxKind.IfStatement)) { return(false); } ifStatement = (IfStatementSyntax)isExpression.Parent; if (!ifStatement.Statement.IsKind(SyntaxKind.Block)) { return(false); } var ifBlock = (BlockSyntax)ifStatement.Statement; if (ifBlock.Statements.Count == 0) { return(false); } var firstStatement = ifBlock.Statements[0]; if (!firstStatement.IsKind(SyntaxKind.LocalDeclarationStatement)) { return(false); } localDeclarationStatement = (LocalDeclarationStatementSyntax)firstStatement; if (localDeclarationStatement.Declaration.Variables.Count != 1) { return(false); } declarator = localDeclarationStatement.Declaration.Variables[0]; if (declarator.Initializer == null) { return(false); } var declaratorValue = declarator.Initializer.Value.WalkDownParentheses(); if (!declaratorValue.IsKind(SyntaxKind.CastExpression)) { return(false); } castExpression = (CastExpressionSyntax)declaratorValue; if (!SyntaxFactory.AreEquivalent(isExpression.Left.WalkDownParentheses(), castExpression.Expression.WalkDownParentheses(), topLevel: false) || !SyntaxFactory.AreEquivalent(isExpression.Right.WalkDownParentheses(), castExpression.Type, topLevel: false)) { return(false); } return(true); }
static bool DidVariableDeclarationTypeCorrespondToObviousCase(SyntaxNodeAnalysisContext nodeContext, LocalDeclarationStatementSyntax localVariable) { var singleVariable = localVariable.Declaration.Variables.First(); var initializer = singleVariable.Initializer; if (initializer == null) { return(false); } var initializerExpression = initializer.Value; var variableTypeName = localVariable.Declaration.Type; var semanticModel = nodeContext.SemanticModel; var variableType = semanticModel.GetSymbolInfo(variableTypeName, nodeContext.CancellationToken).Symbol as ITypeSymbol; return(IsArrayTypeSomeObviousTypeCase(nodeContext, initializerExpression, variableType, localVariable) || IsObjectCreationSomeObviousTypeCase(nodeContext, initializerExpression, variableType) || IsCastingSomeObviousTypeCase(nodeContext, initializerExpression, variableType) /*|| * IsPropertyAccessSomeObviousTypeCase(nodeContext, initializerExpression, variableType)*/); }
public CodeAction(IDocument document, LocalDeclarationStatementSyntax localDeclaration) { this.document = document; this.localDeclaration = localDeclaration; }
private static SyntaxToken ApplyTriviaFromDeclarationToAssignmentIdentifier(LocalDeclarationStatementSyntax declarationStatement, bool firstVariableToAttachTrivia, VariableDeclaratorSyntax variable) { var identifier = variable.Identifier; var typeSyntax = declarationStatement.Declaration.Type; if (firstVariableToAttachTrivia && typeSyntax != null) { var identifierLeadingTrivia = new SyntaxTriviaList(); if (typeSyntax.HasLeadingTrivia) { identifierLeadingTrivia = identifierLeadingTrivia.AddRange(typeSyntax.GetLeadingTrivia()); } identifierLeadingTrivia = identifierLeadingTrivia.AddRange(identifier.LeadingTrivia); identifier = identifier.WithLeadingTrivia(identifierLeadingTrivia); } return(identifier); }
public void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); WriteLeadingTrivia(node); _writer.WriteIndent(); if ((node.Modifiers & Modifiers.Const) != 0) { _writer.WriteKeyword(PrinterKeyword.Const); _writer.WriteSpace(); } node.Declaration.Accept(this); _writer.EndStatement(); WriteTrailingTrivia(node); }
public void Flatten(LocalDeclarationStatementSyntax node, List<FlatStatement> instructions) { TypeInfo ti = Model.GetTypeInfo(node.Declaration.Type); foreach (VariableDeclaratorSyntax vds in node.Declaration.Variables) { Flatten(ti.Type, vds, instructions); } }
private static BlockSyntax WithDeclarationMoved(BlockSyntax scope, LocalDeclarationStatementSyntax declaration, VariableDeclaratorSyntax v, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken) { Func<SyntaxNode, bool> accesses = s => s.DescendantNodes() .OfType<IdentifierNameSyntax>() .Where(e => e.Identifier.ValueText == v.Identifier.ValueText) .Where(e => model.GetSymbolInfo(e).Symbol == model.GetDeclaredSymbol(v)) .Any(); var isOutermostScope = scope.Statements.Contains(declaration); var scopeStatements = isOutermostScope ? scope.Statements.SkipWhile(e => e != declaration).Skip(1).ToArray() : scope.Statements.ToArray(); var statementAccesses = scope.Statements.Where(s => accesses(s)).ToArray(); if (statementAccesses.Length == 0) return null; //unused local, no change var firstAccess = statementAccesses.FirstOrDefault(); var insertBeforeTarget = firstAccess; if (v.Initializer != null && v.Initializer.Value.IsConst(model) != true) { insertBeforeTarget = scopeStatements .TakeWhile(e => e != firstAccess) .SkipWhile(e => e.HasSideEffects(model, assume) == false) .Append(firstAccess) .FirstOrDefault(); } if (statementAccesses.Length == 1 && insertBeforeTarget == firstAccess) { if (firstAccess is BlockSyntax) { var reducedScope = WithDeclarationMoved((BlockSyntax)firstAccess, declaration, v, model, assume, cancellationToken); return scope.WithStatements(scope.Statements.Replace(firstAccess, reducedScope)); } if (firstAccess is IfStatementSyntax) { var s = (IfStatementSyntax)firstAccess; if (!accesses(s.Condition)) { if (!accesses(s.Statement) && s.Else.Statement is BlockSyntax) { return scope.WithStatements( scope.Statements.Replace( s, s.WithElse( s.Else.WithStatement( WithDeclarationMoved( (BlockSyntax)s.Else.Statement, declaration, v, model, assume, cancellationToken))))); } else if (s.Statement is BlockSyntax && (s.Else == null || !accesses(s.Else.Statement))) { return scope.WithStatements( scope.Statements.Replace( s, s.WithStatement( WithDeclarationMoved( (BlockSyntax)s.Statement, declaration, v, model, assume, cancellationToken)))); } } } } if (isOutermostScope && scopeStatements.TakeWhile(e => e != insertBeforeTarget).Where(e => !(e is LocalDeclarationStatementSyntax)).None()) return null; //minimal scope already var newDeclaration = declaration.WithDeclaration(declaration.Declaration.WithVariables(v.SepList1())); return scope.WithStatements(scope.Statements.InsertBefore(insertBeforeTarget, newDeclaration).List()); }
private Method TraverseVarDecls(LocalDeclarationStatementSyntax ldss) { Method retMethod = new Method(); List<Encapsulation> accessability = new List<Encapsulation>(); List<Qualifiers> qualifiers = new List<Qualifiers>(); foreach (SyntaxToken st in ldss.Modifiers) { string modifier = System.Threading.Thread.CurrentThread.CurrentCulture.TextInfo.ToTitleCase(st.ValueText); Encapsulation encap; Qualifiers qual; if (System.Enum.TryParse<Encapsulation>(modifier, out encap)) { accessability.Add(encap); } else if (System.Enum.TryParse<Qualifiers>(modifier, out qual)) { qualifiers.Add(qual); } } foreach (SyntaxNode ss in ldss.ChildNodes()) { if (ss is VariableDeclaratorSyntax) { Variables retVar = new Variables(); retVar = TraverseVariableSyntax(ss as VariableDeclaratorSyntax, accessability, qualifiers); retMethod.AccessedVariables.Add(retVar); } else if (ss is CallStatementSyntax) { retMethod.InvokedMethods.Add(TraverseInvokedMethod(ss as CallStatementSyntax)); } } return retMethod; }
public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { _currentBlock.Nodes.Add(node); }
private async Task <Document> MakeConstAsync(Document document, LocalDeclarationStatementSyntax localDeclaration, CancellationToken cancellationToken) { // Remove the leading trivia from the local declaration. var firstToken = localDeclaration.GetFirstToken(); var leadingTrivia = firstToken.LeadingTrivia; var trimmedLocal = localDeclaration.ReplaceToken( firstToken, firstToken.WithLeadingTrivia(SyntaxTriviaList.Empty)); // Create a const token with the leading trivia. var constToken = SyntaxFactory.Token(leadingTrivia, SyntaxKind.ConstKeyword, SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker)); // Insert the const token into the modifiers list, creating a new modifiers list. var newModifiers = trimmedLocal.Modifiers.Insert(0, constToken); // If the type of declaration is 'var', create a new type name for the // type inferred for 'var'. var variableDeclaration = localDeclaration.Declaration; var variableTypeName = variableDeclaration.Type; if (variableTypeName.IsVar) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); // Special case: Ensure that 'var' isn't actually an alias to another type // (e.g. using var = System.String). var aliasInfo = semanticModel.GetAliasInfo(variableTypeName); if (aliasInfo == null) { // Retrieve the type inferred for var. var type = semanticModel.GetTypeInfo(variableTypeName).ConvertedType; // Special case: Ensure that 'var' isn't actually a type named 'var'. if (type.Name != "var") { // Create a new TypeSyntax for the inferred type. Be careful // to keep any leading and trailing trivia from the var keyword. var typeName = SyntaxFactory.ParseTypeName(type.ToDisplayString()) .WithLeadingTrivia(variableTypeName.GetLeadingTrivia()) .WithTrailingTrivia(variableTypeName.GetTrailingTrivia()); // Add an annotation to simplify the type name. var simplifiedTypeName = typeName.WithAdditionalAnnotations(Simplifier.Annotation); // Replace the type in the variable declaration. variableDeclaration = variableDeclaration.WithType(simplifiedTypeName); } } } // Produce the new local declaration. var newLocal = trimmedLocal.WithModifiers(newModifiers) .WithDeclaration(variableDeclaration); // Add an annotation to format the new local declaration. var formattedLocal = newLocal.WithAdditionalAnnotations(Formatter.Annotation); // Replace the old local declaration with the new local declaration. var root = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = root.ReplaceNode(localDeclaration, formattedLocal); // Return document with transformed tree. return(document.WithSyntaxRoot(newRoot)); }
internal static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration) { ConditionalExpressionSyntax conditionalExpression = GetConditionalExpression(localDeclaration); if (conditionalExpression != null) { await ComputeRefactoringAsync(context, localDeclaration, conditionalExpression).ConfigureAwait(false); } }
public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { visitingConstant = node.Modifiers.Any(SyntaxKind.ConstKeyword); base.VisitLocalDeclarationStatement(node); visitingConstant = false; }
private static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration, ConditionalExpressionSyntax conditionalExpression) { if (localDeclaration?.IsParentKind(SyntaxKind.Block, SyntaxKind.SwitchSection) == true) { TypeSyntax type = localDeclaration.Declaration.Type; if (type != null) { bool success = true; if (type.IsVar) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken); success = typeSymbol?.SupportsExplicitDeclaration() == true; } if (success) { context.RegisterRefactoring( "Replace ?: with if-else", cancellationToken => RefactorAsync(context.Document, localDeclaration, conditionalExpression, cancellationToken)); } } } }
static bool IsArrayTypeSomeObviousTypeCase(SyntaxNodeAnalysisContext nodeContext, ExpressionSyntax initializerExpression, ITypeSymbol variableType, LocalDeclarationStatementSyntax localVariable) { var arrayCreationExpressionSyntax = initializerExpression as ArrayCreationExpressionSyntax; if (arrayCreationExpressionSyntax != null) { if (arrayCreationExpressionSyntax.Type.IsMissing) { return(false); } var arrayType = nodeContext.SemanticModel.GetTypeInfo(arrayCreationExpressionSyntax).ConvertedType; return(arrayType != null && arrayCreationExpressionSyntax.Initializer != null && variableType.Equals(arrayType)); } return(false); }
public override BoundNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { return(new BoundLocalDeclarationStatement(node, (BoundVariableDeclarationStatement)VisitVariableDeclaration(node.Declaration))); }
/// <summary> /// Unwrap /// </summary> /// <param name="declaration"></param> /// <param name="state"></param> /// <returns></returns> private VariableState VisitLocalDeclaration(LocalDeclarationStatementSyntax declaration, ExecutionState state) { return(VisitVariableDeclaration(declaration.Declaration, state)); }
public static async Task ComputeRefactoringAsync(RefactoringContext context, ConditionalExpressionSyntax conditionalExpression) { ExpressionSyntax expression = conditionalExpression.WalkUpParentheses(); SyntaxNode parent = expression.Parent; if (parent.IsKind(SyntaxKind.ReturnStatement, SyntaxKind.YieldReturnStatement)) { var statement = (StatementSyntax)parent; RegisterRefactoring(context, conditionalExpression, statement); if (IsRecursive()) { RegisterRefactoring(context, conditionalExpression, statement, recursive: true); } } else if (parent is AssignmentExpressionSyntax assignment) { if (assignment.Parent is ExpressionStatementSyntax expressionStatement) { RegisterRefactoring(context, conditionalExpression, expressionStatement); if (IsRecursive()) { RegisterRefactoring(context, conditionalExpression, expressionStatement, recursive: true); } } } else { SingleLocalDeclarationStatementInfo localDeclarationInfo = SyntaxInfo.SingleLocalDeclarationStatementInfo(expression); if (localDeclarationInfo.Success) { TypeSyntax type = localDeclarationInfo.Type; SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!type.IsVar || semanticModel.GetTypeSymbol(type, context.CancellationToken)?.SupportsExplicitDeclaration() == true) { LocalDeclarationStatementSyntax statement = localDeclarationInfo.Statement; RegisterRefactoring(context, conditionalExpression, statement, semanticModel); if (IsRecursive()) { RegisterRefactoring(context, conditionalExpression, statement, semanticModel, recursive: true); } } } } bool IsRecursive() { return(conditionalExpression .WhenFalse .WalkDownParentheses() .IsKind(SyntaxKind.ConditionalExpression)); } }
public virtual string GetOrDeclareComponentArray(RoslynEcsTranslator.IterationContext ctx, string componentTypeName, out LocalDeclarationStatementSyntax arrayInitialization, out StatementSyntax arrayDisposal) { return(Parent.GetOrDeclareComponentArray(ctx, componentTypeName, out arrayInitialization, out arrayDisposal)); }
private LocalDeclarationStatementInfo(LocalDeclarationStatementSyntax statement) { Statement = statement; }
private Document RewriteExpressionBodiedMemberAndIntroduceLocalDeclaration( SemanticDocument document, ArrowExpressionClauseSyntax arrowExpression, ExpressionSyntax expression, NameSyntax newLocalName, LocalDeclarationStatementSyntax declarationStatement, bool allOccurrences, CancellationToken cancellationToken) { var oldBody = arrowExpression; var oldParentingNode = oldBody.Parent; var leadingTrivia = oldBody.GetLeadingTrivia() .AddRange(oldBody.ArrowToken.TrailingTrivia); var newStatement = Rewrite(document, expression, newLocalName, document, oldBody.Expression, allOccurrences, cancellationToken); var newBody = SyntaxFactory.Block(declarationStatement, SyntaxFactory.ReturnStatement(newStatement)) .WithLeadingTrivia(leadingTrivia) .WithTrailingTrivia(oldBody.GetTrailingTrivia()) .WithAdditionalAnnotations(Formatter.Annotation); SyntaxNode newParentingNode = null; if (oldParentingNode is BasePropertyDeclarationSyntax baseProperty) { var getAccessor = SyntaxFactory.AccessorDeclaration(SyntaxKind.GetAccessorDeclaration, newBody); var accessorList = SyntaxFactory.AccessorList(SyntaxFactory.List(new[] { getAccessor })); newParentingNode = baseProperty.RemoveNode(oldBody, SyntaxRemoveOptions.KeepNoTrivia); if (newParentingNode.IsKind(SyntaxKind.PropertyDeclaration)) { var propertyDeclaration = ((PropertyDeclarationSyntax)newParentingNode); newParentingNode = propertyDeclaration .WithAccessorList(accessorList) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) .WithTrailingTrivia(propertyDeclaration.SemicolonToken.TrailingTrivia); } else if (newParentingNode.IsKind(SyntaxKind.IndexerDeclaration)) { var indexerDeclaration = ((IndexerDeclarationSyntax)newParentingNode); newParentingNode = indexerDeclaration .WithAccessorList(accessorList) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) .WithTrailingTrivia(indexerDeclaration.SemicolonToken.TrailingTrivia); } } else if (oldParentingNode is BaseMethodDeclarationSyntax baseMethod) { newParentingNode = baseMethod.RemoveNode(oldBody, SyntaxRemoveOptions.KeepNoTrivia) .WithBody(newBody); if (newParentingNode.IsKind(SyntaxKind.MethodDeclaration)) { var methodDeclaration = ((MethodDeclarationSyntax)newParentingNode); newParentingNode = methodDeclaration .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) .WithTrailingTrivia(methodDeclaration.SemicolonToken.TrailingTrivia); } else if (newParentingNode.IsKind(SyntaxKind.OperatorDeclaration)) { var operatorDeclaration = ((OperatorDeclarationSyntax)newParentingNode); newParentingNode = operatorDeclaration .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) .WithTrailingTrivia(operatorDeclaration.SemicolonToken.TrailingTrivia); } else if (newParentingNode.IsKind(SyntaxKind.ConversionOperatorDeclaration)) { var conversionOperatorDeclaration = ((ConversionOperatorDeclarationSyntax)newParentingNode); newParentingNode = conversionOperatorDeclaration .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.None)) .WithTrailingTrivia(conversionOperatorDeclaration.SemicolonToken.TrailingTrivia); } } var newRoot = document.Root.ReplaceNode(oldParentingNode, newParentingNode); return(document.Document.WithSyntaxRoot(newRoot)); }
private static ImmutableArray <IfRefactoring> Analyze( LocalDeclarationStatementSyntax localDeclarationStatement, IfStatementSyntax ifStatement, IfAnalysisOptions options) { VariableDeclaratorSyntax declarator = localDeclarationStatement .Declaration? .Variables .SingleOrDefault(shouldthrow: false); if (declarator == null) { return(Empty); } ElseClauseSyntax elseClause = ifStatement.Else; if (elseClause?.Statement?.IsKind(SyntaxKind.IfStatement) != false) { return(Empty); } SimpleAssignmentStatementInfo assignment1 = SyntaxInfo.SimpleAssignmentStatementInfo(ifStatement.GetSingleStatementOrDefault()); if (!assignment1.Success) { return(Empty); } SimpleAssignmentStatementInfo assignment2 = SyntaxInfo.SimpleAssignmentStatementInfo(elseClause.GetSingleStatementOrDefault()); if (!assignment2.Success) { return(Empty); } if (!assignment1.Left.IsKind(SyntaxKind.IdentifierName)) { return(Empty); } if (!assignment2.Left.IsKind(SyntaxKind.IdentifierName)) { return(Empty); } string identifier1 = ((IdentifierNameSyntax)assignment1.Left).Identifier.ValueText; string identifier2 = ((IdentifierNameSyntax)assignment2.Left).Identifier.ValueText; if (!string.Equals(identifier1, identifier2, StringComparison.Ordinal)) { return(Empty); } if (!string.Equals(identifier1, declarator.Identifier.ValueText, StringComparison.Ordinal)) { return(Empty); } if (!options.CheckSpanDirectives(ifStatement.Parent, TextSpan.FromBounds(localDeclarationStatement.SpanStart, ifStatement.Span.End))) { return(Empty); } return(new LocalDeclarationAndIfElseAssignmentWithConditionalExpression(localDeclarationStatement, ifStatement, assignment1.Right, assignment2.Right).ToImmutableArray()); }
private async Task <Document> IntroduceLocalDeclarationIntoBlockAsync( SemanticDocument document, BlockSyntax block, ExpressionSyntax expression, NameSyntax newLocalName, LocalDeclarationStatementSyntax declarationStatement, bool allOccurrences, CancellationToken cancellationToken) { declarationStatement = declarationStatement.WithAdditionalAnnotations(Formatter.Annotation); SyntaxNode scope = block; // If we're within a non-static local function, our scope for the new local declaration is expanded to include the enclosing member. var localFunction = block.GetAncestor <LocalFunctionStatementSyntax>(); if (localFunction != null && !localFunction.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.StaticKeyword))) { scope = block.GetAncestor <MemberDeclarationSyntax>(); } var matches = FindMatches(document, expression, document, scope, allOccurrences, cancellationToken); Debug.Assert(matches.Contains(expression)); (document, matches) = await ComplexifyParentingStatementsAsync(document, matches, cancellationToken).ConfigureAwait(false); // Our original expression should have been one of the matches, which were tracked as part // of complexification, so we can retrieve the latest version of the expression here. expression = document.Root.GetCurrentNode(expression); var root = document.Root; ISet <StatementSyntax> allAffectedStatements = new HashSet <StatementSyntax>(matches.SelectMany(expr => GetApplicableStatementAncestors(expr))); SyntaxNode innermostCommonBlock; var innermostStatements = new HashSet <StatementSyntax>(matches.Select(expr => GetApplicableStatementAncestors(expr).First())); if (innermostStatements.Count == 1) { // if there was only one match, or all the matches came from the same statement var statement = innermostStatements.Single(); // and the statement is an embedded statement without a block, we want to generate one // around this statement rather than continue going up to find an actual block if (!IsBlockLike(statement.Parent)) { root = root.TrackNodes(allAffectedStatements.Concat(new SyntaxNode[] { expression, statement })); root = root.ReplaceNode(root.GetCurrentNode(statement), SyntaxFactory.Block(root.GetCurrentNode(statement)).WithAdditionalAnnotations(Formatter.Annotation)); expression = root.GetCurrentNode(expression); allAffectedStatements = allAffectedStatements.Select(root.GetCurrentNode).ToSet(); statement = root.GetCurrentNode(statement); } innermostCommonBlock = statement.Parent; } else { innermostCommonBlock = innermostStatements.FindInnermostCommonNode(IsBlockLike); } var firstStatementAffectedIndex = GetFirstStatementAffectedIndex(innermostCommonBlock, matches, GetStatements(innermostCommonBlock).IndexOf(allAffectedStatements.Contains)); var newInnerMostBlock = Rewrite( document, expression, newLocalName, document, innermostCommonBlock, allOccurrences, cancellationToken); var statements = InsertWithinTriviaOfNext(GetStatements(newInnerMostBlock), declarationStatement, firstStatementAffectedIndex); var finalInnerMostBlock = WithStatements(newInnerMostBlock, statements); var newRoot = root.ReplaceNode(innermostCommonBlock, finalInnerMostBlock); return(document.Document.WithSyntaxRoot(newRoot)); }
public static SyntaxToken UsingKeyword(this LocalDeclarationStatementSyntax syntax) { return(UsingKeywordAccessor(syntax)); }
public override void VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node) { base.VisitLocalDeclarationStatement(node); }
public static LocalDeclarationStatementSyntax WithAwaitKeyword(this LocalDeclarationStatementSyntax syntax, SyntaxToken awaitKeyword) { return(WithAwaitKeywordAccessor(syntax, awaitKeyword)); }
protected IEnumerable <StatementSyntax> GenerateConditionalAllocationSyntax( TypePositionInfo info, StubCodeContext context, int stackallocMaxSize) { (_, string nativeIdentifier) = context.GetIdentifiers(info); string allocationMarkerIdentifier = GetAllocationMarkerIdentifier(info, context); string byteLenIdentifier = GetByteLengthIdentifier(info, context); string stackAllocPtrIdentifier = GetStackAllocIdentifier(info, context); // <native> = <allocationExpression>; ExpressionStatementSyntax allocationStatement = ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(nativeIdentifier), GenerateAllocationExpression(info, context, Identifier(byteLenIdentifier), out bool allocationRequiresByteLength))); // int <byteLenIdentifier> = <byteLengthExpression>; LocalDeclarationStatementSyntax byteLenAssignment = LocalDeclarationStatement( VariableDeclaration( PredefinedType(Token(SyntaxKind.IntKeyword)), SingletonSeparatedList( VariableDeclarator(byteLenIdentifier) .WithInitializer(EqualsValueClause( GenerateByteLengthCalculationExpression(info, context)))))); if (!UsesConditionalStackAlloc(info, context)) { List <StatementSyntax> statements = new List <StatementSyntax>(); if (allocationRequiresByteLength) { statements.Add(byteLenAssignment); } statements.Add(allocationStatement); yield return(ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, IdentifierName(nativeIdentifier), LiteralExpression(SyntaxKind.NullLiteralExpression)))); yield return(IfStatement( GenerateNullCheckExpression(info, context), Block(statements))); yield break; } // Code block for stackalloc if number of bytes is below threshold size BlockSyntax marshalOnStack = Block( // byte* <stackAllocPtr> = stackalloc byte[<byteLen>]; LocalDeclarationStatement( VariableDeclaration( PointerType(PredefinedType(Token(SyntaxKind.ByteKeyword))), SingletonSeparatedList( VariableDeclarator(stackAllocPtrIdentifier) .WithInitializer(EqualsValueClause( StackAllocArrayCreationExpression( ArrayType( PredefinedType(Token(SyntaxKind.ByteKeyword)), SingletonList( ArrayRankSpecifier(SingletonSeparatedList <ExpressionSyntax>( IdentifierName(byteLenIdentifier))))))))))), GenerateStackallocOnlyValueMarshalling(info, context, Identifier(byteLenIdentifier), Identifier(stackAllocPtrIdentifier)), // <nativeIdentifier> = <stackAllocPtr>; ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(nativeIdentifier), CastExpression( AsNativeType(info), IdentifierName(stackAllocPtrIdentifier))))); // if (<byteLen> > <StackAllocBytesThreshold>) // { // <allocationStatement>; // <allocationMarker> = true; // } // else // { // byte* <stackAllocPtr> = stackalloc byte[<byteLen>]; // <marshalValueOnStackStatement>; // <native> = (<nativeType>)<stackAllocPtr>; // } IfStatementSyntax allocBlock = IfStatement( BinaryExpression( SyntaxKind.GreaterThanExpression, IdentifierName(byteLenIdentifier), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(stackallocMaxSize))), Block( allocationStatement, ExpressionStatement( AssignmentExpression( SyntaxKind.SimpleAssignmentExpression, IdentifierName(allocationMarkerIdentifier), LiteralExpression(SyntaxKind.TrueLiteralExpression)))), ElseClause(marshalOnStack)); yield return(IfStatement( GenerateNullCheckExpression(info, context), Block(byteLenAssignment, allocBlock))); }
public static LocalDeclarationStatementSyntax WithUsingKeyword(this LocalDeclarationStatementSyntax syntax, SyntaxToken usingKeyword) { return(WithUsingKeywordAccessor(syntax, usingKeyword)); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseCoalesceExpression) && !Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); if (!TryFindNode(root, context.Span, out ExpressionSyntax expression)) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.CannotImplicitlyConvertTypeExplicitConversionExists: { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); TypeInfo typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken); ITypeSymbol type = typeInfo.Type; ITypeSymbol convertedType = typeInfo.ConvertedType; if (type?.IsNamedType() == true) { var namedType = (INamedTypeSymbol)type; if (namedType.ConstructedFrom.SpecialType == SpecialType.System_Nullable_T) { if (convertedType?.IsBoolean() == true || AddComparisonWithBooleanLiteralRefactoring.IsCondition(expression)) { if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddComparisonWithBooleanLiteral)) { CodeAction codeAction = CodeAction.Create( AddComparisonWithBooleanLiteralRefactoring.GetTitle(expression), cancellationToken => AddComparisonWithBooleanLiteralRefactoring.RefactorAsync(context.Document, expression, cancellationToken), GetEquivalenceKey(diagnostic, CodeFixIdentifiers.AddComparisonWithBooleanLiteral)); context.RegisterCodeFix(codeAction, diagnostic); } } else if (namedType.TypeArguments[0].Equals(convertedType)) { if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseCoalesceExpression)) { CodeAction codeAction = CodeAction.Create( "Use coalesce expression", cancellationToken => { ExpressionSyntax defaultValue = convertedType.ToDefaultValueSyntax(semanticModel, expression.SpanStart); ExpressionSyntax newNode = CoalesceExpression(expression.WithoutTrivia(), defaultValue) .WithTriviaFrom(expression) .Parenthesize() .WithFormatterAnnotation(); return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic, CodeFixIdentifiers.UseCoalesceExpression)); context.RegisterCodeFix(codeAction, diagnostic); } } } } if (Settings.IsCodeFixEnabled(CodeFixIdentifiers.CreateSingletonArray) && type?.IsErrorType() == false && !type.Equals(convertedType) && convertedType.IsArrayType()) { var arrayType = (IArrayTypeSymbol)convertedType; if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType)) { CodeAction codeAction = CodeAction.Create( "Create singleton array", cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken), GetEquivalenceKey(diagnostic, CodeFixIdentifiers.CreateSingletonArray)); context.RegisterCodeFix(codeAction, diagnostic); } } break; } case CompilerDiagnosticIdentifiers.ConstantValueCannotBeConverted: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.UseUncheckedExpression)) { break; } CodeAction codeAction = CodeAction.Create( "Use 'unchecked'", cancellationToken => { CheckedExpressionSyntax newNode = CSharpFactory.UncheckedExpression(expression.WithoutTrivia()); newNode = newNode.WithTriviaFrom(expression); return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.ExpressionBeingAssignedMustBeConstant: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConstModifier)) { break; } LocalDeclarationStatementSyntax localDeclarationStatement = GetLocalDeclarationStatement(expression); if (localDeclarationStatement == null) { break; } SyntaxTokenList modifiers = localDeclarationStatement.Modifiers; if (!modifiers.Contains(SyntaxKind.ConstKeyword)) { break; } ModifiersCodeFixes.RemoveModifier(context, diagnostic, localDeclarationStatement, SyntaxKind.ConstKeyword); break; } case CompilerDiagnosticIdentifiers.CannotConvertNullToTypeBecauseItIsNonNullableValueType: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.ReplaceNullLiteralExpressionWithDefaultValue)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeInfo(expression, context.CancellationToken).ConvertedType; if (typeSymbol?.SupportsExplicitDeclaration() == true) { CodeAction codeAction = CodeAction.Create( "Replace 'null' with default value", cancellationToken => { ExpressionSyntax newNode = typeSymbol.ToDefaultValueSyntax(semanticModel, expression.SpanStart); return(context.Document.ReplaceNodeAsync(expression, newNode, cancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); } break; } case CompilerDiagnosticIdentifiers.ResultOfExpressionIsAlwaysConstantSinceValueIsNeverEqualToNull: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveConditionThatIsAlwaysEqualToTrueOrFalse)) { break; } SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); if (!NullCheckExpression.TryCreate(expression, semanticModel, out NullCheckExpression nullCheck, context.CancellationToken)) { break; } if (nullCheck.Kind != NullCheckKind.EqualsToNull && nullCheck.Kind != NullCheckKind.NotEqualsToNull) { break; } CodeAction codeAction = CodeAction.Create( "Remove condition", cancellationToken => { SyntaxNode newRoot = RemoveHelper.RemoveCondition(root, expression, nullCheck.Kind == NullCheckKind.NotEqualsToNull); return(Task.FromResult(context.Document.WithSyntaxRoot(newRoot))); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } }
protected StatementSyntax GenerateByValueOutUnmarshalStatement(TypePositionInfo info, StubCodeContext context) { // Use ManagedSource and NativeDestination spans for by-value marshalling since we're just marshalling back the contents, // not the array itself. // This code is ugly since we're now enforcing readonly safety with ReadOnlySpan for all other scenarios, // but this is an uncommon case so we don't want to design the API around enabling just it. string numElementsIdentifier = MarshallerHelpers.GetNumElementsIdentifier(info, context); string managedSpanIdentifier = MarshallerHelpers.GetManagedSpanIdentifier(info, context); // Span<TElement> <managedSpan> = MemoryMarshal.CreateSpan(ref Unsafe.AsRef(in <GetManagedValuesSource>.GetPinnableReference(), <numElements>)); LocalDeclarationStatementSyntax managedValuesDeclaration = LocalDeclarationStatement(VariableDeclaration( GenericName( Identifier(TypeNames.System_Span), TypeArgumentList( SingletonSeparatedList(_elementInfo.ManagedType.Syntax)) ), SingletonSeparatedList(VariableDeclarator(managedSpanIdentifier).WithInitializer(EqualsValueClause( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, ParseName(TypeNames.System_Runtime_InteropServices_MemoryMarshal), IdentifierName("CreateSpan"))) .WithArgumentList( ArgumentList( SeparatedList( new[] { Argument( InvocationExpression( MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, ParseName(TypeNames.System_Runtime_CompilerServices_Unsafe), IdentifierName("AsRef")), ArgumentList(SingletonSeparatedList( Argument( InvocationExpression( MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, GetManagedValuesSource(info, context), IdentifierName("GetPinnableReference")), ArgumentList())) .WithRefKindKeyword( Token(SyntaxKind.InKeyword)))))) .WithRefKindKeyword( Token(SyntaxKind.RefKeyword)), Argument( IdentifierName(numElementsIdentifier)) })))))))); // Span<TUnmanagedElement> <nativeSpan> = <GetUnmanagedValuesDestination> string nativeSpanIdentifier = MarshallerHelpers.GetNativeSpanIdentifier(info, context); LocalDeclarationStatementSyntax unmanagedValuesDeclaration = LocalDeclarationStatement(VariableDeclaration( GenericName( Identifier(TypeNames.System_Span), TypeArgumentList(SingletonSeparatedList(_unmanagedElementType))), SingletonSeparatedList( VariableDeclarator( Identifier(nativeSpanIdentifier)) .WithInitializer(EqualsValueClause( GetUnmanagedValuesDestination(info, context)))))); return(Block( managedValuesDeclaration, unmanagedValuesDeclaration, GenerateContentsMarshallingStatement( info, context, IdentifierName(numElementsIdentifier), StubCodeContext.Stage.UnmarshalCapture, StubCodeContext.Stage.Unmarshal))); }
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.Parenthesize(), 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.IsKind(SyntaxKind.IdentifierName) && SymbolEqualityComparer.Default.Equals(localSymbol, 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() }; if (forEachStatement.IsEmbedded()) { BlockSyntax block = Block(newStatements).WithFormatterAnnotation(); return(await document.ReplaceNodeAsync(forEachStatement, block, cancellationToken).ConfigureAwait(false)); } return(await document.ReplaceNodeAsync(forEachStatement, newStatements, cancellationToken).ConfigureAwait(false)); } }
/// <summary> /// Creates a new <see cref="Syntax.ModifierListInfo"/> from the specified local declaration statement. /// </summary> /// <param name="localDeclarationStatement"></param> /// <returns></returns> public static ModifierListInfo ModifierListInfo(LocalDeclarationStatementSyntax localDeclarationStatement) { return(Syntax.ModifierListInfo.Create(localDeclarationStatement)); }
/// <summary> /// Creates a new <see cref="Syntax.SingleLocalDeclarationStatementInfo"/> from the specified local declaration statement. /// </summary> /// <param name="localDeclarationStatement"></param> /// <param name="allowMissing"></param> /// <returns></returns> public static SingleLocalDeclarationStatementInfo SingleLocalDeclarationStatementInfo( LocalDeclarationStatementSyntax localDeclarationStatement, bool allowMissing = false) { return(Syntax.SingleLocalDeclarationStatementInfo.Create(localDeclarationStatement, allowMissing)); }
protected abstract void CompileLocalDeclarationStatement(LocalDeclarationStatementSyntax statement);