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.resolver; | 5 library analyzer.src.generated.resolver; |
6 | 6 |
7 import 'dart:collection'; | 7 import 'dart:collection'; |
8 | 8 |
9 import 'package:analyzer/dart/element/element.dart'; | 9 import 'package:analyzer/dart/element/element.dart'; |
10 import 'package:analyzer/dart/element/type.dart'; | 10 import 'package:analyzer/dart/element/type.dart'; |
(...skipping 5397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5408 | 5408 |
5409 /** | 5409 /** |
5410 * The type system in use. | 5410 * The type system in use. |
5411 */ | 5411 */ |
5412 final TypeSystem _typeSystem; | 5412 final TypeSystem _typeSystem; |
5413 | 5413 |
5414 /** | 5414 /** |
5415 * A stack of return types for all of the enclosing | 5415 * A stack of return types for all of the enclosing |
5416 * functions and methods. | 5416 * functions and methods. |
5417 */ | 5417 */ |
| 5418 // TODO(leafp) Handle the implicit union type for Futures |
| 5419 // https://github.com/dart-lang/sdk/issues/25322 |
5418 List<DartType> _returnStack = <DartType>[]; | 5420 List<DartType> _returnStack = <DartType>[]; |
5419 | 5421 |
5420 InferenceContext._(this._errorListener, TypeProvider typeProvider, | 5422 InferenceContext._(this._errorListener, TypeProvider typeProvider, |
5421 this._typeSystem, this._inferenceHints) | 5423 this._typeSystem, this._inferenceHints) |
5422 : _typeProvider = typeProvider; | 5424 : _typeProvider = typeProvider; |
5423 | 5425 |
5424 /** | 5426 /** |
5425 * Get the return type of the current enclosing function, if any. | 5427 * Get the return type of the current enclosing function, if any. |
| 5428 * |
| 5429 * The type returned for a function is the type that is expected |
| 5430 * to be used in a return or yield context. For ordinary functions |
| 5431 * this is the same as the return type of the function. For async |
| 5432 * functions returning Future<T> and for generator functions |
| 5433 * returning Stream<T> or Iterable<T>, this is T. |
5426 */ | 5434 */ |
5427 DartType get returnContext => | 5435 DartType get returnContext => |
5428 (_returnStack.isNotEmpty) ? _returnStack.last : null; | 5436 _returnStack.isNotEmpty ? _returnStack.last : null; |
5429 | 5437 |
5430 /** | 5438 /** |
5431 * Match type [t1] against type [t2] as follows. | 5439 * Match type [t1] against type [t2] as follows. |
5432 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype | 5440 * If `t1 = I<dynamic, ..., dynamic>`, then look for a supertype |
5433 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>` | 5441 * of t1 of the form `K<S0, ..., Sm>` where `t2 = K<S0', ..., Sm'>` |
5434 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'` | 5442 * If the supertype exists, use the constraints `S0 <: S0', ... Sm <: Sm'` |
5435 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`, | 5443 * to derive a concrete instantation for I of the form `<T0, ..., Tn>`, |
5436 * such that `I<T0, .., Tn> <: t2` | 5444 * such that `I<T0, .., Tn> <: t2` |
5437 */ | 5445 */ |
5438 List<DartType> matchTypes(DartType t1, DartType t2) => | 5446 List<DartType> matchTypes(DartType t1, DartType t2) => |
(...skipping 2913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8352 node.rightHandSide, node.leftHandSide.staticType); | 8360 node.rightHandSide, node.leftHandSide.staticType); |
8353 } | 8361 } |
8354 safelyVisit(node.rightHandSide); | 8362 safelyVisit(node.rightHandSide); |
8355 node.accept(elementResolver); | 8363 node.accept(elementResolver); |
8356 node.accept(typeAnalyzer); | 8364 node.accept(typeAnalyzer); |
8357 return null; | 8365 return null; |
8358 } | 8366 } |
8359 | 8367 |
8360 @override | 8368 @override |
8361 Object visitAwaitExpression(AwaitExpression node) { | 8369 Object visitAwaitExpression(AwaitExpression node) { |
8362 //TODO(leafp): Handle the implicit union type here | 8370 // TODO(leafp): Handle the implicit union type here |
8363 DartType contextType = InferenceContext.getType(node); | 8371 // https://github.com/dart-lang/sdk/issues/25322 |
| 8372 DartType contextType = StaticTypeAnalyzer.flattenFutures( |
| 8373 typeProvider, InferenceContext.getType(node)); |
8364 if (contextType != null) { | 8374 if (contextType != null) { |
8365 InterfaceType futureT = | 8375 InterfaceType futureT = |
8366 typeProvider.futureType.substitute4([contextType]); | 8376 typeProvider.futureType.substitute4([contextType]); |
8367 InferenceContext.setType(node.expression, futureT); | 8377 InferenceContext.setType(node.expression, futureT); |
8368 } | 8378 } |
8369 return super.visitAwaitExpression(node); | 8379 return super.visitAwaitExpression(node); |
8370 } | 8380 } |
8371 | 8381 |
8372 @override | 8382 @override |
8373 Object visitBinaryExpression(BinaryExpression node) { | 8383 Object visitBinaryExpression(BinaryExpression node) { |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8887 @override | 8897 @override |
8888 Object visitFunctionExpression(FunctionExpression node) { | 8898 Object visitFunctionExpression(FunctionExpression node) { |
8889 ExecutableElement outerFunction = _enclosingFunction; | 8899 ExecutableElement outerFunction = _enclosingFunction; |
8890 try { | 8900 try { |
8891 _enclosingFunction = node.element; | 8901 _enclosingFunction = node.element; |
8892 _overrideManager.enterScope(); | 8902 _overrideManager.enterScope(); |
8893 try { | 8903 try { |
8894 DartType functionType = InferenceContext.getType(node); | 8904 DartType functionType = InferenceContext.getType(node); |
8895 if (functionType is FunctionType) { | 8905 if (functionType is FunctionType) { |
8896 _inferFormalParameterList(node.parameters, functionType); | 8906 _inferFormalParameterList(node.parameters, functionType); |
8897 InferenceContext.setType(node.body, functionType.returnType); | 8907 DartType returnType = _computeReturnOrYieldType( |
| 8908 functionType.returnType, |
| 8909 _enclosingFunction.isGenerator, |
| 8910 _enclosingFunction.isAsynchronous); |
| 8911 InferenceContext.setType(node.body, returnType); |
8898 } | 8912 } |
8899 super.visitFunctionExpression(node); | 8913 super.visitFunctionExpression(node); |
8900 } finally { | 8914 } finally { |
8901 _overrideManager.exitScope(); | 8915 _overrideManager.exitScope(); |
8902 } | 8916 } |
8903 } finally { | 8917 } finally { |
8904 _enclosingFunction = outerFunction; | 8918 _enclosingFunction = outerFunction; |
8905 } | 8919 } |
8906 return null; | 8920 return null; |
8907 } | 8921 } |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9092 } | 9106 } |
9093 super.visitMapLiteral(node); | 9107 super.visitMapLiteral(node); |
9094 return null; | 9108 return null; |
9095 } | 9109 } |
9096 | 9110 |
9097 @override | 9111 @override |
9098 Object visitMethodDeclaration(MethodDeclaration node) { | 9112 Object visitMethodDeclaration(MethodDeclaration node) { |
9099 ExecutableElement outerFunction = _enclosingFunction; | 9113 ExecutableElement outerFunction = _enclosingFunction; |
9100 try { | 9114 try { |
9101 _enclosingFunction = node.element; | 9115 _enclosingFunction = node.element; |
9102 InferenceContext.setType(node.body, node.element.type?.returnType); | 9116 DartType returnType = _computeReturnOrYieldType( |
| 9117 _enclosingFunction.type?.returnType, |
| 9118 _enclosingFunction.isGenerator, |
| 9119 _enclosingFunction.isAsynchronous); |
| 9120 InferenceContext.setType(node.body, returnType); |
9103 super.visitMethodDeclaration(node); | 9121 super.visitMethodDeclaration(node); |
9104 } finally { | 9122 } finally { |
9105 _enclosingFunction = outerFunction; | 9123 _enclosingFunction = outerFunction; |
9106 } | 9124 } |
9107 return null; | 9125 return null; |
9108 } | 9126 } |
9109 | 9127 |
9110 @override | 9128 @override |
9111 void visitMethodDeclarationInScope(MethodDeclaration node) { | 9129 void visitMethodDeclarationInScope(MethodDeclaration node) { |
9112 super.visitMethodDeclarationInScope(node); | 9130 super.visitMethodDeclarationInScope(node); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9321 return null; | 9339 return null; |
9322 } | 9340 } |
9323 | 9341 |
9324 @override | 9342 @override |
9325 Object visitYieldStatement(YieldStatement node) { | 9343 Object visitYieldStatement(YieldStatement node) { |
9326 DartType returnType = inferenceContext.returnContext; | 9344 DartType returnType = inferenceContext.returnContext; |
9327 if (returnType != null && _enclosingFunction != null) { | 9345 if (returnType != null && _enclosingFunction != null) { |
9328 // If we're not in a generator ([a]sync*, then we shouldn't have a yield. | 9346 // If we're not in a generator ([a]sync*, then we shouldn't have a yield. |
9329 // so don't infer | 9347 // so don't infer |
9330 if (_enclosingFunction.isGenerator) { | 9348 if (_enclosingFunction.isGenerator) { |
9331 // If this is a yield*, then we just propagate the return type downwards | 9349 // If this just a yield, then we just pass on the element type |
9332 DartType type = returnType; | 9350 DartType type = returnType; |
9333 // If this just a yield, then we need to get the element type | 9351 if (node.star != null) { |
9334 if (node.star == null) { | 9352 // If this is a yield*, then we wrap the element return type |
9335 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> | 9353 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> |
9336 InterfaceType wrapperD = _enclosingFunction.isSynchronous | 9354 InterfaceType wrapperType = _enclosingFunction.isSynchronous |
9337 ? typeProvider.iterableDynamicType | 9355 ? typeProvider.iterableType |
9338 : typeProvider.streamDynamicType; | 9356 : typeProvider.streamType; |
9339 // Match the types to instantiate the type arguments if possible | 9357 type = wrapperType.substitute4(<DartType>[type]); |
9340 List<DartType> targs = | |
9341 inferenceContext.matchTypes(wrapperD, returnType); | |
9342 type = (targs?.length == 1) ? targs[0] : null; | |
9343 } | 9358 } |
9344 InferenceContext.setType(node.expression, type); | 9359 InferenceContext.setType(node.expression, type); |
9345 } | 9360 } |
9346 } | 9361 } |
9347 return super.visitYieldStatement(node); | 9362 return super.visitYieldStatement(node); |
9348 } | 9363 } |
9349 | 9364 |
9350 /** | 9365 /** |
9351 * Checks each promoted variable in the current scope for compliance with the
following | 9366 * Checks each promoted variable in the current scope for compliance with the
following |
9352 * specification statement: | 9367 * specification statement: |
(...skipping 20 matching lines...) Expand all Loading... |
9373 */ | 9388 */ |
9374 void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) { | 9389 void _clearTypePromotionsIfPotentiallyMutatedIn(AstNode target) { |
9375 for (Element element in _promoteManager.promotedElements) { | 9390 for (Element element in _promoteManager.promotedElements) { |
9376 if (_isVariablePotentiallyMutatedIn(element, target)) { | 9391 if (_isVariablePotentiallyMutatedIn(element, target)) { |
9377 _promoteManager.setType(element, null); | 9392 _promoteManager.setType(element, null); |
9378 } | 9393 } |
9379 } | 9394 } |
9380 } | 9395 } |
9381 | 9396 |
9382 /** | 9397 /** |
| 9398 * Given the declared return type of a function, compute the type of the |
| 9399 * values which should be returned or yielded as appropriate. If a type |
| 9400 * cannot be computed from the declared return type, return null. |
| 9401 */ |
| 9402 DartType _computeReturnOrYieldType( |
| 9403 DartType declaredType, bool isGenerator, bool isAsynchronous) { |
| 9404 // Ordinary functions just return their declared types. |
| 9405 if (!isGenerator && !isAsynchronous) { |
| 9406 return declaredType; |
| 9407 } |
| 9408 if (isGenerator) { |
| 9409 if (declaredType is! InterfaceType) { |
| 9410 return null; |
| 9411 } |
| 9412 // If it's synchronous, we expect Iterable<T>, otherwise Stream<T> |
| 9413 InterfaceType rawType = isAsynchronous |
| 9414 ? typeProvider.streamDynamicType |
| 9415 : typeProvider.iterableDynamicType; |
| 9416 // Match the types to instantiate the type arguments if possible |
| 9417 List<DartType> typeArgs = |
| 9418 inferenceContext.matchTypes(rawType, declaredType); |
| 9419 return (typeArgs?.length == 1) ? typeArgs[0] : null; |
| 9420 } |
| 9421 // Must be asynchronous to reach here, so strip off any layers of Future |
| 9422 return StaticTypeAnalyzer.flattenFutures(typeProvider, declaredType); |
| 9423 } |
| 9424 |
| 9425 /** |
9383 * The given expression is the expression used to compute the iterator for a | 9426 * The given expression is the expression used to compute the iterator for a |
9384 * for-each statement. Attempt to compute the type of objects that will be | 9427 * for-each statement. Attempt to compute the type of objects that will be |
9385 * assigned to the loop variable and return that type. Return `null` if the | 9428 * assigned to the loop variable and return that type. Return `null` if the |
9386 * type could not be determined. The [iteratorExpression] is the expression | 9429 * type could not be determined. The [iteratorExpression] is the expression |
9387 * that will return the Iterable being iterated over. | 9430 * that will return the Iterable being iterated over. |
9388 */ | 9431 */ |
9389 DartType _getIteratorElementType(Expression iteratorExpression) { | 9432 DartType _getIteratorElementType(Expression iteratorExpression) { |
9390 DartType expressionType = iteratorExpression.bestType; | 9433 DartType expressionType = iteratorExpression.bestType; |
9391 if (expressionType is InterfaceType) { | 9434 if (expressionType is InterfaceType) { |
9392 InterfaceType interfaceType = expressionType; | 9435 InterfaceType interfaceType = expressionType; |
(...skipping 3987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13380 nonFields.add(node); | 13423 nonFields.add(node); |
13381 return null; | 13424 return null; |
13382 } | 13425 } |
13383 | 13426 |
13384 @override | 13427 @override |
13385 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); | 13428 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); |
13386 | 13429 |
13387 @override | 13430 @override |
13388 Object visitWithClause(WithClause node) => null; | 13431 Object visitWithClause(WithClause node) => null; |
13389 } | 13432 } |
OLD | NEW |