| OLD | NEW |
| 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:front_end/file_system.dart'; | 7 import 'package:front_end/file_system.dart'; |
| 8 import 'package:front_end/incremental_kernel_generator.dart'; | 8 import 'package:front_end/incremental_kernel_generator.dart'; |
| 9 import 'package:front_end/incremental_resolved_ast_generator.dart'; | 9 import 'package:front_end/incremental_resolved_ast_generator.dart'; |
| 10 import 'package:front_end/src/base/processed_options.dart'; | 10 import 'package:front_end/src/base/processed_options.dart'; |
| 11 import 'package:front_end/src/fasta/dill/dill_target.dart'; | 11 import 'package:front_end/src/fasta/dill/dill_target.dart'; |
| 12 import 'package:front_end/src/fasta/kernel/kernel_target.dart'; | 12 import 'package:front_end/src/fasta/kernel/kernel_target.dart'; |
| 13 import 'package:front_end/src/fasta/ticker.dart'; | 13 import 'package:front_end/src/fasta/ticker.dart'; |
| 14 import 'package:front_end/src/fasta/translate_uri.dart'; | 14 import 'package:front_end/src/fasta/translate_uri.dart'; |
| 15 import 'package:front_end/src/incremental/file_state.dart'; | |
| 16 import 'package:kernel/kernel.dart' hide Source; | 15 import 'package:kernel/kernel.dart' hide Source; |
| 17 import 'package:kernel/target/vm.dart'; | |
| 18 | 16 |
| 19 dynamic unimplemented() { | 17 dynamic unimplemented() { |
| 20 // TODO(paulberry): get rid of this. | 18 // TODO(paulberry): get rid of this. |
| 21 throw new UnimplementedError(); | 19 throw new UnimplementedError(); |
| 22 } | 20 } |
| 23 | 21 |
| 24 /// Implementation of [IncrementalKernelGenerator]. | 22 /// Implementation of [IncrementalKernelGenerator]. |
| 25 /// | 23 /// |
| 26 /// TODO(scheglov) Update the documentation. | 24 /// TODO(scheglov) Update the documentation. |
| 27 /// | 25 /// |
| 28 /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is | 26 /// Theory of operation: an instance of [IncrementalResolvedAstGenerator] is |
| 29 /// used to obtain resolved ASTs, and these are fed into kernel code generation | 27 /// used to obtain resolved ASTs, and these are fed into kernel code generation |
| 30 /// logic. | 28 /// logic. |
| 31 class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { | 29 class IncrementalKernelGeneratorImpl implements IncrementalKernelGenerator { |
| 32 /// The URI of the program entry point. | 30 /// The URI of the program entry point. |
| 33 final Uri _entryPoint; | 31 final Uri _entryPoint; |
| 34 | 32 |
| 35 /// The compiler options, such as the [FileSystem], the SDK dill location, | 33 /// The compiler options, such as the [FileSystem], the SDK dill location, |
| 36 /// etc. | 34 /// etc. |
| 37 final ProcessedOptions _options; | 35 final ProcessedOptions _options; |
| 38 | 36 |
| 39 /// The set of absolute file URIs that were reported through [invalidate] | |
| 40 /// and not checked for actual changes yet. | |
| 41 final Set<Uri> _invalidatedFiles = new Set<Uri>(); | |
| 42 | |
| 43 /// The object that knows how to resolve "package:" and "dart:" URIs. | 37 /// The object that knows how to resolve "package:" and "dart:" URIs. |
| 44 TranslateUri _uriTranslator; | 38 TranslateUri _uriTranslator; |
| 45 | 39 |
| 46 /// The current file system state. | |
| 47 FileSystemState _fsState; | |
| 48 | |
| 49 /// The cached SDK kernel. | 40 /// The cached SDK kernel. |
| 50 DillTarget _sdkDillTarget; | 41 DillTarget _sdkDillTarget; |
| 51 | 42 |
| 52 IncrementalKernelGeneratorImpl(this._entryPoint, this._options); | 43 IncrementalKernelGeneratorImpl(this._entryPoint, this._options); |
| 53 | 44 |
| 54 @override | 45 @override |
| 55 Future<DeltaProgram> computeDelta( | 46 Future<DeltaProgram> computeDelta( |
| 56 {Future<Null> watch(Uri uri, bool used)}) async { | 47 {Future<Null> watch(Uri uri, bool used)}) async { |
| 57 await _initialize(); | 48 _uriTranslator ??= await _options.getUriTranslator(); |
| 58 await _ensureVmLibrariesLoaded(); | |
| 59 await _refreshInvalidatedFiles(); | |
| 60 | |
| 61 // Ensure that the graph starting at the entry point is ready. | |
| 62 await _fsState.getFile(_entryPoint); | |
| 63 | 49 |
| 64 DillTarget sdkTarget = await _getSdkDillTarget(); | 50 DillTarget sdkTarget = await _getSdkDillTarget(); |
| 65 // TODO(scheglov) Use it to also serve other package kernels. | 51 // TODO(scheglov) Use it to also serve other package kernels. |
| 66 | 52 |
| 67 KernelTarget kernelTarget = new KernelTarget(_fsState.fileSystemView, | 53 KernelTarget kernelTarget = new KernelTarget(_options.fileSystem, sdkTarget, |
| 68 sdkTarget, _uriTranslator, _options.strongMode, null); | 54 _uriTranslator, _options.strongMode, null); |
| 69 kernelTarget.read(_entryPoint); | 55 kernelTarget.read(_entryPoint); |
| 70 | 56 |
| 71 // TODO(scheglov) Replace with a better API. | 57 // TODO(scheglov) Replace with a better API. |
| 72 // Firstly, we don't "write" anything here. | 58 // Firstly, we don't "write" anything here. |
| 73 // Secondly, it catches all the exceptions and write them to `stderr`. | 59 // Secondly, it catches all the exceptions and write them to `stderr`. |
| 74 // This is too interactive and not API-clients friendly. | 60 // This is too interactive and not API-clients friendly. |
| 75 await kernelTarget.writeOutline(null); | 61 await kernelTarget.writeOutline(null); |
| 76 | 62 |
| 77 // TODO(scheglov) Replace with a better API. | 63 // TODO(scheglov) Replace with a better API. |
| 78 Program program = await kernelTarget.writeProgram(null); | 64 Program program = await kernelTarget.writeProgram(null); |
| 79 return new DeltaProgram(program); | 65 return new DeltaProgram(program); |
| 80 } | 66 } |
| 81 | 67 |
| 82 @override | 68 @override |
| 83 void invalidate(Uri uri) { | 69 void invalidate(String path) => unimplemented(); |
| 84 _invalidatedFiles.add(uri); | |
| 85 } | |
| 86 | 70 |
| 87 @override | 71 @override |
| 88 void invalidateAll() => unimplemented(); | 72 void invalidateAll() => unimplemented(); |
| 89 | 73 |
| 90 /// Fasta unconditionally loads all VM libraries. In order to be able to | |
| 91 /// serve them using the file system view, we need to ask [_fsState] for | |
| 92 /// the corresponding files. | |
| 93 Future<Null> _ensureVmLibrariesLoaded() async { | |
| 94 List<String> extraLibraries = new VmTarget(null).extraRequiredLibraries; | |
| 95 for (String absoluteUriStr in extraLibraries) { | |
| 96 Uri absoluteUri = Uri.parse(absoluteUriStr); | |
| 97 Uri fileUri = _uriTranslator.translate(absoluteUri); | |
| 98 await _fsState.getFile(fileUri); | |
| 99 } | |
| 100 } | |
| 101 | |
| 102 /// Return the [DillTarget] that is used inside of [KernelTarget] to | 74 /// Return the [DillTarget] that is used inside of [KernelTarget] to |
| 103 /// resynthesize SDK libraries. | 75 /// resynthesize SDK libraries. |
| 104 Future<DillTarget> _getSdkDillTarget() async { | 76 Future<DillTarget> _getSdkDillTarget() async { |
| 105 if (_sdkDillTarget == null) { | 77 if (_sdkDillTarget == null) { |
| 106 _sdkDillTarget = | 78 _sdkDillTarget = |
| 107 new DillTarget(new Ticker(isVerbose: false), _uriTranslator); | 79 new DillTarget(new Ticker(isVerbose: false), _uriTranslator); |
| 108 // TODO(scheglov) Read the SDK kernel. | 80 // TODO(scheglov) Read the SDK kernel. |
| 109 // _sdkDillTarget.read(options.sdkSummary); | 81 // _sdkDillTarget.read(options.sdkSummary); |
| 110 // await _sdkDillTarget.writeOutline(null); | 82 // await _sdkDillTarget.writeOutline(null); |
| 111 } else { | 83 } else { |
| 112 // Program sdkProgram = _sdkDillTarget.loader.program; | 84 // Program sdkProgram = _sdkDillTarget.loader.program; |
| 113 // sdkProgram.visitChildren(new _ClearCanonicalNamesVisitor()); | 85 // sdkProgram.visitChildren(new _ClearCanonicalNamesVisitor()); |
| 114 } | 86 } |
| 115 return _sdkDillTarget; | 87 return _sdkDillTarget; |
| 116 } | 88 } |
| 117 | |
| 118 /// Ensure that asynchronous data from options is ready. | |
| 119 /// | |
| 120 /// Ideally this data should be prepared in the constructor, but constructors | |
| 121 /// cannot be asynchronous. | |
| 122 Future<Null> _initialize() async { | |
| 123 _uriTranslator ??= await _options.getUriTranslator(); | |
| 124 _fsState ??= new FileSystemState(_options.fileSystem, _uriTranslator); | |
| 125 } | |
| 126 | |
| 127 /// Refresh all the invalidated files and update dependencies. | |
| 128 Future<Null> _refreshInvalidatedFiles() async { | |
| 129 for (Uri fileUri in _invalidatedFiles) { | |
| 130 FileState file = await _fsState.getFile(fileUri); | |
| 131 await file.refresh(); | |
| 132 } | |
| 133 _invalidatedFiles.clear(); | |
| 134 } | |
| 135 } | 89 } |
| 136 | 90 |
| 137 ///// Clears canonical names of [NamedNode] references. | 91 ///// Clears canonical names of [NamedNode] references. |
| 138 //class _ClearCanonicalNamesVisitor extends Visitor { | 92 //class _ClearCanonicalNamesVisitor extends Visitor { |
| 139 // defaultNode(Node node) { | 93 // defaultNode(Node node) { |
| 140 // if (node is NamedNode) { | 94 // if (node is NamedNode) { |
| 141 // node.reference.canonicalName = null; | 95 // node.reference.canonicalName = null; |
| 142 // } | 96 // } |
| 143 // node.visitChildren(this); | 97 // node.visitChildren(this); |
| 144 // } | 98 // } |
| 145 //} | 99 //} |
| OLD | NEW |