roslyn icon indicating copy to clipboard operation
roslyn copied to clipboard

Primary constructor (properties) have sequence points but breakpoints can't be placed

Open tmat opened this issue 1 year ago • 2 comments

Currently the emitted metadata/pdb for primary constructors are incompatible with the implementation of several IDE features (breakpoint placement, EnC, code coverage):

  1. The synthesized constructor assigns parameters to backing fields directly. A sequence point is emitted for the entire constructor and additional sequence point is emitted for each backing field assignment.

Stepping into new C(1,2) makes 3 steps in the constructor: Step 1: image Step 2: image Step 3: image

If the record declaration has a body the entire declaration is active, which is odd: image

  1. The accessors generated for properties specified in primary constructors have sequence points and are not marked by [CompilerGenerated] attribute. When debugging the debugger allows to step into to property accessor and the active statement (yellow span) is displayed over the parameter syntax (note: the user may have stepping into properties disabled: image). This causes code coverage tools to report uncovered code (see https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1567458).

  2. The IDE does not allow placing breakpoints on the syntax of the parameters.

I think we should consider:

  • Instead of assigning to the backing field the constructor emits call to the property setter. This would also fix https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1567458.
  • Make the constructor non-user code (remove all sequence points emitted to the constructor) and mark it [CompilerGenerated].
  • Allow placing breakpoint on any primary constructor parameter in the IDE. Two breakpoints would be placed: onto the getter and onto the setter.
  • Fix EnC to account for these breakpoints. Edits inserting whitespace into the primary constructor declaration, or code around the entire declaration are currently broken. E.g. image

Related: https://github.com/dotnet/csharplang/discussions/5999

tmat avatar Aug 10 '22 00:08 tmat

@davidwengier FYI

tmat avatar Aug 10 '22 00:08 tmat

What's the effect of placing CompilerGenerated on the constructor? It prevents the debugger from stepping in?

RikkiGibson avatar Aug 10 '22 18:08 RikkiGibson

What's the effect of placing CompilerGenerated on the constructor? It prevents the debugger from stepping in?

CompilerGenerated has no effect on debugging.

tmat avatar Jun 15 '23 00:06 tmat

Fixed by https://github.com/dotnet/roslyn/pull/68765

tmat avatar Jul 23 '23 00:07 tmat