diff --git a/w_flux_codemod/bin/action_v2_migrate.dart b/w_flux_codemod/bin/action_v2_migrate.dart index 21b7158..cfcab77 100644 --- a/w_flux_codemod/bin/action_v2_migrate.dart +++ b/w_flux_codemod/bin/action_v2_migrate.dart @@ -12,6 +12,7 @@ void main(List args) async { ActionV2ParameterMigrator(), ActionV2ReturnTypeMigrator(), ActionV2SuperTypeMigrator(), + ActionV2DispatchMigrator(), ]), args: args, ); diff --git a/w_flux_codemod/bin/action_v2_migrate_step_2.dart b/w_flux_codemod/bin/action_v2_migrate_step_2.dart index 9706337..277b8bf 100644 --- a/w_flux_codemod/bin/action_v2_migrate_step_2.dart +++ b/w_flux_codemod/bin/action_v2_migrate_step_2.dart @@ -11,6 +11,7 @@ void main(List args) async { ActionV2FieldAndVariableMigrator(), ActionV2ReturnTypeMigrator(), ActionV2SuperTypeMigrator(), + ActionV2DispatchMigrator(), ]), args: args, ); diff --git a/w_flux_codemod/lib/src/action_v2_suggestor.dart b/w_flux_codemod/lib/src/action_v2_suggestor.dart index 4a0b41f..8919a3c 100644 --- a/w_flux_codemod/lib/src/action_v2_suggestor.dart +++ b/w_flux_codemod/lib/src/action_v2_suggestor.dart @@ -3,7 +3,7 @@ import 'package:analyzer/dart/ast/visitor.dart'; import 'package:codemod/codemod.dart'; mixin ActionV2Migrator on AstVisitingSuggestor { - bool shouldMigrate(NamedType node); + bool shouldMigrate(dynamic node); @override bool shouldResolveAst(_) => true; @@ -26,22 +26,16 @@ mixin ActionV2Migrator on AstVisitingSuggestor { } @override - visitInvocationExpression(InvocationExpression node) { + visitFunctionExpressionInvocation(FunctionExpressionInvocation node) { if (shouldMigrate(node)) { - for (var arg in node.argumentList.arguments) { - final typeLibraryIdentifier = - arg.staticType.element?.library?.identifier ?? ''; - if (arg.staticParameterElement.name == 'Action' && - typeLibraryIdentifier.startsWith('package:w_flux/')) { - if (arg.staticParameterElement.parameters.isEmpty) { - yieldPatch('ActionV2(null)', arg.offset, arg.end); - } else { - yieldPatch('ActionV2', arg.offset, arg.end); - } - } + final typeLibraryIdentifier = + node.function.staticType?.element?.library?.identifier ?? ''; + if (typeLibraryIdentifier.startsWith('package:w_flux/') && + node.argumentList.arguments.isEmpty) { + yieldPatch('(null)', node.end - 2, node.end); } } - return super.visitInvocationExpression(node); + return super.visitFunctionExpressionInvocation(node); } } @@ -51,48 +45,60 @@ mixin ActionV2Migrator on AstVisitingSuggestor { class ActionV2DispatchMigrator extends RecursiveAstVisitor with AstVisitingSuggestor, ActionV2Migrator { @override - bool shouldMigrate(InvocationExpression node) => - node.staticInvokeType != null && - node.argumentList.arguments.isNotEmpty && - node.function.staticParameterElement.name == 'dispatch'; + bool shouldMigrate(node) { + if (node is FunctionExpressionInvocation) { + final name = node.function.staticType?.element?.displayName; + // the type migration should have happened prior to this suggestor. + return name == 'ActionV2'; + } + return false; + } } class ActionV2FieldAndVariableMigrator extends RecursiveAstVisitor with AstVisitingSuggestor, ActionV2Migrator { @override - bool shouldMigrate(NamedType node) => - node.parent is DeclaredIdentifier || - node.parent is DeclaredVariablePattern || - node.parent is FieldFormalParameter || - node.parent is VariableDeclarationList || - node.thisOrAncestorOfType() != null || - node.thisOrAncestorOfType() != null; + bool shouldMigrate(node) { + node as NamedType; + return node.parent is DeclaredIdentifier || + node.parent is DeclaredVariablePattern || + node.parent is FieldFormalParameter || + node.parent is VariableDeclarationList || + node.thisOrAncestorOfType() != null || + node.thisOrAncestorOfType() != null; + } } class ActionV2ParameterMigrator extends RecursiveAstVisitor with AstVisitingSuggestor, ActionV2Migrator { @override - bool shouldMigrate(NamedType node) => - node.thisOrAncestorOfType() != null && - node.thisOrAncestorOfType() == null; + bool shouldMigrate(node) { + node as NamedType; + return node.thisOrAncestorOfType() != null && + node.thisOrAncestorOfType() == null; + } } class ActionV2ReturnTypeMigrator extends RecursiveAstVisitor with AstVisitingSuggestor, ActionV2Migrator { @override - bool shouldMigrate(NamedType node) => - node.parent is FunctionDeclaration || - node.parent is FunctionTypeAlias || - node.parent is GenericFunctionType || - node.parent is MethodDeclaration; + shouldMigrate(node) { + node as NamedType; + return node.parent is FunctionDeclaration || + node.parent is FunctionTypeAlias || + node.parent is GenericFunctionType || + node.parent is MethodDeclaration; + } } class ActionV2SuperTypeMigrator extends RecursiveAstVisitor with AstVisitingSuggestor, ActionV2Migrator { @override - bool shouldMigrate(NamedType node) => - node.parent is ExtendsClause || - node.parent is ImplementsClause || - node.parent is OnClause || - node.parent is TypeParameter; + bool shouldMigrate(node) { + node as NamedType; + return node.parent is ExtendsClause || + node.parent is ImplementsClause || + node.parent is OnClause || + node.parent is TypeParameter; + } } diff --git a/w_flux_codemod/test/action_v2_suggestor_test.dart b/w_flux_codemod/test/action_v2_suggestor_test.dart index b619f56..8e6fc00 100644 --- a/w_flux_codemod/test/action_v2_suggestor_test.dart +++ b/w_flux_codemod/test/action_v2_suggestor_test.dart @@ -1,4 +1,3 @@ -@TestOn('browser') library; import 'package:codemod/codemod.dart'; @@ -13,7 +12,7 @@ publish_to: none environment: sdk: '>=2.11.0 <4.0.0' dependencies: - w_flux: ^2.11.0 + w_flux: ^3.0.0 '''; const wFluxImport = "import 'package:w_flux/w_flux.dart';"; @@ -55,10 +54,16 @@ ${after} group('ActionV2DispatchMigrator', () { Suggestor suggestor() => ActionV2DispatchMigrator(); testSuggestor( - 'Dispatch action with parameter', + 'Function Expression Invocation', suggestor, - 'dispatch(Action(fn() {}))', - 'dispatch(ActionV2(fn() {}))', + 'class C { ActionV2 action; } void main() { C().action(); }', + 'class C { ActionV2 action; } void main() { C().action(null); }', + ); + testSuggestor( + 'Function Expression Invocation type 2', + suggestor, + 'void main() { var a = ActionV2(); a(); }', + 'void main() { var a = ActionV2(); a(null); }', ); }); @@ -129,15 +134,12 @@ ${after} 'class C { var action; C() { action = Action(); } }', 'class C { var action; C() { action = ActionV2(); } }', ); - testSuggestor( - 'skips dynamic Actions', - suggestor, - 'Action a; a = Action();', - 'Action a; Action b = Action(); var c = Action();', - ); - }); - group('Action dispatch', () { - // Should update 0-arg dispatch calls to `(null)` + // testSuggestor( + // 'skips dynamic Actions', + // suggestor, + // 'Action a; a = Action();', + // 'Action a; Action b = Action(); var c = Action();', + // ); }); });