Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(91)

Unified Diff: pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Issue 1462133005: Downwards inference. This adds support to the resolver for downwards (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments 2 Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer/lib/src/generated/static_type_analyzer.dart
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 8ec48e4f3d1bfb60555c3bf2e8a0e5b2fc55f0db..cc639459e38759e4916e2740d243b98e3022ebc9 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -13,6 +13,7 @@ import 'element.dart';
import 'java_engine.dart';
import 'resolver.dart';
import 'scanner.dart' as sc;
+import 'utilities_dart.dart';
/**
* Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@@ -93,6 +94,83 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
/**
+ * Given a constructor name [node] and a type [type], record an inferred type
+ * for the constructor if in strong mode. This is used to fill in any
+ * inferred type parameters found by the resolver.
+ */
+ void inferConstructorName(ConstructorName node, InterfaceType type) {
+ if (_strongMode) {
+ node.type.type = type;
+ _resolver.inferenceContext.recordInference(node.parent, type);
+ }
+ return;
+ }
+
+ /**
+ * Given a formal parameter list and a function type use the function type
+ * to infer types for any of the parameters which have implicit (missing)
+ * types. Only infers types in strong mode. Returns true if inference
+ * has occurred.
+ */
+ bool inferFormalParameterList(
+ FormalParameterList node, DartType functionType) {
+ bool inferred = false;
+ if (_strongMode && node != null && functionType is FunctionType) {
+ void inferType(ParameterElementImpl p, DartType inferredType) {
+ // Check that there is no declared type, and that we have not already
+ // inferred a type in some fashion.
+ if (p.hasImplicitType &&
+ (p.type == null || p.type.isDynamic) &&
+ !inferredType.isDynamic) {
+ p.type = inferredType;
+ inferred = true;
+ }
+ }
+
+ List<ParameterElement> parameters = node.parameterElements;
+
+ {
+ List<DartType> normalParameterTypes = functionType.normalParameterTypes;
+ int normalCount = normalParameterTypes.length;
+ Iterable<ParameterElement> required = parameters
+ .where((p) => p.parameterKind == ParameterKind.REQUIRED)
+ .take(normalCount);
+ int index = 0;
+ for (ParameterElementImpl p in required) {
+ inferType(p, normalParameterTypes[index++]);
+ }
+ }
+
+ {
+ List<DartType> optionalParameterTypes =
+ functionType.optionalParameterTypes;
+ int optionalCount = optionalParameterTypes.length;
+ Iterable<ParameterElement> optional = parameters
+ .where((p) => p.parameterKind == ParameterKind.POSITIONAL)
+ .take(optionalCount);
+ int index = 0;
+ for (ParameterElementImpl p in optional) {
+ inferType(p, optionalParameterTypes[index++]);
+ }
+ }
+
+ {
+ Map<String, DartType> namedParameterTypes =
+ functionType.namedParameterTypes;
+ Iterable<ParameterElement> named =
+ parameters.where((p) => p.parameterKind == ParameterKind.NAMED);
+ for (ParameterElementImpl p in named) {
+ if (!namedParameterTypes.containsKey(p.name)) {
+ continue;
+ }
+ inferType(p, namedParameterTypes[p.name]);
+ }
+ }
+ }
+ return inferred;
+ }
+
+ /**
* The Dart Language Specification, 12.5: <blockquote>The static type of a string literal is
* `String`.</blockquote>
*/
@@ -381,8 +459,19 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
ExecutableElementImpl functionElement =
node.element as ExecutableElementImpl;
- functionElement.returnType =
- _computeStaticReturnTypeOfFunctionExpression(node);
+ DartType computedType = _computeStaticReturnTypeOfFunctionExpression(node);
+ if (_strongMode) {
+ DartType functionType = InferenceContext.getType(node);
+ if (functionType is FunctionType) {
+ DartType returnType = functionType.returnType;
+ if ((computedType.isDynamic || computedType.isBottom) &&
+ !(returnType.isDynamic || returnType.isBottom)) {
+ computedType = functionType.returnType;
Brian Wilkerson 2015/12/01 22:31:09 "functionType.returnType" --> "returnType"?
Leaf 2015/12/01 23:39:24 Done.
+ _resolver.inferenceContext.recordInference(node, functionType);
+ }
+ }
+ }
+ functionElement.returnType = computedType;
_recordPropagatedTypeOfFunction(functionElement, node.body);
_recordStaticType(node, node.element.type);
return null;
@@ -522,6 +611,15 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
staticType = argumentType;
}
}
+ } else {
+ DartType contextType = InferenceContext.getType(node);
+ if (_strongMode &&
+ contextType is InterfaceType &&
+ contextType.typeArguments.length == 1 &&
+ contextType.element == _typeProvider.listType.element) {
+ staticType = contextType.typeArguments[0];
+ _resolver.inferenceContext.recordInference(node, contextType);
+ }
}
_recordStaticType(
node, _typeProvider.listType.substitute4(<DartType>[staticType]));
@@ -559,6 +657,16 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
staticValueType = entryValueType;
}
}
+ } else {
+ DartType contextType = InferenceContext.getType(node);
+ if (_strongMode &&
+ contextType is InterfaceType &&
+ contextType.typeArguments.length == 2 &&
+ contextType.element == _typeProvider.mapType.element) {
+ staticKeyType = contextType.typeArguments[0] ?? staticKeyType;
+ staticValueType = contextType.typeArguments[1] ?? staticValueType;
+ _resolver.inferenceContext.recordInference(node, contextType);
+ }
}
_recordStaticType(
node,
@@ -1679,6 +1787,25 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
/**
+ * Given a local variable declaration and its initializer, attempt to infer
+ * a type for the local variable declaration based on the initializer.
+ * Inference is only done if an explicit type is not present, and if
+ * inferring a type improves the type.
+ */
+ void _inferLocalVariableType(
+ VariableDeclaration node, Expression initializer) {
+ if (initializer != null &&
+ (node.parent as VariableDeclarationList).type == null &&
+ (node.element is LocalVariableElementImpl) &&
+ (initializer.staticType != null) &&
+ (!initializer.staticType.isBottom)) {
+ LocalVariableElementImpl element = node.element;
+ element.type = initializer.staticType;
+ node.name.staticType = initializer.staticType;
+ }
+ }
+
+ /**
* Given a method invocation [node], attempt to infer a better
* type for the result.
*/
@@ -1791,25 +1918,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
/**
- * Given a local variable declaration and its initializer, attempt to infer
- * a type for the local variable declaration based on the initializer.
- * Inference is only done if an explicit type is not present, and if
- * inferring a type improves the type.
- */
- void _inferLocalVariableType(
- VariableDeclaration node, Expression initializer) {
- if (initializer != null &&
- (node.parent as VariableDeclarationList).type == null &&
- (node.element is LocalVariableElementImpl) &&
- (initializer.staticType != null) &&
- (!initializer.staticType.isBottom)) {
- LocalVariableElementImpl element = node.element;
- element.type = initializer.staticType;
- node.name.staticType = initializer.staticType;
- }
- }
-
- /**
* Given a property access [node] with static type [nodeType],
* and [id] is the property name being accessed, infer a type for the
* access itself and its constituent components if the access is to one of the

Powered by Google App Engine
This is Rietveld 408576698