| OLD | NEW | 
|    1 // Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file |    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 |    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. |    3 // BSD-style license that can be found in the LICENSE file. | 
|    4  |    4  | 
|    5 library source_file_provider; |    5 library source_file_provider; | 
|    6  |    6  | 
|    7 import 'dart:async'; |    7 import 'dart:async'; | 
|    8 import 'dart:convert'; |    8 import 'dart:convert'; | 
|    9 import 'dart:io'; |    9 import 'dart:io'; | 
|   10 import 'dart:math' as math; |   10 import 'dart:math' as math; | 
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   49     } |   49     } | 
|   50   } |   50   } | 
|   51  |   51  | 
|   52   Future<List<int>> _readFromFile(Uri resourceUri) { |   52   Future<List<int>> _readFromFile(Uri resourceUri) { | 
|   53     assert(resourceUri.scheme == 'file'); |   53     assert(resourceUri.scheme == 'file'); | 
|   54     List<int> source; |   54     List<int> source; | 
|   55     try { |   55     try { | 
|   56       source = readAll(resourceUri.toFilePath()); |   56       source = readAll(resourceUri.toFilePath()); | 
|   57     } on FileSystemException catch (ex) { |   57     } on FileSystemException catch (ex) { | 
|   58       OSError ose = ex.osError; |   58       OSError ose = ex.osError; | 
|   59       String detail = (ose != null && ose.message != null) |   59       String detail = | 
|   60           ? ' (${ose.message})' |   60           (ose != null && ose.message != null) ? ' (${ose.message})' : ''; | 
|   61           : ''; |  | 
|   62       return new Future.error( |   61       return new Future.error( | 
|   63           "Error reading '${relativize(cwd, resourceUri, isWindows)}'" |   62           "Error reading '${relativize(cwd, resourceUri, isWindows)}'" | 
|   64           "$detail"); |   63           "$detail"); | 
|   65     } |   64     } | 
|   66     dartCharactersRead += source.length; |   65     dartCharactersRead += source.length; | 
|   67     sourceFiles[resourceUri] = |   66     sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile( | 
|   68         new CachingUtf8BytesSourceFile( |   67         resourceUri, relativizeUri(resourceUri), source); | 
|   69             resourceUri, relativizeUri(resourceUri), source); |  | 
|   70     return new Future.value(source); |   68     return new Future.value(source); | 
|   71   } |   69   } | 
|   72  |   70  | 
|   73   Future<List<int>> _readFromHttp(Uri resourceUri) { |   71   Future<List<int>> _readFromHttp(Uri resourceUri) { | 
|   74     assert(resourceUri.scheme == 'http'); |   72     assert(resourceUri.scheme == 'http'); | 
|   75     HttpClient client = new HttpClient(); |   73     HttpClient client = new HttpClient(); | 
|   76     return client.getUrl(resourceUri) |   74     return client | 
 |   75         .getUrl(resourceUri) | 
|   77         .then((HttpClientRequest request) => request.close()) |   76         .then((HttpClientRequest request) => request.close()) | 
|   78         .then((HttpClientResponse response) { |   77         .then((HttpClientResponse response) { | 
|   79           if (response.statusCode != HttpStatus.OK) { |   78       if (response.statusCode != HttpStatus.OK) { | 
|   80             String msg = 'Failure getting $resourceUri: ' |   79         String msg = 'Failure getting $resourceUri: ' | 
|   81                       '${response.statusCode} ${response.reasonPhrase}'; |   80             '${response.statusCode} ${response.reasonPhrase}'; | 
|   82             throw msg; |   81         throw msg; | 
|   83           } |   82       } | 
|   84           return response.toList(); |   83       return response.toList(); | 
|   85         }) |   84     }).then((List<List<int>> splitContent) { | 
|   86         .then((List<List<int>> splitContent) { |   85       int totalLength = splitContent.fold(0, (int old, List list) { | 
|   87            int totalLength = splitContent.fold(0, (int old, List list) { |   86         return old + list.length; | 
|   88              return old + list.length; |   87       }); | 
|   89            }); |   88       Uint8List result = new Uint8List(totalLength); | 
|   90            Uint8List result = new Uint8List(totalLength); |   89       int offset = 0; | 
|   91            int offset = 0; |   90       for (List<int> contentPart in splitContent) { | 
|   92            for (List<int> contentPart in splitContent) { |   91         result.setRange(offset, offset + contentPart.length, contentPart); | 
|   93              result.setRange( |   92         offset += contentPart.length; | 
|   94                  offset, offset + contentPart.length, contentPart); |   93       } | 
|   95              offset += contentPart.length; |   94       dartCharactersRead += totalLength; | 
|   96            } |   95       sourceFiles[resourceUri] = new CachingUtf8BytesSourceFile( | 
|   97            dartCharactersRead += totalLength; |   96           resourceUri, resourceUri.toString(), result); | 
|   98            sourceFiles[resourceUri] = |   97       return result; | 
|   99                new CachingUtf8BytesSourceFile( |   98     }); | 
|  100                    resourceUri, resourceUri.toString(), result); |  | 
|  101            return result; |  | 
|  102          }); |  | 
|  103   } |   99   } | 
|  104  |  100  | 
|  105   // TODO(johnniwinther): Remove this when no longer needed for the old compiler |  101   // TODO(johnniwinther): Remove this when no longer needed for the old compiler | 
|  106   // API. |  102   // API. | 
|  107   Future/*<List<int> | String>*/ call(Uri resourceUri); |  103   Future/*<List<int> | String>*/ call(Uri resourceUri); | 
|  108  |  104  | 
|  109   relativizeUri(Uri uri) => relativize(cwd, uri, isWindows); |  105   relativizeUri(Uri uri) => relativize(cwd, uri, isWindows); | 
|  110  |  106  | 
|  111   SourceFile getSourceFile(Uri resourceUri) { |  107   SourceFile getSourceFile(Uri resourceUri) { | 
|  112     return sourceFiles[resourceUri]; |  108     return sourceFiles[resourceUri]; | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
|  133   int throwOnErrorCount = 0; |  129   int throwOnErrorCount = 0; | 
|  134   api.Diagnostic lastKind = null; |  130   api.Diagnostic lastKind = null; | 
|  135   int fatalCount = 0; |  131   int fatalCount = 0; | 
|  136  |  132  | 
|  137   final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal; |  133   final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal; | 
|  138   final int INFO = |  134   final int INFO = | 
|  139       api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal; |  135       api.Diagnostic.INFO.ordinal | api.Diagnostic.VERBOSE_INFO.ordinal; | 
|  140  |  136  | 
|  141   FormattingDiagnosticHandler([SourceFileProvider provider]) |  137   FormattingDiagnosticHandler([SourceFileProvider provider]) | 
|  142       : this.provider = |  138       : this.provider = | 
|  143           (provider == null) ? new CompilerSourceFileProvider() : provider; |  139             (provider == null) ? new CompilerSourceFileProvider() : provider; | 
|  144  |  140  | 
|  145   void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) { |  141   void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) { | 
|  146     if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return; |  142     if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return; | 
|  147     if (enableColors) { |  143     if (enableColors) { | 
|  148       print('${colors.green("Info:")} $message'); |  144       print('${colors.green("Info:")} $message'); | 
|  149     } else { |  145     } else { | 
|  150       print('Info: $message'); |  146       print('Info: $message'); | 
|  151     } |  147     } | 
|  152   } |  148   } | 
|  153  |  149  | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  164         return 'Internal Error: $message'; |  160         return 'Internal Error: $message'; | 
|  165       case api.Diagnostic.INFO: |  161       case api.Diagnostic.INFO: | 
|  166       case api.Diagnostic.VERBOSE_INFO: |  162       case api.Diagnostic.VERBOSE_INFO: | 
|  167         return 'Info: $message'; |  163         return 'Info: $message'; | 
|  168     } |  164     } | 
|  169     throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})'; |  165     throw 'Unexpected diagnostic kind: $kind (${kind.ordinal})'; | 
|  170   } |  166   } | 
|  171  |  167  | 
|  172   @override |  168   @override | 
|  173   void report(var code, Uri uri, int begin, int end, String message, |  169   void report(var code, Uri uri, int begin, int end, String message, | 
|  174               api.Diagnostic kind) { |  170       api.Diagnostic kind) { | 
|  175     // TODO(ahe): Remove this when source map is handled differently. |  171     // TODO(ahe): Remove this when source map is handled differently. | 
|  176     if (identical(kind.name, 'source map')) return; |  172     if (identical(kind.name, 'source map')) return; | 
|  177  |  173  | 
|  178     if (isAborting) return; |  174     if (isAborting) return; | 
|  179     isAborting = (kind == api.Diagnostic.CRASH); |  175     isAborting = (kind == api.Diagnostic.CRASH); | 
|  180  |  176  | 
|  181     bool fatal = (kind.ordinal & FATAL) != 0; |  177     bool fatal = (kind.ordinal & FATAL) != 0; | 
|  182     bool isInfo = (kind.ordinal & INFO) != 0; |  178     bool isInfo = (kind.ordinal & INFO) != 0; | 
|  183     if (isInfo && uri == null && kind != api.Diagnostic.INFO) { |  179     if (isInfo && uri == null && kind != api.Diagnostic.INFO) { | 
|  184       info(message, kind); |  180       info(message, kind); | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|  212       throw 'Unknown kind: $kind (${kind.ordinal})'; |  208       throw 'Unknown kind: $kind (${kind.ordinal})'; | 
|  213     } |  209     } | 
|  214     if (!enableColors) { |  210     if (!enableColors) { | 
|  215       color = (x) => x; |  211       color = (x) => x; | 
|  216     } |  212     } | 
|  217     if (uri == null) { |  213     if (uri == null) { | 
|  218       print('${color(message)}'); |  214       print('${color(message)}'); | 
|  219     } else { |  215     } else { | 
|  220       SourceFile file = provider.sourceFiles[uri]; |  216       SourceFile file = provider.sourceFiles[uri]; | 
|  221       if (file != null) { |  217       if (file != null) { | 
|  222         print(file.getLocationMessage( |  218         print(file.getLocationMessage(color(message), begin, end, | 
|  223           color(message), begin, end, colorize: color)); |  219             colorize: color)); | 
|  224       } else { |  220       } else { | 
|  225         String position = end - begin > 0 ? '@$begin+${end - begin}' : ''; |  221         String position = end - begin > 0 ? '@$begin+${end - begin}' : ''; | 
|  226         print('${provider.relativizeUri(uri)}$position:\n' |  222         print('${provider.relativizeUri(uri)}$position:\n' | 
|  227               '${color(message)}'); |  223             '${color(message)}'); | 
|  228       } |  224       } | 
|  229     } |  225     } | 
|  230     if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) { |  226     if (fatal && ++fatalCount >= throwOnErrorCount && throwOnError) { | 
|  231       isAborting = true; |  227       isAborting = true; | 
|  232       throw new AbortLeg(message); |  228       throw new AbortLeg(message); | 
|  233     } |  229     } | 
|  234   } |  230   } | 
|  235  |  231  | 
|  236   // TODO(johnniwinther): Remove this when no longer needed for the old compiler |  232   // TODO(johnniwinther): Remove this when no longer needed for the old compiler | 
|  237   // API. |  233   // API. | 
|  238   void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) { |  234   void call(Uri uri, int begin, int end, String message, api.Diagnostic kind) { | 
|  239     return report(null, uri, begin, end, message, kind); |  235     return report(null, uri, begin, end, message, kind); | 
|  240   } |  236   } | 
|  241 } |  237 } | 
|  242  |  238  | 
|  243 typedef void MessageCallback(String message); |  239 typedef void MessageCallback(String message); | 
|  244  |  240  | 
|  245 class RandomAccessFileOutputProvider { |  241 class RandomAccessFileOutputProvider { | 
|  246   final Uri out; |  242   final Uri out; | 
|  247   final Uri sourceMapOut; |  243   final Uri sourceMapOut; | 
|  248   final MessageCallback onInfo; |  244   final MessageCallback onInfo; | 
|  249   final MessageCallback onFailure; |  245   final MessageCallback onFailure; | 
|  250  |  246  | 
|  251   int totalCharactersWritten = 0; |  247   int totalCharactersWritten = 0; | 
|  252   List<String> allOutputFiles = new List<String>(); |  248   List<String> allOutputFiles = new List<String>(); | 
|  253  |  249  | 
|  254   RandomAccessFileOutputProvider(this.out, |  250   RandomAccessFileOutputProvider(this.out, this.sourceMapOut, | 
|  255                                  this.sourceMapOut, |  251       {this.onInfo, this.onFailure}); | 
|  256                                  {this.onInfo, |  | 
|  257                                   this.onFailure}); |  | 
|  258  |  252  | 
|  259   static Uri computePrecompiledUri(Uri out) { |  253   static Uri computePrecompiledUri(Uri out) { | 
|  260     String extension = 'precompiled.js'; |  254     String extension = 'precompiled.js'; | 
|  261     String outPath = out.path; |  255     String outPath = out.path; | 
|  262     if (outPath.endsWith('.js')) { |  256     if (outPath.endsWith('.js')) { | 
|  263       outPath = outPath.substring(0, outPath.length - 3); |  257       outPath = outPath.substring(0, outPath.length - 3); | 
|  264       return out.resolve('$outPath.$extension'); |  258       return out.resolve('$outPath.$extension'); | 
|  265     } else { |  259     } else { | 
|  266       return out.resolve(extension); |  260       return out.resolve(extension); | 
|  267     } |  261     } | 
|  268   } |  262   } | 
|  269  |  263  | 
|  270   EventSink<String> call(String name, String extension) { |  264   EventSink<String> call(String name, String extension) { | 
|  271     Uri uri; |  265     Uri uri; | 
|  272     bool isPrimaryOutput = false; |  266     bool isPrimaryOutput = false; | 
|  273     // TODO (johnniwinther, sigurdm): Make a better interface for |  267     // TODO (johnniwinther, sigurdm): Make a better interface for | 
|  274     // output-providers. |  268     // output-providers. | 
|  275     if (extension == "deferred_map") { |  269     if (extension == "deferred_map") { | 
|  276       uri = out.resolve(name); |  270       uri = out.resolve(name); | 
|  277     } else if (name == '') { |  271     } else if (name == '') { | 
|  278       if (extension == 'js' || extension == 'dart') { |  272       if (extension == 'js' || extension == 'dart') { | 
|  279         isPrimaryOutput = true; |  273         isPrimaryOutput = true; | 
|  280         uri = out; |  274         uri = out; | 
|  281       } else if (extension == 'precompiled.js') { |  275       } else if (extension == 'precompiled.js') { | 
|  282         uri = computePrecompiledUri(out); |  276         uri = computePrecompiledUri(out); | 
|  283         onInfo("File ($uri) is compatible with header" |  277         onInfo("File ($uri) is compatible with header" | 
|  284                " \"Content-Security-Policy: script-src 'self'\""); |  278             " \"Content-Security-Policy: script-src 'self'\""); | 
|  285       } else if (extension == 'js.map' || extension == 'dart.map') { |  279       } else if (extension == 'js.map' || extension == 'dart.map') { | 
|  286         uri = sourceMapOut; |  280         uri = sourceMapOut; | 
|  287       } else if (extension == "info.json") { |  281       } else if (extension == "info.json") { | 
|  288         String outName = out.path.substring(out.path.lastIndexOf('/') + 1); |  282         String outName = out.path.substring(out.path.lastIndexOf('/') + 1); | 
|  289         uri = out.resolve('$outName.$extension'); |  283         uri = out.resolve('$outName.$extension'); | 
|  290       } else { |  284       } else { | 
|  291         onFailure('Unknown extension: $extension'); |  285         onFailure('Unknown extension: $extension'); | 
|  292       } |  286       } | 
|  293     } else { |  287     } else { | 
|  294       uri = out.resolve('$name.$extension'); |  288       uri = out.resolve('$name.$extension'); | 
|  295     } |  289     } | 
|  296  |  290  | 
|  297     if (uri.scheme != 'file') { |  291     if (uri.scheme != 'file') { | 
|  298       onFailure('Unhandled scheme ${uri.scheme} in $uri.'); |  292       onFailure('Unhandled scheme ${uri.scheme} in $uri.'); | 
|  299     } |  293     } | 
|  300  |  294  | 
|  301     RandomAccessFile output; |  295     RandomAccessFile output; | 
|  302     try { |  296     try { | 
|  303       output = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE); |  297       output = new File(uri.toFilePath()).openSync(mode: FileMode.WRITE); | 
|  304     } on FileSystemException catch(e) { |  298     } on FileSystemException catch (e) { | 
|  305       onFailure('$e'); |  299       onFailure('$e'); | 
|  306     } |  300     } | 
|  307  |  301  | 
|  308     allOutputFiles.add(relativize(currentDirectory, uri, Platform.isWindows)); |  302     allOutputFiles.add(relativize(currentDirectory, uri, Platform.isWindows)); | 
|  309  |  303  | 
|  310     int charactersWritten = 0; |  304     int charactersWritten = 0; | 
|  311  |  305  | 
|  312     writeStringSync(String data) { |  306     writeStringSync(String data) { | 
|  313       // Write the data in chunks of 8kb, otherwise we risk running OOM. |  307       // Write the data in chunks of 8kb, otherwise we risk running OOM. | 
|  314       int chunkSize = 8*1024; |  308       int chunkSize = 8 * 1024; | 
|  315  |  309  | 
|  316       int offset = 0; |  310       int offset = 0; | 
|  317       while (offset < data.length) { |  311       while (offset < data.length) { | 
|  318         output.writeStringSync( |  312         output.writeStringSync( | 
|  319             data.substring(offset, math.min(offset + chunkSize, data.length))); |  313             data.substring(offset, math.min(offset + chunkSize, data.length))); | 
|  320         offset += chunkSize; |  314         offset += chunkSize; | 
|  321       } |  315       } | 
|  322       charactersWritten += data.length; |  316       charactersWritten += data.length; | 
|  323     } |  317     } | 
|  324  |  318  | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|  337   var onAdd, onClose; |  331   var onAdd, onClose; | 
|  338  |  332  | 
|  339   EventSinkWrapper(this.onAdd, this.onClose); |  333   EventSinkWrapper(this.onAdd, this.onClose); | 
|  340  |  334  | 
|  341   void add(String data) => onAdd(data); |  335   void add(String data) => onAdd(data); | 
|  342  |  336  | 
|  343   void addError(error, [StackTrace stackTrace]) => throw error; |  337   void addError(error, [StackTrace stackTrace]) => throw error; | 
|  344  |  338  | 
|  345   void close() => onClose(); |  339   void close() => onClose(); | 
|  346 } |  340 } | 
| OLD | NEW |