| 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 |