Skip to content

[pigeon] add error on empty class#11933

Open
tarrinneal wants to merge 1 commit into
flutter:mainfrom
tarrinneal:error-on-empty-class
Open

[pigeon] add error on empty class#11933
tarrinneal wants to merge 1 commit into
flutter:mainfrom
tarrinneal:error-on-empty-class

Conversation

@tarrinneal

@tarrinneal tarrinneal commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

just adds an error if a user tries to use an empty class that isn't sealed

List which issues are fixed by this PR. You must list at least one issue.

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. 2

@flutter-dashboard flutter-dashboard Bot added the CICD Run CI/CD label Jun 18, 2026
@tarrinneal tarrinneal changed the title add error on empty class [pigeon] add error on empty class Jun 18, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates Pigeon to version 27.1.1 and refactors AST validation logic in pigeon_lib_internal.dart to enforce rules on sealed classes, empty classes, and inheritance. It also simplifies field parsing in RootBuilder and adds corresponding tests. The review feedback suggests two improvements to the validation logic: allowing empty subclasses of sealed classes to support idiomatic union types, and checking superClassName to prevent silent validation bypasses when extending undefined classes.

Comment on lines +629 to +633
if (classDefinition.fields.isEmpty && !classDefinition.isSealed) {
result.add(
Error(message: 'Class: "${classDefinition.name}" must contain fields or be sealed.'),
);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

In sealed class hierarchies (union types), it is a very common and idiomatic pattern to have empty subclasses to represent states with no associated data (for example, a Loading or Empty state in a Result or Option union).

Currently, the empty class check flags any non-sealed class with no fields as an error. This will incorrectly reject valid empty subclasses of sealed classes.

To support idiomatic sealed class unions, we should allow empty classes if they are subclasses (i.e., superClassName != null).

Suggested change
if (classDefinition.fields.isEmpty && !classDefinition.isSealed) {
result.add(
Error(message: 'Class: "${classDefinition.name}" must contain fields or be sealed.'),
);
}
if (classDefinition.fields.isEmpty && !classDefinition.isSealed && classDefinition.superClassName == null) {
result.add(
Error(message: 'Class: "${classDefinition.name}" must contain fields or be sealed.'),
);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is Gemini correct here, or is isSealed true for subclasses of a sealed class?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

(Either way, we should have a test of this scenario.)

Comment on lines +634 to +640
if (classDefinition.superClass != null) {
if (!classDefinition.superClass!.isSealed) {
result.add(
Error(message: 'Child class: "${classDefinition.name}" must extend a sealed class.'),
);
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

If a class extends an unknown or undefined class (e.g., due to a typo or because the parent class is missing from the file), classDefinition.superClass will be null while classDefinition.superClassName is non-null. In this case, the current check classDefinition.superClass != null is skipped entirely, allowing the undefined inheritance to pass validation silently.

To prevent this silent bypass, we should check if superClassName is non-null, and flag an error if superClass is either null (meaning the parent class was not found/defined) or not sealed.

Suggested change
if (classDefinition.superClass != null) {
if (!classDefinition.superClass!.isSealed) {
result.add(
Error(message: 'Child class: "${classDefinition.name}" must extend a sealed class.'),
);
}
}
if (classDefinition.superClassName != null) {
if (classDefinition.superClass == null || !classDefinition.superClass!.isSealed) {
result.add(
Error(message: 'Child class: "${classDefinition.name}" must extend a sealed class.'),
);
}
}

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants