Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: pkg/front_end/test/incremental_kernel_generator_test.dart

Issue 2869563002: Initial version of Fasta based IncrementalKernelGenerator. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 6
7 import 'package:analyzer/file_system/physical_file_system.dart';
8 import 'package:analyzer/src/dart/sdk/sdk.dart';
9 import 'package:front_end/compiler_options.dart'; 7 import 'package:front_end/compiler_options.dart';
10 import 'package:front_end/incremental_kernel_generator.dart'; 8 import 'package:front_end/incremental_kernel_generator.dart';
11 import 'package:front_end/memory_file_system.dart'; 9 import 'package:front_end/memory_file_system.dart';
12 import 'package:kernel/ast.dart'; 10 import 'package:kernel/ast.dart';
11 import 'package:kernel/text/ast_to_text.dart';
13 import 'package:test/test.dart'; 12 import 'package:test/test.dart';
14 import 'package:test_reflective_loader/test_reflective_loader.dart'; 13 import 'package:test_reflective_loader/test_reflective_loader.dart';
15 14
15 import 'src/incremental/mock_sdk.dart';
16
16 main() { 17 main() {
17 defineReflectiveSuite(() { 18 defineReflectiveSuite(() {
18 defineReflectiveTests(IncrementalKernelGeneratorTest); 19 defineReflectiveTests(IncrementalKernelGeneratorTest);
19 }); 20 });
20 } 21 }
21 22
22 final _sdkSummary = _readSdkSummary();
23
24 List<int> _readSdkSummary() {
25 var resourceProvider = PhysicalResourceProvider.INSTANCE;
26 var sdk = new FolderBasedDartSdk(resourceProvider,
27 FolderBasedDartSdk.defaultSdkDirectory(resourceProvider))
28 ..useSummary = true;
29 var path = resourceProvider.pathContext
30 .join(sdk.directory.path, 'lib', '_internal', 'strong.sum');
31 return resourceProvider.getFile(path).readAsBytesSync();
32 }
33
34 @reflectiveTest 23 @reflectiveTest
35 class IncrementalKernelGeneratorTest { 24 class IncrementalKernelGeneratorTest {
36 static final sdkSummaryUri = Uri.parse('special:sdk_summary');
37
38 /// Virtual filesystem for testing. 25 /// Virtual filesystem for testing.
39 final fileSystem = new MemoryFileSystem(Uri.parse('file:///')); 26 final fileSystem = new MemoryFileSystem(Uri.parse('file:///'));
40 27
41 /// The object under test. 28 /// The object under test.
42 IncrementalKernelGenerator incrementalKernelGenerator; 29 IncrementalKernelGenerator incrementalKernelGenerator;
43 30
44 Future<Map<Uri, Program>> getInitialState(Uri startingUri) async { 31 /// TODO(scheglov) Why do we return a Map?
45 fileSystem.entityForUri(sdkSummaryUri).writeAsBytesSync(_sdkSummary); 32 /// From the discussion yesterday it seems to me that we always have
33 /// just one program - with all libraries with code, or with some libraries
34 /// with code and some with only outlines.
Paul Berry 2017/05/07 14:17:40 My understanding from talking to Dan Rubel and the
scheglov 2017/05/07 17:38:49 FWIW, having a kernel file per affected library wo
Paul Berry 2017/05/08 12:55:14 Agreed. The way I originally wanted to implement
35 Future<Map<Uri, Program>> getInitialState(Uri entryPoint) async {
36 Map<String, Uri> dartLibraries = createSdkFiles(fileSystem);
37 // TODO(scheglov) Builder the SDK kernel and set it into the options.
38
39 // TODO(scheglov) Make `.packages` file optional.
40
46 incrementalKernelGenerator = new IncrementalKernelGenerator( 41 incrementalKernelGenerator = new IncrementalKernelGenerator(
47 startingUri, 42 entryPoint,
48 new CompilerOptions() 43 new CompilerOptions()
49 ..fileSystem = fileSystem 44 ..fileSystem = fileSystem
45 ..strongMode = true
50 ..chaseDependencies = true 46 ..chaseDependencies = true
51 ..sdkSummary = sdkSummaryUri 47 ..dartLibraries = dartLibraries
52 ..packagesFileUri = new Uri()); 48 ..packagesFileUri = Uri.parse('file:///test/.packages'));
53 return (await incrementalKernelGenerator.computeDelta()).newState; 49 return (await incrementalKernelGenerator.computeDelta()).newState;
54 } 50 }
55 51
56 test_incrementalUpdate_referenceToCore() async { 52 test_updateEntryPoint() async {
57 writeFiles({'/foo.dart': 'main() { print(1); }'}); 53 writeFile('/test/.packages', 'test:lib/');
58 var fooUri = Uri.parse('file:///foo.dart'); 54 String path = '/test/lib/test.dart';
59 var coreUri = Uri.parse('dart:core'); 55 Uri uri = writeFile(
60 var initialState = await getInitialState(fooUri); 56 path,
61 expect(initialState.keys, unorderedEquals([fooUri])); 57 r'''
58 main() {
59 var v = 1;
60 }
61 ''');
62 62
63 void _checkMain(Program program, int expectedArgument) { 63 // Compute the initial state
64 expect(_getLibraryUris(program), unorderedEquals([fooUri, coreUri])); 64 {
65 var mainStatements = _getProcedureStatements( 65 Map<Uri, Program> initialState = await getInitialState(uri);
66 _getProcedure(_getLibrary(program, fooUri), 'main')); 66 expect(initialState.keys, unorderedEquals([uri]));
67 expect(mainStatements, hasLength(1)); 67
68 _checkPrintLiteralInt(mainStatements[0], expectedArgument); 68 Library library = _getLibrary(initialState[uri], uri);
69 var coreLibrary = _getLibrary(program, coreUri); 69 expect(
70 expect(coreLibrary.procedures, hasLength(1)); 70 _getLibraryText(library),
71 expect(coreLibrary.procedures[0].name.name, 'print'); 71 r'''
72 expect(coreLibrary.procedures[0].function.body, isNull); 72 library;
73 import self as self;
74 import "dart:core" as core;
75
76 static method main() → dynamic {
77 core::int v = 1;
78 }
79 ''');
73 } 80 }
74 81
75 _checkMain(initialState[fooUri], 1); 82 // Update the entry point library.
76 writeFiles({'/foo.dart': 'main() { print(2); }'}); 83 writeFile(
77 incrementalKernelGenerator.invalidateAll(); 84 path,
78 var deltaProgram = await incrementalKernelGenerator.computeDelta(); 85 r'''
79 expect(deltaProgram.newState.keys, unorderedEquals([fooUri])); 86 main() {
80 _checkMain(deltaProgram.newState[fooUri], 2); 87 var v = 2.3;
88 }
89 ''');
90
91 // The delta has the updated entry point library.
92 {
93 DeltaProgram delta = await incrementalKernelGenerator.computeDelta();
94 expect(delta.newState.keys, unorderedEquals([uri]));
95
96 Library library = _getLibrary(delta.newState[uri], uri);
97 expect(
98 _getLibraryText(library),
99 r'''
100 library;
101 import self as self;
102 import "dart:core" as core;
103
104 static method main() → dynamic {
105 core::double v = 2.3;
106 }
107 ''');
108 }
81 } 109 }
82 110
83 test_part() async { 111 /// Write the given [text] of the file with the given [path] into the
84 writeFiles({ 112 /// virtual filesystem. Return the URI of the file.
85 '/foo.dart': 'library foo; part "bar.dart"; main() { print(1); f(); }', 113 Uri writeFile(String path, String text) {
86 '/bar.dart': 'part of foo; f() { print(2); }' 114 Uri uri = Uri.parse('file://$path');
87 }); 115 fileSystem.entityForUri(uri).writeAsStringSync(text);
88 var fooUri = Uri.parse('file:///foo.dart'); 116 return uri;
89 var initialState = await getInitialState(fooUri);
90 expect(initialState.keys, unorderedEquals([fooUri]));
91 var library = _getLibrary(initialState[fooUri], fooUri);
92 var mainStatements =
93 _getProcedureStatements(_getProcedure(library, 'main'));
94 var fProcedure = _getProcedure(library, 'f');
95 var fStatements = _getProcedureStatements(fProcedure);
96 expect(mainStatements, hasLength(2));
97 _checkPrintLiteralInt(mainStatements[0], 1);
98 _checkFunctionCall(mainStatements[1], fProcedure);
99 expect(fStatements, hasLength(1));
100 _checkPrintLiteralInt(fStatements[0], 2);
101 // TODO(paulberry): now test incremental updates
102 } 117 }
103 118
119 // test_part() async {
120 // writeFiles({
121 // '/foo.dart': 'library foo; part "bar.dart"; main() { print(1); f(); }',
122 // '/bar.dart': 'part of foo; f() { print(2); }'
123 // });
124 // var fooUri = Uri.parse('file:///foo.dart');
125 // var initialState = await getInitialState(fooUri);
126 // expect(initialState.keys, unorderedEquals([fooUri]));
127 // var library = _getLibrary(initialState[fooUri], fooUri);
128 // var mainStatements =
129 // _getProcedureStatements(_getProcedure(library, 'main'));
130 // var fProcedure = _getProcedure(library, 'f');
131 // var fStatements = _getProcedureStatements(fProcedure);
132 // expect(mainStatements, hasLength(2));
133 // _checkPrintLiteralInt(mainStatements[0], 1);
134 // _checkFunctionCall(mainStatements[1], fProcedure);
135 // expect(fStatements, hasLength(1));
136 // _checkPrintLiteralInt(fStatements[0], 2);
137 // TODO(paulberry): now test incremental updates
138 // }
139
104 /// Write the given file contents to the virtual filesystem. 140 /// Write the given file contents to the virtual filesystem.
105 void writeFiles(Map<String, String> contents) { 141 void writeFiles(Map<String, String> contents) {
106 contents.forEach((path, text) { 142 contents.forEach(writeFile);
107 fileSystem
108 .entityForUri(Uri.parse('file://$path'))
109 .writeAsStringSync(text);
110 });
111 }
112
113 void _checkFunctionCall(Statement statement, Procedure expectedTarget) {
114 expect(statement, new isInstanceOf<ExpressionStatement>());
115 var expressionStatement = statement as ExpressionStatement;
116 expect(
117 expressionStatement.expression, new isInstanceOf<StaticInvocation>());
118 var staticInvocation = expressionStatement.expression as StaticInvocation;
119 expect(staticInvocation.target, same(expectedTarget));
120 }
121
122 void _checkPrintLiteralInt(Statement statement, int expectedArgument) {
123 expect(statement, new isInstanceOf<ExpressionStatement>());
124 var expressionStatement = statement as ExpressionStatement;
125 expect(
126 expressionStatement.expression, new isInstanceOf<StaticInvocation>());
127 var staticInvocation = expressionStatement.expression as StaticInvocation;
128 expect(staticInvocation.target.name.name, 'print');
129 expect(staticInvocation.arguments.positional, hasLength(1));
130 expect(staticInvocation.arguments.positional[0],
131 new isInstanceOf<IntLiteral>());
132 var intLiteral = staticInvocation.arguments.positional[0] as IntLiteral;
133 expect(intLiteral.value, expectedArgument);
134 } 143 }
135 144
136 Library _getLibrary(Program program, Uri uri) { 145 Library _getLibrary(Program program, Uri uri) {
137 for (var library in program.libraries) { 146 for (var library in program.libraries) {
138 if (library.importUri == uri) return library; 147 if (library.importUri == uri) return library;
139 } 148 }
140 throw fail('No library found with URI "$uri"'); 149 throw fail('No library found with URI "$uri"');
141 } 150 }
142 151
143 List<Uri> _getLibraryUris(Program program) => 152 String _getLibraryText(Library library) {
144 program.libraries.map((library) => library.importUri).toList(); 153 StringBuffer buffer = new StringBuffer();
145 154 new Printer(buffer, syntheticNames: new NameSystem())
146 Procedure _getProcedure(Library library, String name) { 155 .writeLibraryFile(library);
147 for (var procedure in library.procedures) { 156 return buffer.toString();
148 if (procedure.name.name == name) return procedure;
149 }
150 throw fail('No function declaration found with name "$name"');
151 }
152
153 List<Statement> _getProcedureStatements(Procedure procedure) {
154 var body = procedure.function.body;
155 expect(body, new isInstanceOf<Block>());
156 return (body as Block).statements;
157 } 157 }
158 } 158 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698