| 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 import 'dart:collection'; | 5 import 'dart:collection'; |
| 6 | 6 |
| 7 import 'package:js_runtime/shared/embedded_names.dart'; | 7 import 'package:js_runtime/shared/embedded_names.dart'; |
| 8 | 8 |
| 9 import '../closure.dart'; | 9 import '../closure.dart'; |
| 10 import '../common.dart'; | 10 import '../common.dart'; |
| (...skipping 2560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2571 bool assertTypeInContext(DartType type, [Spannable spannable]) { | 2571 bool assertTypeInContext(DartType type, [Spannable spannable]) { |
| 2572 return invariant(spannable == null ? CURRENT_ELEMENT_SPANNABLE : spannable, | 2572 return invariant(spannable == null ? CURRENT_ELEMENT_SPANNABLE : spannable, |
| 2573 () { | 2573 () { |
| 2574 ClassElement contextClass = Types.getClassContext(type); | 2574 ClassElement contextClass = Types.getClassContext(type); |
| 2575 return contextClass == null || contextClass == localsHandler.contextClass; | 2575 return contextClass == null || contextClass == localsHandler.contextClass; |
| 2576 }, | 2576 }, |
| 2577 message: "Type '$type' is not valid context of " | 2577 message: "Type '$type' is not valid context of " |
| 2578 "${localsHandler.contextClass}."); | 2578 "${localsHandler.contextClass}."); |
| 2579 } | 2579 } |
| 2580 | 2580 |
| 2581 /// Build a [HTypeConversion] for convertion [original] to type [type]. | 2581 /// Build a [HTypeConversion] for converting [original] to type [type]. |
| 2582 /// | 2582 /// |
| 2583 /// Invariant: [type] must be valid in the context. | 2583 /// Invariant: [type] must be valid in the context. |
| 2584 /// See [LocalsHandler.substInContext]. | 2584 /// See [LocalsHandler.substInContext]. |
| 2585 HInstruction buildTypeConversion( | 2585 HInstruction buildTypeConversion( |
| 2586 HInstruction original, DartType type, int kind) { | 2586 HInstruction original, DartType type, int kind) { |
| 2587 if (type == null) return original; | 2587 if (type == null) return original; |
| 2588 // GENERIC_METHODS: The following statement was added for parsing and |
| 2589 // ignoring method type variables; must be generalized for full support of |
| 2590 // generic methods. |
| 2591 type = type.dynamifyMethodTypeVariableType; |
| 2588 type = type.unaliased; | 2592 type = type.unaliased; |
| 2589 assert(assertTypeInContext(type, original)); | 2593 assert(assertTypeInContext(type, original)); |
| 2590 if (type.isInterfaceType && !type.treatAsRaw) { | 2594 if (type.isInterfaceType && !type.treatAsRaw) { |
| 2591 TypeMask subtype = new TypeMask.subtype(type.element, compiler.world); | 2595 TypeMask subtype = new TypeMask.subtype(type.element, compiler.world); |
| 2592 HInstruction representations = buildTypeArgumentRepresentations(type); | 2596 HInstruction representations = buildTypeArgumentRepresentations(type); |
| 2593 add(representations); | 2597 add(representations); |
| 2594 return new HTypeConversion.withTypeRepresentation( | 2598 return new HTypeConversion.withTypeRepresentation( |
| 2595 type, kind, subtype, original, representations); | 2599 type, kind, subtype, original, representations); |
| 2596 } else if (type.isTypeVariable) { | 2600 } else if (type.isTypeVariable) { |
| 2597 TypeMask subtype = original.instructionType; | 2601 TypeMask subtype = original.instructionType; |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3798 code, backend.readableArrayType, inputs, | 3802 code, backend.readableArrayType, inputs, |
| 3799 nativeBehavior: native.NativeBehavior.PURE_ALLOCATION); | 3803 nativeBehavior: native.NativeBehavior.PURE_ALLOCATION); |
| 3800 return representation; | 3804 return representation; |
| 3801 } | 3805 } |
| 3802 } | 3806 } |
| 3803 | 3807 |
| 3804 @override | 3808 @override |
| 3805 void visitAs(ast.Send node, ast.Node expression, DartType type, _) { | 3809 void visitAs(ast.Send node, ast.Node expression, DartType type, _) { |
| 3806 HInstruction expressionInstruction = visitAndPop(expression); | 3810 HInstruction expressionInstruction = visitAndPop(expression); |
| 3807 if (type.isMalformed) { | 3811 if (type.isMalformed) { |
| 3808 ErroneousElement element = type.element; | 3812 String message; |
| 3809 generateTypeError(node, element.message); | 3813 if (type is MalformedType) { |
| 3814 ErroneousElement element = type.element; |
| 3815 message = element.message; |
| 3816 } else { |
| 3817 assert(type is MethodTypeVariableType); |
| 3818 message = "Method type variables are not reified."; |
| 3819 } |
| 3820 generateTypeError(node, message); |
| 3810 } else { | 3821 } else { |
| 3811 HInstruction converted = buildTypeConversion(expressionInstruction, | 3822 HInstruction converted = buildTypeConversion(expressionInstruction, |
| 3812 localsHandler.substInContext(type), HTypeConversion.CAST_TYPE_CHECK); | 3823 localsHandler.substInContext(type), HTypeConversion.CAST_TYPE_CHECK); |
| 3813 if (converted != expressionInstruction) add(converted); | 3824 if (converted != expressionInstruction) add(converted); |
| 3814 stack.add(converted); | 3825 stack.add(converted); |
| 3815 } | 3826 } |
| 3816 } | 3827 } |
| 3817 | 3828 |
| 3818 @override | 3829 @override |
| 3819 void visitIs(ast.Send node, ast.Node expression, DartType type, _) { | 3830 void visitIs(ast.Send node, ast.Node expression, DartType type, _) { |
| 3820 HInstruction expressionInstruction = visitAndPop(expression); | 3831 HInstruction expressionInstruction = visitAndPop(expression); |
| 3821 push(buildIsNode(node, type, expressionInstruction)); | 3832 push(buildIsNode(node, type, expressionInstruction)); |
| 3822 } | 3833 } |
| 3823 | 3834 |
| 3824 @override | 3835 @override |
| 3825 void visitIsNot(ast.Send node, ast.Node expression, DartType type, _) { | 3836 void visitIsNot(ast.Send node, ast.Node expression, DartType type, _) { |
| 3826 HInstruction expressionInstruction = visitAndPop(expression); | 3837 HInstruction expressionInstruction = visitAndPop(expression); |
| 3827 HInstruction instruction = buildIsNode(node, type, expressionInstruction); | 3838 HInstruction instruction = buildIsNode(node, type, expressionInstruction); |
| 3828 add(instruction); | 3839 add(instruction); |
| 3829 push(new HNot(instruction, backend.boolType)); | 3840 push(new HNot(instruction, backend.boolType)); |
| 3830 } | 3841 } |
| 3831 | 3842 |
| 3832 HInstruction buildIsNode( | 3843 HInstruction buildIsNode( |
| 3833 ast.Node node, DartType type, HInstruction expression) { | 3844 ast.Node node, DartType type, HInstruction expression) { |
| 3834 type = localsHandler.substInContext(type).unaliased; | 3845 type = localsHandler.substInContext(type).unaliased; |
| 3835 if (type.isFunctionType) { | 3846 if (type.isMalformed) { |
| 3847 String message; |
| 3848 if (type is MethodTypeVariableType) { |
| 3849 message = "Method type variables are not reified, " |
| 3850 "so they cannot be tested with an `is` expression."; |
| 3851 } else { |
| 3852 assert(type is MalformedType); |
| 3853 ErroneousElement element = type.element; |
| 3854 message = element.message; |
| 3855 } |
| 3856 generateTypeError(node, message); |
| 3857 HInstruction call = pop(); |
| 3858 return new HIs.compound(type, expression, call, backend.boolType); |
| 3859 } else if (type.isFunctionType) { |
| 3836 List arguments = [buildFunctionType(type), expression]; | 3860 List arguments = [buildFunctionType(type), expression]; |
| 3837 pushInvokeDynamic( | 3861 pushInvokeDynamic( |
| 3838 node, | 3862 node, |
| 3839 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), | 3863 new Selector.call(new PrivateName('_isTest', helpers.jsHelperLibrary), |
| 3840 CallStructure.ONE_ARG), | 3864 CallStructure.ONE_ARG), |
| 3841 null, | 3865 null, |
| 3842 arguments); | 3866 arguments); |
| 3843 return new HIs.compound(type, expression, pop(), backend.boolType); | 3867 return new HIs.compound(type, expression, pop(), backend.boolType); |
| 3844 } else if (type.isTypeVariable) { | 3868 } else if (type.isTypeVariable) { |
| 3845 HInstruction runtimeType = addTypeVariableReference(type); | 3869 HInstruction runtimeType = addTypeVariableReference(type); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 3860 : graph.addConstantNull(compiler); | 3884 : graph.addConstantNull(compiler); |
| 3861 List<HInstruction> inputs = <HInstruction>[ | 3885 List<HInstruction> inputs = <HInstruction>[ |
| 3862 expression, | 3886 expression, |
| 3863 isFieldName, | 3887 isFieldName, |
| 3864 representations, | 3888 representations, |
| 3865 asFieldName | 3889 asFieldName |
| 3866 ]; | 3890 ]; |
| 3867 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); | 3891 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType); |
| 3868 HInstruction call = pop(); | 3892 HInstruction call = pop(); |
| 3869 return new HIs.compound(type, expression, call, backend.boolType); | 3893 return new HIs.compound(type, expression, call, backend.boolType); |
| 3870 } else if (type.isMalformed) { | |
| 3871 ErroneousElement element = type.element; | |
| 3872 generateTypeError(node, element.message); | |
| 3873 HInstruction call = pop(); | |
| 3874 return new HIs.compound(type, expression, call, backend.boolType); | |
| 3875 } else { | 3894 } else { |
| 3876 if (backend.hasDirectCheckFor(type)) { | 3895 if (backend.hasDirectCheckFor(type)) { |
| 3877 return new HIs.direct(type, expression, backend.boolType); | 3896 return new HIs.direct(type, expression, backend.boolType); |
| 3878 } | 3897 } |
| 3879 // The interceptor is not always needed. It is removed by optimization | 3898 // The interceptor is not always needed. It is removed by optimization |
| 3880 // when the receiver type or tested type permit. | 3899 // when the receiver type or tested type permit. |
| 3881 return new HIs.raw( | 3900 return new HIs.raw( |
| 3882 type, expression, invokeInterceptor(expression), backend.boolType); | 3901 type, expression, invokeInterceptor(expression), backend.boolType); |
| 3883 } | 3902 } |
| 3884 } | 3903 } |
| (...skipping 1445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5330 // identifier that refers to the class/typedef) as a constant. | 5349 // identifier that refers to the class/typedef) as a constant. |
| 5331 stack.add(addConstant(node.selector)); | 5350 stack.add(addConstant(node.selector)); |
| 5332 } else { | 5351 } else { |
| 5333 stack.add(addConstant(node)); | 5352 stack.add(addConstant(node)); |
| 5334 } | 5353 } |
| 5335 } | 5354 } |
| 5336 | 5355 |
| 5337 /// Generate the literal for [typeVariable] in the current context. | 5356 /// Generate the literal for [typeVariable] in the current context. |
| 5338 void generateTypeVariableLiteral( | 5357 void generateTypeVariableLiteral( |
| 5339 ast.Send node, TypeVariableType typeVariable) { | 5358 ast.Send node, TypeVariableType typeVariable) { |
| 5340 DartType type = localsHandler.substInContext(typeVariable); | 5359 // GENERIC_METHODS: This provides thin support for method type variables |
| 5341 HInstruction value = analyzeTypeArgument(type, | 5360 // by treating them as malformed when evaluated as a literal. For full |
| 5342 sourceInformation: sourceInformationBuilder.buildGet(node)); | 5361 // support of generic methods this must be revised. |
| 5343 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], | 5362 if (typeVariable is MethodTypeVariableType) { |
| 5344 typeMask: backend.stringType); | 5363 generateTypeError(node, "Method type variables are not reified"); |
| 5345 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); | 5364 } else { |
| 5365 DartType type = localsHandler.substInContext(typeVariable); |
| 5366 HInstruction value = analyzeTypeArgument(type, |
| 5367 sourceInformation: sourceInformationBuilder.buildGet(node)); |
| 5368 pushInvokeStatic(node, helpers.runtimeTypeToString, [value], |
| 5369 typeMask: backend.stringType); |
| 5370 pushInvokeStatic(node, helpers.createRuntimeType, [pop()]); |
| 5371 } |
| 5346 } | 5372 } |
| 5347 | 5373 |
| 5348 /// Generate a call to a type literal. | 5374 /// Generate a call to a type literal. |
| 5349 void generateTypeLiteralCall(ast.Send node) { | 5375 void generateTypeLiteralCall(ast.Send node) { |
| 5350 // This send is of the form 'e(...)', where e is resolved to a type | 5376 // This send is of the form 'e(...)', where e is resolved to a type |
| 5351 // reference. We create a regular closure call on the result of the type | 5377 // reference. We create a regular closure call on the result of the type |
| 5352 // reference instead of creating a NoSuchMethodError to avoid pulling it | 5378 // reference instead of creating a NoSuchMethodError to avoid pulling it |
| 5353 // in if it is not used (e.g., in a try/catch). | 5379 // in if it is not used (e.g., in a try/catch). |
| 5354 HInstruction target = pop(); | 5380 HInstruction target = pop(); |
| 5355 generateCallInvoke(node, target, | 5381 generateCallInvoke(node, target, |
| (...skipping 3241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8597 const _LoopTypeVisitor(); | 8623 const _LoopTypeVisitor(); |
| 8598 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; | 8624 int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP; |
| 8599 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; | 8625 int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP; |
| 8600 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; | 8626 int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP; |
| 8601 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; | 8627 int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP; |
| 8602 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 8628 int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 8603 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; | 8629 int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP; |
| 8604 int visitSwitchStatement(ast.SwitchStatement node) => | 8630 int visitSwitchStatement(ast.SwitchStatement node) => |
| 8605 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; | 8631 HLoopBlockInformation.SWITCH_CONTINUE_LOOP; |
| 8606 } | 8632 } |
| OLD | NEW |