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