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 analyzer.src.generated.static_type_analyzer; | 5 library analyzer.src.generated.static_type_analyzer; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
10 import 'package:analyzer/dart/ast/token.dart'; | 10 import 'package:analyzer/dart/ast/token.dart'; |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 } | 251 } |
252 _resolver.overrideExpression(node.leftHandSide, overrideType, true, true); | 252 _resolver.overrideExpression(node.leftHandSide, overrideType, true, true); |
253 } else if (operator == TokenType.QUESTION_QUESTION_EQ) { | 253 } else if (operator == TokenType.QUESTION_QUESTION_EQ) { |
254 // The static type of a compound assignment using ??= is the least upper | 254 // The static type of a compound assignment using ??= is the least upper |
255 // bound of the static types of the LHS and RHS. | 255 // bound of the static types of the LHS and RHS. |
256 _analyzeLeastUpperBound(node, node.leftHandSide, node.rightHandSide); | 256 _analyzeLeastUpperBound(node, node.leftHandSide, node.rightHandSide); |
257 return null; | 257 return null; |
258 } else { | 258 } else { |
259 ExecutableElement staticMethodElement = node.staticElement; | 259 ExecutableElement staticMethodElement = node.staticElement; |
260 DartType staticType = _computeStaticReturnType(staticMethodElement); | 260 DartType staticType = _computeStaticReturnType(staticMethodElement); |
261 staticType = | 261 staticType = _typeSystem.refineBinaryExpressionType( |
262 _refineAssignmentExpressionType(node, staticType, _getStaticType); | 262 _typeProvider, |
| 263 node.leftHandSide.staticType, |
| 264 operator, |
| 265 node.rightHandSide.staticType, |
| 266 staticType); |
263 _recordStaticType(node, staticType); | 267 _recordStaticType(node, staticType); |
264 MethodElement propagatedMethodElement = node.propagatedElement; | 268 MethodElement propagatedMethodElement = node.propagatedElement; |
265 if (!identical(propagatedMethodElement, staticMethodElement)) { | 269 if (!identical(propagatedMethodElement, staticMethodElement)) { |
266 DartType propagatedType = | 270 DartType propagatedType = |
267 _computeStaticReturnType(propagatedMethodElement); | 271 _computeStaticReturnType(propagatedMethodElement); |
| 272 propagatedType = _typeSystem.refineBinaryExpressionType( |
| 273 _typeProvider, |
| 274 node.leftHandSide.propagatedType, |
| 275 operator, |
| 276 node.rightHandSide.propagatedType, |
| 277 propagatedType); |
268 _resolver.recordPropagatedTypeIfBetter(node, propagatedType); | 278 _resolver.recordPropagatedTypeIfBetter(node, propagatedType); |
269 } | 279 } |
270 } | 280 } |
271 return null; | 281 return null; |
272 } | 282 } |
273 | 283 |
274 /** | 284 /** |
275 * The Dart Language Specification, 16.29 (Await Expressions): | 285 * The Dart Language Specification, 16.29 (Await Expressions): |
276 * | 286 * |
277 * The static type of [the expression "await e"] is flatten(T) where T is | 287 * The static type of [the expression "await e"] is flatten(T) where T is |
(...skipping 1947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2225 */ | 2235 */ |
2226 void _recordStaticType(Expression expression, DartType type) { | 2236 void _recordStaticType(Expression expression, DartType type) { |
2227 if (type == null) { | 2237 if (type == null) { |
2228 expression.staticType = _dynamicType; | 2238 expression.staticType = _dynamicType; |
2229 } else { | 2239 } else { |
2230 expression.staticType = type; | 2240 expression.staticType = type; |
2231 } | 2241 } |
2232 } | 2242 } |
2233 | 2243 |
2234 /** | 2244 /** |
2235 * Attempts to make a better guess for the type of the given assignment | |
2236 * [expression], given that resolution has so far produced the [currentType]. | |
2237 * The [typeAccessor] is used to access the corresponding type of the left | |
2238 * and right operands. | |
2239 */ | |
2240 DartType _refineAssignmentExpressionType(AssignmentExpression expression, | |
2241 DartType currentType, DartType typeAccessor(Expression node)) { | |
2242 Expression leftHandSize = expression.leftHandSide; | |
2243 Expression rightHandSide = expression.rightHandSide; | |
2244 TokenType operator = expression.operator.type; | |
2245 DartType intType = _typeProvider.intType; | |
2246 if (typeAccessor(leftHandSize) == intType) { | |
2247 // int op= double | |
2248 if (operator == TokenType.MINUS_EQ || | |
2249 operator == TokenType.PERCENT_EQ || | |
2250 operator == TokenType.PLUS_EQ || | |
2251 operator == TokenType.STAR_EQ) { | |
2252 DartType doubleType = _typeProvider.doubleType; | |
2253 if (typeAccessor(rightHandSide) == doubleType) { | |
2254 return doubleType; | |
2255 } | |
2256 } | |
2257 // int op= int | |
2258 if (operator == TokenType.MINUS_EQ || | |
2259 operator == TokenType.PERCENT_EQ || | |
2260 operator == TokenType.PLUS_EQ || | |
2261 operator == TokenType.STAR_EQ || | |
2262 operator == TokenType.TILDE_SLASH_EQ) { | |
2263 if (typeAccessor(rightHandSide) == intType) { | |
2264 return intType; | |
2265 } | |
2266 } | |
2267 } | |
2268 // default | |
2269 return currentType; | |
2270 } | |
2271 | |
2272 /** | |
2273 * Create a table mapping HTML tag names to the names of the classes (in 'dart
:html') that | 2245 * Create a table mapping HTML tag names to the names of the classes (in 'dart
:html') that |
2274 * implement those tags. | 2246 * implement those tags. |
2275 * | 2247 * |
2276 * @return the table that was created | 2248 * @return the table that was created |
2277 */ | 2249 */ |
2278 static HashMap<String, String> _createHtmlTagToClassMap() { | 2250 static HashMap<String, String> _createHtmlTagToClassMap() { |
2279 HashMap<String, String> map = new HashMap<String, String>(); | 2251 HashMap<String, String> map = new HashMap<String, String>(); |
2280 map["a"] = "AnchorElement"; | 2252 map["a"] = "AnchorElement"; |
2281 map["area"] = "AreaElement"; | 2253 map["area"] = "AreaElement"; |
2282 map["br"] = "BRElement"; | 2254 map["br"] = "BRElement"; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2363 } | 2335 } |
2364 // merge types | 2336 // merge types |
2365 if (result == null) { | 2337 if (result == null) { |
2366 result = type; | 2338 result = type; |
2367 } else { | 2339 } else { |
2368 result = _typeSystem.getLeastUpperBound(_typeProvider, result, type); | 2340 result = _typeSystem.getLeastUpperBound(_typeProvider, result, type); |
2369 } | 2341 } |
2370 return null; | 2342 return null; |
2371 } | 2343 } |
2372 } | 2344 } |
OLD | NEW |