diff --git a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs index 67cac8870..36cee1c7c 100644 --- a/ICSharpCode.Decompiler/Output/TextTokenWriter.cs +++ b/ICSharpCode.Decompiler/Output/TextTokenWriter.cs @@ -78,7 +78,16 @@ namespace ICSharpCode.Decompiler output.WriteReference(t, name, false); return; case IMember m: - output.WriteReference(m, name, false); + if (IsDynamicMemberReference(nodeStack.Peek())) + { + // A member synthesized for a dynamic access: show its signature on hover, but do not + // make it a navigation target (there is no real member to jump to) - like a local. + output.WriteLocalReference(name, m); + } + else + { + output.WriteReference(m, name, false); + } return; } @@ -140,6 +149,21 @@ namespace ICSharpCode.Decompiler return symbol; } + /// + /// True if the member reference at this node was synthesized for a dynamic member access/invocation. + /// Such members carry a hover tooltip but must not be navigation targets, since they do not exist in + /// metadata. + /// + static bool IsDynamicMemberReference(AstNode node) + { + if (node.Annotation() is CSharp.Resolver.DynamicMemberResolveResult) + return true; + if (node.Slot?.Kind == Slots.TargetExpression && node.Parent is InvocationExpression + && node.Parent.Annotation() is CSharp.Resolver.DynamicInvocationResolveResult) + return true; + return false; + } + object GetCurrentLocalReference() { AstNode node = nodeStack.Peek();