| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 import 'package:kernel/ast.dart' as ir; | 5 import 'package:kernel/ast.dart' as ir; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/names.dart'; | 8 import '../common/names.dart'; |
| 9 import '../compiler.dart'; | 9 import '../compiler.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| 11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
| 12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
| 13 import '../js_backend/backend_helpers.dart'; |
| 13 import '../js_backend/js_backend.dart'; | 14 import '../js_backend/js_backend.dart'; |
| 14 import '../kernel/kernel.dart'; | 15 import '../kernel/kernel.dart'; |
| 15 import '../kernel/kernel_debug.dart'; | 16 import '../kernel/kernel_debug.dart'; |
| 17 import '../native/native.dart' show NativeBehavior; |
| 16 import '../resolution/tree_elements.dart'; | 18 import '../resolution/tree_elements.dart'; |
| 17 import '../tree/tree.dart' as ast; | 19 import '../tree/tree.dart' as ast; |
| 18 import '../types/masks.dart'; | 20 import '../types/masks.dart'; |
| 19 import '../types/types.dart'; | 21 import '../types/types.dart'; |
| 20 import '../universe/call_structure.dart'; | 22 import '../universe/call_structure.dart'; |
| 21 import '../universe/selector.dart'; | 23 import '../universe/selector.dart'; |
| 22 import '../universe/side_effects.dart'; | 24 import '../universe/side_effects.dart'; |
| 23 import '../world.dart'; | 25 import '../world.dart'; |
| 24 import 'locals_handler.dart'; | 26 import 'locals_handler.dart'; |
| 25 import 'types.dart'; | 27 import 'types.dart'; |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 TypeMask get assertThrowReturnType => TypeMaskFactory | 277 TypeMask get assertThrowReturnType => TypeMaskFactory |
| 276 .inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler); | 278 .inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler); |
| 277 | 279 |
| 278 DartType getDartType(ir.DartType type) { | 280 DartType getDartType(ir.DartType type) { |
| 279 return type.accept(_typeConverter); | 281 return type.accept(_typeConverter); |
| 280 } | 282 } |
| 281 | 283 |
| 282 List<DartType> getDartTypes(List<ir.DartType> types) { | 284 List<DartType> getDartTypes(List<ir.DartType> types) { |
| 283 return types.map(getDartType).toList(); | 285 return types.map(getDartType).toList(); |
| 284 } | 286 } |
| 287 |
| 288 @override |
| 289 ForeignKind getForeignKind(ir.StaticInvocation node) { |
| 290 if (isForeignLibrary(node.target.enclosingLibrary)) { |
| 291 switch (node.target.name.name) { |
| 292 case BackendHelpers.JS: |
| 293 return ForeignKind.JS; |
| 294 case BackendHelpers.JS_BUILTIN: |
| 295 return ForeignKind.JS_BUILTIN; |
| 296 case BackendHelpers.JS_EMBEDDED_GLOBAL: |
| 297 return ForeignKind.JS_EMBEDDED_GLOBAL; |
| 298 case BackendHelpers.JS_INTERCEPTOR_CONSTANT: |
| 299 return ForeignKind.JS_INTERCEPTOR_CONSTANT; |
| 300 } |
| 301 } |
| 302 return ForeignKind.NONE; |
| 303 } |
| 304 |
| 305 bool isForeignLibrary(ir.Library node) { |
| 306 return node.importUri == BackendHelpers.DART_FOREIGN_HELPER; |
| 307 } |
| 308 |
| 309 DartType _typeLookup(String typeName) { |
| 310 DartType findIn(Uri uri) { |
| 311 LibraryElement library = _compiler.libraryLoader.lookupLibrary(uri); |
| 312 if (library != null) { |
| 313 Element element = library.find(typeName); |
| 314 if (element != null && element.isClass) { |
| 315 ClassElement cls = element; |
| 316 return cls.rawType; |
| 317 } |
| 318 } |
| 319 return null; |
| 320 } |
| 321 |
| 322 DartType type = findIn(Uris.dart_core); |
| 323 type ??= findIn(BackendHelpers.DART_JS_HELPER); |
| 324 type ??= findIn(BackendHelpers.DART_INTERCEPTORS); |
| 325 type ??= findIn(BackendHelpers.DART_ISOLATE_HELPER); |
| 326 type ??= findIn(Uris.dart_collection); |
| 327 type ??= findIn(Uris.dart_html); |
| 328 return type; |
| 329 } |
| 330 |
| 331 String _getStringArgument(ir.StaticInvocation node, int index) { |
| 332 return node.arguments.positional[index].accept(new Stringifier()); |
| 333 } |
| 334 |
| 335 NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node) { |
| 336 if (node.arguments.positional.length < 2 || |
| 337 node.arguments.named.isNotEmpty) { |
| 338 reporter.reportErrorMessage( |
| 339 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS); |
| 340 return new NativeBehavior(); |
| 341 } |
| 342 String specString = _getStringArgument(node, 0); |
| 343 if (specString == null) { |
| 344 reporter.reportErrorMessage( |
| 345 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST); |
| 346 return new NativeBehavior(); |
| 347 } |
| 348 |
| 349 String codeString = _getStringArgument(node, 1); |
| 350 if (codeString == null) { |
| 351 reporter.reportErrorMessage( |
| 352 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND); |
| 353 return new NativeBehavior(); |
| 354 } |
| 355 |
| 356 return NativeBehavior.ofJsCall(specString, codeString, _typeLookup, |
| 357 CURRENT_ELEMENT_SPANNABLE, reporter, _compiler.coreTypes); |
| 358 } |
| 359 |
| 360 NativeBehavior getNativeBehaviorForJsBuiltinCall(ir.StaticInvocation node) { |
| 361 if (node.arguments.positional.length < 1) { |
| 362 reporter.internalError( |
| 363 CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type."); |
| 364 return new NativeBehavior(); |
| 365 } |
| 366 if (node.arguments.positional.length < 2) { |
| 367 reporter.internalError( |
| 368 CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name."); |
| 369 return new NativeBehavior(); |
| 370 } |
| 371 String specString = _getStringArgument(node, 0); |
| 372 if (specString == null) { |
| 373 reporter.internalError( |
| 374 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument."); |
| 375 return new NativeBehavior(); |
| 376 } |
| 377 return NativeBehavior.ofJsBuiltinCall(specString, _typeLookup, |
| 378 CURRENT_ELEMENT_SPANNABLE, reporter, _compiler.coreTypes); |
| 379 } |
| 380 |
| 381 NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall( |
| 382 ir.StaticInvocation node) { |
| 383 if (node.arguments.positional.length < 1) { |
| 384 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 385 "JS embedded global expression has no type."); |
| 386 return new NativeBehavior(); |
| 387 } |
| 388 if (node.arguments.positional.length < 2) { |
| 389 reporter.internalError( |
| 390 CURRENT_ELEMENT_SPANNABLE, "JS embedded global is missing name."); |
| 391 return new NativeBehavior(); |
| 392 } |
| 393 if (node.arguments.positional.length > 2 || |
| 394 node.arguments.named.isNotEmpty) { |
| 395 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, |
| 396 "JS embedded global has more than 2 arguments."); |
| 397 return new NativeBehavior(); |
| 398 } |
| 399 String specString = _getStringArgument(node, 0); |
| 400 if (specString == null) { |
| 401 reporter.internalError( |
| 402 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument."); |
| 403 return new NativeBehavior(); |
| 404 } |
| 405 return NativeBehavior.ofJsEmbeddedGlobalCall(specString, _typeLookup, |
| 406 CURRENT_ELEMENT_SPANNABLE, reporter, _compiler.coreTypes); |
| 407 } |
| 408 } |
| 409 |
| 410 enum ForeignKind { |
| 411 JS, |
| 412 JS_BUILTIN, |
| 413 JS_EMBEDDED_GLOBAL, |
| 414 JS_INTERCEPTOR_CONSTANT, |
| 415 NONE, |
| 285 } | 416 } |
| 286 | 417 |
| 287 class DartTypeConverter extends ir.DartTypeVisitor<DartType> { | 418 class DartTypeConverter extends ir.DartTypeVisitor<DartType> { |
| 288 final KernelAstAdapter astAdapter; | 419 final KernelAstAdapter astAdapter; |
| 289 | 420 |
| 290 DartTypeConverter(this.astAdapter); | 421 DartTypeConverter(this.astAdapter); |
| 291 | 422 |
| 292 DartType visitType(ir.DartType type) => type.accept(this); | 423 DartType visitType(ir.DartType type) => type.accept(this); |
| 293 | 424 |
| 294 List<DartType> visitTypes(List<ir.DartType> types) { | 425 List<DartType> visitTypes(List<ir.DartType> types) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 341 @override | 472 @override |
| 342 DartType visitDynamicType(ir.DynamicType node) { | 473 DartType visitDynamicType(ir.DynamicType node) { |
| 343 return const DynamicType(); | 474 return const DynamicType(); |
| 344 } | 475 } |
| 345 | 476 |
| 346 @override | 477 @override |
| 347 DartType visitInvalidType(ir.InvalidType node) { | 478 DartType visitInvalidType(ir.InvalidType node) { |
| 348 throw new UnimplementedError("Invalid types not currently supported"); | 479 throw new UnimplementedError("Invalid types not currently supported"); |
| 349 } | 480 } |
| 350 } | 481 } |
| 482 |
| 483 /// Visitor that converts string literals and concatenations of string literals |
| 484 /// into the string value. |
| 485 class Stringifier extends ir.ExpressionVisitor<String> { |
| 486 @override |
| 487 String visitStringLiteral(ir.StringLiteral node) => node.value; |
| 488 |
| 489 @override |
| 490 String visitStringConcatenation(ir.StringConcatenation node) { |
| 491 StringBuffer sb = new StringBuffer(); |
| 492 for (ir.Expression expression in node.expressions) { |
| 493 String value = expression.accept(this); |
| 494 if (value == null) return null; |
| 495 sb.write(value); |
| 496 } |
| 497 return sb.toString(); |
| 498 } |
| 499 } |
| OLD | NEW |