| 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 |