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

Unified Diff: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java

Issue 11140011: Infer function expression parameter types what it is assigned to element with known type (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 2 months 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
« no previous file with comments | « no previous file | compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index 0c740257ddfdfee537c13bf93fc572b460359581..8fad370628ec6a94e5d86df82d56e23261ac11ef 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -426,10 +426,20 @@ public class TypeAnalyzer implements DartCompilationPhase {
Token operator = node.getOperator();
switch (operator) {
case ASSIGN: {
- Type rhs = nonVoidTypeOf(rhsNode);
- if (!hasInferredType(lhsNode)) {
- checkAssignable(rhsNode, lhs, rhs);
+ // prepare RHS type
+ Type rhs = getInvocationArgumentType(rhsNode);
+ try {
+ if (!hasInferredType(lhsNode)) {
+ if (checkAssignable(rhsNode, lhs, rhs)) {
+ inferFunctionLiteralParametersTypes(rhsNode, lhs);
+ }
+ }
+ } finally {
+ if (rhsNode instanceof DartFunctionExpression) {
+ rhsNode.accept(this);
+ }
}
+ // may be replace type of variable
setVariableElementType(lhsNode.getElement(), rhs);
checkAssignableElement(lhsNode);
// if cascade, then use type of "lhs" qualifier
@@ -954,9 +964,10 @@ public class TypeAnalyzer implements DartCompilationPhase {
List<DartParameter> parameterNodes = literal.getFunction().getParameters();
// try to infer types of "normal" parameters
List<Type> requiredNormalParameterTypes = requiredType.getParameterTypes();
- for (int i = 0; i < requiredNormalParameterTypes.size(); i++) {
- DartParameter parameterNode = parameterNodes.get(i);
+ int n = Math.min(requiredNormalParameterTypes.size(), parameterNodes.size());
+ for (int i = 0; i < n; i++) {
Type requiredNormalParameterType = requiredNormalParameterTypes.get(i);
+ DartParameter parameterNode = parameterNodes.get(i);
inferVariableDeclarationType(parameterNode, requiredNormalParameterType);
}
}
@@ -2723,6 +2734,11 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
+ /**
+ * Almost same as {@link #nonVoidTypeOf(DartNode)}, but does not visit
+ * {@link DartFunctionExpression}, because we know its type already and want to infer types of
+ * arguments, and then propagate them into body.
+ */
private Type getInvocationArgumentType(DartExpression argument) {
// We are interesting in the type of expression, without name.
if (argument instanceof DartNamedExpression) {
@@ -2764,15 +2780,21 @@ public class TypeAnalyzer implements DartCompilationPhase {
@Override
public Type visitVariable(DartVariable node) {
- Type result = checkInitializedDeclaration(node, node.getValue());
- // if no type declared for variables, try to use type of value
- {
- DartExpression value = node.getValue();
- if (value != null) {
- Type valueType = value.getType();
- inferVariableDeclarationType(node, valueType);
+ DartExpression value = node.getValue();
+ // if type is declared and right side is closure, infer its parameter types
+ if (value != null) {
+ Type varType = node.getElement().getType();
+ if (isExclicitlySpecifiedType(varType)) {
+ inferFunctionLiteralParametersTypes(value, varType);
}
}
+ // prepare type of value
+ Type result = checkInitializedDeclaration(node, value);
+ // if no type declared for variables, try to use type of value
+ if (value != null) {
+ Type valueType = value.getType();
+ inferVariableDeclarationType(node, valueType);
+ }
// done
return result;
}
@@ -2866,16 +2888,22 @@ public class TypeAnalyzer implements DartCompilationPhase {
if (accessor != null) {
return typeOf(accessor);
} else {
- Type result = checkInitializedDeclaration(node, node.getValue());
+ DartExpression value = node.getValue();
+ // if type is declared and right side is closure, infer its parameter types
+ if (value != null) {
+ Type fieldType = node.getElement().getType();
+ if (isExclicitlySpecifiedType(fieldType)) {
+ inferFunctionLiteralParametersTypes(value, fieldType);
+ }
+ }
+ // prepare type of value
+ Type result = checkInitializedDeclaration(node, value);
// if no type declared for field, try to use type of value
// only final fields, because only in this case we can be sure that field is not assigned
// somewhere, may be even not in this unit
- if (node.getModifiers().isFinal()) {
- DartExpression value = node.getValue();
- if (value != null) {
- Type valueType = value.getType();
- inferVariableDeclarationType(node, valueType);
- }
+ if (node.getModifiers().isFinal() && value != null) {
+ Type valueType = value.getType();
+ inferVariableDeclarationType(node, valueType);
}
// done
return result;
@@ -3379,4 +3407,9 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
}
+
+ private static boolean isExclicitlySpecifiedType(Type fieldType) {
+ return fieldType != null && TypeKind.of(fieldType) != TypeKind.DYNAMIC
+ && !fieldType.isInferred();
+ }
}
« no previous file with comments | « no previous file | compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698