dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.23k stars 1.57k forks source link

unused_element false positive before running a build for private types used in build_to:cache part #51471

Open greglittlefield-wf opened 1 year ago

greglittlefield-wf commented 1 year ago

Before a build is run, private types that are only implemented or instantiated in parts generated via build_to:cache show up as unused, even if they're referenced in other non-generated code.

After a build is run and the generated code becomes available, the lint goes away. This behavior is less than ideal, since these errors can be confusing for devs who haven't built the latest code yet.

Reduced test case:

// ignore: uri_has_not_been_generated
part 'foo.g.dart';

// Results in `unused_element: The declaration '_PrivateType' isn't referenced.`
// Even though it's referenced in _privateType, which is used in main.
class _PrivateType {}

_PrivateType Function() _privateTypeFactory = _$privateTypeFactory;

main() => print(_privateTypeFactory());

where the code generated in something.g.dart might look something like:

part of 'foo.dart';

class _PrivateTypeImplementer implements _PrivateType {}
final _$privateTypeFactory = () => _PrivateTypeImplementer();

This reproduces in all channels currently available in DartPad: 2.18.6, 2.19.0-444.6.beta, 2.19.2, 3.0.0-204.0.dev

The real-world use-case that this affects is private over_react React component declarations:

import 'package:over_react/over_react.dart';

part 'counter.over_react.g.dart';

mixin _CounterProps on UiProps {
  int count;
}

UiFactory<_CounterProps> _$Counter = uiFunction((props) {
  return 'Count: ${props.count}';
}, _$CounterPropsConfig);

For now, we're just adding ignore comments to these so that analysis is consistent both before and after running a build.

bwilkerson commented 1 year ago

It seems reasonable to me that we would stop reporting private members as being unused when there are part files that don't exist.