Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 19, 2025

Fix primary constructor with base class constructor arguments

  • Understand the issue: Primary constructors with base class constructor arguments not properly classified
  • Identify the problem: base-types pattern's #type includes tuple-type which consumes parentheses
  • Create test to reproduce the issue
  • Add base-class-constructor-call pattern to handle type name followed by argument list
  • Update base-types pattern to use new pattern before general #type pattern
  • Enhance pattern to handle generic types and qualified names
  • Add comprehensive tests for classes and records with base class arguments
  • Move tests to constructor.tests.ts per PR review feedback
  • Build and test the changes - all 892 tests passing
  • Run code review - no issues found
  • Run security checks - no vulnerabilities found
  • Final verification complete

Summary

Fixed the issue where primary constructors with base class constructor arguments were not being properly classified. The problem occurred when a class or record with a primary constructor called a base class constructor with arguments, especially lambda expressions.

Examples Fixed

// Lambda argument - now properly tokenized
class Bar(Action action) : Base(() => {}) { }

// Simple argument - now recognized as variable reference
class Derived(string name) : Base(name) { }

// Generic base class - now handles type parameters correctly
class Derived<T>(T value) : Base<T>(value) { }

// Qualified base class - now handles namespace qualifiers
class Derived(string s) : MyNamespace.Base(s) { }

// Records also work
record Bar(Action action) : Base(() => {});

Technical Details

Created a new base-class-constructor-call pattern that matches type names (including generic and qualified names) followed by argument lists. This pattern is included before the general #type pattern in the base-types context, preventing the tuple-type pattern from incorrectly consuming the argument list parentheses.

Tests

Added 12 new tests in constructor.tests.ts covering:

  • Simple arguments in base class constructors
  • Lambda expressions in base class constructors
  • Multiple arguments
  • Base class with interface implementation
  • Both class and record declarations
  • Both block-scoped and file-scoped namespaces
Original prompt

This section details on the original issue you should resolve

<issue_title>Primary constructor with lambda</issue_title>
<issue_description>## Details

What editor are you seeing the problem in? (e.g. Atom, Visual Studio Code, etc.)
vscode
What version of the editor are you using?
1.92.2
What color theme are you using?
dark plus

Repro

class Bar<T1, T2>
{
    public Bar(Action<Foo> a, Action<Bar<T1, T2>> b) {}
}

class Foo() : Bar<char, int>(
    foo => { Console.WriteLine("foo") }, // from foo
    bar => { Console.WriteLine("bar")  }  // from bar
){}

image
</issue_description>

<agent_instructions>In this case the extending class is passing arguments to the base classes constructor using the C# primary constructor language feature. The arguments are not being classified properly by the grammar.</agent_instructions>

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


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits December 19, 2025 22:34
Add support for base class constructor calls in primary constructors by creating
a new base-class-constructor-call pattern that matches type names followed by
argument lists in the base-types context. This fixes the issue where lambda
expressions and other arguments were not being properly classified.

Fixes tokenization of:
- class Bar(Action action) : Base(() => {}) { }
- class Derived(string name) : Base(name) { }
- record Derived(string name) : Base(name);

Co-authored-by: JoeRobich <[email protected]>
…alified names

Enhanced the base-class-constructor-call pattern to properly match:
- Generic base types: class Derived<T>(T value) : Base<T>(value)
- Qualified base types: class Derived(string s) : MyNamespace.Base(s)

This ensures that arguments in base class constructor calls are correctly
tokenized even when the base class has type parameters or namespace qualifiers.

Co-authored-by: JoeRobich <[email protected]>
Copilot AI changed the title [WIP] Fix grammar classification for lambda parameters Fix primary constructor base class argument tokenization Dec 19, 2025
Copilot AI requested a review from JoeRobich December 19, 2025 22:49
…ts.ts

Consolidated primary constructor with base class argument tests into the
existing constructor.tests.ts file as requested in PR review.

Co-authored-by: JoeRobich <[email protected]>
@JoeRobich JoeRobich marked this pull request as ready for review December 19, 2025 23:03
@JoeRobich JoeRobich merged commit 6ef793a into main Dec 19, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Primary constructor with lambda

3 participants