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 |