| 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 native; | 5 library native; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 import 'dart2jslib.dart' hide SourceString; | 8 import 'dart2jslib.dart' hide SourceString; |
| 9 import 'dart_types.dart'; | 9 import 'dart_types.dart'; |
| 10 import 'elements/elements.dart'; | 10 import 'elements/elements.dart'; |
| 11 import 'js_backend/js_backend.dart'; | 11 import 'js_backend/js_backend.dart'; |
| 12 import 'resolution/resolution.dart' show ResolverVisitor; | 12 import 'resolution/resolution.dart' show ResolverVisitor; |
| 13 import 'scanner/scannerlib.dart'; | 13 import 'scanner/scannerlib.dart'; |
| 14 import 'ssa/ssa.dart'; | 14 import 'ssa/ssa.dart'; |
| 15 import 'tree/tree.dart'; | 15 import 'tree/tree.dart'; |
| 16 import 'universe/universe.dart' show SideEffects; | 16 import 'universe/universe.dart' show SideEffects; |
| 17 import 'util/util.dart'; | 17 import 'util/util.dart'; |
| 18 import 'js/js.dart' as js; | 18 import 'js/js.dart' as js; |
| 19 | 19 |
| 20 | 20 |
| 21 /// This class is a temporary work-around until we get a more powerful DartType. | 21 /// This class is a temporary work-around until we get a more powerful DartType. |
| 22 class SpecialType { | 22 class SpecialType { |
| 23 final String name; | 23 final String name; |
| 24 const SpecialType._(this.name); | 24 const SpecialType._(this.name); |
| 25 | 25 |
| 26 /// The type Object, but no subtypes: | 26 /// The type Object, but no subtypes: |
| 27 static const JsObject = const SpecialType._('=Object'); | 27 static const JsObject = const SpecialType._('=Object'); |
| 28 | |
| 29 /// The specific implementation of List that is JavaScript Array: | |
| 30 static const JsArray = const SpecialType._('=List'); | |
| 31 } | 28 } |
| 32 | 29 |
| 33 | 30 |
| 34 /** | 31 /** |
| 35 * This could be an abstract class but we use it as a stub for the dart_backend. | 32 * This could be an abstract class but we use it as a stub for the dart_backend. |
| 36 */ | 33 */ |
| 37 class NativeEnqueuer { | 34 class NativeEnqueuer { |
| 38 /// Initial entry point to native enqueuer. | 35 /// Initial entry point to native enqueuer. |
| 39 void processNativeClasses(Iterable<LibraryElement> libraries) {} | 36 void processNativeClasses(Iterable<LibraryElement> libraries) {} |
| 40 | 37 |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 NativeBehavior getNativeBehaviorOf(Send node) => nativeBehaviors[node]; | 321 NativeBehavior getNativeBehaviorOf(Send node) => nativeBehaviors[node]; |
| 325 | 322 |
| 326 processNativeBehavior(NativeBehavior behavior, cause) { | 323 processNativeBehavior(NativeBehavior behavior, cause) { |
| 327 // TODO(ahe): Is this really a global dependency? | 324 // TODO(ahe): Is this really a global dependency? |
| 328 TreeElements elements = compiler.globalDependencies; | 325 TreeElements elements = compiler.globalDependencies; |
| 329 bool allUsedBefore = unusedClasses.isEmpty; | 326 bool allUsedBefore = unusedClasses.isEmpty; |
| 330 for (var type in behavior.typesInstantiated) { | 327 for (var type in behavior.typesInstantiated) { |
| 331 if (matchedTypeConstraints.contains(type)) continue; | 328 if (matchedTypeConstraints.contains(type)) continue; |
| 332 matchedTypeConstraints.add(type); | 329 matchedTypeConstraints.add(type); |
| 333 if (type is SpecialType) { | 330 if (type is SpecialType) { |
| 334 if (type == SpecialType.JsArray) { | 331 if (type == SpecialType.JsObject) { |
| 335 world.registerInstantiatedClass(compiler.listClass, elements); | |
| 336 } else if (type == SpecialType.JsObject) { | |
| 337 world.registerInstantiatedClass(compiler.objectClass, elements); | 332 world.registerInstantiatedClass(compiler.objectClass, elements); |
| 338 } | 333 } |
| 339 continue; | 334 continue; |
| 340 } | 335 } |
| 341 if (type is InterfaceType) { | 336 if (type is InterfaceType) { |
| 342 if (type.element == compiler.intClass) { | 337 if (type.element == compiler.intClass) { |
| 343 world.registerInstantiatedClass(compiler.intClass, elements); | 338 world.registerInstantiatedClass(compiler.intClass, elements); |
| 344 } else if (type.element == compiler.doubleClass) { | 339 } else if (type.element == compiler.doubleClass) { |
| 345 world.registerInstantiatedClass(compiler.doubleClass, elements); | 340 world.registerInstantiatedClass(compiler.doubleClass, elements); |
| 346 } else if (type.element == compiler.numClass) { | 341 } else if (type.element == compiler.numClass) { |
| 347 world.registerInstantiatedClass(compiler.doubleClass, elements); | 342 world.registerInstantiatedClass(compiler.doubleClass, elements); |
| 348 world.registerInstantiatedClass(compiler.intClass, elements); | 343 world.registerInstantiatedClass(compiler.intClass, elements); |
| 349 } else if (type.element == compiler.stringClass) { | 344 } else if (type.element == compiler.stringClass) { |
| 350 world.registerInstantiatedClass(compiler.stringClass, elements); | 345 world.registerInstantiatedClass(compiler.stringClass, elements); |
| 351 } else if (type.element == compiler.nullClass) { | 346 } else if (type.element == compiler.nullClass) { |
| 352 world.registerInstantiatedClass(compiler.nullClass, elements); | 347 world.registerInstantiatedClass(compiler.nullClass, elements); |
| 353 } else if (type.element == compiler.boolClass) { | 348 } else if (type.element == compiler.boolClass) { |
| 354 world.registerInstantiatedClass(compiler.boolClass, elements); | 349 world.registerInstantiatedClass(compiler.boolClass, elements); |
| 350 } else if (compiler.types.isSubtype( |
| 351 type, compiler.backend.listImplementation.rawType)) { |
| 352 world.registerInstantiatedClass(type.element, elements); |
| 355 } | 353 } |
| 356 } | 354 } |
| 357 assert(type is DartType); | 355 assert(type is DartType); |
| 358 enqueueUnusedClassesMatching( | 356 enqueueUnusedClassesMatching( |
| 359 (nativeClass) => compiler.types.isSubtype(nativeClass.thisType, type), | 357 (nativeClass) => compiler.types.isSubtype(nativeClass.thisType, type), |
| 360 cause, | 358 cause, |
| 361 'subtypeof($type)'); | 359 'subtypeof($type)'); |
| 362 } | 360 } |
| 363 | 361 |
| 364 // Give an info so that library developers can compile with -v to find why | 362 // Give an info so that library developers can compile with -v to find why |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 final SideEffects sideEffects = new SideEffects.empty(); | 625 final SideEffects sideEffects = new SideEffects.empty(); |
| 628 | 626 |
| 629 static NativeBehavior NONE = new NativeBehavior(); | 627 static NativeBehavior NONE = new NativeBehavior(); |
| 630 | 628 |
| 631 static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) { | 629 static NativeBehavior ofJsCall(Send jsCall, Compiler compiler, resolver) { |
| 632 // The first argument of a JS-call is a string encoding various attributes | 630 // The first argument of a JS-call is a string encoding various attributes |
| 633 // of the code. | 631 // of the code. |
| 634 // | 632 // |
| 635 // 'Type1|Type2'. A union type. | 633 // 'Type1|Type2'. A union type. |
| 636 // '=Object'. A JavaScript Object, no subtype. | 634 // '=Object'. A JavaScript Object, no subtype. |
| 637 // '=List'. A JavaScript Array, no subtype. | |
| 638 | 635 |
| 639 var argNodes = jsCall.arguments; | 636 var argNodes = jsCall.arguments; |
| 640 if (argNodes.isEmpty) { | 637 if (argNodes.isEmpty) { |
| 641 compiler.cancel("JS expression has no type", node: jsCall); | 638 compiler.cancel("JS expression has no type", node: jsCall); |
| 642 } | 639 } |
| 643 | 640 |
| 644 var code = argNodes.tail.head; | 641 var code = argNodes.tail.head; |
| 645 if (code is !StringNode || code.isInterpolation) { | 642 if (code is !StringNode || code.isInterpolation) { |
| 646 compiler.cancel('JS code must be a string literal', node: code); | 643 compiler.cancel('JS code must be a string literal', node: code); |
| 647 } | 644 } |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 _escape(parameters.head, compiler); | 806 _escape(parameters.head, compiler); |
| 810 } | 807 } |
| 811 } else { | 808 } else { |
| 812 typesInstantiated.add(type); | 809 typesInstantiated.add(type); |
| 813 } | 810 } |
| 814 } | 811 } |
| 815 | 812 |
| 816 static _parseType(String typeString, Compiler compiler, | 813 static _parseType(String typeString, Compiler compiler, |
| 817 lookup(name), locationNodeOrElement) { | 814 lookup(name), locationNodeOrElement) { |
| 818 if (typeString == '=Object') return SpecialType.JsObject; | 815 if (typeString == '=Object') return SpecialType.JsObject; |
| 819 if (typeString == '=List') return SpecialType.JsArray; | |
| 820 if (typeString == 'dynamic') { | 816 if (typeString == 'dynamic') { |
| 821 return compiler.dynamicClass.computeType(compiler); | 817 return compiler.dynamicClass.computeType(compiler); |
| 822 } | 818 } |
| 823 DartType type = lookup(typeString); | 819 DartType type = lookup(typeString); |
| 824 if (type != null) return type; | 820 if (type != null) return type; |
| 825 | 821 |
| 826 int index = typeString.indexOf('<'); | 822 int index = typeString.indexOf('<'); |
| 827 if (index < 1) { | 823 if (index < 1) { |
| 828 compiler.cancel("Type '$typeString' not found", | 824 compiler.cancel("Type '$typeString' not found", |
| 829 node: _errorNode(locationNodeOrElement, compiler)); | 825 node: _errorNode(locationNodeOrElement, compiler)); |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 'native "..." syntax is restricted to functions with zero parameters', | 1014 'native "..." syntax is restricted to functions with zero parameters', |
| 1019 node: nativeBody); | 1015 node: nativeBody); |
| 1020 } | 1016 } |
| 1021 LiteralString jsCode = nativeBody.asLiteralString(); | 1017 LiteralString jsCode = nativeBody.asLiteralString(); |
| 1022 builder.push(new HForeign.statement( | 1018 builder.push(new HForeign.statement( |
| 1023 new js.LiteralStatement(jsCode.dartString.slowToString()), | 1019 new js.LiteralStatement(jsCode.dartString.slowToString()), |
| 1024 <HInstruction>[], | 1020 <HInstruction>[], |
| 1025 new SideEffects())); | 1021 new SideEffects())); |
| 1026 } | 1022 } |
| 1027 } | 1023 } |
| OLD | NEW |