[pigeon] add error on empty class#11933
Conversation
There was a problem hiding this comment.
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.
| if (classDefinition.fields.isEmpty && !classDefinition.isSealed) { | ||
| result.add( | ||
| Error(message: 'Class: "${classDefinition.name}" must contain fields or be sealed.'), | ||
| ); | ||
| } |
There was a problem hiding this comment.
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).
| 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.'), | |
| ); | |
| } |
There was a problem hiding this comment.
Is Gemini correct here, or is isSealed true for subclasses of a sealed class?
There was a problem hiding this comment.
(Either way, we should have a test of this scenario.)
| if (classDefinition.superClass != null) { | ||
| if (!classDefinition.superClass!.isSealed) { | ||
| result.add( | ||
| Error(message: 'Child class: "${classDefinition.name}" must extend a sealed class.'), | ||
| ); | ||
| } | ||
| } |
There was a problem hiding this comment.
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.
| 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.'), | |
| ); | |
| } | |
| } |
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
[shared_preferences]///).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-assistbot 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
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