Chromium Code Reviews| 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 NativeBehavior getNativeBehaviorForJsCall(ir.StaticInvocation node) { | |
| 332 if (node.arguments.positional.length < 2 || | |
| 333 node.arguments.named.isNotEmpty) { | |
|
Harry Terkelsen
2016/10/31 21:17:09
move the logic to get the specString and codeStrin
Johnni Winther
2016/11/01 11:53:27
Done.
| |
| 334 reporter.reportErrorMessage( | |
| 335 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS); | |
| 336 return new NativeBehavior(); | |
| 337 } | |
| 338 String specString = node.arguments.positional[0].accept(new Stringifier()); | |
| 339 if (specString == null) { | |
| 340 reporter.reportErrorMessage( | |
| 341 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_FIRST); | |
| 342 return new NativeBehavior(); | |
| 343 } | |
| 344 | |
| 345 String codeString = node.arguments.positional[1].accept(new Stringifier()); | |
| 346 if (codeString == null) { | |
| 347 reporter.reportErrorMessage( | |
| 348 CURRENT_ELEMENT_SPANNABLE, MessageKind.WRONG_ARGUMENT_FOR_JS_SECOND); | |
| 349 return new NativeBehavior(); | |
| 350 } | |
| 351 | |
| 352 return NativeBehavior.ofJsCall(specString, codeString, _typeLookup, | |
| 353 CURRENT_ELEMENT_SPANNABLE, reporter, _compiler.coreTypes); | |
| 354 } | |
| 355 | |
| 356 NativeBehavior getNativeBehaviorForJsBuiltinCall(ir.StaticInvocation node) { | |
| 357 if (node.arguments.positional.length < 1) { | |
| 358 reporter.internalError( | |
| 359 CURRENT_ELEMENT_SPANNABLE, "JS builtin expression has no type."); | |
| 360 return new NativeBehavior(); | |
| 361 } | |
| 362 if (node.arguments.positional.length < 2) { | |
| 363 reporter.internalError( | |
| 364 CURRENT_ELEMENT_SPANNABLE, "JS builtin is missing name."); | |
| 365 return new NativeBehavior(); | |
| 366 } | |
| 367 String specString = node.arguments.positional[0].accept(new Stringifier()); | |
| 368 if (specString == null) { | |
| 369 reporter.internalError( | |
| 370 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument."); | |
| 371 return new NativeBehavior(); | |
| 372 } | |
| 373 return NativeBehavior.ofJsBuiltinCall(specString, _typeLookup, | |
| 374 CURRENT_ELEMENT_SPANNABLE, reporter, _compiler.coreTypes); | |
| 375 } | |
| 376 | |
| 377 NativeBehavior getNativeBehaviorForJsEmbeddedGlobalCall( | |
| 378 ir.StaticInvocation node) { | |
| 379 if (node.arguments.positional.length < 1) { | |
| 380 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, | |
| 381 "JS embedded global expression has no type."); | |
| 382 return new NativeBehavior(); | |
| 383 } | |
| 384 if (node.arguments.positional.length < 2) { | |
| 385 reporter.internalError( | |
| 386 CURRENT_ELEMENT_SPANNABLE, "JS embedded global is missing name."); | |
| 387 return new NativeBehavior(); | |
| 388 } | |
| 389 if (node.arguments.positional.length > 2 || | |
| 390 node.arguments.named.isNotEmpty) { | |
| 391 reporter.internalError(CURRENT_ELEMENT_SPANNABLE, | |
| 392 "JS embedded global has more than 2 arguments."); | |
| 393 return new NativeBehavior(); | |
| 394 } | |
| 395 String specString = node.arguments.positional[0].accept(new Stringifier()); | |
| 396 if (specString == null) { | |
| 397 reporter.internalError( | |
| 398 CURRENT_ELEMENT_SPANNABLE, "Unexpected first argument."); | |
| 399 return new NativeBehavior(); | |
| 400 } | |
| 401 return NativeBehavior.ofJsEmbeddedGlobalCall(specString, _typeLookup, | |
| 402 CURRENT_ELEMENT_SPANNABLE, reporter, _compiler.coreTypes); | |
| 403 } | |
| 404 } | |
| 405 | |
| 406 enum ForeignKind { | |
| 407 JS, | |
| 408 JS_BUILTIN, | |
| 409 JS_EMBEDDED_GLOBAL, | |
| 410 JS_INTERCEPTOR_CONSTANT, | |
| 411 NONE, | |
| 285 } | 412 } |
| 286 | 413 |
| 287 class DartTypeConverter extends ir.DartTypeVisitor<DartType> { | 414 class DartTypeConverter extends ir.DartTypeVisitor<DartType> { |
| 288 final KernelAstAdapter astAdapter; | 415 final KernelAstAdapter astAdapter; |
| 289 | 416 |
| 290 DartTypeConverter(this.astAdapter); | 417 DartTypeConverter(this.astAdapter); |
| 291 | 418 |
| 292 DartType visitType(ir.DartType type) => type.accept(this); | 419 DartType visitType(ir.DartType type) => type.accept(this); |
| 293 | 420 |
| 294 List<DartType> visitTypes(List<ir.DartType> types) { | 421 List<DartType> visitTypes(List<ir.DartType> types) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 341 @override | 468 @override |
| 342 DartType visitDynamicType(ir.DynamicType node) { | 469 DartType visitDynamicType(ir.DynamicType node) { |
| 343 return const DynamicType(); | 470 return const DynamicType(); |
| 344 } | 471 } |
| 345 | 472 |
| 346 @override | 473 @override |
| 347 DartType visitInvalidType(ir.InvalidType node) { | 474 DartType visitInvalidType(ir.InvalidType node) { |
| 348 throw new UnimplementedError("Invalid types not currently supported"); | 475 throw new UnimplementedError("Invalid types not currently supported"); |
| 349 } | 476 } |
| 350 } | 477 } |
| 478 | |
| 479 /// Visitor that converts string literals and concatenations of string literals | |
| 480 /// into the string value. | |
| 481 class Stringifier extends ir.ExpressionVisitor<String> { | |
| 482 @override | |
| 483 String visitStringLiteral(ir.StringLiteral node) => node.value; | |
| 484 | |
| 485 @override | |
| 486 String visitStringConcatenation(ir.StringConcatenation node) { | |
| 487 StringBuffer sb = new StringBuffer(); | |
| 488 for (ir.Expression expression in node.expressions) { | |
| 489 String value = expression.accept(this); | |
| 490 if (value == null) return null; | |
| 491 sb.write(value); | |
| 492 } | |
| 493 return sb.toString(); | |
| 494 } | |
| 495 } | |
| OLD | NEW |