-
Notifications
You must be signed in to change notification settings - Fork 58
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
AF-3749: Loosen validation on Factory and meta initializers #222
Conversation
Security InsightsNo security relevant content was detected by automated scans. Action Items
Questions or Comments? Reach out on Slack: #support-infosec. |
Codecov Report
@@ Coverage Diff @@
## master #222 +/- ##
========================================
+ Coverage 90.1% 90.3% +0.2%
========================================
Files 35 35
Lines 1767 1772 +5
========================================
+ Hits 1592 1600 +8
+ Misses 175 172 -3 |
import 'package:source_span/source_span.dart'; | ||
import 'package:transformer_utils/src/transformed_source_file.dart' show getSpan; | ||
import 'package:transformer_utils/transformer_utils.dart'; | ||
|
||
|
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.
#nit extra line
@@ -764,51 +764,21 @@ main() { | |||
}); | |||
}); | |||
|
|||
|
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.
#nit extra line
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.
Nice!! Looks good to me.
@@ -280,6 +275,29 @@ class ParsedDeclarations { | |||
} | |||
} | |||
|
|||
// validate that the factory is initialized correctly | |||
final factory = declarationMap[key_factory].length <= 1 ? singleOrNull(declarationMap[key_factory]) : null; |
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.
#nit should use a different variable name since factory
is a language keyword
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.
FYI factory
just shows up weirdly formatted in GitHub, and isn't officially discouraged for use a variable name since it's a built-in identifier.
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.
Oh, TIL! Thanks Greg :)
final factory = declarationMap[key_factory].length <= 1 ? singleOrNull(declarationMap[key_factory]) : null; | ||
if (factory != null && factory is TopLevelVariableDeclaration) { | ||
final String factoryName = factory.variables.variables.first.name.toString(); | ||
factory.variables.variables.forEach((variable) { |
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.
Should be sufficient to just look at the first variable in this declaration instead of iterating over the list
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.
We should also probably validate that there's only one variable in the declaration, but that's unrelated to these changes PR. (this was cut-pasted)
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.
That is already done in impl_generation, but I moved it to here, since we might as well fail earlier in that case.
// validate that the factory is initialized correctly | ||
final factory = declarationMap[key_factory].length <= 1 ? singleOrNull(declarationMap[key_factory]) : null; | ||
if (factory != null && factory is TopLevelVariableDeclaration) { | ||
final String factoryName = factory.variables.variables.first.name.toString(); |
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.
#nit my preference is to use a field if available rather than relying on a toString()
method (it's not always clear whether or not toString()
has been overridden to provide something meaningful), and in this case there should be a name
field available:
final String factoryName = factory.variables.variables.first.name.toString(); | |
final String factoryName = factory.variables.variables.first.name.name; |
error( | ||
'Factory variables are stubs for the generated factories, and should not have initializers ' | ||
'unless initialized with a valid variable name for Dart 2 builder compatibility. ' | ||
'Should be one of:\n $expectedInitializers', |
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.
Instead of listing all of them (which sort of formalizes the support when really we want it to be temporary), let's provide the initializer value that we will eventually expect it to be
test('_\$ prefixed variable name with private prefix stripped', () { | ||
setUpAndParse(''' | ||
@Factory() | ||
UiFactory<FooProps> _Foo = _\$_Foo; |
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.
private prefix isn't stripped here
UiFactory<FooProps> _Foo = _\$_Foo; | |
UiFactory<FooProps> _Foo = _\$Foo; |
var expectedInitializers = ['\$metaFor${cd.name.name}', '_\$metaFor${cd.name.name}']; | ||
if (isClassPrivate) { | ||
expectedInitializers.add('_\$metaFor${cd.name.name.substring(1)}'); | ||
} |
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.
#nit would be nice to have aTODO or a comment saying which versions need to eventually be removed?
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.
I think addressing #222 (comment) handles that effectively.
QA +1
@Workiva/release-management-p |
Ultimate problem:
The new version of codemod will update the initializer for private factories to
_$_Foo
if the factory name is_Foo
. We need to relax the validation on this initializer to allow for this.It will do the same with the
metaFor
constant.All of the following variations should be supported:
Factories:
$Foo
_$Foo
$_Foo
_$_Foo
_$Foo
Meta fields:
$metaForFoo
_$metaForFoo
$metaFor_Foo
_$metaFor_Foo
_$metaForFoo
Note: once the Dart 2 transition is complete, these restrictions will be tightened down to:
Factories:
_$Foo
_$_Foo
Meta fields:
_$metaForFoo
_$metaFor_Foo
How it was fixed:
Testing suggestions:
Potential areas of regression:
False positive validation warnings on the already codemodded WSD. Hitting the testing suggestions will cover this possible regression.