Пример #1
0
        private static void RunCallbackTest <T>(
            T expected,
            Func <Action <T>, CallbackVisitor> ctor,
            Action <CallbackVisitor, T> call,
            Action <T, T> verifyResults = null
            )
        {
            // Arrange
            object     actual   = null;
            Action <T> callback = t => actual = t;

            CallbackVisitor listener = ctor(callback);

            // Act
            call(listener, expected);

            // Assert
            if (verifyResults == null)
            {
                Assert.Equal(expected, actual);
            }
            else
            {
                verifyResults(expected, (T)actual);
            }
        }
Пример #2
0
        private static void RunSyncContextTest <T>(
            T expected,
            Func <Action <T>, CallbackVisitor> ctor,
            Action <CallbackVisitor, T> call
            )
        {
            // Arrange
            Mock <SynchronizationContext> mockContext = new Mock <SynchronizationContext>();

            mockContext
            .Setup(c => c.Post(It.IsAny <SendOrPostCallback>(), It.IsAny <object>()))
            .Callback <SendOrPostCallback, object>(
                (callback, state) =>
            {
                callback(expected);
            }
                );

            // Act/Assert
            RunCallbackTest <T>(
                default(T),
                callback =>
            {
                CallbackVisitor listener        = ctor(callback);
                listener.SynchronizationContext = mockContext.Object;
                return(listener);
            },
                call,
                (original, actual) =>
            {
                Assert.NotEqual(original, actual);
                Assert.Equal(expected, actual);
            }
                );
        }
        private static string GetUniqueVariableNameForNewScope(SyntaxBase syntax, string name)
        {
            var variableAccesses = new HashSet <string>(LanguageConstants.IdentifierComparer);

            CallbackVisitor.Visit(syntax, child =>
            {
                if (child is VariableAccessSyntax variableAccess)
                {
                    variableAccesses.Add(variableAccess.Name.IdentifierName);
                }

                return(true);
            });

            if (!variableAccesses.Contains(name))
            {
                return(name);
            }

            var index = 1;

            while (true)
            {
                var newName = $"{name}_{index}";

                if (!variableAccesses.Contains(newName))
                {
                    return(newName);
                }
            }
        }
Пример #4
0
        public void ListenerConstructedWithSpanCallbackDoesNotThrowOnStartBlockEndBlockOrError()
        {
            // Arrange
            Action <Span>   spanCallback = _ => { };
            CallbackVisitor listener     = new CallbackVisitor(spanCallback);

            // Act/Assert
            listener.VisitStartBlock(BlockType.Functions);
            listener.VisitError(new RazorError("Error", SourceLocation.Zero));
            listener.VisitEndBlock(BlockType.Functions);
        }
        protected override SyntaxBase ReplaceForSyntax(ForSyntax syntax)
        {
            syntax = (ForSyntax)base.ReplaceForSyntax(syntax);

            // look for range(0, length(<variable>))
            if (!IsLoopIteratorExpression(semanticModel, syntax.Expression, out var arrayVariable))
            {
                return(syntax);
            }

            if (syntax.VariableSection is not LocalVariableSyntax indexVariable)
            {
                return(syntax);
            }

            var arraySymbol      = semanticModel.GetSymbolInfo(arrayVariable);
            var arrayIndexSymbol = semanticModel.GetSymbolInfo(indexVariable);

            if (arraySymbol is null || arrayIndexSymbol is null)
            {
                return(syntax);
            }

            var arrayAccesses            = new HashSet <ArrayAccessSyntax>();
            var independentIndexAccesses = new HashSet <VariableAccessSyntax>();

            CallbackVisitor.Visit(syntax, child =>
            {
                if (child is ArrayAccessSyntax arrayAccess)
                {
                    if (semanticModel.GetSymbolInfo(arrayAccess.BaseExpression) == arraySymbol &&
                        semanticModel.GetSymbolInfo(arrayAccess.IndexExpression) == arrayIndexSymbol)
                    {
                        arrayAccesses.Add(arrayAccess);

                        // we don't want to count the VariableAccessSyntax under this particular node,
                        // so return false to skip visiting children.
                        return(false);
                    }
                }

                if (child is VariableAccessSyntax variableAccess)
                {
                    var accessSymbol = semanticModel.GetSymbolInfo(variableAccess);
                    if (accessSymbol == arrayIndexSymbol)
                    {
                        independentIndexAccesses.Add(variableAccess);
                    }
                }

                return(true);
            });

            if (!arrayAccesses.Any())
            {
                // nothing to really simplify here
                return(syntax);
            }

            var itemVarName = GetUniqueVariableNameForNewScope(syntax, "item");
            var forBody     = CallbackRewriter.Rewrite(syntax.Body, child =>
            {
                if (arrayAccesses.Contains(child))
                {
                    return(new VariableAccessSyntax(SyntaxFactory.CreateIdentifier(itemVarName)));
                }

                return(child);
            });

            SyntaxBase forVariableBlockSyntax;

            if (independentIndexAccesses.Any())
            {
                forVariableBlockSyntax = new ForVariableBlockSyntax(
                    SyntaxFactory.LeftParenToken,
                    new LocalVariableSyntax(SyntaxFactory.CreateIdentifier(itemVarName)),
                    SyntaxFactory.CommaToken,
                    new LocalVariableSyntax(SyntaxFactory.CreateIdentifier(arrayIndexSymbol.Name)),
                    SyntaxFactory.RightParenToken);
            }
            else
            {
                forVariableBlockSyntax = new LocalVariableSyntax(SyntaxFactory.CreateIdentifier(itemVarName));
            }

            var forExpression = new VariableAccessSyntax(SyntaxFactory.CreateIdentifier(arraySymbol.Name));

            return(new ForSyntax(
                       syntax.OpenSquare,
                       syntax.ForKeyword,
                       forVariableBlockSyntax,
                       syntax.InKeyword,
                       forExpression,
                       syntax.Colon,
                       forBody,
                       syntax.CloseSquare));
        }