Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit f4a696c

Browse files
author
Dart CI
committed
Version 2.17.0-30.0.dev
Merge commit 'b449fe4398f5188a54694bfcea8f2dc8f645e45e' into 'dev'
2 parents b2ae0ec + b449fe4 commit f4a696c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+2632
-547
lines changed

pkg/analysis_server/lib/src/services/correction/dart/data_driven.dart

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,17 @@ class DataDriven extends MultiCorrectionProducer {
3333
importedUris.add(Uri.parse(uri));
3434
}
3535
}
36-
var matcher = ElementMatcher.forNode(node);
37-
if (matcher == null) {
38-
// The node doesn't represent an element that can be transformed.
36+
var matchers = ElementMatcher.matchersForNode(node);
37+
if (matchers.isEmpty) {
38+
// The node doesn't represent any element that can be transformed.
3939
return;
4040
}
4141
for (var set in _availableTransformSetsForLibrary(library)) {
42-
for (var transform
43-
in set.transformsFor(matcher, applyingBulkFixes: applyingBulkFixes)) {
44-
yield DataDrivenFix(transform);
42+
for (var matcher in matchers) {
43+
for (var transform in set.transformsFor(matcher,
44+
applyingBulkFixes: applyingBulkFixes)) {
45+
yield DataDrivenFix(transform);
46+
}
4547
}
4648
}
4749
}

pkg/analysis_server/lib/src/services/correction/fix/data_driven/element_matcher.dart

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,14 @@ class ElementMatcher {
2626
final List<ElementKind> validKinds;
2727

2828
/// Initialize a newly created matcher representing a reference to an element
29-
/// with the given [name] in a library that imports the [importedUris].
29+
/// whose name matches the given [components] and element [kinds] in a library
30+
/// that imports the [importedUris].
3031
ElementMatcher(
3132
{required this.importedUris,
3233
required this.components,
33-
List<ElementKind>? kinds})
34+
required List<ElementKind> kinds})
3435
: assert(components.isNotEmpty),
35-
validKinds = kinds ?? const [];
36+
validKinds = kinds;
3637

3738
/// Return `true` if this matcher matches the given [element].
3839
bool matches(ElementDescriptor element) {
@@ -93,25 +94,68 @@ class ElementMatcher {
9394
return false;
9495
}
9596

96-
/// Return an element matcher that will match the element that is, or should
97-
/// be, associated with the given [node], or `null` if there is no appropriate
98-
/// matcher for the node.
99-
static ElementMatcher? forNode(AstNode? node) {
97+
/// Return a list of element matchers that will match the element that is, or
98+
/// should be, associated with the given [node]. The list will be empty if
99+
/// there are no appropriate matchers for the [node].
100+
static List<ElementMatcher> matchersForNode(AstNode? node) {
100101
if (node == null) {
101-
return null;
102+
return const <ElementMatcher>[];
102103
}
103104
var importedUris = _importElementsForNode(node);
104105
if (importedUris == null) {
106+
return const <ElementMatcher>[];
107+
}
108+
var builder = _MatcherBuilder(importedUris);
109+
builder.buildMatchersForNode(node);
110+
return builder.matchers.toList();
111+
}
112+
113+
/// Return the URIs of the imports in the library containing the [node], or
114+
/// `null` if the imports can't be determined.
115+
static List<Uri>? _importElementsForNode(AstNode node) {
116+
var root = node.root;
117+
if (root is! CompilationUnit) {
105118
return null;
106119
}
120+
var importedUris = <Uri>[];
121+
var library = root.declaredElement?.library;
122+
if (library == null) {
123+
return null;
124+
}
125+
for (var importElement in library.imports) {
126+
// TODO(brianwilkerson) Filter based on combinators to help avoid making
127+
// invalid suggestions.
128+
var uri = importElement.importedLibrary?.source.uri;
129+
if (uri != null) {
130+
// The [uri] is `null` if the literal string is not a valid URI.
131+
importedUris.add(uri);
132+
}
133+
}
134+
return importedUris;
135+
}
136+
}
137+
138+
/// A helper class used to build a list of element matchers.
139+
class _MatcherBuilder {
140+
final List<ElementMatcher> matchers = [];
141+
142+
final List<Uri> importedUris;
143+
144+
_MatcherBuilder(this.importedUris);
145+
146+
void buildMatchersForNode(AstNode? node) {
107147
var components = _componentsForNode(node);
108148
if (components == null) {
109-
return null;
149+
return;
110150
}
111-
return ElementMatcher(
112-
importedUris: importedUris,
113-
components: components,
114-
kinds: _kindsForNode(node));
151+
var kinds = _kindsForNode(node) ?? [];
152+
_addMatcher(components: components, kinds: kinds);
153+
}
154+
155+
void _addMatcher(
156+
{required List<String> components, required List<ElementKind> kinds}) {
157+
matchers.add(ElementMatcher(
158+
importedUris: importedUris, components: components, kinds: kinds));
115159
}
116160

117161
/// Return the components of the path of the element associated with the given
@@ -244,30 +288,6 @@ class ElementMatcher {
244288
return null;
245289
}
246290

247-
/// Return the URIs of the imports in the library containing the [node], or
248-
/// `null` if the imports can't be determined.
249-
static List<Uri>? _importElementsForNode(AstNode node) {
250-
var root = node.root;
251-
if (root is! CompilationUnit) {
252-
return null;
253-
}
254-
var importedUris = <Uri>[];
255-
var library = root.declaredElement?.library;
256-
if (library == null) {
257-
return null;
258-
}
259-
for (var importElement in library.imports) {
260-
// TODO(brianwilkerson) Filter based on combinators to help avoid making
261-
// invalid suggestions.
262-
var uri = importElement.importedLibrary?.source.uri;
263-
if (uri != null) {
264-
// The [uri] is `null` if the literal string is not a valid URI.
265-
importedUris.add(uri);
266-
}
267-
}
268-
return importedUris;
269-
}
270-
271291
/// Return `true` if the [node] is a prefix
272292
static bool _isPrefix(AstNode? node) {
273293
return node is SimpleIdentifier && node.staticElement is PrefixElement;
@@ -312,6 +332,7 @@ class ElementMatcher {
312332
}
313333
return const [
314334
ElementKind.classKind,
335+
// ElementKind.constructorKind,
315336
ElementKind.enumKind,
316337
ElementKind.mixinKind,
317338
ElementKind.typedefKind

pkg/analysis_server/test/src/services/correction/fix/data_driven/element_matcher_test.dart

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ abstract class AbstractElementMatcherTest extends DataDrivenFixProcessorTest {
2323
List<ElementKind>? expectedKinds,
2424
List<String>? expectedUris}) {
2525
var node = findNode.any(search);
26-
var matcher = ElementMatcher.forNode(node)!;
26+
var matchers = ElementMatcher.matchersForNode(node);
27+
expect(matchers, hasLength(1));
28+
var matcher = matchers[0];
2729
if (expectedUris != null) {
2830
expect(matcher.importedUris,
2931
unorderedEquals(expectedUris.map((uri) => Uri.parse(uri))));

pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,117 @@ void f() {
706706
''');
707707
}
708708

709+
@failingTest
710+
Future<void> test_material_FlatButton_deprecated() async {
711+
setPackageContent('''
712+
@deprecated
713+
class FlatButton {
714+
factory FlatButton.icon({
715+
Key? key,
716+
required VoidCallback? onPressed,
717+
VoidCallback? onLongPress,
718+
ValueChanged<bool>? onHighlightChanged,
719+
ButtonTextTheme? textTheme,
720+
Color? highlightColor,
721+
Brightness? colorBrightness,
722+
Clip? clipBehavior,
723+
FocusNode? focusNode,
724+
bool autofocus = true,
725+
required Widget icon,
726+
required Widget label,
727+
}) => FlatButton();
728+
FlatButton();
729+
}
730+
class Key {}
731+
class UniqueKey extends Key {}
732+
typedef VoidCallback = void Function();
733+
typedef ValueChanged<T> = void Function(T value);
734+
class ButtonTextTheme {}
735+
class Color {}
736+
class Colors {
737+
static Color blue = Color();
738+
}
739+
class Brightness {
740+
static Brightness dark = Brightness();
741+
}
742+
class Clip {
743+
static Clip hardEdge = Clip();
744+
}
745+
class FocusNode {}
746+
class Widget {}
747+
class Icon extends Widget {
748+
Icon(String icon);
749+
}
750+
class Text extends Widget {
751+
Text(String content);
752+
}
753+
class Icons {
754+
static String ten_k_outlined = '';
755+
}
756+
''');
757+
addPackageDataFile('''
758+
version: 1
759+
transforms:
760+
# Changes made in https://github.com/flutter/flutter/pull/73352
761+
- title: "Migrate to 'TextButton.icon'"
762+
date: 2021-01-08
763+
element:
764+
uris: [ '$importUri' ]
765+
constructor: 'icon'
766+
inClass: 'FlatButton'
767+
changes:
768+
- kind: 'removeParameter'
769+
name: 'onHighlightChanged'
770+
- kind: 'removeParameter'
771+
name: 'textTheme'
772+
- kind: 'removeParameter'
773+
name: 'highlightColor'
774+
- kind: 'removeParameter'
775+
name: 'colorBrightness'
776+
- kind: 'replacedBy'
777+
newElement:
778+
uris: [ '$importUri' ]
779+
constructor: 'icon'
780+
inClass: 'TextButton'
781+
''');
782+
await resolveTestCode('''
783+
import '$importUri';
784+
785+
void f() {
786+
FlatButton.icon(
787+
key: UniqueKey(),
788+
icon: Icon(Icons.ten_k_outlined),
789+
label: Text('FlatButton'),
790+
onPressed: (){},
791+
onLongPress: (){},
792+
clipBehavior: Clip.hardEdge,
793+
focusNode: FocusNode(),
794+
autofocus: true,
795+
onHighlightChanged: (_) {},
796+
textTheme: ButtonTextTheme(),
797+
highlightColor: Colors.blue,
798+
colorBrightness: Brightness.dark,
799+
);
800+
}
801+
''');
802+
await assertHasFix('''
803+
import '$importUri';
804+
805+
void f() {
806+
TextButton.icon(
807+
key: UniqueKey(),
808+
icon: Icon(Icons.ten_k_outlined),
809+
label: Text('FlatButton'),
810+
onPressed: (){},
811+
onLongPress: (){},
812+
clipBehavior: Clip.hardEdge,
813+
focusNode: FocusNode(),
814+
autofocus: true,
815+
);
816+
}
817+
''');
818+
}
819+
709820
Future<void>
710821
test_material_InputDecoration_defaultConstructor_matchFirstCase_deprecated() async {
711822
setPackageContent('''

pkg/analysis_server/test/src/services/correction/fix/data_driven/transform_set_parser_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,7 +784,7 @@ transforms:
784784
(transform.changesSelector as UnconditionalChangesSelector).changes;
785785

786786
ElementMatcher _matcher(String name) =>
787-
ElementMatcher(importedUris: uris, components: [name]);
787+
ElementMatcher(importedUris: uris, components: [name], kinds: const []);
788788

789789
List<Transform> _transforms(String name) =>
790790
result!.transformsFor(_matcher(name), applyingBulkFixes: false);

pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -863,6 +863,7 @@ class InheritanceManager3 {
863863
result.parameters = resultType.parameters;
864864

865865
var field = FieldElementImpl(variableName, -1);
866+
field.enclosingElement = targetClass;
866867
if (firstAccessor.isGetter) {
867868
field.getter = result;
868869
field.type = result.returnType;

0 commit comments

Comments
 (0)