Support for extracting methods with parameters.

R=brianwilkerson@google.com

Bug: https://github.com/flutter/flutter-intellij/issues/1250
Change-Id: I906e14feba246a7704fbbcdaa358730be5916a47
Reviewed-on: https://dart-review.googlesource.com/47945
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2018-03-23 00:26:45 +00:00 committed by commit-bot@chromium.org
parent be867d5fa4
commit ea1d1d7621
2 changed files with 96 additions and 7 deletions

View file

@ -205,11 +205,11 @@ class ExtractWidgetRefactoringImpl extends RefactoringImpl
// We added fields, now add the method parameters.
if (_method != null) {
// TODO(scheglov) test for method parameters
for (var parameter in _method.parameters.parameters) {
if (parameter is NormalFormalParameter) {
_parameters.add(new _Parameter(
parameter.identifier.name, parameter.element.type));
parameter.identifier.name, parameter.element.type,
isMethodParameter: true));
}
}
}
@ -231,10 +231,29 @@ class ExtractWidgetRefactoringImpl extends RefactoringImpl
var collector = new _MethodInvocationsCollector(_method.element);
_enclosingClassNode.accept(collector);
for (var invocation in collector.invocations) {
builder.addReplacement(range.node(invocation), (builder) {
// TODO(scheglov) use arguments
_writeWidgetInstantiation(builder);
});
builder.addReplacement(
range.startEnd(invocation, invocation.argumentList.leftParenthesis),
(builder) {
builder.write('new $name(');
// Insert field references.
for (var parameter in _parameters) {
if (parameter.isMethodParameter) {
break;
}
if (parameter != _parameters.first) {
builder.write(', ');
}
builder.write(parameter.name);
}
// Separate references to fields and method arguments.
if (_parameters.isNotEmpty &&
invocation.argumentList.arguments.isNotEmpty) {
builder.write(', ');
}
},
);
}
}
@ -336,7 +355,10 @@ class _Parameter {
final String name;
final DartType type;
_Parameter(this.name, this.type);
/// Whether the parameter is a parameter of the method being extracted.
final bool isMethodParameter;
_Parameter(this.name, this.type, {this.isMethodParameter = false});
}
class _ParametersCollector extends RecursiveAstVisitor<void> {

View file

@ -357,6 +357,73 @@ class Test extends StatelessWidget {
''');
}
test_method_parameters() async {
addFlutterPackage();
await indexTestUnit(r'''
import 'package:flutter/material.dart';
class MyWidget extends StatelessWidget {
String foo;
@override
Widget build(BuildContext context) {
int bar = 1;
return new Row(
children: <Widget>[
createColumn('aaa', bar),
createColumn('bbb', 2),
],
);
}
Widget createColumn(String p1, int p2) {
var a = new Text('$foo $p1');
var b = new Text('$p2');
return new Column(
children: <Widget>[a, b],
);
}
}
''');
_createRefactoringForStringOffset('createColumn(String');
await _assertSuccessfulRefactoring(r'''
import 'package:flutter/material.dart';
class MyWidget extends StatelessWidget {
String foo;
@override
Widget build(BuildContext context) {
int bar = 1;
return new Row(
children: <Widget>[
new Test(foo, 'aaa', bar),
new Test(foo, 'bbb', 2),
],
);
}
}
class Test extends StatelessWidget {
final String foo;
final String p1;
final int p2;
Test(this.foo, this.p1, this.p2);
@override
Widget build(BuildContext context) {
var a = new Text('$foo $p1');
var b = new Text('$p2');
return new Column(
children: <Widget>[a, b],
);
}
}
''');
}
test_parameters_field_read_enclosingClass() async {
addFlutterPackage();
await indexTestUnit(r'''