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; }
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(); } }
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); }
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; }
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); } }
public override void VisitSimpleLambdaExpression(SimpleLambdaExpressionSyntax node) { CSharpSyntaxNode body = node.Body; if (body.Kind() == SyntaxKind.Block) { VisitBlock((BlockSyntax)body); } }
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); }
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); }
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); }
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); }
/// <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); }