Serialize this-types in NativeBehavior separately.

BUG=
R=het@google.com

Review URL: https://codereview.chromium.org/2150333002 .
This commit is contained in:
Johnni Winther 2016-07-18 10:42:23 +02:00
parent 2107c13ba2
commit 3305201211
6 changed files with 83 additions and 20 deletions

View file

@ -131,12 +131,16 @@ class DebugIterable<E> implements Iterable<E> {
E singleWhere(bool test(E element)) => iterable.singleWhere(test);
E elementAt(int index) => iterable.elementAt(index);
String toString() => iterable.toString();
}
class DebugList<E> extends DebugIterable<E> implements List<E> {
DebugCallback addCallback;
DebugCallback addAllCallback;
DebugList(List<E> list, {this.addCallback}) : super(list);
DebugList(List<E> list, {this.addCallback, this.addAllCallback})
: super(list);
List<E> get list => iterable;
@ -159,7 +163,12 @@ class DebugList<E> extends DebugIterable<E> implements List<E> {
list.add(value);
}
void addAll(Iterable<E> iterable) => list.addAll(iterable);
void addAll(Iterable<E> iterable) {
if (addAllCallback != null) {
addAllCallback('addAll', iterable, null);
}
list.addAll(iterable);
}
Iterable<E> get reversed => list.reversed;

View file

@ -18,8 +18,10 @@ import 'js_backend.dart';
const String _BACKEND_DATA_TAG = 'jsBackendData';
const Key DART_TYPES_RETURNED = const Key('dartTypesReturned');
const Key THIS_TYPES_RETURNED = const Key('thisTypesReturned');
const Key SPECIAL_TYPES_RETURNED = const Key('specialTypesReturned');
const Key DART_TYPES_INSTANTIATED = const Key('dartTypesInstantiated');
const Key THIS_TYPES_INSTANTIATED = const Key('thisTypesInstantiated');
const Key SPECIAL_TYPES_INSTANTIATED = const Key('specialTypesInstantiated');
const Key CODE_TEMPLATE = const Key('codeTemplate');
const Key SIDE_EFFECTS = const Key('sideEffects');
@ -150,15 +152,43 @@ class JavaScriptBackendDeserializer implements DeserializerPlugin {
}
class NativeBehaviorSerialization {
/// Returns a list of the [DartType]s in [types].
static const int NORMAL_TYPE = 0;
static const int THIS_TYPE = 1;
static const int SPECIAL_TYPE = 2;
static int getTypeKind(var type) {
if (type is DartType) {
// TODO(johnniwinther): Remove this when annotation are no longer resolved
// to this-types.
if (type is GenericType &&
type.isGeneric &&
type == type.element.thisType) {
return THIS_TYPE;
}
return NORMAL_TYPE;
}
return SPECIAL_TYPE;
}
/// Returns a list of the non-this-type [DartType]s in [types].
static List<DartType> filterDartTypes(List types) {
return types.where((type) => type is DartType).toList();
return types.where((type) => getTypeKind(type) == NORMAL_TYPE).toList();
}
// TODO(johnniwinther): Remove this when annotation are no longer resolved
// to this-types.
/// Returns a list of the classes of this-types in [types].
static List<Element> filterThisTypes(List types) {
return types
.where((type) => getTypeKind(type) == THIS_TYPE)
.map((type) => type.element)
.toList();
}
/// Returns a list of the names of the [SpecialType]s in [types].
static List<String> filterSpecialTypes(List types) {
return types
.where((type) => type is SpecialType)
.where((type) => getTypeKind(type) == SPECIAL_TYPE)
.map((SpecialType type) => type.name)
.toList();
}
@ -167,11 +197,15 @@ class NativeBehaviorSerialization {
NativeBehavior behavior, ObjectEncoder encoder) {
encoder.setTypes(
DART_TYPES_RETURNED, filterDartTypes(behavior.typesReturned));
encoder.setElements(
THIS_TYPES_RETURNED, filterThisTypes(behavior.typesReturned));
encoder.setStrings(
SPECIAL_TYPES_RETURNED, filterSpecialTypes(behavior.typesReturned));
encoder.setTypes(
DART_TYPES_INSTANTIATED, filterDartTypes(behavior.typesInstantiated));
encoder.setElements(
THIS_TYPES_INSTANTIATED, filterThisTypes(behavior.typesInstantiated));
encoder.setStrings(SPECIAL_TYPES_INSTANTIATED,
filterSpecialTypes(behavior.typesInstantiated));
@ -192,12 +226,20 @@ class NativeBehaviorSerialization {
behavior.typesReturned
.addAll(decoder.getTypes(DART_TYPES_RETURNED, isOptional: true));
behavior.typesReturned.addAll(decoder
.getElements(THIS_TYPES_RETURNED, isOptional: true)
.map((element) => element.thisType)
.toList());
behavior.typesReturned.addAll(decoder
.getStrings(SPECIAL_TYPES_RETURNED, isOptional: true)
.map(SpecialType.fromName));
behavior.typesInstantiated
.addAll(decoder.getTypes(DART_TYPES_INSTANTIATED, isOptional: true));
behavior.typesInstantiated.addAll(decoder
.getElements(THIS_TYPES_INSTANTIATED, isOptional: true)
.map((element) => element.thisType)
.toList());
behavior.typesInstantiated.addAll(decoder
.getStrings(SPECIAL_TYPES_INSTANTIATED, isOptional: true)
.map(SpecialType.fromName));

View file

@ -692,6 +692,7 @@ class Serializer {
/// Helper used to check that external references are serialized by
/// the right kind.
bool verifyElement(var found, var expected) {
if (found == null) return false;
found = found.declaration;
if (found == expected) return true;
if (found.isAbstractField && expected.isGetter) {

View file

@ -33,7 +33,8 @@ class MemorySourceFileProvider extends SourceFileProvider {
}
String source = memorySourceFiles[resourceUri.path];
if (source == null) {
return new Future.error(new Exception('No such file $resourceUri'));
return new Future.error(new Exception(
'No such memory file $resourceUri in ${memorySourceFiles.keys}'));
}
this.sourceFiles[resourceUri] =
new StringSourceFile.fromUri(resourceUri, source);
@ -48,7 +49,8 @@ class MemorySourceFileProvider extends SourceFileProvider {
}
String source = memorySourceFiles[resourceUri.path];
if (source == null) {
throw new Exception('No such file $resourceUri');
throw new Exception(
'No such memory file $resourceUri in ${memorySourceFiles.keys}');
}
return new StringSourceFile.fromUri(resourceUri, source);
}

View file

@ -169,7 +169,10 @@ class SerializedData {
final Uri uri;
final String data;
SerializedData(this.uri, this.data);
SerializedData(this.uri, this.data) {
assert(uri != null);
assert(data != null);
}
Map<String, String> toMemorySourceFiles([Map<String, String> input]) {
Map<String, String> sourceFiles = <String, String>{};
@ -200,13 +203,6 @@ class SerializedData {
}
}
String extractSerializedData(
Compiler compiler, Iterable<LibraryElement> libraries) {
BufferedEventSink sink = new BufferedEventSink();
compiler.serialization.serializeToSink(sink, libraries);
return sink.text;
}
Future<List<SerializedData>> preserializeData(
SerializedData serializedData, Test test) async {
if (test == null ||
@ -223,19 +219,20 @@ Future<List<SerializedData>> preserializeData(
if (test.unserializedSourceFiles != null) {
sourceFiles.addAll(test.unserializedSourceFiles);
}
OutputCollector outputCollector = new OutputCollector();
Compiler compiler = compilerFor(
memorySourceFiles: sourceFiles,
resolutionInputs: serializedData.toUris(),
options: [Flags.analyzeOnly, Flags.analyzeMain]);
options: [Flags.resolveOnly],
outputProvider: outputCollector);
compiler.librariesToAnalyzeWhenRun = uriList;
compiler.serialization.supportSerialization = true;
await compiler.run(null);
List<LibraryElement> libraries = <LibraryElement>[];
for (Uri uri in uriList) {
libraries.add(compiler.libraryLoader.lookupLibrary(uri));
}
SerializedData additionalSerializedData =
new SerializedData(Uri.parse('memory:additional.data'),
extractSerializedData(compiler, libraries));
SerializedData additionalSerializedData = new SerializedData(
Uri.parse('memory:additional.data'),
outputCollector.getOutput('', 'data'));
return <SerializedData>[serializedData, additionalSerializedData];
}

View file

@ -629,6 +629,18 @@ import "dart:core" deferred as core;
test() {
core.loadLibrary().then((_) => null);
}
''',
}),
const Test('Use of dart:indexed_db', const {
'main.dart': '''
import 'a.dart';
main() {}
''',
}, preserializedSourceFiles: const {
'a.dart': '''
import 'dart:indexed_db';
''',
}),
];