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

Side by Side Diff: tools/patch_sdk.dart

Issue 2453773002: Reland "Merge more Kernel infrastructure from kernel_sdk SDK fork." (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « tests/language/language_kernel.status ('k') | tools/patch_sdk.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env dart 1 #!/usr/bin/env dart
2 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 2 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
3 // for details. All rights reserved. Use of this source code is governed by a 3 // for details. All rights reserved. Use of this source code is governed by a
4 // BSD-style license that can be found in the LICENSE file. 4 // BSD-style license that can be found in the LICENSE file.
5 5
6 /// Command line tool to merge the SDK libraries and our patch files. 6 /// Command line tool to merge the SDK libraries and our patch files.
7 /// This is currently designed as an offline tool, but we could automate it. 7 /// This is currently designed as an offline tool, but we could automate it.
8 8
9 import 'dart:io'; 9 import 'dart:io';
10 import 'dart:math' as math; 10 import 'dart:math' as math;
11 11
12 import 'package:analyzer/analyzer.dart'; 12 import 'package:analyzer/analyzer.dart';
13 import 'package:analyzer/src/generated/sdk.dart'; 13 import 'package:analyzer/src/generated/sdk.dart';
14 import 'package:path/path.dart' as path; 14 import 'package:path/path.dart' as path;
15 15
16 void main(List<String> argv) { 16 void main(List<String> argv) {
17 if (argv.length < 2) { 17 var base = path.fromUri(Platform.script);
18 var self = path.relative(path.fromUri(Platform.script)); 18 var dartDir = path.dirname(path.dirname(path.absolute(base)));
19 var toolDir = path.relative(path.dirname(path.fromUri(Platform.script)));
20 19
21 var inputExample = path.join(toolDir, 'input_sdk'); 20 if (argv.length != 4 ||
21 !argv.isEmpty && argv.first != 'vm' && argv.first != 'ddc') {
22 var self = path.relative(base);
23 print('Usage: $self MODE SDK_DIR PATCH_DIR OUTPUT_DIR');
24 print('MODE must be one of ddc or vm.');
25
26 var toolDir = path.relative(path.dirname(base));
27 var sdkExample = path.join(toolDir, 'input_sdk');
28 var patchExample = path.join(sdkExample, 'patch');
22 var outExample = 29 var outExample =
23 path.relative(path.normalize(path.join('gen', 'patched_sdk'))); 30 path.relative(path.normalize(path.join('gen', 'patched_sdk')));
31 print('For example:');
32 print('\$ $self ddc $sdkExample $patchExample $outExample');
24 33
25 print('Usage: $self INPUT_DIR OUTPUT_DIR'); 34 var repositoryDir = path.relative(path.dirname(path.dirname(base)));
26 print('For example:'); 35 sdkExample = path.relative(path.join(repositoryDir, 'sdk'));
27 print('\$ $self $inputExample $outExample'); 36 patchExample = path.relative(path.join(repositoryDir, 'out', 'DebugX64',
37 'obj', 'gen', 'patch'));
38 outExample = path.relative(path.join(repositoryDir, 'out', 'DebugX64',
39 'obj', 'gen', 'patched_sdk'));
40 print('or:');
41 print('\$ $self vm $sdkExample $patchExample $outExample');
42
28 exit(1); 43 exit(1);
29 } 44 }
30 45
31 var input = argv[0]; 46 var mode = argv[0];
47 var input = argv[1];
32 var sdkLibIn = path.join(input, 'lib'); 48 var sdkLibIn = path.join(input, 'lib');
33 var patchIn = path.join(input, 'patch'); 49 var patchIn = argv[2];
50 var sdkOut = path.join(argv[3], 'lib');
51
34 var privateIn = path.join(input, 'private'); 52 var privateIn = path.join(input, 'private');
35 var sdkOut = path.join(argv[1], 'lib');
36
37 var INTERNAL_PATH = '_internal/compiler/js_lib/'; 53 var INTERNAL_PATH = '_internal/compiler/js_lib/';
38 54
39 // Copy libraries.dart and version 55 // Copy and patch libraries.dart and version
40 var libContents = new File(path.join(sdkLibIn, '_internal', 'libraries.dart')) 56 var libContents = new File(path.join(sdkLibIn, '_internal',
41 .readAsStringSync(); 57 'sdk_library_metadata', 'lib', 'libraries.dart')).readAsStringSync();
42 _writeSync(path.join(sdkOut, '_internal', 'libraries.dart'), libContents); 58 var patchedLibContents = libContents;
59 if (mode == 'vm') {
60 libContents = libContents.replaceAll(
61 ' libraries = const {',
62 ''' libraries = const {
63
64 "_builtin": const LibraryInfo(
65 "_builtin/_builtin.dart",
66 categories: "Client,Server",
67 implementation: true,
68 documented: false,
69 platforms: VM_PLATFORM),
70
71 "profiler": const LibraryInfo(
72 "profiler/profiler.dart",
73 maturity: Maturity.DEPRECATED,
74 documented: false),
75
76 "_vmservice": const LibraryInfo(
77 "vmservice/vmservice.dart",
78 implementation: true,
79 documented: false,
80 platforms: VM_PLATFORM),
81
82 "vmservice_io": const LibraryInfo(
83 "vmservice_io/vmservice_io.dart",
84 implementation: true,
85 documented: false,
86 platforms: VM_PLATFORM),
87
88 ''');
89 }
43 _writeSync( 90 _writeSync(
44 path.join( 91 path.join(
45 sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'), 92 sdkOut, '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'),
46 libContents); 93 libContents);
47 _writeSync(path.join(sdkOut, '..', 'version'), 94 if (mode == 'ddc') {
48 new File(path.join(sdkLibIn, '..', 'version')).readAsStringSync()); 95 _writeSync(path.join(sdkOut, '..', 'version'),
96 new File(path.join(sdkLibIn, '..', 'version')).readAsStringSync());
97 }
49 98
50 // Parse libraries.dart 99 // Parse libraries.dart
51 var sdkLibraries = _getSdkLibraries(libContents); 100 var sdkLibraries = _getSdkLibraries(libContents);
52 101
53 // Enumerate core libraries and apply patches 102 // Enumerate core libraries and apply patches
54 for (SdkLibrary library in sdkLibraries) { 103 for (SdkLibrary library in sdkLibraries) {
55 // TODO(jmesserly): analyzer does not handle the default case of 104 // TODO(jmesserly): analyzer does not handle the default case of
56 // "both platforms" correctly, and treats it as being supported on neither. 105 // "both platforms" correctly, and treats it as being supported on neither.
57 // So instead we skip explicitly marked as VM libs. 106 // So instead we skip explicitly marked as either VM or dart2js libs.
58 if (library.isVmLibrary) continue; 107 if (mode == 'ddc' ? libary.isVmLibrary : library.isDart2JsLibrary) {
108 continue;
109 }
59 110
60 var libraryOut = path.join(sdkLibIn, library.path); 111 var libraryOut = path.join(sdkLibIn, library.path);
61 var libraryIn; 112 var libraryIn;
62 if (library.path.contains(INTERNAL_PATH)) { 113 if (mode == 'vm' && library.path.contains('typed_data.dart')) {
114 // dart:typed_data is unlike the other libraries in the SDK. The VM does
115 // not apply a patch to the base SDK implementation of the library.
116 // Instead, the VM provides a replacement implementation and ignores the
117 // sources in the SDK.
118 libraryIn =
119 path.join(dartDir, 'runtime', 'lib', 'typed_data.dart');
120 } else if (mode == 'ddc' && library.path.contains(INTERNAL_PATH)) {
63 libraryIn = 121 libraryIn =
64 path.join(privateIn, library.path.replaceAll(INTERNAL_PATH, '')); 122 path.join(privateIn, library.path.replaceAll(INTERNAL_PATH, ''));
65 } else { 123 } else {
66 libraryIn = libraryOut; 124 libraryIn = libraryOut;
67 } 125 }
68 126
69 var libraryFile = new File(libraryIn); 127 var libraryFile = new File(libraryIn);
70 if (libraryFile.existsSync()) { 128 if (libraryFile.existsSync()) {
71 var outPaths = <String>[libraryOut]; 129 var outPaths = <String>[libraryOut];
72 var libraryContents = libraryFile.readAsStringSync(); 130 var libraryContents = libraryFile.readAsStringSync();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
112 needsUpdate = true; 170 needsUpdate = true;
113 break; 171 break;
114 } 172 }
115 } 173 }
116 174
117 if (needsUpdate) { 175 if (needsUpdate) {
118 var contents = <String>[libraryContents]; 176 var contents = <String>[libraryContents];
119 contents.addAll(partFiles.map((f) => f.readAsStringSync())); 177 contents.addAll(partFiles.map((f) => f.readAsStringSync()));
120 if (patchExists) { 178 if (patchExists) {
121 var patchContents = patchFile.readAsStringSync(); 179 var patchContents = patchFile.readAsStringSync();
122 contents = _patchLibrary(contents, patchContents); 180 contents = _patchLibrary(
181 patchFile.toString(), contents, patchContents);
123 } 182 }
124 183
125 for (var i = 0; i < outPaths.length; i++) { 184 for (var i = 0; i < outPaths.length; i++) {
185 if (path.basename(outPaths[i]) == 'internal.dart') {
186 contents[i] += '''
187
188 /// Marks a function as an external implementation ("native" in the Dart VM).
189 ///
190 /// Provides a backend-specific String that can be used to identify the
191 /// function's implementation
192 class ExternalName {
193 final String name;
194 const ExternalName(this.name);
195 }
196 ''';
197 }
198
126 _writeSync(outPaths[i], contents[i]); 199 _writeSync(outPaths[i], contents[i]);
127 } 200 }
128 } 201 }
129 } 202 }
130 } 203 }
204 if (mode == 'vm') {
205
206 for (var tuple in [['_builtin', 'builtin.dart']]) {
207 var vmLibrary = tuple[0];
208 var dartFile = tuple[1];
209
210 // The "dart:_builtin" library is only available for the DartVM.
211 var builtinLibraryIn = path.join(dartDir, 'runtime', 'bin', dartFile);
212 var builtinLibraryOut = path.join(sdkOut, vmLibrary, '${vmLibrary}.dart');
213 _writeSync(builtinLibraryOut, new File(builtinLibraryIn).readAsStringSync( ));
214 }
215
216 for (var file in ['loader.dart', 'server.dart', 'vmservice_io.dart']) {
217 var libraryIn = path.join(dartDir, 'runtime', 'bin', 'vmservice', file);
218 var libraryOut = path.join(sdkOut, 'vmservice_io', file);
219 _writeSync(libraryOut, new File(libraryIn).readAsStringSync());
220 }
221 }
131 } 222 }
132 223
133 /// Writes a file, creating the directory if needed. 224 /// Writes a file, creating the directory if needed.
134 void _writeSync(String filePath, String contents) { 225 void _writeSync(String filePath, String contents) {
135 var outDir = new Directory(path.dirname(filePath)); 226 var outDir = new Directory(path.dirname(filePath));
136 if (!outDir.existsSync()) outDir.createSync(recursive: true); 227 if (!outDir.existsSync()) outDir.createSync(recursive: true);
137 228
138 new File(filePath).writeAsStringSync(contents); 229 new File(filePath).writeAsStringSync(contents);
139 } 230 }
140 231
141 /// Merges dart:* library code with code from *_patch.dart file. 232 /// Merges dart:* library code with code from *_patch.dart file.
142 /// 233 ///
143 /// Takes a list of the library's parts contents, with the main library contents 234 /// Takes a list of the library's parts contents, with the main library contents
144 /// first in the list, and the contents of the patch file. 235 /// first in the list, and the contents of the patch file.
145 /// 236 ///
146 /// The result will have `@patch` implementations merged into the correct place 237 /// The result will have `@patch` implementations merged into the correct place
147 /// (e.g. the class or top-level function declaration) and all other 238 /// (e.g. the class or top-level function declaration) and all other
148 /// declarations introduced by the patch will be placed into the main library 239 /// declarations introduced by the patch will be placed into the main library
149 /// file. 240 /// file.
150 /// 241 ///
151 /// This is purely a syntactic transformation. Unlike dart2js patch files, there 242 /// This is purely a syntactic transformation. Unlike dart2js patch files, there
152 /// is no semantic meaning given to the *_patch files, and they do not magically 243 /// is no semantic meaning given to the *_patch files, and they do not magically
153 /// get their own library scope, etc. 244 /// get their own library scope, etc.
154 /// 245 ///
155 /// Editorializing: the dart2js approach requires a Dart front end such as 246 /// Editorializing: the dart2js approach requires a Dart front end such as
156 /// package:analyzer to semantically model a feature beyond what is specified 247 /// package:analyzer to semantically model a feature beyond what is specified
157 /// in the Dart language. Since this feature is only for the convenience of 248 /// in the Dart language. Since this feature is only for the convenience of
158 /// writing the dart:* libraries, and not a tool given to Dart developers, it 249 /// writing the dart:* libraries, and not a tool given to Dart developers, it
159 /// seems like a non-ideal situation. Instead we keep the preprocessing simple. 250 /// seems like a non-ideal situation. Instead we keep the preprocessing simple.
160 List<String> _patchLibrary(List<String> partsContents, String patchContents) { 251 List<String> _patchLibrary(String name,
252 List<String> partsContents,
253 String patchContents) {
161 var results = <StringEditBuffer>[]; 254 var results = <StringEditBuffer>[];
162 255
163 // Parse the patch first. We'll need to extract bits of this as we go through 256 // Parse the patch first. We'll need to extract bits of this as we go through
164 // the other files. 257 // the other files.
165 var patchFinder = new PatchFinder.parseAndVisit(patchContents); 258 final patchFinder = new PatchFinder.parseAndVisit(name, patchContents);
166 259
167 // Merge `external` declarations with the corresponding `@patch` code. 260 // Merge `external` declarations with the corresponding `@patch` code.
168 for (var partContent in partsContents) { 261 for (var partContent in partsContents) {
169 var partEdits = new StringEditBuffer(partContent); 262 var partEdits = new StringEditBuffer(partContent);
170 var partUnit = parseCompilationUnit(partContent); 263 var partUnit = parseCompilationUnit(partContent);
171 partUnit.accept(new PatchApplier(partEdits, patchFinder)); 264 partUnit.accept(new PatchApplier(partEdits, patchFinder));
172 results.add(partEdits); 265 results.add(partEdits);
173 } 266 }
174 return new List<String>.from(results.map((e) => e.toString())); 267 return new List<String>.from(results.map((e) => e.toString()));
175 } 268 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
271 } 364 }
272 365
273 class PatchFinder extends GeneralizingAstVisitor { 366 class PatchFinder extends GeneralizingAstVisitor {
274 final String contents; 367 final String contents;
275 final CompilationUnit unit; 368 final CompilationUnit unit;
276 369
277 final Map patches = <String, Declaration>{}; 370 final Map patches = <String, Declaration>{};
278 final Map mergeMembers = <String, List<ClassMember>>{}; 371 final Map mergeMembers = <String, List<ClassMember>>{};
279 final List mergeDeclarations = <CompilationUnitMember>[]; 372 final List mergeDeclarations = <CompilationUnitMember>[];
280 373
281 PatchFinder.parseAndVisit(String contents) 374 PatchFinder.parseAndVisit(String name, String contents)
282 : contents = contents, 375 : contents = contents,
283 unit = parseCompilationUnit(contents) { 376 unit = parseCompilationUnit(contents, name: name) {
284 visitCompilationUnit(unit); 377 visitCompilationUnit(unit);
285 } 378 }
286 379
287 @override 380 @override
288 visitCompilationUnitMember(CompilationUnitMember node) { 381 visitCompilationUnitMember(CompilationUnitMember node) {
289 mergeDeclarations.add(node); 382 mergeDeclarations.add(node);
290 } 383 }
291 384
292 @override 385 @override
293 visitClassDeclaration(ClassDeclaration node) { 386 visitClassDeclaration(ClassDeclaration node) {
(...skipping 27 matching lines...) Expand all
321 visitFunctionBody(node) {} // skip method bodies 414 visitFunctionBody(node) {} // skip method bodies
322 } 415 }
323 416
324 String _qualifiedName(Declaration node) { 417 String _qualifiedName(Declaration node) {
325 var parent = node.parent; 418 var parent = node.parent;
326 var className = ''; 419 var className = '';
327 if (parent is ClassDeclaration) { 420 if (parent is ClassDeclaration) {
328 className = parent.name.name + '.'; 421 className = parent.name.name + '.';
329 } 422 }
330 var name = (node as dynamic).name; 423 var name = (node as dynamic).name;
331 return className + (name != null ? name.name : ''); 424 name = (name != null ? name.name : '');
425
426 var accessor = '';
427 if (node is MethodDeclaration) {
428 if (node.isGetter) accessor = 'get:';
429 else if (node.isSetter) accessor = 'set:';
430 }
431 return className + accessor + name;
332 } 432 }
333 433
334 bool _isPatch(AnnotatedNode node) => node.metadata.any(_isPatchAnnotation); 434 bool _isPatch(AnnotatedNode node) => node.metadata.any(_isPatchAnnotation);
335 435
336 bool _isPatchAnnotation(Annotation m) => 436 bool _isPatchAnnotation(Annotation m) =>
337 m.name.name == 'patch' && m.constructorName == null && m.arguments == null; 437 m.name.name == 'patch' && m.constructorName == null && m.arguments == null;
338 438
339 /// Editable string buffer. 439 /// Editable string buffer.
340 /// 440 ///
341 /// Applies a series of edits (insertions, removals, replacements) using 441 /// Applies a series of edits (insertions, removals, replacements) using
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 if (diff != 0) return diff; 527 if (diff != 0) return diff;
428 return end - other.end; 528 return end - other.end;
429 } 529 }
430 } 530 }
431 531
432 List<SdkLibrary> _getSdkLibraries(String contents) { 532 List<SdkLibrary> _getSdkLibraries(String contents) {
433 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); 533 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true);
434 parseCompilationUnit(contents).accept(libraryBuilder); 534 parseCompilationUnit(contents).accept(libraryBuilder);
435 return libraryBuilder.librariesMap.sdkLibraries; 535 return libraryBuilder.librariesMap.sdkLibraries;
436 } 536 }
OLDNEW
« no previous file with comments | « tests/language/language_kernel.status ('k') | tools/patch_sdk.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698