| OLD | NEW |
| 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 var self = path.relative(path.fromUri(Platform.script)); |
| 17 if (argv.length < 2) { | 18 if (argv.length < 2) { |
| 18 var self = path.relative(path.fromUri(Platform.script)); | |
| 19 var toolDir = path.relative(path.dirname(path.fromUri(Platform.script))); | 19 var toolDir = path.relative(path.dirname(path.fromUri(Platform.script))); |
| 20 | 20 |
| 21 var inputExample = path.join(toolDir, 'input_sdk'); | 21 var inputExample = path.join(toolDir, 'input_sdk'); |
| 22 var outExample = | 22 var outExample = |
| 23 path.relative(path.normalize(path.join('gen', 'patched_sdk'))); | 23 path.relative(path.normalize(path.join('gen', 'patched_sdk'))); |
| 24 | 24 |
| 25 print('Usage: $self INPUT_DIR OUTPUT_DIR'); | 25 print('Usage: $self INPUT_DIR OUTPUT_DIR'); |
| 26 print('For example:'); | 26 print('For example:'); |
| 27 print('\$ $self $inputExample $outExample'); | 27 print('\$ $self $inputExample $outExample'); |
| 28 exit(1); | 28 exit(1); |
| 29 } | 29 } |
| 30 | 30 |
| 31 var selfModifyTime = new File(self).lastModifiedSync().millisecondsSinceEpoch; |
| 32 |
| 31 var input = argv[0]; | 33 var input = argv[0]; |
| 32 var sdkLibIn = path.join(input, 'lib'); | 34 var sdkLibIn = path.join(input, 'lib'); |
| 33 var patchIn = path.join(input, 'patch'); | 35 var patchIn = path.join(input, 'patch'); |
| 34 var privateIn = path.join(input, 'private'); | 36 var privateIn = path.join(input, 'private'); |
| 35 var sdkOut = path.join(argv[1], 'lib'); | 37 var sdkOut = path.join(argv[1], 'lib'); |
| 36 | 38 |
| 37 var INTERNAL_PATH = '_internal/compiler/js_lib/'; | 39 var INTERNAL_PATH = '_internal/compiler/js_lib/'; |
| 38 | 40 |
| 39 // Copy libraries.dart and version | 41 // Copy libraries.dart and version |
| 40 var libContents = new File(path.join(sdkLibIn, '_internal', 'libraries.dart')) | 42 var libContents = new File(path.join(sdkLibIn, '_internal', 'libraries.dart')) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 64 path.join(privateIn, library.path.replaceAll(INTERNAL_PATH, '')); | 66 path.join(privateIn, library.path.replaceAll(INTERNAL_PATH, '')); |
| 65 } else { | 67 } else { |
| 66 libraryIn = libraryOut; | 68 libraryIn = libraryOut; |
| 67 } | 69 } |
| 68 | 70 |
| 69 var libraryFile = new File(libraryIn); | 71 var libraryFile = new File(libraryIn); |
| 70 if (libraryFile.existsSync()) { | 72 if (libraryFile.existsSync()) { |
| 71 var outPaths = <String>[libraryOut]; | 73 var outPaths = <String>[libraryOut]; |
| 72 var libraryContents = libraryFile.readAsStringSync(); | 74 var libraryContents = libraryFile.readAsStringSync(); |
| 73 | 75 |
| 74 int inputModifyTime = | 76 int inputModifyTime = math.max(selfModifyTime, |
| 75 libraryFile.lastModifiedSync().millisecondsSinceEpoch; | 77 libraryFile.lastModifiedSync().millisecondsSinceEpoch); |
| 76 var partFiles = <File>[]; | 78 var partFiles = <File>[]; |
| 77 for (var part in parseDirectives(libraryContents).directives) { | 79 for (var part in parseDirectives(libraryContents).directives) { |
| 78 if (part is PartDirective) { | 80 if (part is PartDirective) { |
| 79 var partPath = part.uri.stringValue; | 81 var partPath = part.uri.stringValue; |
| 80 outPaths.add(path.join(path.dirname(libraryOut), partPath)); | 82 outPaths.add(path.join(path.dirname(libraryOut), partPath)); |
| 81 | 83 |
| 82 var partFile = new File(path.join(path.dirname(libraryIn), partPath)); | 84 var partFile = new File(path.join(path.dirname(libraryIn), partPath)); |
| 83 partFiles.add(partFile); | 85 partFiles.add(partFile); |
| 84 inputModifyTime = math.max(inputModifyTime, | 86 inputModifyTime = math.max(inputModifyTime, |
| 85 partFile.lastModifiedSync().millisecondsSinceEpoch); | 87 partFile.lastModifiedSync().millisecondsSinceEpoch); |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 var patchNode = patch.patches[name]; | 258 var patchNode = patch.patches[name]; |
| 257 if (patchNode == null) { | 259 if (patchNode == null) { |
| 258 print('warning: patch not found for $name: $node'); | 260 print('warning: patch not found for $name: $node'); |
| 259 return; | 261 return; |
| 260 } | 262 } |
| 261 | 263 |
| 262 Annotation patchMeta = patchNode.metadata.lastWhere(_isPatchAnnotation); | 264 Annotation patchMeta = patchNode.metadata.lastWhere(_isPatchAnnotation); |
| 263 int start = patchMeta.endToken.next.offset; | 265 int start = patchMeta.endToken.next.offset; |
| 264 var code = patch.contents.substring(start, patchNode.end); | 266 var code = patch.contents.substring(start, patchNode.end); |
| 265 | 267 |
| 268 // Const factory constructors can't be legally parsed from the patch file, |
| 269 // so we need to omit the "const" there, but still preserve it. |
| 270 if (node is ConstructorDeclaration && |
| 271 node.constKeyword != null && |
| 272 patchNode is ConstructorDeclaration && |
| 273 patchNode.constKeyword == null) { |
| 274 code = 'const $code'; |
| 275 } |
| 276 |
| 266 // For some node like static fields, the node's offset doesn't include | 277 // For some node like static fields, the node's offset doesn't include |
| 267 // the external keyword. Also starting from the keyword lets us preserve | 278 // the external keyword. Also starting from the keyword lets us preserve |
| 268 // documentation comments. | 279 // documentation comments. |
| 269 edits.replace(externalKeyword.offset, node.end, code); | 280 edits.replace(externalKeyword.offset, node.end, code); |
| 270 } | 281 } |
| 271 } | 282 } |
| 272 | 283 |
| 273 class PatchFinder extends GeneralizingAstVisitor { | 284 class PatchFinder extends GeneralizingAstVisitor { |
| 274 final String contents; | 285 final String contents; |
| 275 final CompilationUnit unit; | 286 final CompilationUnit unit; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 427 if (diff != 0) return diff; | 438 if (diff != 0) return diff; |
| 428 return end - other.end; | 439 return end - other.end; |
| 429 } | 440 } |
| 430 } | 441 } |
| 431 | 442 |
| 432 List<SdkLibrary> _getSdkLibraries(String contents) { | 443 List<SdkLibrary> _getSdkLibraries(String contents) { |
| 433 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); | 444 var libraryBuilder = new SdkLibrariesReader_LibraryBuilder(true); |
| 434 parseCompilationUnit(contents).accept(libraryBuilder); | 445 parseCompilationUnit(contents).accept(libraryBuilder); |
| 435 return libraryBuilder.librariesMap.sdkLibraries; | 446 return libraryBuilder.librariesMap.sdkLibraries; |
| 436 } | 447 } |
| OLD | NEW |