| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /// API for compiling Dart source code to .dill (Kernel IR) files. | |
| 6 library front_end.vm; | |
| 7 // TODO(ahe): Convert this file to use the API in `../../kernel_generator.dart` | |
| 8 // and `../../compiler_options.dart`. | |
| 9 | |
| 10 import 'dart:async' show Future; | |
| 11 | |
| 12 import 'dart:io' show File, Platform; | |
| 13 | |
| 14 import 'dart:typed_data' show Uint8List; | |
| 15 | |
| 16 import 'package:front_end/file_system.dart'; | |
| 17 import 'package:front_end/physical_file_system.dart'; | |
| 18 | |
| 19 import 'fasta.dart' as fasta; | |
| 20 | |
| 21 import 'package:kernel/target/targets.dart' show TargetFlags; | |
| 22 import 'package:kernel/target/vm_fasta.dart' show VmFastaTarget; | |
| 23 | |
| 24 /// Compilation status codes. | |
| 25 /// | |
| 26 /// Note: The [index] property of these constants must match | |
| 27 /// `Dart_KernelCompilationStatus` in | |
| 28 /// [dart_api.h](../../../../runtime/include/dart_api.h). | |
| 29 enum Status { | |
| 30 /// Compilation was successful. | |
| 31 ok, | |
| 32 | |
| 33 /// Compilation failed with a compile time error. | |
| 34 error, | |
| 35 | |
| 36 /// Compiler crashed. | |
| 37 crash, | |
| 38 } | |
| 39 | |
| 40 abstract class CompilationResult { | |
| 41 CompilationResult._(); | |
| 42 | |
| 43 factory CompilationResult.ok(Uint8List bytes) = _CompilationOk; | |
| 44 | |
| 45 factory CompilationResult.errors(List<String> errors) = _CompilationError; | |
| 46 | |
| 47 factory CompilationResult.error(String error) { | |
| 48 return new _CompilationError(<String>[error]); | |
| 49 } | |
| 50 | |
| 51 factory CompilationResult.crash(Object exception, StackTrace stack) = | |
| 52 _CompilationCrash; | |
| 53 | |
| 54 Status get status; | |
| 55 | |
| 56 get payload; | |
| 57 | |
| 58 List toResponse() => [status.index, payload]; | |
| 59 } | |
| 60 | |
| 61 Future<CompilationResult> parseScript(Uri script, | |
| 62 {bool verbose: false, bool strongMode: false}) async { | |
| 63 return parseScriptInFileSystem(script, PhysicalFileSystem.instance, | |
| 64 verbose: verbose, strongMode: strongMode); | |
| 65 } | |
| 66 | |
| 67 Future<CompilationResult> parseScriptInFileSystem( | |
| 68 Uri script, FileSystem fileSystem, | |
| 69 {bool verbose: false, bool strongMode: false}) async { | |
| 70 final Uri packagesUri = (Platform.packageConfig != null) | |
| 71 ? Uri.parse(Platform.packageConfig) | |
| 72 : await _findPackagesFile(fileSystem, script); | |
| 73 if (packagesUri == null) { | |
| 74 throw "Could not find .packages"; | |
| 75 } | |
| 76 | |
| 77 final Uri patchedSdk = Uri.base | |
| 78 .resolveUri(new Uri.file(Platform.resolvedExecutable)) | |
| 79 .resolveUri(new Uri.directory("patched_sdk")); | |
| 80 | |
| 81 if (verbose) { | |
| 82 print("""DFE: Requesting compilation { | |
| 83 scriptUri: ${script} | |
| 84 packagesUri: ${packagesUri} | |
| 85 patchedSdk: ${patchedSdk} | |
| 86 }"""); | |
| 87 } | |
| 88 | |
| 89 try { | |
| 90 return await fasta.parseScriptInFileSystem(script, fileSystem, packagesUri, | |
| 91 patchedSdk, new VmFastaTarget(new TargetFlags(strongMode: strongMode)), | |
| 92 verbose: verbose); | |
| 93 } catch (err, stack) { | |
| 94 return new CompilationResult.crash(err, stack); | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 class _CompilationOk extends CompilationResult { | |
| 99 final Uint8List bytes; | |
| 100 | |
| 101 _CompilationOk(this.bytes) : super._(); | |
| 102 | |
| 103 @override | |
| 104 Status get status => Status.ok; | |
| 105 | |
| 106 @override | |
| 107 get payload => bytes; | |
| 108 | |
| 109 String toString() => "_CompilationOk(${bytes.length} bytes)"; | |
| 110 } | |
| 111 | |
| 112 abstract class _CompilationFail extends CompilationResult { | |
| 113 _CompilationFail() : super._(); | |
| 114 | |
| 115 String get errorString; | |
| 116 | |
| 117 @override | |
| 118 get payload => errorString; | |
| 119 } | |
| 120 | |
| 121 class _CompilationError extends _CompilationFail { | |
| 122 final List<String> errors; | |
| 123 | |
| 124 _CompilationError(this.errors); | |
| 125 | |
| 126 @override | |
| 127 Status get status => Status.error; | |
| 128 | |
| 129 @override | |
| 130 String get errorString => errors.take(10).join('\n'); | |
| 131 | |
| 132 String toString() => "_CompilationError(${errorString})"; | |
| 133 } | |
| 134 | |
| 135 class _CompilationCrash extends _CompilationFail { | |
| 136 final Object exception; | |
| 137 final StackTrace stack; | |
| 138 | |
| 139 _CompilationCrash(this.exception, this.stack); | |
| 140 | |
| 141 @override | |
| 142 Status get status => Status.crash; | |
| 143 | |
| 144 @override | |
| 145 String get errorString => "${exception}\n${stack}"; | |
| 146 | |
| 147 String toString() => "_CompilationCrash(${errorString})"; | |
| 148 } | |
| 149 | |
| 150 /// This duplicates functionality from the Loader which we can't easily | |
| 151 /// access from here. | |
| 152 Future<Uri> _findPackagesFile(FileSystem fileSystem, Uri base) async { | |
| 153 var dir = new File.fromUri(base).parent; | |
| 154 while (true) { | |
| 155 final packagesFile = dir.uri.resolve(".packages"); | |
| 156 if (await fileSystem.entityForUri(packagesFile).exists()) { | |
| 157 return packagesFile; | |
| 158 } | |
| 159 if (dir.parent.path == dir.path) { | |
| 160 break; | |
| 161 } | |
| 162 dir = dir.parent; | |
| 163 } | |
| 164 return null; | |
| 165 } | |
| OLD | NEW |