mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 10:49:00 +00:00
Add support for patching fields.
R=brianwilkerson@google.com, paulberry@google.com BUG= Review URL: https://codereview.chromium.org/2416073002 .
This commit is contained in:
parent
2022348b11
commit
2b40c57781
2 changed files with 109 additions and 3 deletions
|
@ -100,9 +100,26 @@ class SdkPatcher {
|
|||
|
||||
void _patchClassMembers(
|
||||
ClassDeclaration baseClass, ClassDeclaration patchClass) {
|
||||
String className = baseClass.name.name;
|
||||
List<ClassMember> membersToAppend = [];
|
||||
for (ClassMember patchMember in patchClass.members) {
|
||||
if (patchMember is MethodDeclaration) {
|
||||
if (patchMember is FieldDeclaration) {
|
||||
if (_hasPatchAnnotation(patchMember.metadata)) {
|
||||
_failInPatch('attempts to patch a field', patchMember.offset);
|
||||
}
|
||||
List<VariableDeclaration> fields = patchMember.fields.variables;
|
||||
if (fields.length != 1) {
|
||||
_failInPatch('contains a field declaration with more than one field',
|
||||
patchMember.offset);
|
||||
}
|
||||
String name = fields[0].name.name;
|
||||
if (!Identifier.isPrivateName(className) &&
|
||||
!Identifier.isPrivateName(name)) {
|
||||
// TODO(scheglov) allow adding public fields into dart:_internal
|
||||
_failInPatch('contains a public field', patchMember.offset);
|
||||
}
|
||||
membersToAppend.add(patchMember);
|
||||
} else if (patchMember is MethodDeclaration) {
|
||||
String name = patchMember.name.name;
|
||||
if (_hasPatchAnnotation(patchMember.metadata)) {
|
||||
for (ClassMember baseMember in baseClass.members) {
|
||||
|
@ -181,7 +198,7 @@ class SdkPatcher {
|
|||
}
|
||||
} else {
|
||||
if (name == null) {
|
||||
if (!Identifier.isPrivateName(baseClass.name.name)) {
|
||||
if (!Identifier.isPrivateName(className)) {
|
||||
_failInPatch(
|
||||
'contains an unnamed public constructor', patchMember.offset);
|
||||
}
|
||||
|
@ -191,7 +208,6 @@ class SdkPatcher {
|
|||
membersToAppend.add(patchMember);
|
||||
}
|
||||
} else {
|
||||
// TODO(scheglov) support field
|
||||
String className = patchClass.name.name;
|
||||
_failInPatch('contains an unsupported class member in $className',
|
||||
patchMember.offset);
|
||||
|
|
|
@ -226,6 +226,96 @@ class C {
|
|||
_assertPrevNextToken(constructor.endToken, clazz.rightBracket);
|
||||
}
|
||||
|
||||
test_class_field_append() {
|
||||
CompilationUnit unit = _doTopLevelPatching(
|
||||
r'''
|
||||
class C {
|
||||
void a() {}
|
||||
}
|
||||
''',
|
||||
r'''
|
||||
@patch
|
||||
class C {
|
||||
int _b = 42;
|
||||
}
|
||||
''');
|
||||
_assertUnitCode(unit, 'class C {void a() {} int _b = 42;}');
|
||||
ClassDeclaration clazz = unit.declarations[0];
|
||||
MethodDeclaration a = clazz.members[0];
|
||||
FieldDeclaration b = clazz.members[1];
|
||||
_assertPrevNextToken(a.endToken, b.beginToken);
|
||||
_assertPrevNextToken(b.endToken, clazz.rightBracket);
|
||||
}
|
||||
|
||||
test_class_field_append_fail_moreThanOne() {
|
||||
expect(() {
|
||||
_doTopLevelPatching(
|
||||
r'''
|
||||
class A {}
|
||||
''',
|
||||
r'''
|
||||
@patch
|
||||
class A {
|
||||
@patch
|
||||
int _f1, _f2;
|
||||
}
|
||||
''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
test_class_field_append_fail_notPrivate() {
|
||||
expect(() {
|
||||
_doTopLevelPatching(
|
||||
r'''
|
||||
class A {}
|
||||
''',
|
||||
r'''
|
||||
@patch
|
||||
class A {
|
||||
@patch
|
||||
int b;
|
||||
}
|
||||
''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
test_class_field_append_publiInPrivateClass() {
|
||||
CompilationUnit unit = _doTopLevelPatching(
|
||||
r'''
|
||||
class _C {
|
||||
void a() {}
|
||||
}
|
||||
''',
|
||||
r'''
|
||||
@patch
|
||||
class _C {
|
||||
int b = 42;
|
||||
}
|
||||
''');
|
||||
_assertUnitCode(unit, 'class _C {void a() {} int b = 42;}');
|
||||
ClassDeclaration clazz = unit.declarations[0];
|
||||
MethodDeclaration a = clazz.members[0];
|
||||
FieldDeclaration b = clazz.members[1];
|
||||
_assertPrevNextToken(a.endToken, b.beginToken);
|
||||
_assertPrevNextToken(b.endToken, clazz.rightBracket);
|
||||
}
|
||||
|
||||
test_class_field_patch_fail() {
|
||||
expect(() {
|
||||
_doTopLevelPatching(
|
||||
r'''
|
||||
class A {}
|
||||
''',
|
||||
r'''
|
||||
@patch
|
||||
class A {
|
||||
@patch
|
||||
int _f;
|
||||
}
|
||||
''');
|
||||
}, throwsArgumentError);
|
||||
}
|
||||
|
||||
test_class_getter_append() {
|
||||
CompilationUnit unit = _doTopLevelPatching(
|
||||
r'''
|
||||
|
|
Loading…
Reference in a new issue