Chromium Code Reviews| 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 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 while (true) { | 225 while (true) { | 
| 226 inferrer.inferExpression(section.variable.initializer, null, false); | 226 inferrer.inferExpression(section.variable.initializer, null, false); | 
| 227 if (section.body is! Let) break; | 227 if (section.body is! Let) break; | 
| 228 section = section.body; | 228 section = section.body; | 
| 229 } | 229 } | 
| 230 inferrer.listener.cascadeExpressionExit(this, lhsType); | 230 inferrer.listener.cascadeExpressionExit(this, lhsType); | 
| 231 return lhsType; | 231 return lhsType; | 
| 232 } | 232 } | 
| 233 } | 233 } | 
| 234 | 234 | 
| 235 /// Concrete shadow object representing a complex assignment in kernel form. | |
| 
 
ahe
2017/06/08 14:16:33
What is a complex assignment?
 
Paul Berry
2017/06/08 16:17:04
I'm still figuring out exactly where to draw the l
 
 | |
| 236 class KernelComplexAssign extends Let implements KernelExpression { | |
| 237 KernelComplexAssign(VariableDeclaration variable, Expression body) | |
| 238 : super(variable, body); | |
| 239 | |
| 240 @override | |
| 241 void _collectDependencies(KernelDependencyCollector collector) { | |
| 242 // Assignment expressions are not immediately evident expressions. | |
| 243 collector.recordNotImmediatelyEvident(fileOffset); | |
| 244 } | |
| 245 | |
| 246 @override | |
| 247 DartType _inferExpression( | |
| 248 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | |
| 249 return inferrer.inferIndexAssign(this, typeContext, typeNeeded); | |
| 250 } | |
| 251 } | |
| 252 | |
| 235 /// Concrete shadow object representing a conditional expression in kernel form. | 253 /// Concrete shadow object representing a conditional expression in kernel form. | 
| 236 /// Shadow object for [ConditionalExpression]. | 254 /// Shadow object for [ConditionalExpression]. | 
| 237 class KernelConditionalExpression extends ConditionalExpression | 255 class KernelConditionalExpression extends ConditionalExpression | 
| 238 implements KernelExpression { | 256 implements KernelExpression { | 
| 257 /// Indicates whether this conditional expression is associated with a `??=` | |
| 258 /// in a null-aware compound assignment. | |
| 259 final bool _isNullAwareCombiner; | |
| 260 | |
| 239 KernelConditionalExpression( | 261 KernelConditionalExpression( | 
| 240 Expression condition, Expression then, Expression otherwise) | 262 Expression condition, Expression then, Expression otherwise, | 
| 241 : super(condition, then, otherwise, const DynamicType()); | 263 {bool isNullAwareCombiner: false}) | 
| 264 : _isNullAwareCombiner = isNullAwareCombiner, | |
| 265 super(condition, then, otherwise, const DynamicType()); | |
| 242 | 266 | 
| 243 @override | 267 @override | 
| 244 void _collectDependencies(KernelDependencyCollector collector) { | 268 void _collectDependencies(KernelDependencyCollector collector) { | 
| 245 // Inference dependencies are the union of the inference dependencies of the | 269 // Inference dependencies are the union of the inference dependencies of the | 
| 246 // two returned sub-expressions. | 270 // two returned sub-expressions. | 
| 247 collector.collectDependencies(then); | 271 collector.collectDependencies(then); | 
| 248 collector.collectDependencies(otherwise); | 272 collector.collectDependencies(otherwise); | 
| 249 } | 273 } | 
| 250 | 274 | 
| 251 @override | 275 @override | 
| 252 DartType _inferExpression( | 276 DartType _inferExpression( | 
| 253 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 277 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 
| 254 typeNeeded = | 278 typeNeeded = | 
| 255 inferrer.listener.conditionalExpressionEnter(this, typeContext) || | 279 inferrer.listener.conditionalExpressionEnter(this, typeContext) || | 
| 256 typeNeeded; | 280 typeNeeded; | 
| 257 if (!inferrer.isTopLevel) { | 281 if (!inferrer.isTopLevel) { | 
| 258 inferrer.inferExpression( | 282 inferrer.inferExpression( | 
| 259 condition, inferrer.coreTypes.boolClass.rawType, false); | 283 condition, inferrer.coreTypes.boolClass.rawType, false); | 
| 260 } | 284 } | 
| 261 DartType thenType = inferrer.inferExpression(then, typeContext, true); | 285 DartType thenType = inferrer.inferExpression(then, typeContext, true); | 
| 262 DartType otherwiseType = | 286 DartType otherwiseType = | 
| 263 inferrer.inferExpression(otherwise, typeContext, true); | 287 inferrer.inferExpression(otherwise, typeContext, true); | 
| 264 DartType type = inferrer.typeSchemaEnvironment | 288 DartType type = inferrer.typeSchemaEnvironment | 
| 265 .getLeastUpperBound(thenType, otherwiseType); | 289 .getLeastUpperBound(thenType, otherwiseType); | 
| 266 staticType = type; | 290 staticType = type; | 
| 267 var inferredType = typeNeeded ? type : null; | 291 var inferredType = typeNeeded ? type : null; | 
| 268 inferrer.listener.conditionalExpressionExit(this, inferredType); | 292 inferrer.listener.conditionalExpressionExit(this, inferredType); | 
| 269 return inferredType; | 293 return inferredType; | 
| 270 } | 294 } | 
| 295 | |
| 296 /// Helper method allowing [_isNullAwareCombiner] to be checked from outside | |
| 297 /// this library without adding a public member to the class. | |
| 298 static bool isNullAwareCombiner(KernelConditionalExpression e) => | |
| 299 e._isNullAwareCombiner; | |
| 271 } | 300 } | 
| 272 | 301 | 
| 273 /// Shadow object for [ConstructorInvocation]. | 302 /// Shadow object for [ConstructorInvocation]. | 
| 274 class KernelConstructorInvocation extends ConstructorInvocation | 303 class KernelConstructorInvocation extends ConstructorInvocation | 
| 275 implements KernelExpression { | 304 implements KernelExpression { | 
| 276 final Member _initialTarget; | 305 final Member _initialTarget; | 
| 277 | 306 | 
| 278 KernelConstructorInvocation( | 307 KernelConstructorInvocation( | 
| 279 Constructor target, this._initialTarget, Arguments arguments, | 308 Constructor target, this._initialTarget, Arguments arguments, | 
| 280 {bool isConst: false}) | 309 {bool isConst: false}) | 
| (...skipping 750 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1031 } | 1060 } | 
| 1032 } | 1061 } | 
| 1033 | 1062 | 
| 1034 /// Shadow object for [MethodInvocation]. | 1063 /// Shadow object for [MethodInvocation]. | 
| 1035 class KernelMethodInvocation extends MethodInvocation | 1064 class KernelMethodInvocation extends MethodInvocation | 
| 1036 implements KernelExpression { | 1065 implements KernelExpression { | 
| 1037 /// Indicates whether this method invocation is a call to a `call` method | 1066 /// Indicates whether this method invocation is a call to a `call` method | 
| 1038 /// resulting from the invocation of a function expression. | 1067 /// resulting from the invocation of a function expression. | 
| 1039 final bool _isImplicitCall; | 1068 final bool _isImplicitCall; | 
| 1040 | 1069 | 
| 1070 /// Indicates whether this method invocation invokes the operator that | |
| 1071 /// combines old and new values in a compound assignment. | |
| 1072 final bool _isCombiner; | |
| 1073 | |
| 1041 KernelMethodInvocation(Expression receiver, Name name, Arguments arguments, | 1074 KernelMethodInvocation(Expression receiver, Name name, Arguments arguments, | 
| 1042 {bool isImplicitCall: false, Procedure interfaceTarget}) | 1075 {bool isImplicitCall: false, | 
| 1076 Procedure interfaceTarget, | |
| 1077 bool isCombiner: false}) | |
| 1043 : _isImplicitCall = isImplicitCall, | 1078 : _isImplicitCall = isImplicitCall, | 
| 1079 _isCombiner = isCombiner, | |
| 1044 super(receiver, name, arguments, interfaceTarget); | 1080 super(receiver, name, arguments, interfaceTarget); | 
| 1045 | 1081 | 
| 1046 @override | 1082 @override | 
| 1047 void _collectDependencies(KernelDependencyCollector collector) { | 1083 void _collectDependencies(KernelDependencyCollector collector) { | 
| 1048 // The inference dependencies are the inference dependencies of the | 1084 // The inference dependencies are the inference dependencies of the | 
| 1049 // receiver. | 1085 // receiver. | 
| 1050 collector.collectDependencies(receiver); | 1086 collector.collectDependencies(receiver); | 
| 1051 } | 1087 } | 
| 1052 | 1088 | 
| 1053 @override | 1089 @override | 
| 1054 DartType _inferExpression( | 1090 DartType _inferExpression( | 
| 1055 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 1091 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 
| 1092 if (identical(name.name, '[]=')) { | |
| 1093 return inferrer.inferIndexAssign(this, typeContext, typeNeeded); | |
| 1094 } | |
| 1056 typeNeeded = inferrer.listener.methodInvocationEnter(this, typeContext) || | 1095 typeNeeded = inferrer.listener.methodInvocationEnter(this, typeContext) || | 
| 1057 typeNeeded; | 1096 typeNeeded; | 
| 1058 // First infer the receiver so we can look up the method that was invoked. | 1097 // First infer the receiver so we can look up the method that was invoked. | 
| 1059 var receiverType = inferrer.inferExpression(receiver, null, true); | 1098 var receiverType = inferrer.inferExpression(receiver, null, true); | 
| 1060 bool isOverloadedArithmeticOperator = false; | 1099 bool isOverloadedArithmeticOperator = false; | 
| 1061 Member interfaceMember; | 1100 Member interfaceMember = | 
| 1062 if (receiverType is InterfaceType) { | 1101 inferrer.findMethodInvocationMember(receiverType, this); | 
| 1063 interfaceMember = inferrer.classHierarchy | 1102 if (interfaceMember is Procedure) { | 
| 1064 .getInterfaceMember(receiverType.classNode, name); | 1103 isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment | 
| 1065 // Our non-strong golden files currently don't include interface | 1104 .isOverloadedArithmeticOperator(interfaceMember); | 
| 1066 // targets, so we can't store the interface target without causing tests | |
| 1067 // to fail. TODO(paulberry): fix this. | |
| 1068 if (inferrer.strongMode) { | |
| 1069 if (interfaceMember != null) { | |
| 1070 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, | |
| 1071 'target', new InstrumentationValueForMember(interfaceMember)); | |
| 1072 } | |
| 1073 // interfaceTarget is currently required to be a procedure, so we skip | |
| 1074 // if it's anything else. TODO(paulberry): fix this - see | |
| 1075 // https://codereview.chromium.org/2923653003/. | |
| 1076 if (interfaceMember is Procedure) { | |
| 1077 interfaceTarget = interfaceMember; | |
| 1078 } | |
| 1079 } | |
| 1080 if (interfaceMember is Procedure) { | |
| 1081 isOverloadedArithmeticOperator = inferrer.typeSchemaEnvironment | |
| 1082 .isOverloadedArithmeticOperator(interfaceMember); | |
| 1083 } | |
| 1084 } | 1105 } | 
| 1085 var calleeType = inferrer.getCalleeFunctionType( | 1106 var calleeType = inferrer.getCalleeFunctionType( | 
| 1086 interfaceMember, receiverType, name, !_isImplicitCall); | 1107 interfaceMember, receiverType, name, !_isImplicitCall); | 
| 1087 var inferredType = inferrer.inferInvocation(typeContext, typeNeeded, | 1108 var inferredType = inferrer.inferInvocation(typeContext, typeNeeded, | 
| 1088 fileOffset, calleeType, calleeType.returnType, arguments, | 1109 fileOffset, calleeType, calleeType.returnType, arguments, | 
| 1089 isOverloadedArithmeticOperator: isOverloadedArithmeticOperator, | 1110 isOverloadedArithmeticOperator: isOverloadedArithmeticOperator, | 
| 1090 receiverType: receiverType); | 1111 receiverType: receiverType); | 
| 1091 inferrer.listener.methodInvocationExit(this, inferredType); | 1112 inferrer.listener.methodInvocationExit(this, inferredType); | 
| 1092 return inferredType; | 1113 return inferredType; | 
| 1093 } | 1114 } | 
| 1115 | |
| 1116 /// Helper method allowing [_isCombiner] to be checked from outside this | |
| 1117 /// library without adding a public member to the class. | |
| 1118 static bool isCombiner(KernelMethodInvocation e) => e._isCombiner; | |
| 1094 } | 1119 } | 
| 1095 | 1120 | 
| 1096 /// Shadow object for [Not]. | 1121 /// Shadow object for [Not]. | 
| 1097 class KernelNot extends Not implements KernelExpression { | 1122 class KernelNot extends Not implements KernelExpression { | 
| 1098 KernelNot(Expression operand) : super(operand); | 1123 KernelNot(Expression operand) : super(operand); | 
| 1099 | 1124 | 
| 1100 @override | 1125 @override | 
| 1101 void _collectDependencies(KernelDependencyCollector collector) { | 1126 void _collectDependencies(KernelDependencyCollector collector) { | 
| 1102 // No inference dependencies. | 1127 // No inference dependencies. | 
| 1103 } | 1128 } | 
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1156 // field dependencies. So we don't need to do anything here. | 1181 // field dependencies. So we don't need to do anything here. | 
| 1157 } | 1182 } | 
| 1158 | 1183 | 
| 1159 @override | 1184 @override | 
| 1160 DartType _inferExpression( | 1185 DartType _inferExpression( | 
| 1161 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 1186 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 
| 1162 typeNeeded = | 1187 typeNeeded = | 
| 1163 inferrer.listener.propertyGetEnter(this, typeContext) || typeNeeded; | 1188 inferrer.listener.propertyGetEnter(this, typeContext) || typeNeeded; | 
| 1164 // First infer the receiver so we can look up the getter that was invoked. | 1189 // First infer the receiver so we can look up the getter that was invoked. | 
| 1165 var receiverType = inferrer.inferExpression(receiver, null, true); | 1190 var receiverType = inferrer.inferExpression(receiver, null, true); | 
| 1166 Member interfaceMember; | 1191 Member interfaceMember = | 
| 1167 if (receiverType is InterfaceType) { | 1192 inferrer.findInterfaceMember(receiverType, name, fileOffset); | 
| 1168 interfaceMember = inferrer.classHierarchy | 1193 if (inferrer.isTopLevel && | 
| 1169 .getInterfaceMember(receiverType.classNode, name); | 1194 ((interfaceMember is Procedure && | 
| 1170 if (inferrer.isTopLevel && | 1195 interfaceMember.kind == ProcedureKind.Getter) || | 
| 1171 ((interfaceMember is Procedure && | 1196 interfaceMember is Field)) { | 
| 1172 interfaceMember.kind == ProcedureKind.Getter) || | 1197 // References to fields and getters can't be relied upon for top level | 
| 1173 interfaceMember is Field)) { | 1198 // inference. | 
| 1174 // References to fields and getters can't be relied upon for top level | 1199 inferrer.recordNotImmediatelyEvident(fileOffset); | 
| 1175 // inference. | |
| 1176 inferrer.recordNotImmediatelyEvident(fileOffset); | |
| 1177 } | |
| 1178 // Our non-strong golden files currently don't include interface targets, | |
| 1179 // so we can't store the interface target without causing tests to fail. | |
| 1180 // TODO(paulberry): fix this. | |
| 1181 if (inferrer.strongMode) { | |
| 1182 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, | |
| 1183 'target', new InstrumentationValueForMember(interfaceMember)); | |
| 1184 interfaceTarget = interfaceMember; | |
| 1185 } | |
| 1186 } | 1200 } | 
| 1201 interfaceTarget = interfaceMember; | |
| 1187 var inferredType = | 1202 var inferredType = | 
| 1188 inferrer.getCalleeType(interfaceMember, receiverType, name); | 1203 inferrer.getCalleeType(interfaceMember, receiverType, name); | 
| 1189 // TODO(paulberry): Infer tear-off type arguments if appropriate. | 1204 // TODO(paulberry): Infer tear-off type arguments if appropriate. | 
| 1190 inferrer.listener.propertyGetExit(this, inferredType); | 1205 inferrer.listener.propertyGetExit(this, inferredType); | 
| 1191 return typeNeeded ? inferredType : null; | 1206 return typeNeeded ? inferredType : null; | 
| 1192 } | 1207 } | 
| 1193 } | 1208 } | 
| 1194 | 1209 | 
| 1195 /// Shadow object for [PropertyGet]. | 1210 /// Shadow object for [PropertyGet]. | 
| 1196 class KernelPropertySet extends PropertySet implements KernelExpression { | 1211 class KernelPropertySet extends PropertySet implements KernelExpression { | 
| (...skipping 11 matching lines...) Expand all Loading... | |
| 1208 collector.recordNotImmediatelyEvident(fileOffset); | 1223 collector.recordNotImmediatelyEvident(fileOffset); | 
| 1209 } | 1224 } | 
| 1210 | 1225 | 
| 1211 @override | 1226 @override | 
| 1212 DartType _inferExpression( | 1227 DartType _inferExpression( | 
| 1213 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 1228 KernelTypeInferrer inferrer, DartType typeContext, bool typeNeeded) { | 
| 1214 typeNeeded = | 1229 typeNeeded = | 
| 1215 inferrer.listener.propertySetEnter(this, typeContext) || typeNeeded; | 1230 inferrer.listener.propertySetEnter(this, typeContext) || typeNeeded; | 
| 1216 // First infer the receiver so we can look up the setter that was invoked. | 1231 // First infer the receiver so we can look up the setter that was invoked. | 
| 1217 var receiverType = inferrer.inferExpression(receiver, null, true); | 1232 var receiverType = inferrer.inferExpression(receiver, null, true); | 
| 1218 Member interfaceMember; | 1233 Member interfaceMember = inferrer | 
| 1219 if (receiverType is InterfaceType) { | 1234 .findInterfaceMember(receiverType, name, fileOffset, setter: true); | 
| 1220 interfaceMember = inferrer.classHierarchy | 1235 interfaceTarget = interfaceMember; | 
| 1221 .getInterfaceMember(receiverType.classNode, name, setter: true); | |
| 1222 // Our non-strong golden files currently don't include interface targets, | |
| 1223 // so we can't store the interface target without causing tests to fail. | |
| 1224 // TODO(paulberry): fix this. | |
| 1225 if (inferrer.strongMode) { | |
| 1226 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, | |
| 1227 'target', new InstrumentationValueForMember(interfaceMember)); | |
| 1228 interfaceTarget = interfaceMember; | |
| 1229 } | |
| 1230 } | |
| 1231 var setterType = inferrer.getSetterType(interfaceMember, receiverType); | 1236 var setterType = inferrer.getSetterType(interfaceMember, receiverType); | 
| 1232 var inferredType = inferrer.inferExpression(value, setterType, typeNeeded); | 1237 var inferredType = inferrer.inferExpression(value, setterType, typeNeeded); | 
| 1233 inferrer.listener.propertySetExit(this, inferredType); | 1238 inferrer.listener.propertySetExit(this, inferredType); | 
| 1234 return typeNeeded ? inferredType : null; | 1239 return typeNeeded ? inferredType : null; | 
| 1235 } | 1240 } | 
| 1236 } | 1241 } | 
| 1237 | 1242 | 
| 1238 /// Concrete shadow object representing a redirecting initializer in kernel | 1243 /// Concrete shadow object representing a redirecting initializer in kernel | 
| 1239 /// form. | 1244 /// form. | 
| 1240 class KernelRedirectingInitializer extends RedirectingInitializer | 1245 class KernelRedirectingInitializer extends RedirectingInitializer | 
| (...skipping 549 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1790 final bool _implicitlyTyped; | 1795 final bool _implicitlyTyped; | 
| 1791 | 1796 | 
| 1792 final int _functionNestingLevel; | 1797 final int _functionNestingLevel; | 
| 1793 | 1798 | 
| 1794 bool _mutatedInClosure = false; | 1799 bool _mutatedInClosure = false; | 
| 1795 | 1800 | 
| 1796 bool _mutatedAnywhere = false; | 1801 bool _mutatedAnywhere = false; | 
| 1797 | 1802 | 
| 1798 final bool _isLocalFunction; | 1803 final bool _isLocalFunction; | 
| 1799 | 1804 | 
| 1805 /// Indicates whether this variable declaration exists for the sole purpose of | |
| 1806 /// discarding a return value in a complex desugared expression. | |
| 1807 final bool _isDiscarding; | |
| 
 
ahe
2017/06/08 14:16:33
It would be easier for for me to understand the me
 
Paul Berry
2017/06/08 16:17:04
I'm open to changing this, but I think "voidContex
 
 | |
| 1808 | |
| 1800 KernelVariableDeclaration(String name, this._functionNestingLevel, | 1809 KernelVariableDeclaration(String name, this._functionNestingLevel, | 
| 1801 {Expression initializer, | 1810 {Expression initializer, | 
| 1802 DartType type, | 1811 DartType type, | 
| 1803 bool isFinal: false, | 1812 bool isFinal: false, | 
| 1804 bool isConst: false, | 1813 bool isConst: false, | 
| 1805 bool isLocalFunction: false}) | 1814 bool isLocalFunction: false}) | 
| 1806 : _implicitlyTyped = type == null, | 1815 : _implicitlyTyped = type == null, | 
| 1807 _isLocalFunction = isLocalFunction, | 1816 _isLocalFunction = isLocalFunction, | 
| 1817 _isDiscarding = false, | |
| 1808 super(name, | 1818 super(name, | 
| 1809 initializer: initializer, | 1819 initializer: initializer, | 
| 1810 type: type ?? const DynamicType(), | 1820 type: type ?? const DynamicType(), | 
| 1811 isFinal: isFinal, | 1821 isFinal: isFinal, | 
| 1812 isConst: isConst); | 1822 isConst: isConst); | 
| 1813 | 1823 | 
| 1814 KernelVariableDeclaration.forValue( | 1824 KernelVariableDeclaration.forValue( | 
| 1815 Expression initializer, this._functionNestingLevel) | 1825 Expression initializer, this._functionNestingLevel, | 
| 1826 {bool isDiscarding: false}) | |
| 1816 : _implicitlyTyped = true, | 1827 : _implicitlyTyped = true, | 
| 1817 _isLocalFunction = false, | 1828 _isLocalFunction = false, | 
| 1829 _isDiscarding = isDiscarding, | |
| 1818 super.forValue(initializer); | 1830 super.forValue(initializer); | 
| 1819 | 1831 | 
| 1820 @override | 1832 @override | 
| 1821 void _inferStatement(KernelTypeInferrer inferrer) { | 1833 void _inferStatement(KernelTypeInferrer inferrer) { | 
| 1822 inferrer.listener.variableDeclarationEnter(this); | 1834 inferrer.listener.variableDeclarationEnter(this); | 
| 1823 var declaredType = _implicitlyTyped ? null : type; | 1835 var declaredType = _implicitlyTyped ? null : type; | 
| 1824 if (initializer != null) { | 1836 if (initializer != null) { | 
| 1825 var inferredType = inferrer.inferDeclarationType(inferrer.inferExpression( | 1837 var inferredType = inferrer.inferDeclarationType(inferrer.inferExpression( | 
| 1826 initializer, declaredType, _implicitlyTyped)); | 1838 initializer, declaredType, _implicitlyTyped)); | 
| 1827 if (inferrer.strongMode && _implicitlyTyped) { | 1839 if (inferrer.strongMode && _implicitlyTyped) { | 
| 1828 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, | 1840 inferrer.instrumentation?.record(Uri.parse(inferrer.uri), fileOffset, | 
| 1829 'type', new InstrumentationValueForType(inferredType)); | 1841 'type', new InstrumentationValueForType(inferredType)); | 
| 1830 type = inferredType; | 1842 type = inferredType; | 
| 1831 } | 1843 } | 
| 1832 } | 1844 } | 
| 1833 inferrer.listener.variableDeclarationExit(this); | 1845 inferrer.listener.variableDeclarationExit(this); | 
| 1834 } | 1846 } | 
| 1835 | 1847 | 
| 1848 /// Helper method allowing [_isDiscarding] to be checked from outside this | |
| 1849 /// library without adding a public member to the class. | |
| 1850 static bool isDiscarding(VariableDeclaration v) => | |
| 1851 v is KernelVariableDeclaration && v._isDiscarding; | |
| 1852 | |
| 1836 /// Determine whether the given [KernelVariableDeclaration] had an implicit | 1853 /// Determine whether the given [KernelVariableDeclaration] had an implicit | 
| 1837 /// type. | 1854 /// type. | 
| 1838 /// | 1855 /// | 
| 1839 /// This is static to avoid introducing a method that would be visible to | 1856 /// This is static to avoid introducing a method that would be visible to | 
| 1840 /// the kernel. | 1857 /// the kernel. | 
| 1841 static bool isImplicitlyTyped(KernelVariableDeclaration variable) => | 1858 static bool isImplicitlyTyped(KernelVariableDeclaration variable) => | 
| 1842 variable._implicitlyTyped; | 1859 variable._implicitlyTyped; | 
| 1843 } | 1860 } | 
| 1844 | 1861 | 
| 1845 /// Concrete shadow object representing a read from a variable in kernel form. | 1862 /// Concrete shadow object representing a read from a variable in kernel form. | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1941 } | 1958 } | 
| 1942 | 1959 | 
| 1943 transformChildren(v) { | 1960 transformChildren(v) { | 
| 1944 return internalError("Internal error: Unsupported operation."); | 1961 return internalError("Internal error: Unsupported operation."); | 
| 1945 } | 1962 } | 
| 1946 | 1963 | 
| 1947 visitChildren(v) { | 1964 visitChildren(v) { | 
| 1948 return internalError("Internal error: Unsupported operation."); | 1965 return internalError("Internal error: Unsupported operation."); | 
| 1949 } | 1966 } | 
| 1950 } | 1967 } | 
| OLD | NEW |