OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 /// This file declares a "shadow hierarchy" of concrete classes which extend | 5 /// This file declares a "shadow hierarchy" of concrete classes which extend |
6 /// the kernel class hierarchy, adding methods and fields needed by the | 6 /// the kernel class hierarchy, adding methods and fields needed by the |
7 /// BodyBuilder. | 7 /// BodyBuilder. |
8 /// | 8 /// |
9 /// Instances of these classes may be created using the factory methods in | 9 /// Instances of these classes may be created using the factory methods in |
10 /// `ast_factory.dart`. | 10 /// `ast_factory.dart`. |
(...skipping 917 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
928 'returnType', new InstrumentationValueForType(inferredReturnType)); | 928 'returnType', new InstrumentationValueForType(inferredReturnType)); |
929 function.returnType = inferredReturnType; | 929 function.returnType = inferredReturnType; |
930 } | 930 } |
931 inferrer.closureContext = oldClosureContext; | 931 inferrer.closureContext = oldClosureContext; |
932 var inferredType = typeNeeded ? function.functionType : null; | 932 var inferredType = typeNeeded ? function.functionType : null; |
933 inferrer.listener.functionExpressionExit(this, inferredType); | 933 inferrer.listener.functionExpressionExit(this, inferredType); |
934 return inferredType; | 934 return inferredType; |
935 } | 935 } |
936 } | 936 } |
937 | 937 |
| 938 /// Concrete shadow object representing an if-null expression. |
| 939 /// |
| 940 /// An if-null expression of the form `a ?? b` is represented as the kernel |
| 941 /// expression: |
| 942 /// |
| 943 /// let v = a in v == null ? b : v |
| 944 class KernelIfNullExpression extends Let implements KernelExpression { |
| 945 KernelIfNullExpression(VariableDeclaration variable, Expression body) |
| 946 : super(variable, body); |
| 947 |
| 948 @override |
| 949 ConditionalExpression get body => super.body; |
| 950 |
| 951 /// Returns the expression to the left of `??`. |
| 952 Expression get _lhs => variable.initializer; |
| 953 |
| 954 /// Returns the expression to the right of `??`. |
| 955 Expression get _rhs => body.then; |
| 956 |
| 957 @override |
| 958 void _collectDependencies(KernelDependencyCollector collector) { |
| 959 // If-null expressions are not immediately evident expressions. |
| 960 collector.recordNotImmediatelyEvident(fileOffset); |
| 961 } |
| 962 |
| 963 @override |
| 964 DartType _inferExpression( |
| 965 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { |
| 966 typeNeeded = inferrer.listener.ifNullEnter(this, typeContext) || typeNeeded; |
| 967 // To infer `e0 ?? e1` in context K: |
| 968 // - Infer e0 in context K to get T0 |
| 969 var lhsType = inferrer.inferExpression(_lhs, typeContext, true); |
| 970 variable.type = lhsType; |
| 971 // - Let J = T0 if K is `_` else K. |
| 972 var rhsContext = typeContext ?? lhsType; |
| 973 // - Infer e1 in context J to get T1 |
| 974 var rhsType = |
| 975 inferrer.inferExpression(_rhs, rhsContext, typeContext == null); |
| 976 // - Let T = greatest closure of K with respect to `?` if K is not `_`, else |
| 977 // UP(t0, t1) |
| 978 // - Then the inferred type is T. |
| 979 var inferredType = typeContext == null |
| 980 ? inferrer.typeSchemaEnvironment.getLeastUpperBound(lhsType, rhsType) |
| 981 : greatestClosure(inferrer.coreTypes, typeContext); |
| 982 body.staticType = inferredType; |
| 983 inferrer.listener.ifNullExit(this, inferredType); |
| 984 return inferredType; |
| 985 } |
| 986 } |
| 987 |
938 /// Concrete shadow object representing an if statement in kernel form. | 988 /// Concrete shadow object representing an if statement in kernel form. |
939 class KernelIfStatement extends IfStatement implements KernelStatement { | 989 class KernelIfStatement extends IfStatement implements KernelStatement { |
940 KernelIfStatement(Expression condition, Statement then, Statement otherwise) | 990 KernelIfStatement(Expression condition, Statement then, Statement otherwise) |
941 : super(condition, then, otherwise); | 991 : super(condition, then, otherwise); |
942 | 992 |
943 @override | 993 @override |
944 void _inferStatement(KernelTypeInferrer inferrer) { | 994 void _inferStatement(KernelTypeInferrer inferrer) { |
945 inferrer.listener.ifStatementEnter(this); | 995 inferrer.listener.ifStatementEnter(this); |
946 inferrer.inferExpression( | 996 inferrer.inferExpression( |
947 condition, inferrer.coreTypes.boolClass.rawType, false); | 997 condition, inferrer.coreTypes.boolClass.rawType, false); |
(...skipping 1273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2221 } | 2271 } |
2222 | 2272 |
2223 transformChildren(v) { | 2273 transformChildren(v) { |
2224 return internalError("Internal error: Unsupported operation."); | 2274 return internalError("Internal error: Unsupported operation."); |
2225 } | 2275 } |
2226 | 2276 |
2227 visitChildren(v) { | 2277 visitChildren(v) { |
2228 return internalError("Internal error: Unsupported operation."); | 2278 return internalError("Internal error: Unsupported operation."); |
2229 } | 2279 } |
2230 } | 2280 } |
OLD | NEW |