| OLD | NEW | 
|---|
| 1 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 code_generator; | 5 library code_generator; | 
| 6 | 6 | 
| 7 import 'glue.dart'; | 7 import 'glue.dart'; | 
| 8 | 8 | 
| 9 import '../../closure.dart' show ClosureClassElement; | 9 import '../../closure.dart' show ClosureClassElement; | 
| 10 import '../../common/codegen.dart' show CodegenRegistry; | 10 import '../../common/codegen.dart' show CodegenRegistry; | 
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 350 | 350 | 
| 351   @override | 351   @override | 
| 352   js.Expression visitTypeOperator(tree_ir.TypeOperator node) { | 352   js.Expression visitTypeOperator(tree_ir.TypeOperator node) { | 
| 353     js.Expression value = visitExpression(node.value); | 353     js.Expression value = visitExpression(node.value); | 
| 354     List<js.Expression> typeArguments = visitExpressionList(node.typeArguments); | 354     List<js.Expression> typeArguments = visitExpressionList(node.typeArguments); | 
| 355     DartType type = node.type; | 355     DartType type = node.type; | 
| 356     if (type is InterfaceType) { | 356     if (type is InterfaceType) { | 
| 357       glue.registerIsCheck(type, registry); | 357       glue.registerIsCheck(type, registry); | 
| 358       ClassElement clazz = type.element; | 358       ClassElement clazz = type.element; | 
| 359 | 359 | 
|  | 360       // Handle some special checks against classes that exist only in | 
|  | 361       // the compile-time class hierarchy, not at runtime. | 
|  | 362       // TODO(sra): Is this correct? The field tests are only valid with the | 
|  | 363       // precondition that [value] is an Array. They will crash on `null`. | 
|  | 364       if (clazz == glue.jsExtendableArrayClass) { | 
|  | 365         assert(node.isTypeTest); | 
|  | 366         return js.js(r'!#.fixed$length', <js.Expression>[value]); | 
|  | 367       } else if (clazz == glue.jsMutableArrayClass) { | 
|  | 368         assert(node.isTypeTest); | 
|  | 369         return js.js(r'!#.immutable$list', <js.Expression>[value]); | 
|  | 370       } | 
|  | 371 | 
| 360       if (glue.isStringClass(clazz)) { | 372       if (glue.isStringClass(clazz)) { | 
| 361         if (node.isTypeTest) { | 373         if (node.isTypeTest) { | 
| 362           return js.js(r'typeof # === "string"', <js.Expression>[value]); | 374           return js.js(r'typeof # === "string"', <js.Expression>[value]); | 
| 363         } | 375         } | 
| 364         // TODO(sra): Implement fast cast via calling 'stringTypeCast'. | 376         // TODO(sra): Implement fast cast via calling 'stringTypeCast'. | 
| 365       } else if (glue.isBoolClass(clazz)) { | 377       } else if (glue.isBoolClass(clazz)) { | 
| 366         if (node.isTypeTest) { | 378         if (node.isTypeTest) { | 
| 367           return js.js(r'typeof # === "boolean"', <js.Expression>[value]); | 379           return js.js(r'typeof # === "boolean"', <js.Expression>[value]); | 
| 368         } | 380         } | 
| 369         // TODO(sra): Implement fast cast via calling 'boolTypeCast'. | 381         // TODO(sra): Implement fast cast via calling 'boolTypeCast'. | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 409       js.Expression typeValue = typeArguments.single; | 421       js.Expression typeValue = typeArguments.single; | 
| 410 | 422 | 
| 411       return buildStaticHelperInvocation( | 423       return buildStaticHelperInvocation( | 
| 412           function, | 424           function, | 
| 413           <js.Expression>[value, typeValue]); | 425           <js.Expression>[value, typeValue]); | 
| 414     } | 426     } | 
| 415     return giveup(node, 'type check unimplemented for $type.'); | 427     return giveup(node, 'type check unimplemented for $type.'); | 
| 416   } | 428   } | 
| 417 | 429 | 
| 418   @override | 430   @override | 
| 419   js.Expression visitGetTypeTestProperty(tree_ir.GetTypeTestProperty node) { |  | 
| 420     js.Expression object = visitExpression(node.object); |  | 
| 421     DartType dartType = node.dartType; |  | 
| 422     assert(dartType.isInterfaceType); |  | 
| 423     glue.registerIsCheck(dartType, registry); |  | 
| 424     js.Expression property = glue.getTypeTestTag(dartType); |  | 
| 425     return js.js(r'#.#', [object, property]); |  | 
| 426   } |  | 
| 427 |  | 
| 428   @override |  | 
| 429   js.Expression visitVariableUse(tree_ir.VariableUse node) { | 431   js.Expression visitVariableUse(tree_ir.VariableUse node) { | 
| 430     return buildVariableAccess(node.variable); | 432     return buildVariableAccess(node.variable); | 
| 431   } | 433   } | 
| 432 | 434 | 
| 433   js.Expression buildVariableAccess(tree_ir.Variable variable) { | 435   js.Expression buildVariableAccess(tree_ir.Variable variable) { | 
| 434     return new js.VariableUse(getVariableName(variable)); | 436     return new js.VariableUse(getVariableName(variable)); | 
| 435   } | 437   } | 
| 436 | 438 | 
| 437   @override | 439   @override | 
| 438   js.Expression visitAssign(tree_ir.Assign node) { | 440   js.Expression visitAssign(tree_ir.Assign node) { | 
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 810       return buildStaticHelperInvocation( | 812       return buildStaticHelperInvocation( | 
| 811           glue.getTypeArgumentByIndex(), | 813           glue.getTypeArgumentByIndex(), | 
| 812           [visitExpression(node.target), index], | 814           [visitExpression(node.target), index], | 
| 813           sourceInformation: node.sourceInformation); | 815           sourceInformation: node.sourceInformation); | 
| 814     } | 816     } | 
| 815   } | 817   } | 
| 816 | 818 | 
| 817   @override | 819   @override | 
| 818   js.Expression visitTypeExpression(tree_ir.TypeExpression node) { | 820   js.Expression visitTypeExpression(tree_ir.TypeExpression node) { | 
| 819     List<js.Expression> arguments = visitExpressionList(node.arguments); | 821     List<js.Expression> arguments = visitExpressionList(node.arguments); | 
| 820     return glue.generateTypeRepresentation(node.dartType, arguments, registry); | 822     return glue.generateTypeRepresentation(node.dartType, arguments); | 
| 821   } | 823   } | 
| 822 | 824 | 
| 823   js.Node handleForeignCode(tree_ir.ForeignCode node) { | 825   js.Node handleForeignCode(tree_ir.ForeignCode node) { | 
| 824     registry.registerStaticUse(node.dependency); | 826     registry.registerStaticUse(node.dependency); | 
| 825     // TODO(sra): Should this be in CodegenRegistry? |  | 
| 826     glue.registerNativeBehavior(node.nativeBehavior, node); |  | 
| 827     return node.codeTemplate.instantiate(visitExpressionList(node.arguments)); | 827     return node.codeTemplate.instantiate(visitExpressionList(node.arguments)); | 
| 828   } | 828   } | 
| 829 | 829 | 
| 830   @override | 830   @override | 
| 831   js.Expression visitForeignExpression(tree_ir.ForeignExpression node) { | 831   js.Expression visitForeignExpression(tree_ir.ForeignExpression node) { | 
| 832     return handleForeignCode(node); | 832     return handleForeignCode(node); | 
| 833   } | 833   } | 
| 834 | 834 | 
| 835   @override | 835   @override | 
| 836   void visitForeignStatement(tree_ir.ForeignStatement node) { | 836   void visitForeignStatement(tree_ir.ForeignStatement node) { | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 886       case BuiltinOperator.IsFalsy: | 886       case BuiltinOperator.IsFalsy: | 
| 887         return new js.Prefix('!', args[0]); | 887         return new js.Prefix('!', args[0]); | 
| 888       case BuiltinOperator.IsNumber: | 888       case BuiltinOperator.IsNumber: | 
| 889         return js.js('typeof # === "number"', args); | 889         return js.js('typeof # === "number"', args); | 
| 890       case BuiltinOperator.IsNotNumber: | 890       case BuiltinOperator.IsNotNumber: | 
| 891         return js.js('typeof # !== "number"', args); | 891         return js.js('typeof # !== "number"', args); | 
| 892       case BuiltinOperator.IsFloor: | 892       case BuiltinOperator.IsFloor: | 
| 893         return js.js('Math.floor(#) === #', args); | 893         return js.js('Math.floor(#) === #', args); | 
| 894       case BuiltinOperator.IsNumberAndFloor: | 894       case BuiltinOperator.IsNumberAndFloor: | 
| 895         return js.js('typeof # === "number" && Math.floor(#) === #', args); | 895         return js.js('typeof # === "number" && Math.floor(#) === #', args); | 
| 896       case BuiltinOperator.IsFixedLengthJSArray: |  | 
| 897         // TODO(sra): Remove boolify (i.e. !!). |  | 
| 898         return js.js(r'!!#.fixed$length', args); |  | 
| 899       case BuiltinOperator.IsExtendableJSArray: |  | 
| 900         return js.js(r'!#.fixed$length', args); |  | 
| 901       case BuiltinOperator.IsModifiableJSArray: |  | 
| 902         return js.js(r'!#.immutable$list', args); |  | 
| 903       case BuiltinOperator.IsUnmodifiableJSArray: |  | 
| 904         // TODO(sra): Remove boolify (i.e. !!). |  | 
| 905         return js.js(r'!!#.immutable$list', args); |  | 
| 906     } | 896     } | 
| 907   } | 897   } | 
| 908 | 898 | 
| 909   /// The JS name of a built-in method. | 899   /// The JS name of a built-in method. | 
| 910   static final Map<BuiltinMethod, String> builtinMethodName = | 900   static final Map<BuiltinMethod, String> builtinMethodName = | 
| 911     const <BuiltinMethod, String>{ | 901     const <BuiltinMethod, String>{ | 
| 912       BuiltinMethod.Push: 'push', | 902       BuiltinMethod.Push: 'push', | 
| 913       BuiltinMethod.Pop: 'pop', | 903       BuiltinMethod.Pop: 'pop', | 
| 914   }; | 904   }; | 
| 915 | 905 | 
| 916   @override | 906   @override | 
| 917   js.Expression visitApplyBuiltinMethod(tree_ir.ApplyBuiltinMethod node) { | 907   js.Expression visitApplyBuiltinMethod(tree_ir.ApplyBuiltinMethod node) { | 
| 918     String name = builtinMethodName[node.method]; | 908     String name = builtinMethodName[node.method]; | 
| 919     js.Expression receiver = visitExpression(node.receiver); | 909     js.Expression receiver = visitExpression(node.receiver); | 
| 920     List<js.Expression> args = visitExpressionList(node.arguments); | 910     List<js.Expression> args = visitExpressionList(node.arguments); | 
| 921     return js.js('#.#(#)', [receiver, name, args]); | 911     return js.js('#.#(#)', [receiver, name, args]); | 
| 922   } | 912   } | 
| 923 | 913 | 
| 924   @override | 914   @override | 
| 925   js.Expression visitAwait(tree_ir.Await node) { | 915   js.Expression visitAwait(tree_ir.Await node) { | 
| 926     return new js.Await(visitExpression(node.input)); | 916     return new js.Await(visitExpression(node.input)); | 
| 927   } | 917   } | 
| 928 | 918 | 
| 929   visitFunctionExpression(tree_ir.FunctionExpression node) { | 919   visitFunctionExpression(tree_ir.FunctionExpression node) { | 
| 930     // FunctionExpressions are currently unused. | 920     // FunctionExpressions are currently unused. | 
| 931     // We might need them if we want to emit raw JS nested functions. | 921     // We might need them if we want to emit raw JS nested functions. | 
| 932     throw 'FunctionExpressions should not be used'; | 922     throw 'FunctionExpressions should not be used'; | 
| 933   } | 923   } | 
| 934 } | 924 } | 
| OLD | NEW | 
|---|