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

Unified Diff: pkg/dart_scanner/lib/io.dart

Issue 2631503002: Modify scanner and parser to be standalone packages. (Closed)
Patch Set: Created 3 years, 11 months 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 side-by-side diff with in-line comments
Download patch
Index: pkg/dart_scanner/lib/io.dart
diff --git a/pkg/dart_scanner/lib/io.dart b/pkg/dart_scanner/lib/io.dart
index 94052cb6bc0f8448f4a12af6715bf4b610b448ac..29c52f6f0cef8ad3118a84557b864f6e257da699 100644
--- a/pkg/dart_scanner/lib/io.dart
+++ b/pkg/dart_scanner/lib/io.dart
@@ -1,408 +1,44 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2016, 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.
-
-library source_file_provider;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math' as math;
-import 'dart:typed_data';
-
-import '../compiler.dart' as api show Diagnostic;
-import '../compiler_new.dart' as api;
-import '../compiler_new.dart';
-import 'colors.dart' as colors;
-import 'dart2js.dart' show AbortLeg;
-import 'filenames.dart';
-import 'io/source_file.dart';
-import 'util/uri_extras.dart';
-
-abstract class SourceFileProvider implements CompilerInput {
- bool isWindows = (Platform.operatingSystem == 'windows');
- Uri cwd = currentDirectory;
- Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
- int dartCharactersRead = 0;
-
- Future<String> readStringFromUri(Uri resourceUri) {
- return readUtf8BytesFromUri(resourceUri).then(UTF8.decode);
- }
-
- Future<List<int>> readUtf8BytesFromUri(Uri resourceUri) {
- if (resourceUri.scheme == 'file') {
- return _readFromFile(resourceUri);
- } else if (resourceUri.scheme == 'http' || resourceUri.scheme == 'https') {
- return _readFromHttp(resourceUri);
- } else {
- throw new ArgumentError("Unknown scheme in uri '$resourceUri'");
- }
- }
-
- Future<List<int>> _readFromFile(Uri resourceUri) {
- assert(resourceUri.scheme == 'file');
- List<int> source;
- try {
- source = readAll(resourceUri.toFilePath());
- } on FileSystemException catch (ex) {
- String message = ex.osError?.message;
- String detail = message != null ? ' ($message)' : '';
- return new Future.error(
- "Error reading '${relativizeUri(resourceUri)}' $detail");
- }
- dartCharactersRead += source.length;
- sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
- resourceUri, relativizeUri(resourceUri), source);
- return new Future.value(source);
- }
-
- Future<List<int>> _readFromHttp(Uri resourceUri) {
- assert(resourceUri.scheme == 'http');
- HttpClient client = new HttpClient();
- return client
- .getUrl(resourceUri)
- .then((HttpClientRequest request) => request.close())
- .then((HttpClientResponse response) {
- if (response.statusCode != HttpStatus.OK) {
- String msg = 'Failure getting $resourceUri: '
- '${response.statusCode} ${response.reasonPhrase}';
- throw msg;
- }
- return response.toList();
- }).then((List<List<int>> splitContent) {
- int totalLength = splitContent.fold(0, (int old, List list) {
- return old + list.length;
- });
- Uint8List result = new Uint8List(totalLength);
- int offset = 0;
- for (List<int> contentPart in splitContent) {
- result.setRange(offset, offset + contentPart.length, contentPart);
- offset += contentPart.length;
- }
- dartCharactersRead += totalLength;
- sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile(
- resourceUri, resourceUri.toString(), result);
- return result;
- });
- }
-
- // TODO(johnniwinther): Remove this when no longer needed for the old compiler
- // API.
- Future/*<List<int> | String>*/ call(Uri resourceUri) => throw "unimplemented";
-
- relativizeUri(Uri uri) => relativize(cwd, uri, isWindows);
-
- SourceFile getSourceFile(Uri resourceUri) {
- return sourceFiles[resourceUri];
- }
-}
-
-List<int> readAll(String filename) {
- var file = (new File(filename)).openSync();
- var length = file.lengthSync();
- // +1 to have a 0 terminated list, see [Scanner].
- var buffer = new Uint8List(length + 1);
- file.readIntoSync(buffer, 0, length);
- file.closeSync();
- return buffer;
-}
-
-class CompilerSourceFileProvider extends SourceFileProvider {
- // TODO(johnniwinther): Remove this when no longer needed for the old compiler
- // API.
- Future<List<int>> call(Uri resourceUri) => readFromUri(resourceUri);
-
- @override
- Future readFromUri(Uri uri) => readUtf8BytesFromUri(uri);
-}
-
-class FormattingDiagnosticHandler implements CompilerDiagnostics {
- final SourceFileProvider provider;
- bool showWarnings = true;
- bool showHints = true;
- bool verbose = false;
- bool isAborting = false;
- bool enableColors = false;
- bool throwOnError = false;
- int throwOnErrorCount = 0;
- api.Diagnostic lastKind = null;
- int fatalCount = 0;
-
- final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal;
- final int INFO =
- api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal;
-
- FormattingDiagnosticHandler([SourceFileProvider provider])
- : this.provider =
- (provider == null) ? new CompilerSourceFileProvider() : provider;
-
- void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
- if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
- if (enableColors) {
- print('${colors.green("Info:")} $message');
- } else {
- print('Info: $message');
- }
- }
-
- /// Adds [kind] specific prefix to [message].
- String prefixMessage(String message, api.Diagnostic kind) {
- switch (kind) {
- case api.Diagnostic.ERROR:
- return 'Error: $message';
- case api.Diagnostic.WARNING:
- return 'Warning: $message';
- case api.Diagnostic.HINT:
- return 'Hint: $message';
- case api.Diagnostic.CRASH:
- return 'Internal Error: $message';
- case api.Diagnostic.INFO:
- case api.Diagnostic.VERBOSE_INFO:
- return 'Info: $message';
- }
- throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})';
- }
-
- @override
- void report(var code, Uri uri, int begin, int end, String message,
- api.Diagnostic kind) {
- if (isAborting) return;
- isAborting = (kind == api.Diagnostic.CRASH);
-
- bool fatal = (kind.ordinal & FATAL) != 0;
- bool isInfo = (kind.ordinal & INFO) != 0;
- if (isInfo && uri == null && kind != api.Diagnostic.INFO) {
- info(message, kind);
- return;
- }
-
- message = prefixMessage(message, kind);
-
- // [lastKind] records the previous non-INFO kind we saw.
- // This is used to suppress info about a warning when warnings are
- // suppressed, and similar for hints.
- if (kind != api.Diagnostic.INFO) {
- lastKind = kind;
- }
- var color;
- if (kind == api.Diagnostic.ERROR) {
- color = colors.red;
- } else if (kind == api.Diagnostic.WARNING) {
- if (!showWarnings) return;
- color = colors.magenta;
- } else if (kind == api.Diagnostic.HINT) {
- if (!showHints) return;
- color = colors.cyan;
- } else if (kind == api.Diagnostic.CRASH) {
- color = colors.red;
- } else if (kind == api.Diagnostic.INFO) {
- if (lastKind == api.Diagnostic.WARNING && !showWarnings) return;
- if (lastKind == api.Diagnostic.HINT && !showHints) return;
- color = colors.green;
- } else {
- throw 'Unknown kind: $kind (${kind.ordinal})';
- }
- if (!enableColors) {
- color = (x) => x;
- }
- if (uri == null) {
- print('${color(message)}');
- } else {
- SourceFile file = provider.sourceFiles[uri];
- if (file != null) {
- print(file.getLocationMessage(color(message), begin, end,
- colorize: color));
- } else {
- String position = end - begin > 0 ? '@$begin+${end - begin}' : '';
- print('${provider.relativizeUri(uri)}$position:\n'
- '${color(message)}');
- }
- }
- if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) {
- isAborting = true;
- throw new AbortLeg(message);
- }
- }
-
- // TODO(johnniwinther): Remove this when no longer needed for the old compiler
- // API.
- void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) {
- return report(null, uri, begin, end, message, kind);
- }
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'dart:async' show
+ Future;
+
+import 'dart:io' show
+ File,
+ RandomAccessFile;
+
+import 'dart:typed_data' show
+ Uint8List;
+
+List<int> readBytesFromFileSync(Uri uri) {
+ RandomAccessFile file = new File.fromUri(uri).openSync();
+ Uint8List list;
+ try {
+ int length = file.lengthSync();
+ // +1 to have a 0 terminated list, see [Scanner].
+ list = new Uint8List(length + 1);
+ file.readIntoSync(list, 0, length);
+ } finally {
+ file.closeSync();
+ }
+ return list;
}
-typedef void MessageCallback(String message);
-
-class RandomAccessFileOutputProvider implements CompilerOutput {
- final Uri out;
- final Uri sourceMapOut;
- final Uri resolutionOutput;
- final MessageCallback onInfo;
- final MessageCallback onFailure;
-
- int totalCharactersWritten = 0;
- List<String> allOutputFiles = new List<String>();
-
- RandomAccessFileOutputProvider(this.out, this.sourceMapOut,
- {this.onInfo, this.onFailure, this.resolutionOutput});
-
- static Uri computePrecompiledUri(Uri out) {
- String extension = 'precompiled.js';
- String outPath = out.path;
- if (outPath.endsWith('.js')) {
- outPath = outPath.substring(0, outPath.length - 3);
- return out.resolve('$outPath.$extension');
- } else {
- return out.resolve(extension);
- }
- }
-
- EventSink<String> call(String name, String extension) {
- return createEventSink(name, extension);
- }
-
- EventSink<String> createEventSink(String name, String extension) {
- Uri uri;
- bool isPrimaryOutput = false;
- // TODO (johnniwinther, sigurdm): Make a better interface for
- // output-providers.
- if (extension == "deferred_map") {
- uri = out.resolve(name);
- } else if (name == '') {
- if (extension == 'js' || extension == 'dart') {
- isPrimaryOutput = true;
- uri = out;
- } else if (extension == 'precompiled.js') {
- uri = computePrecompiledUri(out);
- onInfo("File ($uri) is compatible with header"
- " \"Content-Security-Policy: script-src 'self'\"");
- } else if (extension == 'js.map' || extension == 'dart.map') {
- uri = sourceMapOut;
- } else if (extension == 'info.json') {
- String outName = out.path.substring(out.path.lastIndexOf('/') + 1);
- uri = out.resolve('$outName.$extension');
- } else if (extension == 'data') {
- if (resolutionOutput == null) {
- onFailure('Serialization target unspecified.');
- }
- uri = resolutionOutput;
- } else {
- onFailure('Unknown extension: $extension');
- }
- } else {
- uri = out.resolve('$name.$extension');
- }
-
- if (uri.scheme != 'file') {
- onFailure('Unhandled scheme ${uri.scheme} in $uri.');
- }
-
- RandomAccessFile output;
- try {
- output = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE);
- } on FileSystemException catch (e) {
- onFailure('$e');
- }
-
- allOutputFiles.add(relativize(currentDirectory, uri, Platform.isWindows));
-
- int charactersWritten = 0;
-
- writeStringSync(String data) {
- // Write the data in chunks of 8kb, otherwise we risk running OOM.
- int chunkSize = 8 * 1024;
-
- int offset = 0;
- while (offset < data.length) {
- output.writeStringSync(
- data.substring(offset, math.min(offset + chunkSize, data.length)));
- offset += chunkSize;
- }
- charactersWritten += data.length;
- }
-
- onDone() {
- output.closeSync();
- if (isPrimaryOutput) {
- totalCharactersWritten += charactersWritten;
- }
- }
-
- return new _EventSinkWrapper(writeStringSync, onDone);
- }
-}
-
-class _EventSinkWrapper extends EventSink<String> {
- var onAdd, onClose;
-
- _EventSinkWrapper(this.onAdd, this.onClose);
-
- void add(String data) => onAdd(data);
-
- void addError(error, [StackTrace stackTrace]) => throw error;
-
- void close() => onClose();
-}
-
-/// Adapter to integrate dart2js in bazel.
-///
-/// To handle bazel's special layout:
-///
-/// * We specify a .packages configuration file that expands packages to their
-/// corresponding bazel location. This way there is no need to create a pub
-/// cache prior to invoking dart2js.
-///
-/// * We provide an implicit mapping that can make all urls relative to the
-/// bazel root.
-/// To the compiler, URIs look like:
-/// file:///bazel-root/a/b/c.dart
-///
-/// even though in the file system the file is located at:
-/// file:///path/to/the/actual/bazel/root/a/b/c.dart
-///
-/// This mapping serves two purposes:
-/// - It makes compiler results independent of the machine layout, which
-/// enables us to share results across bazel runs and across machines.
-///
-/// - It hides the distinction between generated and source files. That way
-/// we can use the standard package-resolution mechanism and ignore the
-/// internals of how files are organized within bazel.
-///
-/// When invoking the compiler, bazel will use `package:` and
-/// `file:///bazel-root/` URIs to specify entrypoints.
-///
-/// The mapping is specified using search paths relative to the current
-/// directory. When this provider looks up a file, the bazel-root folder is
-/// replaced by the first directory in the search path containing the file, if
-/// any. For example, given the search path ".,bazel-bin/", and a URL
-/// of the form `file:///bazel-root/a/b.dart`, this provider will check if the
-/// file exists under "./a/b.dart", then check under "bazel-bin/a/b.dart". If
-/// none of the paths matches, it will attempt to load the file from
-/// `/bazel-root/a/b.dart` which will likely fail.
-class BazelInputProvider extends SourceFileProvider {
- final List<Uri> dirs;
-
- BazelInputProvider(List<String> searchPaths)
- : dirs = searchPaths.map(_resolve).toList();
-
- static _resolve(String path) => currentDirectory.resolve(path);
-
- @override
- Future readFromUri(Uri uri) async {
- var resolvedUri = uri;
- var path = uri.path;
- if (path.startsWith('/bazel-root')) {
- path = path.substring('/bazel-root/'.length);
- for (var dir in dirs) {
- var file = dir.resolve(path);
- if (await new File.fromUri(file).exists()) {
- resolvedUri = file;
- break;
- }
- }
- }
- var result = await readUtf8BytesFromUri(resolvedUri);
- sourceFiles[uri] = sourceFiles[resolvedUri];
- return result;
- }
+Future<List<int>> readBytesFromFile(Uri uri) async {
+ RandomAccessFile file = await new File.fromUri(uri).open();
+ Uint8List list;
+ try {
+ int length = await file.length();
+ // +1 to have a 0 terminated list, see [Scanner].
+ list = new Uint8List(length + 1);
+ int read = await file.readInto(list);
+ if (read != length) {
+ throw "Error reading file: ${uri}";
+ }
+ } finally {
+ await file.close();
+ }
+ return list;
}

Powered by Google App Engine
This is Rietveld 408576698