Allow new public names in patches for the dart:_internal library.

R=paulberry@google.com, brianwilkerson@google.com
BUG=

Review URL: https://codereview.chromium.org/2413403002 .
This commit is contained in:
Konstantin Shcheglov 2016-10-13 14:52:22 -07:00
parent 1ebde18da6
commit 4c065c8443
2 changed files with 52 additions and 5 deletions

View file

@ -21,6 +21,7 @@ import 'package:path/src/context.dart';
* [SdkPatcher] applies patches to SDK [CompilationUnit].
*/
class SdkPatcher {
bool _allowNewPublicNames;
String _baseDesc;
String _patchDesc;
CompilationUnit _patchUnit;
@ -46,8 +47,10 @@ class SdkPatcher {
'The URI of the unit to patch must have the "dart" scheme: $uri');
}
List<String> uriSegments = uri.pathSegments;
libraryUriStr = 'dart:${uriSegments.first}';
String libraryName = uriSegments.first;
libraryUriStr = 'dart:$libraryName';
isLibraryDefiningUnit = uriSegments.length == 1;
_allowNewPublicNames = libraryName == '_internal';
}
// Prepare the patch files to apply.
List<String> patchPaths;
@ -90,6 +93,9 @@ class SdkPatcher {
}
void _failIfPublicName(AstNode node, String name) {
if (_allowNewPublicNames) {
return;
}
if (!Identifier.isPrivateName(name)) {
_failInPatch('contains a public declaration "$name"', node.offset);
}
@ -121,9 +127,9 @@ class SdkPatcher {
patchMember.offset);
}
String name = fields[0].name.name;
if (!Identifier.isPrivateName(className) &&
if (!_allowNewPublicNames &&
!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);
@ -206,7 +212,7 @@ class SdkPatcher {
}
} else {
if (name == null) {
if (!Identifier.isPrivateName(className)) {
if (!_allowNewPublicNames && !Identifier.isPrivateName(className)) {
_failInPatch(
'contains an unnamed public constructor', patchMember.offset);
}

View file

@ -279,7 +279,7 @@ class A {
}, throwsArgumentError);
}
test_class_field_append_publiInPrivateClass() {
test_class_field_append_publicInPrivateClass() {
CompilationUnit unit = _doTopLevelPatching(
r'''
class _C {
@ -480,6 +480,47 @@ final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
}, throwsArgumentError);
}
test_internal_allowNewPublicNames() {
_setSdkLibraries(r'''
final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
'_internal' : const LibraryInfo(
'internal/internal.dart',
patches: {VM_PLATFORM: ['internal/internal_patch.dart']}),
};''');
File file = provider.newFile(
_p('/sdk/lib/internal/internal.dart'),
r'''
library dart._internal;
class A {}
class B {
B();
}
''');
provider.newFile(
_p('/sdk/lib/internal/internal_patch.dart'),
r'''
@patch
class B {
int newField;
B.newConstructor();
int newMethod() => 1;
}
class NewClass {}
int newFunction() => 2;
''');
_createSdk();
Source source = file.createSource(FastUri.parse('dart:_internal'));
CompilationUnit unit = SdkPatcher.parse(source, true, listener);
patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
_assertUnitCode(
unit,
'library dart._internal; class A {} '
'class B {B(); int newField; B.newConstructor(); int newMethod() => 1;} '
'class NewClass {} int newFunction() => 2;');
}
test_part() {
String baseLibCode = r'''
library test;