Index: pkg/front_end/lib/src/fasta/vm.dart |
diff --git a/pkg/front_end/lib/src/fasta/vm.dart b/pkg/front_end/lib/src/fasta/vm.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..d9f7de810af59cefe73f1b9e9a3d2836067d213a |
--- /dev/null |
+++ b/pkg/front_end/lib/src/fasta/vm.dart |
@@ -0,0 +1,144 @@ |
+// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+/// API for compiling Dart source code to .dill (Kernel IR) files. |
+library front_end.vm; |
+// TODO(ahe): Move this to lib/ once the API has matured. |
+ |
+import 'dart:async' show Future; |
+ |
+import 'dart:io' show File, Platform; |
+ |
+import 'dart:typed_data' show Uint8List; |
+ |
+import 'outline.dart' as fasta; |
+ |
+/// Compilation status codes. |
+/// |
+/// Note: The [index] property of these constants must match |
+/// `Dart_KernelCompilationStatus` in |
+/// [dart_api.h](../../../../runtime/include/dart_api.h). |
+enum Status { |
+ /// Compilation was successful. |
+ ok, |
+ |
+ /// Compilation failed with a compile time error. |
+ error, |
+ |
+ /// Compiler crashed. |
+ crash, |
+} |
+ |
+abstract class CompilationResult { |
+ CompilationResult._(); |
+ |
+ factory CompilationResult.ok(Uint8List bytes) = _CompilationOk; |
+ |
+ factory CompilationResult.error(List<String> errors) = _CompilationError; |
+ |
+ factory CompilationResult.crash(Object exception, StackTrace stack) = |
+ _CompilationCrash; |
+ |
+ Status get status; |
+ |
+ get payload; |
+ |
+ List toResponse() => [status.index, payload]; |
+} |
+ |
+Future<CompilationResult> parseScript(Uri script, {bool verbose: false}) async { |
+ final Uri packagesUri = (Platform.packageConfig != null) |
+ ? Uri.parse(Platform.packageConfig) |
+ : await _findPackagesFile(script); |
+ if (packagesUri == null) { |
+ throw "Could not find .packages"; |
+ } |
+ |
+ final Uri patchedSdk = Uri.base |
+ .resolveUri(new Uri.file(Platform.resolvedExecutable)) |
+ .resolveUri(new Uri.directory("patched_sdk")); |
+ |
+ if (verbose) { |
+ print("""DFE: Requesting compilation { |
+ scriptUri: ${script} |
+ packagesUri: ${packagesUri} |
+ patchedSdk: ${patchedSdk} |
+}"""); |
+ } |
+ |
+ try { |
+ return await fasta.parseScript(script, packagesUri, patchedSdk, verbose); |
+ } catch (err, stack) { |
+ return new CompilationResult.crash(err, stack); |
+ } |
+} |
+ |
+class _CompilationOk extends CompilationResult { |
+ final Uint8List bytes; |
+ |
+ _CompilationOk(this.bytes) : super._(); |
+ |
+ @override |
+ Status get status => Status.ok; |
+ |
+ @override |
+ get payload => bytes; |
+ |
+ String toString() => "_CompilationOk(${bytes.length} bytes)"; |
+} |
+ |
+abstract class _CompilationFail extends CompilationResult { |
+ _CompilationFail() : super._(); |
+ |
+ String get errorString; |
+ |
+ @override |
+ get payload => errorString; |
+} |
+ |
+class _CompilationError extends _CompilationFail { |
+ final List<String> errors; |
+ |
+ _CompilationError(this.errors); |
+ |
+ @override |
+ Status get status => Status.error; |
+ |
+ @override |
+ String get errorString => errors.take(10).join('\n'); |
+ |
+ String toString() => "_CompilationError(${errorString})"; |
+} |
+ |
+class _CompilationCrash extends _CompilationFail { |
+ final Object exception; |
+ final StackTrace stack; |
+ |
+ _CompilationCrash(this.exception, this.stack); |
+ |
+ @override |
+ Status get status => Status.crash; |
+ |
+ @override |
+ String get errorString => "${exception}\n${stack}"; |
+ |
+ String toString() => "_CompilationCrash(${errorString})"; |
+} |
+ |
+/// This duplicates functionality from the Loader which we can't easily |
+/// access from here. |
+Future<Uri> _findPackagesFile(Uri base) async { |
+ var dir = new File.fromUri(base).parent; |
+ while (true) { |
+ final packagesFile = dir.uri.resolve(".packages"); |
+ if (await new File.fromUri(packagesFile).exists()) { |
+ return packagesFile; |
+ } |
+ if (dir.parent.path == dir.path) { |
+ break; |
+ } |
+ dir = dir.parent; |
+ } |
+ return null; |
+} |