| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 leg_apiimpl; | 5 library leg_apiimpl; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:convert'; | 8 import 'dart:convert'; |
| 9 | 9 |
| 10 import '../compiler_new.dart' as api; |
| 11 import 'dart2jslib.dart' as leg; |
| 12 import 'tree/tree.dart' as tree; |
| 13 import 'elements/elements.dart' as elements; |
| 14 import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES; |
| 15 import 'package:sdk_library_metadata/libraries.dart' as library_info show LIBRAR
IES; |
| 16 import 'io/source_file.dart'; |
| 10 import 'package:package_config/packages.dart'; | 17 import 'package:package_config/packages.dart'; |
| 11 import 'package:package_config/packages_file.dart' as pkgs; | 18 import 'package:package_config/packages_file.dart' as pkgs; |
| 12 import 'package:package_config/src/packages_impl.dart' | 19 import 'package:package_config/src/packages_impl.dart' |
| 13 show NonFilePackagesDirectoryPackages, MapPackages; | 20 show NonFilePackagesDirectoryPackages, MapPackages; |
| 14 import 'package:package_config/src/util.dart' show checkValidPackageUri; | 21 import 'package:package_config/src/util.dart' show checkValidPackageUri; |
| 15 import 'package:sdk_library_metadata/libraries.dart' hide LIBRARIES; | |
| 16 import 'package:sdk_library_metadata/libraries.dart' as library_info show LIBRAR
IES; | |
| 17 | |
| 18 import '../compiler_new.dart' as api; | |
| 19 import 'dart2jslib.dart' as leg; | |
| 20 import 'elements/elements.dart' as elements; | |
| 21 import 'io/source_file.dart'; | |
| 22 import 'messages.dart'; | |
| 23 import 'script.dart'; | |
| 24 import 'tree/tree.dart' as tree; | |
| 25 import 'util/util.dart' show | |
| 26 NO_LOCATION_SPANNABLE, | |
| 27 Spannable; | |
| 28 | 22 |
| 29 const bool forceIncrementalSupport = | 23 const bool forceIncrementalSupport = |
| 30 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); | 24 const bool.fromEnvironment('DART2JS_EXPERIMENTAL_INCREMENTAL_SUPPORT'); |
| 31 | 25 |
| 32 class Compiler extends leg.Compiler { | 26 class Compiler extends leg.Compiler { |
| 33 api.CompilerInput provider; | 27 api.CompilerInput provider; |
| 34 api.CompilerDiagnostics handler; | 28 api.CompilerDiagnostics handler; |
| 35 final Uri libraryRoot; | 29 final Uri libraryRoot; |
| 36 final Uri packageConfig; | 30 final Uri packageConfig; |
| 37 final Uri packageRoot; | 31 final Uri packageRoot; |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 Uri resolvedUri, tree.Node node) { | 206 Uri resolvedUri, tree.Node node) { |
| 213 if (resolvedUri.scheme == 'dart') { | 207 if (resolvedUri.scheme == 'dart') { |
| 214 return translateDartUri(importingLibrary, resolvedUri, node); | 208 return translateDartUri(importingLibrary, resolvedUri, node); |
| 215 } | 209 } |
| 216 return resolvedUri; | 210 return resolvedUri; |
| 217 } | 211 } |
| 218 | 212 |
| 219 /** | 213 /** |
| 220 * Reads the script designated by [readableUri]. | 214 * Reads the script designated by [readableUri]. |
| 221 */ | 215 */ |
| 222 Future<Script> readScript(Spannable node, Uri readableUri) { | 216 Future<leg.Script> readScript(leg.Spannable node, Uri readableUri) { |
| 223 if (!readableUri.isAbsolute) { | 217 if (!readableUri.isAbsolute) { |
| 224 if (node == null) node = NO_LOCATION_SPANNABLE; | 218 if (node == null) node = leg.NO_LOCATION_SPANNABLE; |
| 225 internalError(node, | 219 internalError(node, |
| 226 'Relative uri $readableUri provided to readScript(Uri).'); | 220 'Relative uri $readableUri provided to readScript(Uri).'); |
| 227 } | 221 } |
| 228 | 222 |
| 229 // We need to store the current element since we are reporting read errors | 223 // We need to store the current element since we are reporting read errors |
| 230 // asynchronously and therefore need to restore the current element for | 224 // asynchronously and therefore need to restore the current element for |
| 231 // [node] to be valid. | 225 // [node] to be valid. |
| 232 elements.Element element = currentElement; | 226 elements.Element element = currentElement; |
| 233 void reportReadError(exception) { | 227 void reportReadError(exception) { |
| 234 if (element == null || node == null) { | 228 if (element == null || node == null) { |
| 235 reportError( | 229 reportError( |
| 236 new leg.SourceSpan(readableUri, 0, 0), | 230 new leg.SourceSpan(readableUri, 0, 0), |
| 237 MessageKind.READ_SELF_ERROR, | 231 leg.MessageKind.READ_SELF_ERROR, |
| 238 {'uri': readableUri, 'exception': exception}); | 232 {'uri': readableUri, 'exception': exception}); |
| 239 } else { | 233 } else { |
| 240 withCurrentElement(element, () { | 234 withCurrentElement(element, () { |
| 241 reportError( | 235 reportError( |
| 242 node, | 236 node, |
| 243 MessageKind.READ_SCRIPT_ERROR, | 237 leg.MessageKind.READ_SCRIPT_ERROR, |
| 244 {'uri': readableUri, 'exception': exception}); | 238 {'uri': readableUri, 'exception': exception}); |
| 245 }); | 239 }); |
| 246 } | 240 } |
| 247 } | 241 } |
| 248 | 242 |
| 249 Uri resourceUri = translateUri(node, readableUri); | 243 Uri resourceUri = translateUri(node, readableUri); |
| 250 if (resourceUri == null) return synthesizeScript(node, readableUri); | 244 if (resourceUri == null) return synthesizeScript(node, readableUri); |
| 251 if (resourceUri.scheme == 'dart-ext') { | 245 if (resourceUri.scheme == 'dart-ext') { |
| 252 if (!allowNativeExtensions) { | 246 if (!allowNativeExtensions) { |
| 253 withCurrentElement(element, () { | 247 withCurrentElement(element, () { |
| 254 reportError(node, MessageKind.DART_EXT_NOT_SUPPORTED); | 248 reportError(node, leg.MessageKind.DART_EXT_NOT_SUPPORTED); |
| 255 }); | 249 }); |
| 256 } | 250 } |
| 257 return synthesizeScript(node, readableUri); | 251 return synthesizeScript(node, readableUri); |
| 258 } | 252 } |
| 259 | 253 |
| 260 // TODO(johnniwinther): Wrap the result from [provider] in a specialized | 254 // TODO(johnniwinther): Wrap the result from [provider] in a specialized |
| 261 // [Future] to ensure that we never execute an asynchronous action without | 255 // [Future] to ensure that we never execute an asynchronous action without |
| 262 // setting up the current element of the compiler. | 256 // setting up the current element of the compiler. |
| 263 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { | 257 return new Future.sync(() => callUserProvider(resourceUri)).then((data) { |
| 264 SourceFile sourceFile; | 258 SourceFile sourceFile; |
| 265 if (data is List<int>) { | 259 if (data is List<int>) { |
| 266 sourceFile = new Utf8BytesSourceFile(resourceUri, data); | 260 sourceFile = new Utf8BytesSourceFile(resourceUri, data); |
| 267 } else if (data is String) { | 261 } else if (data is String) { |
| 268 sourceFile = new StringSourceFile.fromUri(resourceUri, data); | 262 sourceFile = new StringSourceFile.fromUri(resourceUri, data); |
| 269 } else { | 263 } else { |
| 270 String message = "Expected a 'String' or a 'List<int>' from the input " | 264 String message = "Expected a 'String' or a 'List<int>' from the input " |
| 271 "provider, but got: ${Error.safeToString(data)}."; | 265 "provider, but got: ${Error.safeToString(data)}."; |
| 272 reportReadError(message); | 266 reportReadError(message); |
| 273 } | 267 } |
| 274 // We use [readableUri] as the URI for the script since need to preserve | 268 // We use [readableUri] as the URI for the script since need to preserve |
| 275 // the scheme in the script because [Script.uri] is used for resolving | 269 // the scheme in the script because [Script.uri] is used for resolving |
| 276 // relative URIs mentioned in the script. See the comment on | 270 // relative URIs mentioned in the script. See the comment on |
| 277 // [LibraryLoader] for more details. | 271 // [LibraryLoader] for more details. |
| 278 return new Script(readableUri, resourceUri, sourceFile); | 272 return new leg.Script(readableUri, resourceUri, sourceFile); |
| 279 }).catchError((error) { | 273 }).catchError((error) { |
| 280 reportReadError(error); | 274 reportReadError(error); |
| 281 return synthesizeScript(node, readableUri); | 275 return synthesizeScript(node, readableUri); |
| 282 }); | 276 }); |
| 283 } | 277 } |
| 284 | 278 |
| 285 Future<Script> synthesizeScript(Spannable node, Uri readableUri) { | 279 Future<leg.Script> synthesizeScript(leg.Spannable node, Uri readableUri) { |
| 286 return new Future.value( | 280 return new Future.value( |
| 287 new Script( | 281 new leg.Script( |
| 288 readableUri, readableUri, | 282 readableUri, readableUri, |
| 289 new StringSourceFile.fromUri( | 283 new StringSourceFile.fromUri( |
| 290 readableUri, | 284 readableUri, |
| 291 "// Synthetic source file generated for '$readableUri'."), | 285 "// Synthetic source file generated for '$readableUri'."), |
| 292 isSynthesized: true)); | 286 isSynthesized: true)); |
| 293 } | 287 } |
| 294 | 288 |
| 295 /** | 289 /** |
| 296 * Translates a readable URI into a resource URI. | 290 * Translates a readable URI into a resource URI. |
| 297 * | 291 * |
| 298 * See [LibraryLoader] for terminology on URIs. | 292 * See [LibraryLoader] for terminology on URIs. |
| 299 */ | 293 */ |
| 300 Uri translateUri(Spannable node, Uri readableUri) { | 294 Uri translateUri(leg.Spannable node, Uri readableUri) { |
| 301 switch (readableUri.scheme) { | 295 switch (readableUri.scheme) { |
| 302 case 'package': return translatePackageUri(node, readableUri); | 296 case 'package': return translatePackageUri(node, readableUri); |
| 303 default: return readableUri; | 297 default: return readableUri; |
| 304 } | 298 } |
| 305 } | 299 } |
| 306 | 300 |
| 307 Uri translateDartUri(elements.LibraryElement importingLibrary, | 301 Uri translateDartUri(elements.LibraryElement importingLibrary, |
| 308 Uri resolvedUri, tree.Node node) { | 302 Uri resolvedUri, tree.Node node) { |
| 309 LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); | 303 LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path); |
| 310 String path = lookupLibraryPath(libraryInfo); | 304 String path = lookupLibraryPath(libraryInfo); |
| 311 if (libraryInfo != null && | 305 if (libraryInfo != null && |
| 312 libraryInfo.category == "Internal") { | 306 libraryInfo.category == "Internal") { |
| 313 bool allowInternalLibraryAccess = false; | 307 bool allowInternalLibraryAccess = false; |
| 314 if (importingLibrary != null) { | 308 if (importingLibrary != null) { |
| 315 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { | 309 if (importingLibrary.isPlatformLibrary || importingLibrary.isPatch) { |
| 316 allowInternalLibraryAccess = true; | 310 allowInternalLibraryAccess = true; |
| 317 } else if (importingLibrary.canonicalUri.path.contains( | 311 } else if (importingLibrary.canonicalUri.path.contains( |
| 318 'sdk/tests/compiler/dart2js_native')) { | 312 'sdk/tests/compiler/dart2js_native')) { |
| 319 allowInternalLibraryAccess = true; | 313 allowInternalLibraryAccess = true; |
| 320 } | 314 } |
| 321 } | 315 } |
| 322 if (!allowInternalLibraryAccess) { | 316 if (!allowInternalLibraryAccess) { |
| 323 if (importingLibrary != null) { | 317 if (importingLibrary != null) { |
| 324 reportError( | 318 reportError( |
| 325 node, | 319 node, |
| 326 MessageKind.INTERNAL_LIBRARY_FROM, | 320 leg.MessageKind.INTERNAL_LIBRARY_FROM, |
| 327 {'resolvedUri': resolvedUri, | 321 {'resolvedUri': resolvedUri, |
| 328 'importingUri': importingLibrary.canonicalUri}); | 322 'importingUri': importingLibrary.canonicalUri}); |
| 329 } else { | 323 } else { |
| 330 reportError( | 324 reportError( |
| 331 node, | 325 node, |
| 332 MessageKind.INTERNAL_LIBRARY, | 326 leg.MessageKind.INTERNAL_LIBRARY, |
| 333 {'resolvedUri': resolvedUri}); | 327 {'resolvedUri': resolvedUri}); |
| 334 } | 328 } |
| 335 } | 329 } |
| 336 } | 330 } |
| 337 if (path == null) { | 331 if (path == null) { |
| 338 reportError(node, MessageKind.LIBRARY_NOT_FOUND, | 332 reportError(node, leg.MessageKind.LIBRARY_NOT_FOUND, |
| 339 {'resolvedUri': resolvedUri}); | 333 {'resolvedUri': resolvedUri}); |
| 340 return null; | 334 return null; |
| 341 } | 335 } |
| 342 if (resolvedUri.path == 'html' || | 336 if (resolvedUri.path == 'html' || |
| 343 resolvedUri.path == 'io') { | 337 resolvedUri.path == 'io') { |
| 344 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart | 338 // TODO(ahe): Get rid of mockableLibraryUsed when test.dart |
| 345 // supports this use case better. | 339 // supports this use case better. |
| 346 mockableLibraryUsed = true; | 340 mockableLibraryUsed = true; |
| 347 } | 341 } |
| 348 return libraryRoot.resolve(path); | 342 return libraryRoot.resolve(path); |
| 349 } | 343 } |
| 350 | 344 |
| 351 Uri resolvePatchUri(String dartLibraryPath) { | 345 Uri resolvePatchUri(String dartLibraryPath) { |
| 352 String patchPath = lookupPatchPath(dartLibraryPath); | 346 String patchPath = lookupPatchPath(dartLibraryPath); |
| 353 if (patchPath == null) return null; | 347 if (patchPath == null) return null; |
| 354 return libraryRoot.resolve(patchPath); | 348 return libraryRoot.resolve(patchPath); |
| 355 } | 349 } |
| 356 | 350 |
| 357 Uri translatePackageUri(Spannable node, Uri uri) { | 351 Uri translatePackageUri(leg.Spannable node, Uri uri) { |
| 358 try { | 352 try { |
| 359 checkValidPackageUri(uri); | 353 checkValidPackageUri(uri); |
| 360 } on ArgumentError catch (e) { | 354 } on ArgumentError catch (e) { |
| 361 reportError( | 355 reportError( |
| 362 node, | 356 node, |
| 363 MessageKind.INVALID_PACKAGE_URI, | 357 leg.MessageKind.INVALID_PACKAGE_URI, |
| 364 {'uri': uri, 'exception': e.message}); | 358 {'uri': uri, 'exception': e.message}); |
| 365 return null; | 359 return null; |
| 366 } | 360 } |
| 367 return packages.resolve(uri, | 361 return packages.resolve(uri, |
| 368 notFound: (Uri notFound) { | 362 notFound: (Uri notFound) { |
| 369 reportError( | 363 reportError( |
| 370 node, | 364 node, |
| 371 MessageKind.LIBRARY_NOT_FOUND, | 365 leg.MessageKind.LIBRARY_NOT_FOUND, |
| 372 {'resolvedUri': uri} | 366 {'resolvedUri': uri} |
| 373 ); | 367 ); |
| 374 return null; | 368 return null; |
| 375 }); | 369 }); |
| 376 } | 370 } |
| 377 | 371 |
| 378 Future setupPackages(Uri uri) { | 372 Future setupPackages(Uri uri) { |
| 379 if (packageRoot != null) { | 373 if (packageRoot != null) { |
| 380 // Use "non-file" packages because the file version requires a [Directory] | 374 // Use "non-file" packages because the file version requires a [Directory] |
| 381 // and we can't depend on 'dart:io' classes. | 375 // and we can't depend on 'dart:io' classes. |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 } | 410 } |
| 417 } | 411 } |
| 418 int total = totalCompileTime.elapsedMilliseconds; | 412 int total = totalCompileTime.elapsedMilliseconds; |
| 419 log('Total compile-time ${total}msec;' | 413 log('Total compile-time ${total}msec;' |
| 420 ' unaccounted ${total - cumulated}msec'); | 414 ' unaccounted ${total - cumulated}msec'); |
| 421 return success; | 415 return success; |
| 422 }); | 416 }); |
| 423 }); | 417 }); |
| 424 } | 418 } |
| 425 | 419 |
| 426 void reportDiagnostic(Spannable node, | 420 void reportDiagnostic(leg.Spannable node, |
| 427 Message message, | 421 leg.Message message, |
| 428 api.Diagnostic kind) { | 422 api.Diagnostic kind) { |
| 429 leg.SourceSpan span = spanFromSpannable(node); | 423 leg.SourceSpan span = spanFromSpannable(node); |
| 430 if (identical(kind, api.Diagnostic.ERROR) | 424 if (identical(kind, api.Diagnostic.ERROR) |
| 431 || identical(kind, api.Diagnostic.CRASH) | 425 || identical(kind, api.Diagnostic.CRASH) |
| 432 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { | 426 || (fatalWarnings && identical(kind, api.Diagnostic.WARNING))) { |
| 433 compilationFailed = true; | 427 compilationFailed = true; |
| 434 } | 428 } |
| 435 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For | 429 // [:span.uri:] might be [:null:] in case of a [Script] with no [uri]. For |
| 436 // instance in the [Types] constructor in typechecker.dart. | 430 // instance in the [Types] constructor in typechecker.dart. |
| 437 if (span == null || span.uri == null) { | 431 if (span == null || span.uri == null) { |
| 438 callUserHandler(message, null, null, null, '$message', kind); | 432 callUserHandler(message, null, null, null, '$message', kind); |
| 439 } else { | 433 } else { |
| 440 callUserHandler( | 434 callUserHandler( |
| 441 message, span.uri, span.begin, span.end, '$message', kind); | 435 message, span.uri, span.begin, span.end, '$message', kind); |
| 442 } | 436 } |
| 443 } | 437 } |
| 444 | 438 |
| 445 bool get isMockCompilation { | 439 bool get isMockCompilation { |
| 446 return mockableLibraryUsed | 440 return mockableLibraryUsed |
| 447 && (options.indexOf('--allow-mock-compilation') != -1); | 441 && (options.indexOf('--allow-mock-compilation') != -1); |
| 448 } | 442 } |
| 449 | 443 |
| 450 void callUserHandler(Message message, Uri uri, int begin, int end, | 444 void callUserHandler(leg.Message message, Uri uri, int begin, int end, |
| 451 String text, api.Diagnostic kind) { | 445 String text, api.Diagnostic kind) { |
| 452 try { | 446 try { |
| 453 userHandlerTask.measure(() { | 447 userHandlerTask.measure(() { |
| 454 handler.report(message, uri, begin, end, text, kind); | 448 handler.report(message, uri, begin, end, text, kind); |
| 455 }); | 449 }); |
| 456 } catch (ex, s) { | 450 } catch (ex, s) { |
| 457 diagnoseCrashInUserCode( | 451 diagnoseCrashInUserCode( |
| 458 'Uncaught exception in diagnostic handler', ex, s); | 452 'Uncaught exception in diagnostic handler', ex, s); |
| 459 rethrow; | 453 rethrow; |
| 460 } | 454 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 484 print('$message: ${tryToString(exception)}'); | 478 print('$message: ${tryToString(exception)}'); |
| 485 print(tryToString(stackTrace)); | 479 print(tryToString(stackTrace)); |
| 486 } | 480 } |
| 487 | 481 |
| 488 fromEnvironment(String name) => environment[name]; | 482 fromEnvironment(String name) => environment[name]; |
| 489 | 483 |
| 490 LibraryInfo lookupLibraryInfo(String libraryName) { | 484 LibraryInfo lookupLibraryInfo(String libraryName) { |
| 491 return library_info.LIBRARIES[libraryName]; | 485 return library_info.LIBRARIES[libraryName]; |
| 492 } | 486 } |
| 493 } | 487 } |
| OLD | NEW |