示例#1
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            // loop uses iterator once?
            var declaredSymbol = model.GetDeclaredSymbol(forLoop);
            var singleRead = forLoop.Statement.DescendantNodes()
                             .OfType<SimpleNameSyntax>()
                             .Where(e => model.GetSymbolInfo(e).Symbol == declaredSymbol)
                             .SingleOrDefaultAllowMany();
            if (singleRead == null) yield break;

            // safe iterator projection?
            var guaranteedProjectionPerIteration = forLoop.Statement.CompleteExecutionGuaranteesChildExecutedExactlyOnce(singleRead);
            var projection = singleRead.AncestorsAndSelf()
                             .TakeWhile(e => !(e is StatementSyntax))
                             .OfType<ExpressionSyntax>()
                             .TakeWhile(e => model.GetTypeInfo(e).Type.SpecialType != SpecialType.System_Void)
                             .TakeWhile(e => guaranteedProjectionPerIteration == true || e.HasSideEffects(model, assume) == false)
                             .LastOrDefault();
            if (projection == null) yield break;
            if (projection.TryEvalAlternativeComparison(singleRead, model, assume) == true) yield break;

            // build replacement loop
            var projectedCollection = forLoop.Expression
                                      .Accessing("Select")
                                      .Invoking(forLoop.Identifier.Lambdad(projection).Args1());
            var newBody = forLoop.Statement.ReplaceNode(projection, singleRead);
            var replacedLoop = forLoop.WithExpression(projectedCollection).WithStatement(newBody);

            // expose as code action/issue
            yield return new ReplaceAction(
                "Project collection",
                forLoop,
                replacedLoop);
        }
示例#2
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            var body = forLoop.Statement.Statements();
            if (body.None()) yield break;

            var unconditionalStatements = body.Skip(1);
            var conditionalStatement = body.First() as IfStatementSyntax;
            if (conditionalStatement == null) yield break;

            var trueBranch = conditionalStatement.Statement.Statements().AppendUnlessJumps(unconditionalStatements).Block();
            var falseBranch = conditionalStatement.ElseStatementOrEmptyBlock().Statements().AppendUnlessJumps(unconditionalStatements).Block();

            var falseIsEmpty = falseBranch.HasSideEffects(model, assume) == false;
            var trueIsEmpty = trueBranch.HasSideEffects(model, assume) == false;
            if (falseIsEmpty == trueIsEmpty) yield break;

            var condition = falseIsEmpty ? conditionalStatement.Condition : conditionalStatement.Condition.Inverted();
            var conditionalActions = falseIsEmpty ? trueBranch : falseBranch;

            var query = forLoop.Expression.Accessing("Where").Invoking(forLoop.Identifier.Lambdad(condition).Args1());

            var forWhereDo = forLoop.WithExpression(query).WithStatement(conditionalActions);

            yield return new ReplaceAction(
                "Filter collection",
                forLoop,
                forWhereDo);
        }
示例#3
0
        public override void VisitForEachStatement(ForEachStatementSyntax node)
        {
            var variable = node.Identifier.GetText();
            var coll = EmitExpression(node.Expression);
            _writer.WriteLine("    for(var {0} in {1}) {{", variable, coll);

            base.VisitForEachStatement(node);

            _writer.WriteLine("    }");
        }
示例#4
0
        protected override SyntaxNode VisitForEachStatement(ForEachStatementSyntax node)
        {
            if (!node.DescendentNodes().OfType<BlockSyntax>().Any())
            {
                node = node.Update (node.ForEachKeyword, node.OpenParenToken, node.Type,
                                    node.Identifier, node.InKeyword, node.Expression, node.CloseParenToken,
                                    Syntax.Block (statements: node.Statement));
            }

            return base.VisitForEachStatement (node);
        }
示例#5
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax loop, ISemanticModel model, Assumptions assume, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (loop.Type.IsVar) yield break;
            var declaredType = model.GetTypeInfo(loop.Type).Type as ITypeSymbol;
            var collectionType = model.GetTypeInfo(loop.Expression).Type as ITypeSymbol;
            if (declaredType == null || collectionType == null) yield break;
            var allInterfaces = new List<INamedTypeSymbol>();
            allInterfaces.AddRange(collectionType.AllInterfaces);
            if (collectionType is INamedTypeSymbol) allInterfaces.Add((INamedTypeSymbol)collectionType);
            var enumerableTypes = allInterfaces
                                  .Where(e => e.OriginalDefinition.SpecialType == SpecialType.System_Collections_Generic_IEnumerable_T)
                                  .ToArray();
            if (enumerableTypes.Count() != 1) yield break;
            var itemType = enumerableTypes.Single().TypeArguments.Single();

            if (!declaredType.Equals(itemType)) yield break;
            yield return new ReplaceAction("Use 'var'", loop.Type, Syntax.IdentifierName("var"));
        }
示例#6
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assumptions, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (forLoop.IsAnyIterationSufficient(model, assumptions) == true)
                yield break; // a more appropriate code issue handles this case

            // can the loop be replaced by its first or last iteration?
            var isFirstSufficient = forLoop.IsFirstIterationSufficient(model, assumptions) == true;
            var isLastSufficient = forLoop.IsLastIterationSufficient(model, assumptions) == true;
            var firstVsLast = isFirstSufficient ? "First"
                            : isLastSufficient ? "Last"
                            : null;
            if (firstVsLast == null) yield break;

            // do we know how to translate?
            var loopStatements = forLoop.Statement.Statements();
            var rawThenStatements = loopStatements.SkipLast(loopStatements.Last().IsIntraLoopJump() ? 1 : 0).ToArray();
            if (rawThenStatements.Any(e => e.HasTopLevelIntraLoopJumps())) yield break; // don't know how to translate jumps that aren't at the end

            // wrap collection items in a type with a new null value (so that a null result definitively indicates an empty collection)
            var iteratorType = ((LocalSymbol)model.GetDeclaredSymbol(forLoop)).Type;
            var nuller = GetNullabledQueryAndValueGetter(iteratorType, forLoop.Identifier, forLoop.Expression);
            var nullableQuery = nuller.Item1;
            var valueGetter = nuller.Item2;
            var tempNullableLocalName = Syntax.Identifier("_" + forLoop.Identifier.ValueText);
            var tempNullableLocalGet = Syntax.IdentifierName(tempNullableLocalName);

            // build replacement
            var iteratorReads = forLoop.Statement.ReadsOfLocalVariable(forLoop.Identifier).ToArray();
            var desiredIterationQuery = nullableQuery.Accessing(firstVsLast + "OrDefault").Invoking();
            var condition = tempNullableLocalGet.BOpNotEquals(Syntax.LiteralExpression(SyntaxKind.NullLiteralExpression));
            var useDenulledLocal = iteratorReads.Length > 2;
            var thenStatement = useDenulledLocal
                              ? rawThenStatements.Prepend(forLoop.Identifier.VarInit(valueGetter(tempNullableLocalGet))).Block()
                              : rawThenStatements.Select(e => e.ReplaceNodes(iteratorReads, (n, a) => valueGetter(tempNullableLocalGet))).Block();
            var replacementStatements = new StatementSyntax[] {
                tempNullableLocalName.VarInit(desiredIterationQuery),
                condition.IfThen(thenStatement)
            };

            // expose as code action/issue
            yield return forLoop.MakeReplaceStatementWithManyAction(
                replacementStatements,
                "Execute " + firstVsLast + " if any");
        }
示例#7
0
        public static IEnumerable<ReplaceAction> GetSimplifications(ForEachStatementSyntax forLoop, ISemanticModel model, Assumptions assumptions, CancellationToken cancellationToken = default(CancellationToken))
        {
            // loop body idempotent and independent of the iterator?
            if (forLoop.IsAnyIterationSufficient(model, assumptions) != true) yield break;

            // build replacement if statement, if possible
            var loopStatements = forLoop.Statement.Statements();
            if (loopStatements.None()) yield break;
            var ifBody = loopStatements.SkipLast(loopStatements.Last().IsIntraLoopJump() ? 1 : 0).Block();
            if (ifBody.HasTopLevelIntraLoopJumps()) yield break;
            var ifCondition = forLoop.Expression.Accessing("Any").Invoking();
            var rawReplacement = Syntax.IfStatement(
                condition: ifCondition,
                statement: ifBody);
            var replacement = rawReplacement.IncludingTriviaSurrounding(forLoop, TrivialTransforms.Placement.Around);

            // expose as code action/issue
            yield return new ReplaceAction(
                "Execute once if any",
                forLoop,
                replacement);
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, ForEachStatementSyntax forEachStatement)
        {
            if (context.SupportsSemanticModel)
            {
                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ChangeTypeAccordingToExpression))
                {
                    await ChangeTypeAccordingToExpressionAsync(context, forEachStatement).ConfigureAwait(false);
                }

                if (context.IsAnyRefactoringEnabled(
                        RefactoringIdentifiers.ChangeExplicitTypeToVar,
                        RefactoringIdentifiers.ChangeVarToExplicitType))
                {
                    await ChangeTypeAsync(context, forEachStatement).ConfigureAwait(false);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenameIdentifierAccordingToTypeName))
                {
                    await RenameIdentifierAccordingToTypeNameAsync(context, forEachStatement).ConfigureAwait(false);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceForEachWithFor) &&
                    context.Span.IsEmpty &&
                    ReplaceForEachWithForRefactoring.CanRefactor(forEachStatement, await context.GetSemanticModelAsync().ConfigureAwait(false), context.CancellationToken))
                {
                    context.RegisterRefactoring(
                        "Replace foreach with for",
                        cancellationToken => ReplaceForEachWithForRefactoring.RefactorAsync(context.Document, forEachStatement, cancellationToken));
                }
            }
        }
示例#9
0
 public void Flatten(ForEachStatementSyntax node, List<FlatStatement> instructions)
 {
     throw new NotImplementedException("foreach");
 }
示例#10
0
 public void Flatten(ForEachStatementSyntax node, List<FlatStatement> instructions)
 {
     // foreach is unrolled by a rewriter. we should never get this.
     throw new NotImplementedException("foreach");
 }
示例#11
0
 private ForEachVariableStatementSyntax CreateForEachVariableStatement(INamedTypeSymbol tupleType, ForEachStatementSyntax forEachStatement)
 {
     // Copy all the tokens/nodes from the existing foreach statement to the new foreach statement.
     // However, convert the existing declaration over to a "var (x, y)" declaration or (int x, int y)
     // tuple expression.
     return(SyntaxFactory.ForEachVariableStatement(
                forEachStatement.AttributeLists,
                forEachStatement.AwaitKeyword,
                forEachStatement.ForEachKeyword,
                forEachStatement.OpenParenToken,
                CreateTupleOrDeclarationExpression(tupleType, forEachStatement.Type),
                forEachStatement.InKeyword,
                forEachStatement.Expression,
                forEachStatement.CloseParenToken,
                forEachStatement.Statement));
 }
示例#12
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, ForEachStatementSyntax forEachStatement)
        {
            if (context.IsAnyRefactoringEnabled(
                    RefactoringIdentifiers.ChangeExplicitTypeToVar,
                    RefactoringIdentifiers.ChangeVarToExplicitType))
            {
                await ChangeTypeAsync(context, forEachStatement).ConfigureAwait(false);
            }

            if (context.IsRefactoringEnabled(RefactoringIdentifiers.RenameIdentifierAccordingToTypeName))
            {
                await RenameIdentifierAccordingToTypeNameAsync(context, forEachStatement).ConfigureAwait(false);
            }

            if (context.IsAnyRefactoringEnabled(RefactoringIdentifiers.ReplaceForEachWithFor, RefactoringIdentifiers.ReplaceForEachWithForAndReverseLoop) &&
                context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(forEachStatement))
            {
                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(forEachStatement.Expression, context.CancellationToken);

                if (SymbolUtility.HasAccessibleIndexer(typeSymbol, semanticModel, forEachStatement.SpanStart))
                {
                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceForEachWithFor))
                    {
                        context.RegisterRefactoring(
                            "Replace foreach with for",
                            cancellationToken => ReplaceForEachWithForRefactoring.RefactorAsync(context.Document, forEachStatement, semanticModel: semanticModel, reverseLoop: false, cancellationToken: cancellationToken),
                            RefactoringIdentifiers.ReplaceForEachWithFor);
                    }

                    if (context.IsRefactoringEnabled(RefactoringIdentifiers.ReplaceForEachWithForAndReverseLoop))
                    {
                        context.RegisterRefactoring(
                            "Replace foreach with for and reverse loop",
                            cancellationToken => ReplaceForEachWithForRefactoring.RefactorAsync(context.Document, forEachStatement, semanticModel: semanticModel, reverseLoop: true, cancellationToken: cancellationToken),
                            RefactoringIdentifiers.ReplaceForEachWithForAndReverseLoop);
                    }
                }
            }
        }
示例#13
0
        public override SyntaxNode VisitForEachStatement(ForEachStatementSyntax node)
        {
            /*
            {
            var s__iter = scripts.GetEnumerator();
            using(s__iter as IDisposable)
            {
            if(s__iter.MoveNext())
            {
            do
            {
                Script s = (Script)s__iter.Current;
                // do stuff
            }
            while(s__iter.MoveNext());
            }
            }
            }
             */
            string itername = node.Identifier.ToString() + "__iter";

            return base.Visit
            (
                Syntax.Block
                (
                    Syntax.LocalDeclarationStatement
                    (
                        Syntax.VariableDeclaration
                        (
                            Syntax.IdentifierName
                            (
                                "var"
                            ),
                            Syntax.SeparatedList<VariableDeclaratorSyntax>
                            (
                                Syntax.VariableDeclarator
                                (
                                    Syntax.Identifier(itername),
                                    null,
                                    Syntax.EqualsValueClause
                                    (
                                        Syntax.Token(SyntaxKind.EqualsToken),
                                        Syntax.InvocationExpression
                                        (
                                            Syntax.MemberAccessExpression
                                            (
                                                SyntaxKind.MemberAccessExpression,
                                                node.Expression,
                                                Syntax.IdentifierName("GetEnumerator")
                                            )
                                        )
                                    )
                                )
                            )
                        )
                    ),
                    Syntax.UsingStatement
                    (
                        null,
                        Syntax.CastExpression
                        (
                            Syntax.ParseTypeName("System.IDisposable"),
                            Syntax.IdentifierName(itername)
                        ),
                        Syntax.Block
                        (
                            Syntax.IfStatement
                            (
                                Syntax.InvocationExpression
                                (
                                    Syntax.MemberAccessExpression
                                    (
                                        SyntaxKind.MemberAccessExpression,
                                        Syntax.IdentifierName(itername),
                                        Syntax.IdentifierName("MoveNext")
                                    )
                                ),
                                Syntax.Block
                                (
                                    Syntax.DoStatement
                                    (
                                        Syntax.Block
                                        (
                                            Syntax.LocalDeclarationStatement
                                            (
                                                Syntax.VariableDeclaration
                                                (
                                                    node.Type,
                                                    Syntax.SeparatedList<VariableDeclaratorSyntax>
                                                    (
                                                        Syntax.VariableDeclarator
                                                        (
                                                            node.Identifier,
                                                            null,
                                                            Syntax.EqualsValueClause
                                                            (
                                                                Syntax.CastExpression
                                                                (
                                                                    node.Type,
                                                                    Syntax.MemberAccessExpression
                                                                    (
                                                                        SyntaxKind.MemberAccessExpression,
                                                                        Syntax.IdentifierName(itername),
                                                                        Syntax.IdentifierName("Current")
                                                                    )
                                                                )
                                                            )
                                                        )
                                                    )
                                                )
                                            ),
                                            node.Statement
                                        ),
                                        Syntax.InvocationExpression(
                                            Syntax.MemberAccessExpression
                                            (
                                                SyntaxKind.MemberAccessExpression,
                                                Syntax.IdentifierName(itername),
                                                Syntax.IdentifierName("MoveNext")
                                            )
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            ).NormalizeWhitespace();
        }
 internal static void Analyze(SyntaxNodeAnalysisContext context, ForEachStatementSyntax forEachStatement)
 {
     AnalyzeExpression(context, forEachStatement.Expression);
 }
示例#15
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     _expressions.Add(node.Identifier.ValueText);
     AddExpressionTerms(node.Expression, _expressions);
 }
 public override void VisitForEachStatement([NotNull] ForEachStatementSyntax node)
 {
     LoopStatementLocation = node.ForEachKeyword.GetLocation();
 }
示例#17
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="node"></param>
 /// <remarks>
 /// Statements will cause an AST walker to be created, thus we don't need to go further deeper in the
 /// tree by visiting the node.
 /// </remarks>
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     this.VisitStatement(node);
 }
示例#18
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     VisitCommonForEachStatement(node);
 }
示例#19
0
 public sealed override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     _builder.Add(node);
     base.VisitForEachStatement(node);
 }
 public static ForEachStatementSyntax WithAwaitKeyword(this ForEachStatementSyntax syntax, SyntaxToken awaitKeyword)
 {
     return(WithAwaitKeywordAccessor(syntax, awaitKeyword));
 }
 public static SyntaxToken AwaitKeyword(this ForEachStatementSyntax syntax)
 {
     return(AwaitKeywordAccessor(syntax));
 }
        private static bool?EnumeratorTypeMatchesTheVariableType(SyntaxNodeAnalysisContext context, ForEachStatementSyntax forEachStatement)
        {
            var variableType   = context.SemanticModel.GetTypeInfoSafe(forEachStatement.Type, context.CancellationToken).Type;
            var enumerableType =
                context.SemanticModel.GetTypeInfoSafe(forEachStatement.Expression, context.CancellationToken);
            var elementType = GetElementType(context, enumerableType.ConvertedType);

            if (elementType == null)
            {
                return(null);
            }

            return(variableType.IsSameType(elementType));
        }
 public override StatementSyntax VisitForEachStatement([NotNull] ForEachStatementSyntax node)
 {
     return(node.Statement);
 }
示例#24
0
        protected override SyntaxNode VisitForEachStatement(ForEachStatementSyntax node)
        {
            node = node.Update (node.ForEachKeyword, node.OpenParenToken, node.Type,
                                node.Identifier, node.InKeyword, node.Expression, node.CloseParenToken,
                                GetLoopBlock (node.Statement));

            this.loopLevel++;
            var statement = base.VisitForEachStatement ((ForEachStatementSyntax)node.WithAdditionalAnnotations (this.isLoop));
            this.loopLevel--;
            return statement;
        }
        /// <inheritdoc/>
        public override SyntaxNode?VisitForEachStatement(ForEachStatementSyntax node)
        {
            Context.ReportDiagnostic(ForEachStatement, node);

            return(base.VisitForEachStatement(node));
        }
 /// <summary>
 /// Add sequence point |here|:
 /// 
 /// foreach (|Type var| in expr) { }
 /// </summary>
 /// <remarks>
 /// Hit every iteration.
 /// </remarks>
 private void AddForEachIterationVariableSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement iterationVarDecl)
 {
     if (this.generateDebugInfo)
     {
         TextSpan iterationVarDeclSpan = TextSpan.FromBounds(forEachSyntax.Type.Span.Start, forEachSyntax.Identifier.Span.End);
         iterationVarDecl = new BoundSequencePointWithSpan(forEachSyntax, iterationVarDecl, iterationVarDeclSpan);
     }
 }
示例#27
0
        private ForEachStatement TraverseForeachStatement(ForEachStatementSyntax fess, ref int returnCnt, bool nested = false)
        {
            ForEachStatement foreachStm = new ForEachStatement();
            foreachStm.IsNested = nested;
            foreachStm.ConditionCount = 1;
            bool skipId = false;
            int skipIds = 0;
            foreach (SyntaxNode sn in fess.ChildNodes())
            {
                if (sn is BinaryExpressionSyntax)
                {
                    foreachStm.ConditionCount++;
                }
                else if (sn is VariableDeclaratorSyntax)
                {
                    foreachStm.AccessedVars.Add(TraverseVariableSyntax(sn as VariableDeclaratorSyntax, null, null));
                    skipId = true;
                }
                else if (sn is InvocationExpressionSyntax)
                {
                    InvokedMethod invokedMethod = TraverseInvokedMethod(sn as InvocationExpressionSyntax);
                    foreachStm.InvokedMethods.Add(invokedMethod);
                    skipId = true;
                    skipIds = invokedMethod.Parameters.Count;
                }
                else if (sn is IdentifierNameSyntax)
                {
                    if (!skipId)
                    {
                        Variables variable = new Variables();
                        variable.IsReferenced = true;

                        variable.Name = (sn as IdentifierNameSyntax).Identifier.ValueText;
                        foreachStm.AccessedVars.Add(variable);
                    }
                    else if (skipIds == 0)
                    {
                        skipId = false;
                    }
                    else
                    {
                        skipIds--;
                    }
                }

            }

            ForBlockSyntax fbs = fess.Parent as ForBlockSyntax;

            foreach (StatementSyntax ss in fbs.Statements)
            {
                if (ss is AssignmentStatementSyntax)
                {
                    //TODO: need to look at more than just then name!
                    Method tempMethod = TraverseAccessVars(ss as AssignmentStatementSyntax);

                    foreachStm.AccessedVars.AddRange(tempMethod.AccessedVariables);
                    foreachStm.InvokedMethods.AddRange(tempMethod.InvokedMethods);
                }
                else if (ss is LocalDeclarationStatementSyntax)
                {
                    Method tempMethod = TraverseVarDecls(ss as LocalDeclarationStatementSyntax);
                    foreachStm.AccessedVars.AddRange(tempMethod.AccessedVariables);
                    foreachStm.InvokedMethods.AddRange(tempMethod.InvokedMethods);
                }
                else if (ss is SingleLineIfStatementSyntax)
                {
                    Decisions decision = TraverseIfStatement(ss as SingleLineIfStatementSyntax, ref returnCnt, true);
                    foreachStm.Nested.AddRange(decision.IfStatements);
                    foreachStm.Nested.AddRange(decision.ElseStatements);
                }
                else if (ss is MultiLineIfBlockSyntax)
                {
                    Decisions decisions = TraverseMultiIfStatement(ss as MultiLineIfBlockSyntax, ref returnCnt, true);
                    foreachStm.Nested.AddRange(decisions.IfStatements);
                    foreachStm.Nested.AddRange(decisions.ElseStatements);
                }
                else if (ss is ForBlockSyntax)
                {
                    Decisions tempDecision = TraverseForStatement(ss as ForBlockSyntax, ref returnCnt, true);
                    foreachStm.Nested.AddRange(tempDecision.IfStatements);
                    foreachStm.Nested.AddRange(tempDecision.ElseStatements);
                    foreachStm.Nested.AddRange(tempDecision.ForEachStatements);
                    foreachStm.Nested.AddRange(tempDecision.ForStatements);
                    foreachStm.Nested.AddRange(tempDecision.WhileLoops);
                    foreachStm.Nested.AddRange(tempDecision.DoWhileLoops);
                    foreachStm.Nested.AddRange(tempDecision.Catches);
                    foreachStm.Nested.AddRange(tempDecision.SwitchStatements);
                }
                else if (ss is ElseStatementSyntax)
                {
                    foreachStm.Nested.Add(TravsereElseStatement(ss as ElseStatementSyntax, ref returnCnt, true));
                }
                else if (ss is SelectBlockSyntax)
                {
                    foreachStm.Nested.Add(TraverseSwitchStatement(ss as SelectBlockSyntax, ref returnCnt, true));
                }
                else if (ss is DoLoopBlockSyntax)
                {
                    foreachStm.Nested.Add(TraverseDoWhileLoop(ss as DoLoopBlockSyntax, ref returnCnt, true));
                }
                else if (ss is WhileBlockSyntax)
                {
                    foreachStm.Nested.Add(TraverseWhileLoop(ss as WhileBlockSyntax, ref returnCnt, true));
                }
                else if (ss is CallStatementSyntax)
                {
                    foreachStm.InvokedMethods.Add(TraverseInvokedMethod(ss as CallStatementSyntax));
                }
                else if (ss is ReturnStatementSyntax)
                {
                    Method tempMethod = TraverseReturnStatement(ss as ReturnStatementSyntax);
                    foreachStm.InvokedMethods.AddRange(tempMethod.InvokedMethods);
                    foreachStm.AccessedVars.AddRange(tempMethod.AccessedVariables);
                    returnCnt++;
                }
            }
            return foreachStm;
        }
示例#28
0
        public static Task <Document> RefactorAsync(
            Document document,
            ForEachStatementSyntax forEachStatement,
            SemanticModel semanticModel,
            bool reverseLoop = false,
            CancellationToken cancellationToken = default)
        {
            string name = NameGenerator.Default.EnsureUniqueLocalName(
                DefaultNames.ForVariable,
                semanticModel,
                forEachStatement.Statement.SpanStart,
                cancellationToken: cancellationToken);

            SyntaxToken identifier = Identifier(name);

            if (name != DefaultNames.ForVariable)
            {
                identifier = identifier.WithRenameAnnotation();
            }

            ExpressionSyntax forEachExpression = forEachStatement.Expression;

            MemberAccessExpressionSyntax countOrLengthMemberAccess = SimpleMemberAccessExpression(
                forEachExpression.WithoutTrivia(),
                IdentifierName(CSharpUtility.GetCountOrLengthPropertyName(forEachExpression, semanticModel, cancellationToken)));

            VariableDeclarationSyntax    declaration;
            BinaryExpressionSyntax       condition;
            PostfixUnaryExpressionSyntax incrementor;

            if (reverseLoop)
            {
                declaration = VariableDeclaration(
                    IntType(),
                    identifier,
                    EqualsValueClause(
                        SubtractExpression(
                            countOrLengthMemberAccess,
                            NumericLiteralExpression(1))));

                condition = GreaterThanOrEqualExpression(IdentifierName(name), NumericLiteralExpression(0));

                incrementor = PostDecrementExpression(IdentifierName(name));
            }
            else
            {
                declaration = VariableDeclaration(
                    IntType(),
                    identifier,
                    EqualsValueClause(NumericLiteralExpression(0)));

                condition = LessThanExpression(
                    IdentifierName(name),
                    countOrLengthMemberAccess);

                incrementor = PostIncrementExpression(IdentifierName(name));
            }

            StatementSyntax statement = forEachStatement.Statement.ReplaceNodes(
                GetVariableReferences(forEachStatement, semanticModel, cancellationToken),
                (node, _) =>
            {
                return(ElementAccessExpression(
                           forEachExpression.WithoutTrivia(),
                           BracketedArgumentList(SingletonSeparatedList(Argument(IdentifierName(name))))
                           ).WithTriviaFrom(node));
            });

            ForStatementSyntax forStatement = ForStatement(
                declaration: declaration,
                initializers: default(SeparatedSyntaxList <ExpressionSyntax>),
                condition: condition,
                incrementors: SingletonSeparatedList <ExpressionSyntax>(incrementor),
                statement: statement);

            forStatement = forStatement
                           .WithTriviaFrom(forEachStatement)
                           .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(forEachStatement, forStatement, cancellationToken));
        }
示例#29
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
 }
示例#30
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     State.IncreaseComplexityByNestingPlusOne(node.ForEachKeyword);
     State.VisitWithNesting(node, base.VisitForEachStatement);
 }
示例#31
0
        //public override void VisitFinallyClause(FinallyClauseSyntax node)
        //{
        //    base.VisitFinallyClause(node);
        //}

        //public override void VisitFixedStatement(FixedStatementSyntax node)
        //{
        //    base.VisitFixedStatement(node);
        //}

        public override void VisitForEachStatement(ForEachStatementSyntax node)
        {
            Visit(node.Expression);
            Visit(node.Statement);
            //base.VisitForEachStatement(node);
        }
示例#32
0
        public override SyntaxNode VisitForEachStatement(ForEachStatementSyntax node)
        {
            node = (ForEachStatementSyntax)base.VisitForEachStatement(node);

            if (!node.CloseParenToken.IsMissing && node.Statement.Kind != SyntaxKind.Block)
            {
                return CodeAnnotations.Formatting.AddAnnotationTo(
                    Syntax.ForEachStatement(
                        node.ForEachKeyword,
                        node.OpenParenToken,
                        node.Type,
                        node.Identifier,
                        node.InKeyword,
                        node.Expression,
                        node.CloseParenToken,
                        WrapStatementWithBlock(node.Statement)));
            }
            else
            {
                return node;
            }
        }
示例#33
0
 private void HighlightForEachStatement(ForEachStatementSyntax statement, List <TextSpan> spans)
 {
     spans.Add(statement.ForEachKeyword.Span);
 }
 public void SetStatement(SyntaxNode statement)
 {
     this.statement = (ForEachStatementSyntax) statement;
 }
示例#35
0
 /// <inheritdoc/>
 public override bool VisitForEachStatement(ForEachStatementSyntax node)
 {
     return(this.VisitStatement(node));
 }
示例#36
0
        public void VisitForEachStatement(ForEachStatementSyntax node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            node.Validate();

            WriteLeadingTrivia(node);

            _writer.WriteIndent();
            _writer.WriteKeyword(PrinterKeyword.ForEach);

            if (_writer.Configuration.Spaces.BeforeParentheses.ForEachParentheses)
                _writer.WriteSpace();

            _writer.WriteSyntax(Syntax.OpenParen);

            if (_writer.Configuration.Spaces.WithinParentheses.ForEachParentheses)
                _writer.WriteSpace();

            node.Type.Accept(this);
            _writer.WriteSpace();
            _writer.WriteIdentifier(node.Identifier);
            _writer.WriteSpace();
            _writer.WriteKeyword(PrinterKeyword.In);
            _writer.WriteSpace();
            node.Expression.Accept(this);

            if (_writer.Configuration.Spaces.WithinParentheses.ForEachParentheses)
                _writer.WriteSpace();

            _writer.WriteSyntax(Syntax.CloseParen);

            VisitBlockStatement(node.Statement);

            WriteTrailingTrivia(node);
        }
示例#37
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     Emit <ForEachBlock, ForEachStatementSyntax>(node);
 }
示例#38
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     this.Found |= node.Identifier.ValueText == this.name;
     base.VisitForEachStatement(node);
 }
 //
 // Summary:
 //     Called when the visitor visits a ForEachStatementSyntax node.
 public virtual void VisitForEachStatement(ForEachStatementSyntax node);
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     AddLocation(node.ForEachKeyword);
     base.VisitForEachStatement(node);
 }
示例#41
0
 public AggregateTransformer(ForEachStatementSyntax @foreach) : base(@foreach)
 {
 }
示例#42
0
        public override SyntaxNode VisitForEachStatement(ForEachStatementSyntax node)
        {
            this.loopLevel++;

            var statement = base.VisitForEachStatement (node
                                .WithStatement (GetLoopBlock (node.Statement)))
                            .WithAdditionalAnnotations (this.isLoop);

            this.loopLevel--;

            return statement;
        }
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     FindSpellingMistakesForIdentifier(node.Identifier);
     base.VisitForEachStatement(node);
 }
 /// <summary>
 /// Add sequence point |here|:
 /// 
 /// foreach (Type var in |expr|) { }
 /// </summary>
 /// <remarks>
 /// Hit once, before looping begins.
 /// </remarks>
 private void AddForEachExpressionSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement collectionVarDecl)
 {
     if (this.generateDebugInfo)
     {
         // NOTE: This is slightly different from Dev10.  In Dev10, when you stop the debugger
         // on the collection expression, you can see the (uninitialized) iteration variable.
         // In Roslyn, you cannot because the iteration variable is re-declared in each iteration
         // of the loop and is, therefore, not yet in scope.
         collectionVarDecl = new BoundSequencePoint(forEachSyntax.Expression, collectionVarDecl);
     }
 }
示例#45
0
 public override void VisitForEachStatement(ForEachStatementSyntax node)
 {
     base.VisitForEachStatement(node);
     _counter++;
 }
 /// <summary>
 /// Add sequence point |here|:
 /// 
 /// |foreach| (Type var in expr) { }
 /// </summary>
 /// <remarks>
 /// Hit once, before looping begins.
 /// </remarks>
 private void AddForEachKeywordSequencePoint(ForEachStatementSyntax forEachSyntax, ref BoundStatement result)
 {
     if (this.generateDebugInfo)
     {
         BoundSequencePointWithSpan foreachKeywordSequencePoint = new BoundSequencePointWithSpan(forEachSyntax, null, forEachSyntax.ForEachKeyword.Span);
         result = new BoundStatementList(forEachSyntax, ReadOnlyArray<BoundStatement>.CreateFrom(foreachKeywordSequencePoint, result));
     }
 }
 public override void VisitForEachStatement(ForEachStatementSyntax node) => counter.CheckNesting(node.ForEachKeyword, () => base.VisitForEachStatement(node));
示例#48
0
        private ExpressionSyntax TryVisitInvocationExpression(InvocationExpressionSyntax node, ForEachStatementSyntax containingForEach)
        {
            var memberAccess = node.Expression as MemberAccessExpressionSyntax;

            if (memberAccess != null)
            {
                var symbol = semantic.GetSymbolInfo(memberAccess).Symbol as IMethodSymbol;
                var owner  = node.AncestorsAndSelf().FirstOrDefault(x => x is MethodDeclarationSyntax);
                if (owner == null)
                {
                    return(null);
                }
                currentMethodIsStatic          = semantic.GetDeclaredSymbol((MethodDeclarationSyntax)owner).IsStatic;
                currentMethodName              = ((MethodDeclarationSyntax)owner).Identifier.ValueText;
                currentMethodTypeParameters    = ((MethodDeclarationSyntax)owner).TypeParameterList;
                currentMethodConstraintClauses = ((MethodDeclarationSyntax)owner).ConstraintClauses;


                if (IsSupportedMethod(node))
                {
                    var chain = new List <LinqStep>();
                    chain.Add(new LinqStep(GetMethodFullName(node), node.ArgumentList.Arguments.Select(x => x.Expression).ToList(), node));
                    var c        = node;
                    var lastNode = node;
                    while (c.Expression is MemberAccessExpressionSyntax)
                    {
                        c = ((MemberAccessExpressionSyntax)c.Expression).Expression as InvocationExpressionSyntax;
                        if (c != null && IsSupportedMethod(c))
                        {
                            chain.Add(new LinqStep(GetMethodFullName(c), c.ArgumentList.Arguments.Select(x => x.Expression).ToList(), c));
                            lastNode = c;
                        }
                        else
                        {
                            break;
                        }
                    }
                    if (containingForEach != null)
                    {
                        chain.Insert(0, new LinqStep(IEnumerableForEachMethod, new[] { SyntaxFactory.SimpleLambdaExpression(SyntaxFactory.Parameter(containingForEach.Identifier), containingForEach.Statement) })
                        {
                            Lambda = new Lambda(containingForEach.Statement, new[] { CreateParameter(containingForEach.Identifier, semantic.GetTypeInfo(containingForEach.Type).ConvertedType) })
                        });
                    }
                    if (!chain.Any(x => x.Arguments.Any(y => y is AnonymousFunctionExpressionSyntax)))
                    {
                        return(null);
                    }
                    if (chain.Count == 1 && RootMethodsThatRequireYieldReturn.Contains(chain[0].MethodName))
                    {
                        return(null);
                    }


                    var flowsIn  = new List <ISymbol>();
                    var flowsOut = new List <ISymbol>();
                    foreach (var item in chain)
                    {
                        foreach (var arg in item.Arguments)
                        {
                            if (item.Lambda != null)
                            {
                                var dataFlow = semantic.AnalyzeDataFlow(item.Lambda.Body);
                                var pname    = item.Lambda.Parameters.Single().Identifier.ValueText;
                                foreach (var k in dataFlow.DataFlowsIn)
                                {
                                    if (k.Name == pname)
                                    {
                                        continue;
                                    }
                                    if (!flowsIn.Contains(k))
                                    {
                                        flowsIn.Add(k);
                                    }
                                }
                                foreach (var k in dataFlow.DataFlowsOut)
                                {
                                    if (k.Name == pname)
                                    {
                                        continue;
                                    }
                                    if (!flowsOut.Contains(k))
                                    {
                                        flowsOut.Add(k);
                                    }
                                }
                            }
                            else
                            {
                                var dataFlow = semantic.AnalyzeDataFlow(arg);
                                foreach (var k in dataFlow.DataFlowsIn)
                                {
                                    if (!flowsIn.Contains(k))
                                    {
                                        flowsIn.Add(k);
                                    }
                                }
                                foreach (var k in dataFlow.DataFlowsOut)
                                {
                                    if (!flowsOut.Contains(k))
                                    {
                                        flowsOut.Add(k);
                                    }
                                }
                            }
                        }
                    }

                    currentFlow = flowsIn
                                  .Union(flowsOut)
                                  .Where(x => (x as IParameterSymbol)?.IsThis != true)
                                  .Select(x => CreateVariableCapture(x, flowsOut)) ?? Enumerable.Empty <VariableCapture>();

                    var collection = ((MemberAccessExpressionSyntax)lastNode.Expression).Expression;

                    if (IsAnonymousType(semantic.GetTypeInfo(collection).Type))
                    {
                        return(null);
                    }


                    var semanticReturnType = semantic.GetTypeInfo(node).Type;
                    if (IsAnonymousType(semanticReturnType) || currentFlow.Any(x => IsAnonymousType(GetSymbolType(x.Symbol))))
                    {
                        return(null);
                    }



                    return(TryRewrite(chain.First().MethodName, collection, semanticReturnType, chain, node)
                           .WithLeadingTrivia(((CSharpSyntaxNode)containingForEach ?? node).GetLeadingTrivia())
                           .WithTrailingTrivia(((CSharpSyntaxNode)containingForEach ?? node).GetTrailingTrivia()));
                }
            }
            return(null);
        }
示例#49
0
 // foreach语句
 public virtual void VisitForEachStatementSyntax(ForEachStatementSyntax value)
 {
     DefaultVisit(value);
 }