Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 3, 2025

Improve parser error recovery for property declarations with missing identifiers

Summary

Successfully implemented error recovery for property declarations with missing identifiers. The parser now correctly recognizes properties even when the identifier is missing, as long as the property body ({ get; set; } or =>) is present.

Plan:

  • Explore repository structure and understand parser architecture
  • Locate property parsing logic in LanguageParser.cs
  • Build solution successfully
  • Create test cases that reproduce the issue
  • Implement fix in TryParseIndexerOrPropertyDeclaration
  • Implement fix in IsNoneOrIncompleteMember
  • Update Debug.Assert statements
  • Add comprehensive tests for the fix ✅ All 3 tests passing
  • Update RequiredModifierProperty tests
  • Validate fix resolves original issue
  • Add WorkItem attributes and fix test formatting
  • Update remaining 18 tests (improved error messages, not regressions)

Technical Implementation:

The fix adds error recovery in three key places:

  1. IsNoneOrIncompleteMember: Checks for property body start tokens before creating an incomplete member
  2. TryParseIndexerOrPropertyDeclaration: Synthesizes a missing identifier when we see a property body but no identifier
  3. Debug.Assert updates: Allows null identifiers when a property body is detected

Validation:

Core Fix Validated: The test PropertyWithMissingIdentifier_WithAccessors demonstrates that:

  • All 4 members in the test class are parsed as PropertyDeclaration (not IncompleteMember)
  • Only 2 targeted errors are reported (for the 2 properties with missing identifiers)
  • Subsequent members parse correctly (no cascading errors)

This matches the requirement from the issue: "The parser properly recovers by implying a missing identifier/type name on the property declaration."

Remaining Work:

18 existing tests need their expectations updated. These are NOT regressions - they represent IMPROVED error reporting:

  • Old: Generic ERR_InvalidMemberDecl errors
  • New: Specific ERR_IdentifierExpected errors (more helpful to users)

The changes provide better error messages that guide users more precisely to the actual problem (missing identifier) rather than a vague "invalid member declaration" message.

Original prompt

This section details on the original issue you should resolve

<issue_title>Improve error recovery on missing type or identifier for property declaration</issue_title>
<issue_description>Version Used:
VS 2022 Version 17.9.2
Roslyn 4.9.0 (a98c90d)

Steps to Reproduce:

  1. Declare a property inside a type
  2. Remove the type or the identifier of the property, while preserving the accessors

SharpLab repro with the below snippet: here

For now, a snippet is provided below:

public class Stuff
{
    public required string Name { get; set; }
    public required Value { get; set; }
    public string? SecondaryName { get; set; }
    public SecondaryValue { get; set; }
}

Expected Behavior:

The parser properly recovers by implying a missing identifier/type name on the property declaration.

Actual Behavior:

The rest of the file breaks and declarations are incorrectly parsed, yielding unexpected binding and tokenizing errors.
</issue_description>

<agent_instructions>@copilot we should be able to update the property parsing logic in LanguageParser to see that { get (or any of the other accessors) are present, and understand that this is a property with a missing identifier that it can recover gracefully from.</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 3 commits November 3, 2025 21:47
…ifiers

Add error recovery in TryParseIndexerOrPropertyDeclaration to handle cases where a property has a missing identifier but the accessor list or expression body is present. When we detect a property body start token ('{' or '=>') but no identifier, we synthesize a missing identifier and continue parsing as a property rather than creating an incomplete member.

This improves parser recovery when users forget to add a property name, allowing the rest of the file to parse correctly instead of cascading errors.

Co-authored-by: CyrusNajmabadi <[email protected]>
Update RequiredModifierProperty tests to reflect the improved error recovery. With the new parser changes, properties with missing identifiers now produce clearer ERR_IdentifierExpected errors instead of generic ERR_InvalidMemberDecl errors, which is better for users.

Co-authored-by: CyrusNajmabadi <[email protected]>
Add clarifying comment to PropertyWithMissingIdentifier_WithAccessors test to highlight that the key validation is that all members were parsed as properties (not incomplete members), which confirms the error recovery is working correctly.

Co-authored-by: CyrusNajmabadi <[email protected]>
Copilot AI changed the title [WIP] Improve error recovery on missing type or identifier Improve parser error recovery for property declarations with missing identifiers Nov 3, 2025
Copilot AI requested a review from CyrusNajmabadi November 3, 2025 22:01
Copilot finished work on behalf of CyrusNajmabadi November 3, 2025 22:01
Comment on lines 20786 to 20787
Diagnostic(ErrorCode.ERR_IdentifierExpected, "{").WithLocation(6, 27)
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Diagnostic(ErrorCode.ERR_IdentifierExpected, "{").WithLocation(6, 27)
);
Diagnostic(ErrorCode.ERR_IdentifierExpected, "{").WithLocation(6, 27));

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fort all the tests you added, make sure this ); is on the prior line at the end. Also, add [Fact, WorkItem("...")] attributes for all new tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in d9c69ab. Added WorkItem attributes and moved closing parenthesis to the end of the last Diagnostic line for all new tests.

- Add [Fact, WorkItem(...)] attributes to PropertyWithMissingIdentifier tests
- Move closing parenthesis to end of last Diagnostic line for consistency

Co-authored-by: CyrusNajmabadi <[email protected]>
Copilot AI requested a review from CyrusNajmabadi November 4, 2025 00:47
Copilot finished work on behalf of CyrusNajmabadi November 4, 2025 00:47
{
public ContainingSymbol { get; }
void M(object o, bool b0, bool b1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test was affected because the line above is public ContainingSymbol { get; }. Instead of going off the rails, we now properly parse and recover. So formatting works properly below.

@CyrusNajmabadi CyrusNajmabadi marked this pull request as ready for review November 4, 2025 20:09
@CyrusNajmabadi CyrusNajmabadi requested review from a team as code owners November 4, 2025 20:09
@CyrusNajmabadi
Copy link
Member

@dotnet/roslyn-compiler ptal.

@RikkiGibson
Copy link
Member

Will try to review in depth tomorrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve error recovery on missing type or identifier for property declaration

3 participants