示例#1
0
        public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
        {
            Debug.Assert(IsInsideClass);

            // If this lambda is an Expression and is suitable for hoisting, we rewrite this into a field access.
            //
            //  Before:
            //      public Task ExecuteAsync(...)
            //      {
            //          ...
            //          Html.EditorFor(m => m.Price);
            //          ...
            //      }
            //
            //
            //  After:
            //      private static readonly Expression<Func<Product, decimal>> __h0 = m => m.Price;
            //      public Task ExecuteAsync(...)
            //      {
            //          ...
            //          Html.EditorFor(__h0);
            //          ...
            //      }
            //
            var type = SemanticModel.GetTypeInfo(node);

            // Due to an anomaly where Roslyn (depending on code sample) may finish compilation without diagnostic
            // errors (this code path does not execute when diagnostic errors are present) we need to validate that
            // the ConvertedType was determined/is not null.
            if (type.ConvertedType == null ||
                type.ConvertedType.Name != typeof(Expression).Name &&
                type.ConvertedType.ContainingNamespace.Name != typeof(Expression).Namespace)
            {
                return node;
            }

            if (!node.Parent.IsKind(SyntaxKind.Argument))
            {
                return node;
            }

            var parameter = node.Parameter;
            if (IsValidForHoisting(parameter, node.Body))
            {
                // Replace with a MemberAccess
                var memberName = string.Format(FieldNameTemplate, Expressions.Count);
                var memberAccess = PadMemberAccess(node, SyntaxFactory.IdentifierName(memberName));
                Expressions.Add(new KeyValuePair<SimpleLambdaExpressionSyntax, IdentifierNameSyntax>(node, memberAccess));
                return memberAccess;
            }

            return node;
        }
示例#2
0
        public static string SimpleLambdaExpression(SimpleLambdaExpressionSyntax lambda)
        {
            var output = "{ (" + lambda.Parameter.Identifier.Text;
            
            if (lambda.Parameter.Type != null)
            {
                output += ": " + SyntaxNode(lambda.Parameter.Type);
            }

            output += ") in" + NewLine;
            return output + Block((BlockSyntax)lambda.Body, false) + NewLine + "}";
        }
            public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
            {
                if (_predicate(node) && CanSimplify(_document, node, _cancellationToken))
                {
                    var invocation = TryGetInvocationExpression(node.Body);
                    if (invocation != null)
                    {
                        return SimplifyInvocation(invocation);
                    }
                }

                return base.VisitSimpleLambdaExpression(node);
            }
		public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
		{
			this.lambdaStack.Push(node);

			try
			{
				return base.VisitSimpleLambdaExpression(node);
			}
			finally
			{
				this.lambdaStack.Pop();
			}
		}
示例#5
0
        public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
        {
            Debug.Assert(IsInsideClass);

            // If this lambda is an Expression and is suitable for hoisting, we rewrite this into a field access.
            //
            //  Before:
            //      public Task ExecuteAsync(...)
            //      {
            //          ...
            //          Html.EditorFor(m => m.Price);
            //          ...
            //      }
            //
            //
            //  After:
            //      private static readonly Expression<Func<Product, decimal>> __h0 = m => m.Price;
            //      public Task ExecuteAsync(...)
            //      {
            //          ...
            //          Html.EditorFor(__h0);
            //          ...
            //      }
            //
            var type = SemanticModel.GetTypeInfo(node);
            if (type.ConvertedType.Name != typeof(Expression).Name &&
                type.ConvertedType.ContainingNamespace.Name != typeof(Expression).Namespace)
            {
                return node;
            }

            if (!node.Parent.IsKind(SyntaxKind.Argument))
            {
                return node;
            }

            var parameter = node.Parameter;
            if (IsValidForHoisting(parameter, node.Body))
            {
                // Replace with a MemberAccess
                var memberName = string.Format(FieldNameTemplate, Expressions.Count);
                var memberAccess = PadMemberAccess(node, SyntaxFactory.IdentifierName(memberName));
                Expressions.Add(new KeyValuePair<SimpleLambdaExpressionSyntax, IdentifierNameSyntax>(node, memberAccess));
                return memberAccess;
            }

            return node;
        }
 public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     // ignore lambdas
 }
 public override bool VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     return false;
 }
            private IEnumerable<ITypeSymbol> InferTypeInSimpleLambdaExpression(SimpleLambdaExpressionSyntax lambdaExpression, SyntaxToken? previousToken = null)
            {
                // If we have a position, it has to be after the lambda arrow.
                if (previousToken.HasValue && previousToken.Value != lambdaExpression.ArrowToken)
                {
                    return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
                }

                return InferTypeInLambdaExpression(lambdaExpression);
            }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     this.OnNodeVisited(node, this.type.IsInstanceOfType(node));
     base.VisitSimpleLambdaExpression(node);
 }
 private static SyntaxNode ConvertSimpleLambdaToAsync(SimpleLambdaExpressionSyntax simpleLambda)
 {
     return SyntaxFactory.SimpleLambdaExpression(
                         SyntaxFactory.Token(SyntaxKind.AsyncKeyword),
                         simpleLambda.Parameter,
                         simpleLambda.ArrowToken,
                         simpleLambda.RefKeyword,
                         simpleLambda.Body)
                         .WithTriviaFrom(simpleLambda)
                         .WithAdditionalAnnotations(Formatter.Annotation);
 }
示例#11
0
 public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     VisitLambdaExpression(node);
 }
            public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
            {
                var newNode = base.VisitSimpleLambdaExpression(node);

                if (newNode is SimpleLambdaExpressionSyntax)
                {
                    var simpleLambda = (SimpleLambdaExpressionSyntax)newNode;

                    // First, try to add a cast to the lambda.
                    ExpressionSyntax newLambdaExpressionBodyWithCast;
                    if (TryGetLambdaExpressionBodyWithCast(node, simpleLambda, out newLambdaExpressionBodyWithCast))
                    {
                        simpleLambda = simpleLambda.WithBody(newLambdaExpressionBodyWithCast);
                    }

                    // Next, try to add a type to the lambda parameter
                    if (_expandParameter)
                    {
                        var parameterSymbol = _semanticModel.GetDeclaredSymbol(node.Parameter);
                        if (parameterSymbol?.Type?.ContainsAnonymousType() == false)
                        {
                            var typeSyntax = parameterSymbol.Type.GenerateTypeSyntax().WithTrailingTrivia(s_oneWhitespaceSeparator);
                            var newSimpleLambdaParameter = simpleLambda.Parameter.WithType(typeSyntax).WithoutTrailingTrivia();

                            var parenthesizedLambda = SyntaxFactory.ParenthesizedLambdaExpression(
                                simpleLambda.AsyncKeyword,
                                SyntaxFactory.ParameterList(SyntaxFactory.SingletonSeparatedList(newSimpleLambdaParameter))
                                    .WithTrailingTrivia(simpleLambda.Parameter.GetTrailingTrivia())
                                    .WithLeadingTrivia(simpleLambda.Parameter.GetLeadingTrivia()),
                                simpleLambda.ArrowToken,
                                simpleLambda.RefKeyword,
                                simpleLambda.Body).WithAdditionalAnnotations(Simplifier.Annotation);

                            return SimplificationHelpers.CopyAnnotations(from: simpleLambda, to: parenthesizedLambda);
                        }
                    }

                    return simpleLambda;
                }

                return newNode;
            }
示例#13
0
        private static IdentifierNameSyntax PadMemberAccess(
            SimpleLambdaExpressionSyntax node,
            IdentifierNameSyntax memberAccess)
        {
            // We want to make the new span 
            var originalSpan = node.GetLocation().GetMappedLineSpan();

            // Start by collecting all the trivia 'inside' the expression - we need to tack that on the end, but
            // if it ends with a newline, don't include that.
            var innerTrivia = SyntaxFactory.TriviaList(node.DescendantTrivia(descendIntoChildren: n => true));
            if (innerTrivia.Count > 0 && innerTrivia[innerTrivia.Count - 1].IsKind(SyntaxKind.EndOfLineTrivia))
            {
                innerTrivia = innerTrivia.RemoveAt(innerTrivia.Count - 1);
            }

            memberAccess = memberAccess.WithTrailingTrivia(innerTrivia);

            // If everything is all on one line, then make sure the spans are the same, to compensate
            // for the expression potentially being longer than the variable name.
            var lineSpan = originalSpan.EndLinePosition.Line - originalSpan.StartLinePosition.Line;
            if (lineSpan == 0)
            {
                var padding = node.Span.Length - memberAccess.FullSpan.Length;
                var trailingTrivia =
                    SyntaxFactory.TriviaList(memberAccess.GetTrailingTrivia())
                    .Add(SyntaxFactory.Whitespace(new string(' ', padding)))
                    .AddRange(node.GetTrailingTrivia());

                return
                    memberAccess
                    .WithLeadingTrivia(node.GetLeadingTrivia())
                    .WithTrailingTrivia(trailingTrivia);
            }
            else
            {
                // If everything isn't on the same line, we need to pad out the last line.
                var padding =
                    originalSpan.EndLinePosition.Character -
                    originalSpan.StartLinePosition.Character;

                var trailingTrivia =
                    SyntaxFactory.TriviaList(memberAccess.GetTrailingTrivia())
                    .Add(SyntaxFactory.Whitespace(new string(' ', padding)))
                    .AddRange(node.GetTrailingTrivia());

                return
                    memberAccess
                    .WithLeadingTrivia(node.GetLeadingTrivia())
                    .WithTrailingTrivia(trailingTrivia);
            }
        }
示例#14
0
 public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     CSharpSyntaxNode body = node.Body;
     if (body.Kind() == SyntaxKind.Block)
     {
         VisitBlock((BlockSyntax)body);
     }
 }
示例#15
0
 public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     return base.VisitSimpleLambdaExpression(node);
 }
            public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
            {
                var saveCurrentScope = currentScope;
                var parametersScope = new DeclarationScope(saveCurrentScope);
                currentScope = parametersScope;

                Visit(node.Parameter);

                Debug.Assert(currentScope == parametersScope);
                currentScope = new DeclarationScope(parametersScope);

                Visit(node.Body);

                Debug.Assert(currentScope.Parent == parametersScope);
                Debug.Assert(currentScope.Parent.Parent == saveCurrentScope);
                currentScope = saveCurrentScope;
            }
 public static void Go(OutputWriter writer, SimpleLambdaExpressionSyntax expression)
 {
     Go(writer, new[] {expression.Parameter}, expression.Body, TypeProcessor.GetTypeInfo(expression));
 }
        public static CompilationUnitSyntax RefactorSimpleLambdaInstance(CompilationUnitSyntax syntax, InvocationExpressionSyntax apmSyntax, IMethodSymbol apmSymbol, SimpleLambdaExpressionSyntax lambda)
        {
            if (lambda.Body.CSharpKind() != SyntaxKind.Block)
                throw new NotImplementedException("Lambda body must be rewritten as BlockSyntax - it is now: " + lambda.Body.CSharpKind() + ": lambda: " + lambda);

            var lambdaBlock = (BlockSyntax)lambda.Body;

            var originatingMethodSyntax = apmSyntax.FirstAncestorOrSelf<MethodDeclarationSyntax>();

            // TODO: This precondition'i Analyzer'a koy!!! 
            if (originatingMethodSyntax == null || !originatingMethodSyntax.ReturnsVoid())
            {
                throw new Exception("PRECONDITION: Initiating method does not return void");
            }

            // TODO: Look up the symbol to check that it actually exists.
            var methodNameBase = GetAsyncMethodNameBase(apmSyntax);

            var endStatement = TryFindEndAPMCallSyntaxNode(lambdaBlock, methodNameBase);

            if (endStatement != null)
            {
                return RewriteNotNestedInstance(syntax, originatingMethodSyntax, apmSyntax, lambdaBlock, endStatement, methodNameBase, );
            }

            // Every method invocation might lead to the target EndXxx. Try to find it recursively.
            // Once found, rewrite the methods in the invocation path, one by one.
            // Finally, rewrite the originating method, and the method with the EndXxx statement.

            var invocationPathToEndXxx = TryFindCallGraphPathToEndXxx(lambdaBlock, methodNameBase, model);

            if (invocationPathToEndXxx.Count == 0)
            {
                throw new PreconditionException("Could not find End call in lambda body call graph");
            }

            // These two get special treatment.
            var initialCall = invocationPathToEndXxx.RemoveLast();
            var endXxxCall = invocationPathToEndXxx.RemoveFirst();

            IMethodSymbol endXxxMethod;
            try
            {
                endXxxMethod = model.LookupMethodSymbol(endXxxCall);
            }
            catch (SymbolMissingException e)
            {
                Logger.Error("No symbol found for APM End invocation: {0}", endXxxCall, e);

                throw new RefactoringException("No symbol found for APM End invocation: " + endXxxCall, e);
            }

            var taskTypeParameter = endXxxMethod.ReturnType.Name;

            var replacements = new List<SyntaxReplacementPair>(invocationPathToEndXxx.Count + 2);

            // Replace all intermediate methods on the call graph path.
            replacements.AddRange(
                invocationPathToEndXxx.Select(
                    invocation => new SyntaxReplacementPair(
                        invocation.ContainingMethod(),
                        RewriteCallGraphPathComponent(invocation, taskTypeParameter)
                    )
                )
            );

            // Replace method that contains BeginXxx call.
            var taskName = FreeTaskName(originatingMethodSyntax);
            replacements.Add(
                new SyntaxReplacementPair(
                    originatingMethodSyntax,
                    RewriteOriginatingMethod(
                        apmSyntax,
                        RewriteOriginatingMethodLambdaBlock(lambda, initialCall, taskName),
                        methodNameBase,
                        taskName
                    )
                )
            );

            // Replace method that contains the EndXxx call.
            replacements.Add(
                new SyntaxReplacementPair(
                    endXxxCall.ContainingMethod(),
                    RewriteEndXxxContainingMethod(
                        endXxxCall,
                        taskTypeParameter
                    )
                )
            );

            return syntax
                .ReplaceAll(replacements)
                .WithUsingSystemThreadingTasks()
                .Format(workspace);
        }
示例#19
0
 public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     tracker.AddIdentifier(node.Parameter.Identifier);
     Visit(node.Body);
     tracker.RemoveIdentifier(node.Parameter.Identifier);
 }
 public override void VisitSimpleLambdaExpression(Microsoft.CodeAnalysis.CSharp.Syntax.SimpleLambdaExpressionSyntax node)
 {
     base.VisitSimpleLambdaExpression(node);
     VisitBody("Lambda expression", node.ArrowToken, node.Body as StatementSyntax, null);
 }
        /// <summary>
        /// Finds the Left-most Expresison of the expression tree if it is a MemberAccessExpressionSyntax or a ElementAccessExpressionSyntax
        /// </summary>
        /// <param name="lambda"></param>
        /// <returns></returns>
        public static SyntaxNode GetLeftMostAccessExpression(SimpleLambdaExpressionSyntax lambda)
        {
            // The Lamba might look like
            // a => a.b.c().d or 
            // a => a[2].b.c().d

            // The left most part of the body should be a SimpleNameSyntax with the same name as the lambda argument
            var nameSyntax = lambda.Body.DescendantTokens().FirstOrDefault().Parent as SimpleNameSyntax;

            if (nameSyntax == null || nameSyntax.ToString() != lambda.Parameter.ToString()) return null;

            // We can convert it if we find a MemberAccessExpressionSyntax or an ElementAccessExpressionSyntax as the parent
            var parent = nameSyntax.Parent;
            if (parent is MemberAccessExpressionSyntax || parent is ElementAccessExpressionSyntax)
                return parent;

            return null;
        }
            public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
            {
                var newNode = base.VisitSimpleLambdaExpression(node);

                if (newNode is SimpleLambdaExpressionSyntax && _expandParameter)
                {
                    var newSimpleLambda = (SimpleLambdaExpressionSyntax)newNode;
                    var parameterSymbol = _semanticModel.GetDeclaredSymbol(node.Parameter);
                    if (parameterSymbol != null && parameterSymbol.Kind == SymbolKind.Parameter)
                    {
                        if (parameterSymbol.Type != null)
                        {
                            var typeSyntax = parameterSymbol.Type.GenerateTypeSyntax().WithTrailingTrivia(s_oneWhitespaceSeparator);
                            var newSimpleLambdaParameter = newSimpleLambda.Parameter.WithType(typeSyntax).WithoutTrailingTrivia();

                            var parenthesizedLambda = SyntaxFactory.ParenthesizedLambdaExpression(
                                newSimpleLambda.AsyncKeyword,
                                SyntaxFactory.ParameterList(SyntaxFactory.SingletonSeparatedList(newSimpleLambdaParameter))
                                    .WithTrailingTrivia(newSimpleLambda.Parameter.GetTrailingTrivia())
                                    .WithLeadingTrivia(newSimpleLambda.Parameter.GetLeadingTrivia()),
                                newSimpleLambda.ArrowToken,
                                newSimpleLambda.Body).WithAdditionalAnnotations(Simplifier.Annotation);

                            return SimplificationHelpers.CopyAnnotations(newNode, parenthesizedLambda);
                        }
                    }
                }

                return newNode;
            }
 private ITypeSymbol InferTypeForFirstParameterOfSimpleLambda(
     SimpleLambdaExpressionSyntax lambdaExpression)
 {
     return InferTypeForFirstParameterOfLambda(
         lambdaExpression, lambdaExpression.Parameter);
 }
示例#24
0
        public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
        {
            var name = node.Parameter.Identifier.ValueText;
            parameters[name] = Expression.Parameter(paramTypes[0], name);

            base.VisitSimpleLambdaExpression(node);

            expression = Expression.Lambda(expression, parameters.Values);
        }
示例#25
0
        public override SyntaxNode VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
        {
            var info = _semanticModel.GetTypeInfo(node);

            _output.Write(node, "function ({0}) ", node.Parameter.Identifier.ValueText);
            _output.TrivialWriteLine('{');
            _output.IncreaseIndent();
                
            if (info.DelegateReturnValue())
                _output.TrivialWrite("return ");
            this.Visit(node.Body);
            if (node.Body.Kind() != SyntaxKind.Block)
                _output.TrivialWriteLine(';');

            _output.DecreaseIndent();
            _output.TrivialWrite('}');

            return node;
        }
 private SyntaxNode FixSimpleLambda(SimpleLambdaExpressionSyntax lambda)
 {
     return lambda.WithAsyncKeyword(default(SyntaxToken)).WithPrependedLeadingTrivia(lambda.AsyncKeyword.LeadingTrivia);
 }
示例#27
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node)
 {
     this.OnNodeVisited(node);
     if (!this.traverseRootOnly) base.VisitSimpleLambdaExpression(node);
 }
 private SyntaxNode FixSimpleLambda(SimpleLambdaExpressionSyntax lambda)
 {
     return lambda.WithoutLeadingTrivia()
                  .WithAsyncKeyword(s_asyncToken.WithPrependedLeadingTrivia(lambda.GetLeadingTrivia()));
 }
 public SimpleLambdaExpressionTranslation(SimpleLambdaExpressionSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
     Body = syntax.Body.Get<CSharpSyntaxTranslation>(this);
     Parameter = syntax.Parameter.Get<ParameterTranslation>(this);
 }