Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/source_file_provider.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2013, 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 library source_file_provider;
6
7 import 'dart:async';
8 import 'dart:convert';
9 import 'dart:io';
10 import 'dart:math' as math;
11
12 import '../compiler.dart' as api show Diagnostic, DiagnosticHandler;
13 import 'dart2js.dart' show AbortLeg;
14 import 'colors.dart' as colors;
15 import 'source_file.dart';
16 import 'filenames.dart';
17 import 'util/uri_extras.dart';
18 import 'dart:typed_data';
19
20 List<int> readAll(String filename) {
21 var file = (new File(filename)).openSync();
22 var length = file.lengthSync();
23 // +1 to have a 0 terminated list, see [Scanner].
24 var buffer = new Uint8List(length + 1);
25 var bytes = file.readIntoSync(buffer, 0, length);
26 file.closeSync();
27 return buffer;
28 }
29
30 abstract class SourceFileProvider {
31 bool isWindows = (Platform.operatingSystem == 'windows');
32 Uri cwd = currentDirectory;
33 Map<String, SourceFile> sourceFiles = <String, SourceFile>{};
34 int dartCharactersRead = 0;
35
36 Future<String> readStringFromUri(Uri resourceUri) {
37 return readUtf8BytesFromUri(resourceUri).then(UTF8.decode);
38 }
39
40 Future<List<int>> readUtf8BytesFromUri(Uri resourceUri) {
41 if (resourceUri.scheme == 'file') {
42 return _readFromFile(resourceUri);
43 } else if (resourceUri.scheme == 'http' || resourceUri.scheme == 'https') {
44 return _readFromHttp(resourceUri);
45 } else {
46 throw new ArgumentError("Unknown scheme in uri '$resourceUri'");
47 }
48 }
49
50 Future<List<int>> _readFromFile(Uri resourceUri) {
51 assert(resourceUri.scheme == 'file');
52 List<int> source;
53 try {
54 source = readAll(resourceUri.toFilePath());
55 } on FileSystemException catch (ex) {
56 return new Future.error(
57 "Error reading '${relativize(cwd, resourceUri, isWindows)}' "
58 "(${ex.osError})");
59 }
60 dartCharactersRead += source.length;
61 sourceFiles[resourceUri.toString()] =
62 new CachingUtf8BytesSourceFile(relativizeUri(resourceUri), source);
63 return new Future.value(source);
64 }
65
66 Future<List<int>> _readFromHttp(Uri resourceUri) {
67 assert(resourceUri.scheme == 'http');
68 HttpClient client = new HttpClient();
69 return client.getUrl(resourceUri)
70 .then((HttpClientRequest request) => request.close())
71 .then((HttpClientResponse response) {
72 if (response.statusCode != HttpStatus.OK) {
73 String msg = 'Failure getting $resourceUri: '
74 '${response.statusCode} ${response.reasonPhrase}';
75 throw msg;
76 }
77 return response.toList();
78 })
79 .then((List<List<int>> splitContent) {
80 int totalLength = splitContent.fold(0, (int old, List list) {
81 return old + list.length;
82 });
83 Uint8List result = new Uint8List(totalLength);
84 int offset = 0;
85 for (List<int> contentPart in splitContent) {
86 result.setRange(
87 offset, offset + contentPart.length, contentPart);
88 offset += contentPart.length;
89 }
90 dartCharactersRead += totalLength;
91 sourceFiles[resourceUri.toString()] =
92 new CachingUtf8BytesSourceFile(resourceUri.toString(), result);
93 return result;
94 });
95 }
96
97 Future/*<List<int> | String>*/ call(Uri resourceUri);
98
99 relativizeUri(Uri uri) => relativize(cwd, uri, isWindows);
100 }
101
102 class CompilerSourceFileProvider extends SourceFileProvider {
103 Future<List<int>> call(Uri resourceUri) => readUtf8BytesFromUri(resourceUri);
104 }
105
106 class FormattingDiagnosticHandler {
107 final SourceFileProvider provider;
108 bool showWarnings = true;
109 bool showHints = true;
110 bool verbose = false;
111 bool isAborting = false;
112 bool enableColors = false;
113 bool throwOnError = false;
114 int throwOnErrorCount = 0;
115 api.Diagnostic lastKind = null;
116 int fatalCount = 0;
117
118 final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal;
119 final int INFO =
120 api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal;
121
122 FormattingDiagnosticHandler([SourceFileProvider provider])
123 : this.provider =
124 (provider == null) ? new CompilerSourceFileProvider() : provider;
125
126 void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
127 if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
128 if (enableColors) {
129 print('${colors.green("Info:")} $message');
130 } else {
131 print('Info: $message');
132 }
133 }
134
135 /// Adds [kind] specific prefix to [message].
136 String prefixMessage(String message, api.Diagnostic kind) {
137 switch (kind) {
138 case api.Diagnostic.ERROR:
139 return 'Error: $message';
140 case api.Diagnostic.WARNING:
141 return 'Warning: $message';
142 case api.Diagnostic.HINT:
143 return 'Hint: $message';
144 case api.Diagnostic.CRASH:
145 return 'Internal Error: $message';
146 case api.Diagnostic.INFO:
147 case api.Diagnostic.VERBOSE_INFO:
148 return 'Info: $message';
149 }
150 throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})';
151 }
152
153 void diagnosticHandler(Uri uri, int begin, int end, String message,
154 api.Diagnostic kind) {
155 // TODO(ahe): Remove this when source map is handled differently.
156 if (identical(kind.name, 'source map')) return;
157
158 if (isAborting) return;
159 isAborting = (kind == api.Diagnostic.CRASH);
160
161 bool fatal = (kind.ordinal & FATAL) != 0;
162 bool isInfo = (kind.ordinal & INFO) != 0;
163 if (isInfo && uri == null && kind != api.Diagnostic.INFO) {
164 info(message, kind);
165 return;
166 }
167
168 message = prefixMessage(message, kind);
169
170 // [previousKind]/[lastKind] records the previous non-INFO kind we saw.
171 // This is used to suppress info about a warning when warnings are
172 // suppressed, and similar for hints.
173 var previousKind = lastKind;
174 if (kind != api.Diagnostic.INFO) {
175 lastKind = kind;
176 }
177 var color;
178 if (kind == api.Diagnostic.ERROR) {
179 color = colors.red;
180 } else if (kind == api.Diagnostic.WARNING) {
181 if (!showWarnings) return;
182 color = colors.magenta;
183 } else if (kind == api.Diagnostic.HINT) {
184 if (!showHints) return;
185 color = colors.cyan;
186 } else if (kind == api.Diagnostic.CRASH) {
187 color = colors.red;
188 } else if (kind == api.Diagnostic.INFO) {
189 if (lastKind == api.Diagnostic.WARNING && !showWarnings) return;
190 if (lastKind == api.Diagnostic.HINT && !showHints) return;
191 color = colors.green;
192 } else {
193 throw 'Unknown kind: $kind (${kind.ordinal})';
194 }
195 if (!enableColors) {
196 color = (x) => x;
197 }
198 if (uri == null) {
199 print('${color(message)}');
200 } else {
201 SourceFile file = provider.sourceFiles[uri.toString()];
202 if (file != null) {
203 print(file.getLocationMessage(
204 color(message), begin, end, colorize: color));
205 } else {
206 print('${provider.relativizeUri(uri)}@$begin+${end - begin}:'
207 ' [$kind] ${color(message)}');
208 }
209 }
210 if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) {
211 isAborting = true;
212 throw new AbortLeg(message);
213 }
214 }
215
216 void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) {
217 return diagnosticHandler(uri, begin, end, message, kind);
218 }
219 }
220
221 typedef void MessageCallback(String message);
222
223 class RandomAccessFileOutputProvider {
224 final Uri out;
225 final Uri sourceMapOut;
226 final MessageCallback onInfo;
227 final MessageCallback onFailure;
228
229 int totalCharactersWritten = 0;
230 List<String> allOutputFiles = new List<String>();
231
232 RandomAccessFileOutputProvider(this.out,
233 this.sourceMapOut,
234 {this.onInfo,
235 this.onFailure});
236
237 static Uri computePrecompiledUri(Uri out) {
238 String extension = 'precompiled.js';
239 String outPath = out.path;
240 if (outPath.endsWith('.js')) {
241 outPath = outPath.substring(0, outPath.length - 3);
242 return out.resolve('$outPath.$extension');
243 } else {
244 return out.resolve(extension);
245 }
246 }
247
248 EventSink<String> call(String name, String extension) {
249 Uri uri;
250 String sourceMapFileName;
251 bool isPrimaryOutput = false;
252 if (name == '') {
253 if (extension == 'js' || extension == 'dart') {
254 isPrimaryOutput = true;
255 uri = out;
256 sourceMapFileName =
257 sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1);
258 } else if (extension == 'precompiled.js') {
259 uri = computePrecompiledUri(out);
260 onInfo("File ($uri) is compatible with header"
261 " \"Content-Security-Policy: script-src 'self'\"");
262 } else if (extension == 'js.map' || extension == 'dart.map') {
263 uri = sourceMapOut;
264 } else if (extension == 'info.html' || extension == "info.json") {
265 String outName = out.path.substring(out.path.lastIndexOf('/') + 1);
266 uri = out.resolve('$outName.$extension');
267 } else {
268 onFailure('Unknown extension: $extension');
269 }
270 } else {
271 uri = out.resolve('$name.$extension');
272 }
273
274 if (uri.scheme != 'file') {
275 onFailure('Unhandled scheme ${uri.scheme} in $uri.');
276 }
277
278 RandomAccessFile output;
279 try {
280 output = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
281 } on FileSystemException catch(e) {
282 onFailure('$e');
283 }
284
285 allOutputFiles.add(relativize(currentDirectory, uri, Platform.isWindows));
286
287 int charactersWritten = 0;
288
289 writeStringSync(String data) {
290 // Write the data in chunks of 8kb, otherwise we risk running OOM.
291 int chunkSize = 8*1024;
292
293 int offset = 0;
294 while (offset < data.length) {
295 output.writeStringSync(
296 data.substring(offset, math.min(offset + chunkSize, data.length)));
297 offset += chunkSize;
298 }
299 charactersWritten += data.length;
300 }
301
302 onDone() {
303 output.closeSync();
304 if (isPrimaryOutput) {
305 totalCharactersWritten += charactersWritten;
306 }
307 }
308
309 return new EventSinkWrapper(writeStringSync, onDone);
310 }
311 }
312
313 class EventSinkWrapper extends EventSink<String> {
314 var onAdd, onClose;
315
316 EventSinkWrapper(this.onAdd, this.onClose);
317
318 void add(String data) => onAdd(data);
319
320 void addError(error, [StackTrace stackTrace]) => throw error;
321
322 void close() => onClose();
323 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698