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 |