private static SyntaxNode ReplaceWithLambda(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod) { var parameterList = anonymousMethod.ParameterList; SyntaxNode lambdaExpression; SyntaxToken arrowToken; if (parameterList == null) { ImmutableArray <string> argumentList = ImmutableArray <string> .Empty; switch (anonymousMethod.Parent.Kind()) { case SyntaxKind.Argument: argumentList = GetMethodInvocationArgumentList(semanticModel, anonymousMethod); break; case SyntaxKind.EqualsValueClause: argumentList = GetEqualsArgumentList(semanticModel, anonymousMethod); break; case SyntaxKind.AddAssignmentExpression: case SyntaxKind.SubtractAssignmentExpression: var list = GetAssignmentArgumentList(semanticModel, anonymousMethod); if (list == null) { return(null); } argumentList = list.Value; break; case SyntaxKind.ArrowExpressionClause: case SyntaxKind.ReturnStatement: argumentList = GetMemberReturnTypeArgumentList(semanticModel, anonymousMethod); if (argumentList.IsEmpty) { return(null); } break; } List <ParameterSyntax> parameters = GenerateUniqueParameterNames(semanticModel, anonymousMethod, argumentList); var newList = (parameters.Count > 0) ? SyntaxFactory.SeparatedList(parameters, Enumerable.Repeat(ParameterListSeparator, parameters.Count - 1)) : SyntaxFactory.SeparatedList <ParameterSyntax>(); parameterList = SyntaxFactory.ParameterList(newList) .WithLeadingTrivia(anonymousMethod.DelegateKeyword.LeadingTrivia); arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken) .WithTrailingTrivia(anonymousMethod.DelegateKeyword.TrailingTrivia); } else { parameterList = parameterList.WithLeadingTrivia(anonymousMethod.DelegateKeyword.TrailingTrivia); arrowToken = SyntaxFactory.Token(SyntaxKind.EqualsGreaterThanToken) .WithTrailingTrivia(SyntaxFactory.ElasticSpace); } foreach (var parameter in parameterList.Parameters) { if (!IsValid(parameter)) { return(anonymousMethod); } } if (parameterList.Parameters.Count == 1) { var parameterSyntax = RemoveType(parameterList.Parameters[0]); var trailingTrivia = parameterSyntax.GetTrailingTrivia() .Concat(parameterList.CloseParenToken.LeadingTrivia) .Concat(parameterList.CloseParenToken.TrailingTrivia.WithoutTrailingWhitespace()) .Concat(new[] { SyntaxFactory.ElasticSpace }); var leadingTrivia = parameterList.OpenParenToken.LeadingTrivia .Concat(parameterList.OpenParenToken.TrailingTrivia) .Concat(parameterSyntax.GetLeadingTrivia()); parameterSyntax = parameterSyntax .WithLeadingTrivia(leadingTrivia) .WithTrailingTrivia(trailingTrivia); lambdaExpression = SyntaxFactory.SimpleLambdaExpression(anonymousMethod.AsyncKeyword, parameterSyntax, arrowToken, anonymousMethod.Body); } else { var parameterListSyntax = RemoveType(parameterList) .WithTrailingTrivia(parameterList.GetTrailingTrivia().WithoutTrailingWhitespace().Add(SyntaxFactory.ElasticSpace)); lambdaExpression = SyntaxFactory.ParenthesizedLambdaExpression(anonymousMethod.AsyncKeyword, parameterListSyntax, arrowToken, anonymousMethod.Body); } return(lambdaExpression .WithAdditionalAnnotations(Formatter.Annotation)); }
private static SyntaxNode GenerateInvocation(ObjectCreationExpressionSyntax newNode, AnonymousMethodExpressionSyntax func) { return(InvocationExpression( expression: MemberAccessExpression( kind: SyntaxKind.SimpleMemberAccessExpression, expression: ParenthesizedExpression(CastExpression( type: ParseTypeName($"Func<{newNode.Type}>"), expression: func ) ), name: IdentifierName(nameof(Action.Invoke)) ) )); }
private static ImmutableArray <string> GetEqualsArgumentList(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod) { var equalsValueClauseSyntax = (EqualsValueClauseSyntax)anonymousMethod.Parent; var variableDeclaration = (VariableDeclarationSyntax)equalsValueClauseSyntax.Parent.Parent; var symbol = semanticModel.GetSymbolInfo(variableDeclaration.Type); var namedTypeSymbol = (INamedTypeSymbol)symbol.Symbol; return(namedTypeSymbol.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray()); }
private static ImmutableArray <string> GetMemberReturnTypeArgumentList(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod) { var enclosingSymbol = semanticModel.GetEnclosingSymbol(anonymousMethod.Parent.SpanStart); return(!(((IMethodSymbol)enclosingSymbol).ReturnType is INamedTypeSymbol returnType) ? ImmutableArray <string> .Empty : returnType.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray()); }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) => OnlyOnParent(node, () => base.VisitAnonymousMethodExpression(node));
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { _anonymousFunctionDepth++; base.VisitAnonymousMethodExpression(node); _anonymousFunctionDepth--; }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { VisitBlock(node.Block); }
private SyntaxNode FixAnonymousMethod(AnonymousMethodExpressionSyntax method) { return(method.WithAsyncKeyword(default(SyntaxToken)).WithPrependedLeadingTrivia(method.AsyncKeyword.LeadingTrivia)); }
public override bool VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { return(false); }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { _returningPoint.Push(node); base.VisitAnonymousMethodExpression(node); _returningPoint.Pop(); }
/* public static Action<BreakpointInfo> SynchronousBreakRemote(BreakpointInfo info) * { * return (info) => * { * EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); * void resumeHandler(object sender, EventArgs e) * { * waitHandle.Set(); * } * * Dispatcher.UIThread.InvokeAsync(() => * { * EditorControl.ActiveBreakpoint = info.BreakpointSpan.Start - PreSource.Length - 1; * EditorControl.SetSelection(info.BreakpointSpan.End - PreSource.Length - 1, 0); * BreakpointPanel.SetContent(info); * BreakpointPanel.ResumeClicked += resumeHandler; * this.FindAncestorOfType<Window>().Closing += resumeHandler; * OpenSidePanel(); * }); * * waitHandle.WaitOne(); * * Dispatcher.UIThread.InvokeAsync(() => * { * CloseSidePanel(); * BreakpointPanel.ResumeClicked -= resumeHandler; * this.FindAncestorOfType<Window>().Closing -= resumeHandler; * EditorControl.ActiveBreakpoint = -1; * }); * } * }*/ /// <summary> /// Compile the source code to an <see cref="Assembly"/>. /// </summary> /// <param name="synchronousBreak">The function to handle synchronous breakpoints. If this is <see langword="null" />, these breakpoints will be skipped. If you want to enable the default UI for breakpoints, use <see cref="SynchronousBreak(BreakpointInfo)"/> (or a function that calls it after performing additional operations).</param> /// <param name="asynchronousBreak">The function to handle asynchronous breakpoints. If this is <see langword="null" />, these breakpoints will be skipped. If you want to enable the default UI for breakpoints, use <see cref="AsynchronousBreak(BreakpointInfo)"/> (or a function that calls it after performing additional operations).</param> /// <returns>An <see cref="Assembly"/> containing the compiled code, or <see langword="null"/> if the compilation fails, as well as a <see cref="CSharpCompilation"/> that also contains information about any compilation errors.</returns> public async Task <(Assembly Assembly, CSharpCompilation Compilation)> Compile(Func <BreakpointInfo, bool> synchronousBreak = null, Func <BreakpointInfo, Task <bool> > asynchronousBreak = null) { string source = null; await Dispatcher.UIThread.InvokeAsync(() => { source = this.FullSource; }); SourceText sourceText = SourceText.From(source); ImmutableList <MetadataReference> references; lock (ReferencesLock) { references = References; } SyntaxTree tree = await this.OriginalDocument.WithText(sourceText).GetSyntaxTreeAsync(); CSharpCompilation comp = CSharpCompilation.Create("compilation", new[] { tree }, references, this.CompilationOptions); string debuggerGuid = "_" + System.Guid.NewGuid().ToString("N"); if (synchronousBreak != null || asynchronousBreak != null) { List <(TextSpan, bool)> validBreakpoints = new List <(TextSpan, bool)>(); foreach (int i in source.AllIndicesOf(Utils.BreakpointMarker)) { SyntaxNode node = tree.GetRoot().FindNode(new TextSpan(i, 1)); SyntaxNode fullNode = node; while (fullNode.Parent != null && !fullNode.Kind().IsStatement()) { fullNode = fullNode.Parent; } if (fullNode.Kind().IsStatement()) { SyntaxNode methodNode = fullNode; while (methodNode.Parent != null && methodNode.Kind() != SyntaxKind.MethodDeclaration && methodNode.Kind() != SyntaxKind.ParenthesizedLambdaExpression && methodNode.Kind() != SyntaxKind.AnonymousMethodExpression) { methodNode = methodNode.Parent; } if (methodNode.Kind() == SyntaxKind.MethodDeclaration || methodNode.Kind() == SyntaxKind.ParenthesizedLambdaExpression || methodNode.Kind() == SyntaxKind.AnonymousMethodExpression) { bool isAsync = false; if (methodNode.Kind() == SyntaxKind.MethodDeclaration) { MethodDeclarationSyntax method = (MethodDeclarationSyntax)methodNode; foreach (SyntaxToken token in method.Modifiers) { if (token.Text == "async") { isAsync = true; } } } else if (methodNode.Kind() == SyntaxKind.ParenthesizedLambdaExpression) { ParenthesizedLambdaExpressionSyntax method = (ParenthesizedLambdaExpressionSyntax)methodNode; if (method.AsyncKeyword.Text == "async") { isAsync = true; } } else if (methodNode.Kind() == SyntaxKind.AnonymousMethodExpression) { AnonymousMethodExpressionSyntax method = (AnonymousMethodExpressionSyntax)methodNode; if (method.AsyncKeyword.Text == "async") { isAsync = true; } } if ((!isAsync && synchronousBreak != null) || (isAsync && asynchronousBreak != null)) { validBreakpoints.Add((new TextSpan(i, Utils.BreakpointMarker.Length), isAsync)); } } } } SyntaxTree debuggerTree = BreakpointInfo.GetDebuggerSyntaxTree(debuggerGuid); SemanticModel model = comp.GetSemanticModel(tree, false); for (int i = validBreakpoints.Count - 1; i >= 0; i--) { ILocalSymbol[] locals = (from el in model.LookupSymbols(validBreakpoints[i].Item1.Start) where el.Kind == SymbolKind.Local && !el.IsInaccessibleLocal(model, validBreakpoints[i].Item1.Start, tree.GetRoot().FindNode(validBreakpoints[i].Item1)) && !string.IsNullOrEmpty(el.Name) select(ILocalSymbol) el).ToArray(); string breakpointSource = BreakpointInfo.GetBreakpointSource(validBreakpoints[i].Item1, locals, model, debuggerGuid, validBreakpoints[i].Item2); sourceText = sourceText.Replace(validBreakpoints[i].Item1, breakpointSource); } string text = sourceText.ToString(); tree = await this.OriginalDocument.WithText(sourceText).GetSyntaxTreeAsync(); comp = CSharpCompilation.Create("compilation", new[] { debuggerTree, tree }, references, this.CompilationOptions); } using MemoryStream ms = new MemoryStream(); EmitResult result = comp.Emit(ms); if (!result.Success) { return(null, comp); } else { ms.Seek(0, SeekOrigin.Begin); Assembly assembly = Assembly.Load(ms.ToArray()); if (synchronousBreak != null || asynchronousBreak != null) { assembly.GetType(debuggerGuid + ".Debugger").InvokeMember("Breakpoint", BindingFlags.Static | BindingFlags.Public | BindingFlags.SetField, null, null, new object[] { BreakpointInfo.GetBreakpointFunction(synchronousBreak) }); assembly.GetType(debuggerGuid + ".Debugger").InvokeMember("BreakpointAsync", BindingFlags.Static | BindingFlags.Public | BindingFlags.SetField, null, null, new object[] { BreakpointInfo.GetBreakpointAsyncFunction(asynchronousBreak) }); } return(assembly, comp); } }
public override SyntaxNode VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { //cut child traversal return(node); }
internal static SyntaxNode WithoutAsyncModifier(AnonymousMethodExpressionSyntax method) => method.WithAsyncKeyword(default).WithPrependedLeadingTrivia(method.AsyncKeyword.LeadingTrivia);
public static Lambda Create(ExpressionNodeInfo info, AnonymousMethodExpressionSyntax node) => new Lambda(info, node);
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { // ignore anonymous methods }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { VisitLocal(node); base.VisitAnonymousMethodExpression(node); }
private SyntaxNode FixAnonymousMethod(AnonymousMethodExpressionSyntax method) { return(method.WithoutLeadingTrivia() .WithAsyncKeyword(s_asyncToken.WithPrependedLeadingTrivia(method.GetLeadingTrivia()))); }
internal static ParametersInfo ParametersInfo( AnonymousMethodExpressionSyntax anonymousMethod, bool allowMissing = false) { return(Syntax.ParametersInfo.Create(anonymousMethod, allowMissing)); }
private static async Task <Document> RefactorAsync( Document document, SyntaxNode node, CancellationToken cancellationToken) { SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false); switch (node.Kind()) { case SyntaxKind.MethodDeclaration: { var methodDeclaration = (MethodDeclarationSyntax)node; IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodDeclaration, cancellationToken); UseAsyncAwaitRewriter rewriter = UseAsyncAwaitRewriter.Create(methodSymbol); var newNode = (MethodDeclarationSyntax)rewriter.VisitMethodDeclaration(methodDeclaration); newNode = ModifierList <MethodDeclarationSyntax> .Instance.Insert(newNode, SyntaxKind.AsyncKeyword); return(await document.ReplaceNodeAsync(methodDeclaration, newNode, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.LocalFunctionStatement: { var localFunction = (LocalFunctionStatementSyntax)node; IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(localFunction, cancellationToken); UseAsyncAwaitRewriter rewriter = UseAsyncAwaitRewriter.Create(methodSymbol); var newBody = (BlockSyntax)rewriter.VisitBlock(localFunction.Body); LocalFunctionStatementSyntax newNode = localFunction.WithBody(newBody); newNode = ModifierList <LocalFunctionStatementSyntax> .Instance.Insert(newNode, SyntaxKind.AsyncKeyword); return(await document.ReplaceNodeAsync(localFunction, newNode, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.SimpleLambdaExpression: { var lambda = (SimpleLambdaExpressionSyntax)node; var methodSymbol = (IMethodSymbol)semanticModel.GetSymbol(lambda, cancellationToken); UseAsyncAwaitRewriter rewriter = UseAsyncAwaitRewriter.Create(methodSymbol); var newBody = (BlockSyntax)rewriter.VisitBlock((BlockSyntax)lambda.Body); SimpleLambdaExpressionSyntax newNode = lambda .WithBody(newBody) .WithAsyncKeyword(Token(SyntaxKind.AsyncKeyword)); return(await document.ReplaceNodeAsync(lambda, newNode, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.ParenthesizedLambdaExpression: { var lambda = (ParenthesizedLambdaExpressionSyntax)node; var methodSymbol = (IMethodSymbol)semanticModel.GetSymbol(lambda, cancellationToken); UseAsyncAwaitRewriter rewriter = UseAsyncAwaitRewriter.Create(methodSymbol); var newBody = (BlockSyntax)rewriter.VisitBlock((BlockSyntax)lambda.Body); ParenthesizedLambdaExpressionSyntax newNode = lambda .WithBody(newBody) .WithAsyncKeyword(Token(SyntaxKind.AsyncKeyword)); return(await document.ReplaceNodeAsync(lambda, newNode, cancellationToken).ConfigureAwait(false)); } case SyntaxKind.AnonymousMethodExpression: { var anonymousMethod = (AnonymousMethodExpressionSyntax)node; var methodSymbol = (IMethodSymbol)semanticModel.GetSymbol(anonymousMethod, cancellationToken); UseAsyncAwaitRewriter rewriter = UseAsyncAwaitRewriter.Create(methodSymbol); var newBody = (BlockSyntax)rewriter.VisitBlock((BlockSyntax)anonymousMethod.Body); AnonymousMethodExpressionSyntax newNode = anonymousMethod .WithBody(newBody) .WithAsyncKeyword(Token(SyntaxKind.AsyncKeyword)); return(await document.ReplaceNodeAsync(anonymousMethod, newNode, cancellationToken).ConfigureAwait(false)); } } throw new InvalidOperationException(); }
private SyntaxNode FixAnonymousMethod(AnonymousMethodExpressionSyntax method) => method.WithAsyncKeyword(default).WithPrependedLeadingTrivia(method.AsyncKeyword.LeadingTrivia);
/// <summary> /// /// </summary> /// <param name="node"></param> /// <param name="semanticModel"></param> /// <returns></returns> /// <remarks> /// Must be a type derived from <see cref="MethodDeclaration"/>. /// </remarks> protected virtual AnonymousMethodDeclaration CreateHelper(AnonymousMethodExpressionSyntax node, SemanticModel semanticModel) { return(new AnonymousMethodDeclaration(node, semanticModel)); }
private static ImmutableArray <string> GetMethodInvocationArgumentList(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod) { var argumentSyntax = (ArgumentSyntax)anonymousMethod.Parent; var argumentListSyntax = (BaseArgumentListSyntax)argumentSyntax.Parent; var originalInvocableExpression = argumentListSyntax.Parent; var originalSymbolInfo = semanticModel.GetSymbolInfo(originalInvocableExpression); var argumentIndex = SA1130UseLambdaSyntax.FindParameterIndex(originalSymbolInfo, argumentSyntax, argumentListSyntax); var parameterList = SA1130UseLambdaSyntax.GetDelegateParameterList(originalSymbolInfo.Symbol, argumentIndex); return(parameterList.Parameters.Select(p => p.Identifier.ToString()).ToImmutableArray()); }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { throw new NotSupportedException("Anonymous method expression is not supported"); }
private static ImmutableArray <string>?GetAssignmentArgumentList(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod) { var assignmentExpressionSyntax = (AssignmentExpressionSyntax)anonymousMethod.Parent; var symbol = semanticModel.GetSymbolInfo(assignmentExpressionSyntax.Left); if (symbol.Symbol == null) { return(null); } var eventSymbol = (IEventSymbol)symbol.Symbol; var namedTypeSymbol = (INamedTypeSymbol)eventSymbol.Type; return(namedTypeSymbol.DelegateInvokeMethod.Parameters.Select(ps => ps.Name).ToImmutableArray()); }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { IsComplex = true; base.VisitAnonymousMethodExpression(node); }
private static List <ParameterSyntax> GenerateUniqueParameterNames(SemanticModel semanticModel, AnonymousMethodExpressionSyntax anonymousMethod, ImmutableArray <string> argumentNames) { var parameters = new List <ParameterSyntax>(); foreach (var argumentName in argumentNames) { var baseName = argumentName; var newName = baseName; var index = 0; while (semanticModel.LookupSymbols(anonymousMethod.SpanStart, name: newName).Length > 0) { index++; newName = baseName + index; } parameters.Add(SyntaxFactory.Parameter(SyntaxFactory.Identifier(newName)).WithType(null)); } return(parameters); }
/// <summary> /// delegate() { /// .... /// } /// </summary> /// <param name="node"></param> public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { BuildAnonymousMethod(node, base.VisitAnonymousMethodExpression); }
public override SyntaxNode VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { return(node); }
public void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { if (node == null) throw new ArgumentNullException("node"); node.Validate(); ExpressionStart(node); if (node.Modifiers != Modifiers.None) { _writer.WriteModifiers(node.Modifiers); _writer.WriteSpace(); } _writer.WriteKeyword(PrinterKeyword.Delegate); node.ParameterList.Accept(this); _writer.PushBraceFormatting(_writer.Configuration.BracesLayout.AnonymousMethodDeclaration, false); bool isSimple = _writer.Configuration.LineBreaksAndWrapping.Other.PlaceSimpleAnonymousMethodOnSingleLine && IsSimpleBody(node.Block); if (isSimple) _writer.PushSingleLineBody(true); node.Block.Accept(this); if (isSimple) _writer.PopSingleLineBody(); _writer.PopBraceFormatting(); ExpressionEnd(node); }
public override void VisitAnonymousMethodExpression(AnonymousMethodExpressionSyntax node) { }
private Lambda(ExpressionNodeInfo info, AnonymousMethodExpressionSyntax node) : this(info.SetKind(ExprKind.ANONYMOUS_METHOD), node.Body, node.ParameterList == null ? Enumerable.Empty <ParameterSyntax>() : node.ParameterList.Parameters) { }