mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:09:48 +00:00
Check for references/writes to superclass members.
R=brianwilkerson@google.com Change-Id: I9907df6d773923fe6801034208a21f17fc86178b Reviewed-on: https://dart-review.googlesource.com/47581 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
15bf72615d
commit
8658a7403e
|
@ -274,6 +274,8 @@ class _ParametersCollector extends RecursiveAstVisitor<void> {
|
|||
final RefactoringStatus status = new RefactoringStatus();
|
||||
final List<_Parameter> parameters = [];
|
||||
|
||||
List<ClassElement> enclosingClasses;
|
||||
|
||||
_ParametersCollector(this.enclosingClass, this.expressionRange);
|
||||
|
||||
@override
|
||||
|
@ -286,7 +288,7 @@ class _ParametersCollector extends RecursiveAstVisitor<void> {
|
|||
|
||||
DartType type;
|
||||
if (element is MethodElement) {
|
||||
if (element.enclosingElement == enclosingClass) {
|
||||
if (_isMemberOfEnclosingClass(element)) {
|
||||
status.addError(
|
||||
"Reference to an enclosing class method cannot be extracted.");
|
||||
}
|
||||
|
@ -300,7 +302,7 @@ class _ParametersCollector extends RecursiveAstVisitor<void> {
|
|||
}
|
||||
} else if (element is PropertyAccessorElement) {
|
||||
PropertyInducingElement field = element.variable;
|
||||
if (field.enclosingElement == enclosingClass) {
|
||||
if (_isMemberOfEnclosingClass(field)) {
|
||||
if (node.inSetterContext()) {
|
||||
status.addError("Write to '$elementName' cannot be extracted.");
|
||||
} else {
|
||||
|
@ -313,4 +315,20 @@ class _ParametersCollector extends RecursiveAstVisitor<void> {
|
|||
parameters.add(new _Parameter(elementName, type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return `true` if the given [element] is a member of the [enclosingClass]
|
||||
* or one of its supertypes, interfaces, or mixins.
|
||||
*/
|
||||
bool _isMemberOfEnclosingClass(Element element) {
|
||||
if (enclosingClass != null) {
|
||||
if (enclosingClasses == null) {
|
||||
enclosingClasses = <ClassElement>[]
|
||||
..add(enclosingClass)
|
||||
..addAll(enclosingClass.allSupertypes.map((t) => t.element));
|
||||
}
|
||||
return enclosingClasses.contains(element.enclosingElement);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -226,6 +226,33 @@ class MyWidget extends StatelessWidget {
|
|||
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
|
||||
}
|
||||
|
||||
test_invocation_enclosingSuperClass() async {
|
||||
addFlutterPackage();
|
||||
await indexTestUnit(r'''
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class MyInterface {
|
||||
void foo();
|
||||
}
|
||||
|
||||
abstract class MyWidget extends StatelessWidget implements MyInterface {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new GestureDetector(
|
||||
child: new Text(''),
|
||||
onTap: () {
|
||||
foo();
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
''');
|
||||
_createRefactoringForStringOffset('new GestureDetector');
|
||||
|
||||
RefactoringStatus status = await refactoring.checkAllConditions();
|
||||
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
|
||||
}
|
||||
|
||||
test_invocation_otherClass() async {
|
||||
addFlutterPackage();
|
||||
await indexTestUnit(r'''
|
||||
|
@ -437,6 +464,33 @@ class MyWidget extends StatelessWidget {
|
|||
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
|
||||
}
|
||||
|
||||
test_parameters_field_write_enclosingSuperClass() async {
|
||||
addFlutterPackage();
|
||||
await indexTestUnit(r'''
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
abstract class MySuperWidget extends StatelessWidget {
|
||||
String field;
|
||||
}
|
||||
|
||||
class MyWidget extends MySuperWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return new GestureDetector(
|
||||
child: new Text(''),
|
||||
onTap: () {
|
||||
field = '';
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
''');
|
||||
_createRefactoringForStringOffset('new GestureDetector');
|
||||
|
||||
RefactoringStatus status = await refactoring.checkAllConditions();
|
||||
assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR);
|
||||
}
|
||||
|
||||
test_parameters_field_write_otherClass() async {
|
||||
addFlutterPackage();
|
||||
await indexTestUnit(r'''
|
||||
|
|
Loading…
Reference in a new issue