-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[mustache_template] Initial import #9944
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[mustache_template] Initial import #9944
Conversation
Updates the minimum Flutter/Dart SDK, and applies the autoformatter.
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
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 imports the mustache_template
package into the repository. The changes include updating repository metadata, license checks, and fixing some analysis warnings from the original, older codebase. My review focuses on improving code quality, fixing bugs, and ensuring consistency with modern Dart practices. I've found some critical issues like incorrect API definitions that would cause compilation errors and bugs where exceptions are created but not thrown. I've also found several medium-severity issues, including syntax errors in README examples, opportunities for code simplification, and improved type safety.
void render({Object? value}) { | ||
_checkClosed(); | ||
if (_node is! SectionNode) { | ||
_error('LambdaContext.render() can only be called on section tags.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _error
method returns a TemplateException
, but it is not being thrown. This will lead to unexpected behavior as the function will complete without an error. The exception should be thrown.
_error('LambdaContext.render() can only be called on section tags.'); | |
throw _error('LambdaContext.render() can only be called on section tags.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This definitely seems bad. It's a behavioral change so I'm not going to change it here, but I've added a TODO on these lines so that we don't forget.
_error( | ||
'LambdaContext.renderString() can only be called on section tags.', | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The _error
method returns a TemplateException
, but it is not being thrown here. This will lead to unexpected behavior as the function will implicitly return null
instead of throwing an error. The exception should be thrown.
_error( | |
'LambdaContext.renderString() can only be called on section tags.', | |
); | |
throw _error( | |
'LambdaContext.renderString() can only be called on section tags.', | |
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See previous comment.
factory Template( | ||
String source, { | ||
bool lenient, | ||
bool htmlEscapeValues, | ||
String name, | ||
PartialResolver? partialResolver, | ||
String delimiters, | ||
}) = t.Template.fromSource; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The named parameters in this factory constructor are non-nullable and don't have default values or a required
keyword, which will cause analysis errors in Dart 3. They should be updated to match the implementation in Template.fromSource
, using default values and nullable types where appropriate.
factory Template( | |
String source, { | |
bool lenient, | |
bool htmlEscapeValues, | |
String name, | |
PartialResolver? partialResolver, | |
String delimiters, | |
}) = t.Template.fromSource; | |
factory Template( | |
String source, { | |
bool lenient = false, | |
bool htmlEscapeValues = true, | |
String? name, | |
PartialResolver? partialResolver, | |
String delimiters = '{{ }}', | |
}) = t.Template.fromSource; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is weird, and looks like a mistake in the initial conversion to NNBD, but I'm not going to change it here.
throw _errorEof(); | ||
} | ||
if (token.type != type) { | ||
throw _error('Expected: $type found: ${token.type}.', _offset); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error is reported at _offset
, which points to the position after the unexpected token. For a more accurate error location, it would be better to use token.start
.
throw _error('Expected: $type found: ${token.type}.', _offset); | |
throw _error('Expected: $type found: ${token.type}.', token.start); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not changing; could be done later.
node = null; | ||
|
||
default: | ||
throw Exception('Unreachable code'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added TODO.
final Template? template = | ||
partialResolver == null | ||
? null | ||
: (partialResolver!(partialName) as Template?); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is due to some weird namespaced importing (there are two names for Template in this file) that I'm not going to try to unwind here.
// which contains the key name, this is object[name]. For other | ||
// objects, this is object.name or object.name(). If no property | ||
// by the given name exists, this method returns noSuchProperty. | ||
Object? _getNamedProperty(dynamic object, dynamic name) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change does indeed appear to be safe, so I've made it.
if (ex is TemplateException) { | ||
expect(ex.message, startsWith(VALUE_MISSING)); | ||
} else { | ||
fail('Unexpecetd type: $ex'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed since it's test code.
I will get a CLA exemption once the PR is ready to land, since this is a third_party import. |
85985cd
to
ca20ab8
Compare
Also, thanks for this import and filing the follow-up issues! |
ca20ab8
to
a35fc7d
Compare
Fix violations of repo checks: - Fix/suppress analysis warnings - Some via `dart fix`, some manual - Add repo-level metadata - Update license check command to recognize this package - Add a temporary code-excerpt exclusion - Update pubspec.yaml metadata - Add METADATA file - Bump version to 2.0.1 to release the changes - Fix minor README issues - Add TODOs for some areas that should be investigated in the future
a35fc7d
to
cfe8bcd
Compare
Argh, I didn't mean to I think it's probably not worth trying to unwind that though. In practice, since the history of the package is almost all >7 years old, it's probably not a big deal. |
I'll try to leave my branch alive so that this PR can be used for looking into history of specific lines if we ever need to do that. There's also https://github.com/jonahwilliams/mustache, and https://github.com/xxgreg/mustache which is the original source in case Jonah's repo goes away at some point. |
flutter/packages@42bb347...98580c6 2025-09-04 stuartmorgan@google.com [mustache_template] Initial import (flutter/packages#9944) 2025-09-04 69874219+WillBLogical@users.noreply.github.com [google_maps_flutter_web] Omit styles when cloudMapId is set (flutter/packages#9869) 2025-09-03 lukas.mirbt@hotmail.com [go_router_builder] Fix unnecessary whitespace in generated `RelativeGoRouteData` (flutter/packages#9875) 2025-09-03 james@somethingwild.co.nz [google_maps_flutter_web] Stop listening to map events when disposed (flutter/packages#9250) 2025-09-03 borisshishov@gmail.com [flutter_svg] loader buffer fix (flutter/packages#9898) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…r#174943) flutter/packages@42bb347...98580c6 2025-09-04 stuartmorgan@google.com [mustache_template] Initial import (flutter/packages#9944) 2025-09-04 69874219+WillBLogical@users.noreply.github.com [google_maps_flutter_web] Omit styles when cloudMapId is set (flutter/packages#9869) 2025-09-03 lukas.mirbt@hotmail.com [go_router_builder] Fix unnecessary whitespace in generated `RelativeGoRouteData` (flutter/packages#9875) 2025-09-03 james@somethingwild.co.nz [google_maps_flutter_web] Stop listening to map events when disposed (flutter/packages#9250) 2025-09-03 borisshishov@gmail.com [flutter_svg] loader buffer fix (flutter/packages#9898) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages-flutter-autoroll Please CC flutter-ecosystem@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
The
mustache_template
package has been transferred to theflutter.dev
publisher, so this imports it into our repository and updates it to follow repository conventions:dart fix
, some manualmustache_template
was itself a fork by a Flutter team member of the third-partymustache
package, so the import is intothird_party/packages/
, updating the repo license check to recognize the license of this package.The original code is quite old, and as a result still used a lot of implicit dynamic typing. Some of that that has been addressed in this import, but the trickier aspects have been left for future work, as converting from implicit dynamic typing to specified types has the potential for runtime regressions. (It's possible that even the more minor changes made here will cause regressions that will need fast-follow, but all the tests still pass, and the manual
test/all.dart
tests do not have any failures that were not present before making changes to the imported code).Issues filed for future follow-up work:
flutter/flutter#174721
flutter/flutter#174722
flutter/flutter#174742
Pre-Review Checklist
[shared_preferences]
pubspec.yaml
with an appropriate new version according to the pub versioning philosophy, or I have commented below to indicate which version change exemption this PR falls under1.CHANGELOG.md
to add a description of the change, following repository CHANGELOG style, or I have commented below to indicate which CHANGELOG exemption this PR falls under1.///
).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 ↩3