Linter Demo Errors: 0Warnings: 6File: /home/fstrocco/Dart/dart/benchmark/compiler/lib/src/source_file_provider.dart // Copyright (c) 2013, 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 '../compiler.dart' as api show Diagnostic, DiagnosticHandler; import 'dart2js.dart' show AbortLeg; import 'colors.dart' as colors; import 'io/source_file.dart'; import 'filenames.dart'; import 'util/uri_extras.dart'; import 'dart:typed_data'; List 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); var bytes = file.readIntoSync(buffer, 0, length); file.closeSync(); return buffer; } abstract class SourceFileProvider { bool isWindows = (Platform.operatingSystem == 'windows'); Uri cwd = currentDirectory; Map sourceFiles = {}; int dartCharactersRead = 0; Future readStringFromUri(Uri resourceUri) { return readUtf8BytesFromUri(resourceUri).then(UTF8.decode); } Future> 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> _readFromFile(Uri resourceUri) { assert(resourceUri.scheme == 'file'); List source; try { source = readAll(resourceUri.toFilePath()); } on FileSystemException catch (ex) { OSError ose = ex.osError; String detail = (ose != null && ose.message != null) ? ' (${ose.message})' : ''; return new Future.error( "Error reading '${relativize(cwd, resourceUri, isWindows)}'" "$detail"); } dartCharactersRead += source.length; sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile( resourceUri, relativizeUri(resourceUri), source); return new Future.value(source); } Future> _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> splitContent) { int totalLength = splitContent.fold(0, (int old, List list) { return old + list.length; }); Uint8List result = new Uint8List(totalLength); int offset = 0; for (List 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; }); } Future/* | String>*/ call(Uri resourceUri); relativizeUri(Uri uri) => relativize(cwd, uri, isWindows); } class CompilerSourceFileProvider extends SourceFileProvider { Future> call(Uri resourceUri) => readUtf8BytesFromUri(resourceUri); } class FormattingDiagnosticHandler { 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})'; } void diagnosticHandler(Uri uri, int begin, int end, String message, api.Diagnostic kind) { // TODO(ahe): Remove this when source map is handled differently. if (identical(kind.name, 'source map')) return; 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); // [previousKind]/[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. var previousKind = lastKind; 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); } } void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) { return diagnosticHandler(uri, begin, end, message, kind); } } typedef void MessageCallback(String message); class RandomAccessFileOutputProvider { final Uri out; final Uri sourceMapOut; final MessageCallback onInfo; final MessageCallback onFailure; int totalCharactersWritten = 0; List allOutputFiles = new List(); RandomAccessFileOutputProvider(this.out, this.sourceMapOut, {this.onInfo, this.onFailure}); 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 call(String name, String extension) { Uri uri; String sourceMapFileName; 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; sourceMapFileName = sourceMapOut.path.substring(sourceMapOut.path.lastIndexOf('/') + 1); } 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 { 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 { var onAdd, onClose; EventSinkWrapper(this.onAdd, this.onClose); void add(String data) => onAdd(data); void addError(error, [StackTrace stackTrace]) => throw error; void close() => onClose(); }