Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Dart fix may apply extra commas, causing analysis failure #49065

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

Closed
Piinks opened this issue May 19, 2022 · 7 comments
Closed

Dart fix may apply extra commas, causing analysis failure #49065

Piinks opened this issue May 19, 2022 · 7 comments
Assignees
Labels
devexp-data-driven-fixes Issues with the analysis server's support for data-driven fixes legacy-area-analyzer Use area-devexp instead. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@Piinks
Copy link
Contributor

Piinks commented May 19, 2022

Found in flutter/flutter#97972

This change adds a fix rule that removes one parameter from a constructor and adds several others. In some cases, more than one comma is being applied by the fix rule, and is causing a customer test to fail because of it.

The fix rule includes a comma, but if it is omitted, the other cases fail analysis due to a missing comma.

I have simplified the rule to reproduce:

- title: "Migrate 'ThemeData.toggleableActiveColor' to individual themes"
    date: 2022-05-18
    element:
      uris: [ 'material.dart' ]
      constructor: ''
      inClass: 'ThemeData'
    changes:
    - kind: 'removeParameter'
      name: 'toggleableActiveColor'
    - kind: 'addParameter'
      index: 96
      name: 'checkboxTheme'
      style: optional_named
      argumentValue:
        expression: "CheckboxThemeData(\n
                       fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                     ),"
        requiredIf: "toggleableActiveColor != ''"
    - kind: 'addParameter'
      index: 98
      name: 'radioTheme'
      style: optional_named
      argumentValue:
        expression: "RadioThemeData(\n
                       fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                     ),"
        requiredIf:  "toggleableActiveColor != ''"
    - kind: 'addParameter'
      index: 100
      name: 'switchTheme'
      style: optional_named
      argumentValue:
        expression: "SwitchThemeData(\n
                       thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                       trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                     )"
        requiredIf: "toggleableActiveColor != ''"
    variables:
      toggleableActiveColor:
        kind: 'fragment'
        value: 'arguments[toggleableActiveColor]'

Code migration

// Before
  ThemeData themeData = ThemeData();
  themeData = ThemeData(toggleableActiveColor: Colors.black);
  themeData = ThemeData(
    toggleableActiveColor: Colors.black,
  );
  themeData = ThemeData(
    colorScheme: _colorScheme,
    appBarTheme: AppBarTheme(
      color: _colorScheme.primary,
      iconTheme: IconThemeData(color: _colorScheme.onPrimary),
    ),
    bottomAppBarTheme: BottomAppBarTheme(
      color: _colorScheme.primary,
    ),
    canvasColor: _colorScheme.background,
    toggleableActiveColor: _colorScheme.primary,
    highlightColor: Colors.transparent,
    indicatorColor: _colorScheme.onPrimary,
    primaryColor: _colorScheme.primary,
    backgroundColor: Colors.white,
    scaffoldBackgroundColor: _colorScheme.background,
    snackBarTheme: const SnackBarThemeData(
      behavior: SnackBarBehavior.floating,
    ),
    typography: Typography.material2018(
      platform: defaultTargetPlatform,
    ),
    visualDensity: VisualDensity.standard,
  );
// After
  ThemeData themeData = ThemeData();
  themeData = ThemeData(checkboxTheme: CheckboxThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ),radioTheme: RadioThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ),switchTheme: SwitchThemeData(
 thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ));
  themeData = ThemeData(
    checkboxTheme: CheckboxThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ),radioTheme: RadioThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ),switchTheme: SwitchThemeData(
 thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ),
  );
  themeData = ThemeData(
    colorScheme: _colorScheme,
    appBarTheme: AppBarTheme(
      color: _colorScheme.primary,
      iconTheme: IconThemeData(color: _colorScheme.onPrimary),
    ),
    bottomAppBarTheme: BottomAppBarTheme(
      color: _colorScheme.primary,
    ),
    canvasColor: _colorScheme.background,
    highlightColor: Colors.transparent,
    indicatorColor: _colorScheme.onPrimary,
    primaryColor: _colorScheme.primary,
    backgroundColor: Colors.white,
    scaffoldBackgroundColor: _colorScheme.background,
    snackBarTheme: const SnackBarThemeData(
      behavior: SnackBarBehavior.floating,
    ),
    typography: Typography.material2018(
      platform: defaultTargetPlatform,
    ),
    visualDensity: VisualDensity.standard, checkboxTheme: CheckboxThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 ),, radioTheme: RadioThemeData( // <-- extra comma
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 ),, switchTheme: SwitchThemeData( // <-- extra comma
 thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 ),
  );
@Piinks
Copy link
Contributor Author

Piinks commented May 19, 2022

cc @bwilkerson & @TahaTesser

@bwilkerson
Copy link
Member

@pq @keertip

@lrhn lrhn added the legacy-area-analyzer Use area-devexp instead. label May 19, 2022
@pq pq added devexp-data-driven-fixes Issues with the analysis server's support for data-driven fixes bug labels May 19, 2022
@pq
Copy link
Member

pq commented May 19, 2022

The fix rule includes a comma, but if it is omitted, the other cases fail analysis due to a missing comma.

Ah! You shouldn't need to add a comma -- the fix should handle that for you. If it's easy for you to run it without the comma and share the spot we are failing to add it, that'd make a repro on our side a breeze. No worries if not though. I can work with what you have above too.

Thanks!

@pq
Copy link
Member

pq commented May 19, 2022

(PS: thanks for the super thoughtful and thorough report! 💎)

@Piinks
Copy link
Contributor Author

Piinks commented May 19, 2022

Thanks! Here is the inverse - omitting commas from the end of the fix expression, and the resulting migration that is missing commas in some cases and failing analysis:

Rule
- title: "Migrate 'ThemeData.toggleableActiveColor' to individual themes"
    date: 2022-05-18
    element:
      uris: [ 'material.dart' ]
      constructor: ''
      inClass: 'ThemeData'
    changes:
    - kind: 'removeParameter'
      name: 'toggleableActiveColor'
    - kind: 'addParameter'
      index: 96
      name: 'checkboxTheme'
      style: optional_named
      argumentValue:
        expression: "CheckboxThemeData(\n
                       fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                     )"
        requiredIf: "toggleableActiveColor != ''"
    - kind: 'addParameter'
      index: 98
      name: 'radioTheme'
      style: optional_named
      argumentValue:
        expression: "RadioThemeData(\n
                       fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                     )"
        requiredIf:  "toggleableActiveColor != ''"
    - kind: 'addParameter'
      index: 100
      name: 'switchTheme'
      style: optional_named
      argumentValue:
        expression: "SwitchThemeData(\n
                       thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                       trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {\n
                         return states.contains(MaterialState.selected) ? {% toggleableActiveColor %} : null;\n
                       }),\n
                     )"
        requiredIf: "toggleableActiveColor != ''"
    variables:
      toggleableActiveColor:
        kind: 'fragment'
        value: 'arguments[toggleableActiveColor]'
Code before migration
ThemeData themeData = ThemeData();
  themeData = ThemeData(toggleableActiveColor: Colors.black);
  themeData = ThemeData(
    toggleableActiveColor: Colors.black,
  );
  themeData = ThemeData(
    colorScheme: _colorScheme,
    appBarTheme: AppBarTheme(
      color: _colorScheme.primary,
      iconTheme: IconThemeData(color: _colorScheme.onPrimary),
    ),
    bottomAppBarTheme: BottomAppBarTheme(
      color: _colorScheme.primary,
    ),
    canvasColor: _colorScheme.background,
    toggleableActiveColor: _colorScheme.primary,
    highlightColor: Colors.transparent,
    indicatorColor: _colorScheme.onPrimary,
    primaryColor: _colorScheme.primary,
    backgroundColor: Colors.white,
    scaffoldBackgroundColor: _colorScheme.background,
    snackBarTheme: const SnackBarThemeData(
      behavior: SnackBarBehavior.floating,
    ),
    typography: Typography.material2018(
      platform: defaultTargetPlatform,
    ),
    visualDensity: VisualDensity.standard,
  );
Code after migration
ThemeData themeData = ThemeData();
  themeData = ThemeData(checkboxTheme: CheckboxThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 )radioTheme: RadioThemeData( // <-- missing comma
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 )switchTheme: SwitchThemeData( // <-- missing comma
 thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ));
  themeData = ThemeData(
    checkboxTheme: CheckboxThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 )radioTheme: RadioThemeData( // <-- missing comma
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 )switchTheme: SwitchThemeData( // <-- missing comma
 thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? Colors.black : null;
 }),
 ),
  );
  themeData = ThemeData(
    colorScheme: _colorScheme,
    appBarTheme: AppBarTheme(
      color: _colorScheme.primary,
      iconTheme: IconThemeData(color: _colorScheme.onPrimary),
    ),
    bottomAppBarTheme: BottomAppBarTheme(
      color: _colorScheme.primary,
    ),
    canvasColor: _colorScheme.background,
    highlightColor: Colors.transparent,
    indicatorColor: _colorScheme.onPrimary,
    primaryColor: _colorScheme.primary,
    backgroundColor: Colors.white,
    scaffoldBackgroundColor: _colorScheme.background,
    snackBarTheme: const SnackBarThemeData(
      behavior: SnackBarBehavior.floating,
    ),
    typography: Typography.material2018(
      platform: defaultTargetPlatform,
    ),
    visualDensity: VisualDensity.standard, checkboxTheme: CheckboxThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 ), radioTheme: RadioThemeData(
 fillColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 ), switchTheme: SwitchThemeData(
 thumbColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 trackColor: MaterialStateProperty.resolveWith<Color?>((Set<MaterialState> states) {
 return states.contains(MaterialState.selected) ? _colorScheme.primary : null;
 }),
 ),
  );

// <-- here and above notates the places where the commas are wrong.

@pq
Copy link
Member

pq commented May 19, 2022

This is fantastic. Thanks!

@srawlins srawlins added the P2 A bug or feature request we're likely to work on label May 20, 2022
@srawlins srawlins added type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) and removed bug labels Jun 1, 2022
@keertip keertip self-assigned this Jun 9, 2022
@keertip
Copy link
Contributor

keertip commented Jun 22, 2022

@keertip keertip closed this as completed Jun 22, 2022
@keertip keertip modified the milestone: Dart 3 beta 3 Mar 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
devexp-data-driven-fixes Issues with the analysis server's support for data-driven fixes legacy-area-analyzer Use area-devexp instead. P2 A bug or feature request we're likely to work on type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

6 participants