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