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();