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

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

Issue 11364032: Issue 6107. Infer cascade type when it is assigned to the element with know type (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 1 month 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 454b0b0ae32870614a8c720cf1ee3f8ac2834d8a..82deb87fe8b0859f423b10665f2ddd4471985e00 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -784,31 +784,6 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
}
- /**
- * @return the {@link Type} which is both "a" and "b" types. May be "dynamic" if "a" and "b"
- * don't form hierarchy.
- */
- Type getUnionType(Type curType, Type newType) {
- if (TypeKind.of(curType) == TypeKind.DYNAMIC) {
- return newType;
- }
- if (TypeKind.of(newType) == TypeKind.DYNAMIC) {
- return curType;
- }
- if (types.isSubtype(curType, newType)) {
- return curType;
- }
- if (types.isSubtype(newType, curType)) {
- return newType;
- }
- // if InterfaceType, use union
- if (curType instanceof InterfaceType && newType instanceof InterfaceType) {
- return types.unionTypes(ImmutableList.of((InterfaceType) curType, (InterfaceType) newType));
- }
- // keep type as is
- return curType;
- }
-
void restore() {
for (Entry<VariableElement, Type> entry : typesMap.entrySet()) {
Elements.setType(entry.getKey(), entry.getValue());
@@ -817,6 +792,31 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
/**
+ * @return the {@link Type} which is both "a" and "b" types. May be "dynamic" if "a" and "b"
+ * don't form hierarchy.
+ */
+ private Type getUnionType(Type curType, Type newType) {
+ if (TypeKind.of(curType) == TypeKind.DYNAMIC) {
+ return newType;
+ }
+ if (TypeKind.of(newType) == TypeKind.DYNAMIC) {
+ return curType;
+ }
+ if (types.isSubtype(curType, newType)) {
+ return curType;
+ }
+ if (types.isSubtype(newType, curType)) {
+ return newType;
+ }
+ // if InterfaceType, use union
+ if (curType instanceof InterfaceType && newType instanceof InterfaceType) {
+ return types.unionTypes(ImmutableList.of((InterfaceType) curType, (InterfaceType) newType));
+ }
+ // keep type as is
+ return curType;
+ }
+
+ /**
* @return <code>true</code> if we can prove that given {@link DartStatement} always leads to
* the exit from the enclosing function.
*/
@@ -1174,33 +1174,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
{
Set<String> usedNamedParametersPositional = Sets.newHashSet();
Set<String> usedNamedParametersNamed = Sets.newHashSet();
- // Prepare named parameters.
Map<String, Type> namedParameterTypes = ftype.getNamedParameterTypes();
- Iterator<Entry<String, Type>> namedParameterTypesIterator =
- namedParameterTypes.entrySet().iterator();
-// // Check positional arguments for named parameters.
-// while (namedParameterTypesIterator.hasNext()
-// && argumentTypes.hasNext()
-// && !(argumentNodes.get(argumentIndex) instanceof DartNamedExpression)) {
-// Entry<String, Type> namedEntry = namedParameterTypesIterator.next();
-// String parameterName = namedEntry.getKey();
-// usedNamedParametersPositional.add(parameterName);
-// Type namedType = namedEntry.getValue();
-// namedType.getClass(); // quick null check
-// Type argumentType = argumentTypes.next();
-// argumentType.getClass(); // quick null check
-// DartExpression argumentNode = argumentNodes.get(argumentIndex);
-// if (parameters != null) {
-// argumentNode.setInvocationParameterId(parameters.get(argumentIndex));
-// } else {
-// argumentNode.setInvocationParameterId(argumentIndex);
-// }
-// if (checkAssignable(argumentNode, namedType, argumentType)) {
-// inferFunctionLiteralParametersTypes(argumentNode, namedType);
-// }
-// argumentIndex++;
-// }
- // Check named arguments for named parameters.
while (argumentTypes.hasNext()
&& argumentNodes.get(argumentIndex) instanceof DartNamedExpression) {
DartNamedExpression namedExpression =
@@ -1348,11 +1322,18 @@ public class TypeAnalyzer implements DartCompilationPhase {
if (node == null) {
return dynamicType;
}
+ // prepare new type
Type result = node.accept(this);
if (result == null) {
return dynamicType;
}
- node.setType(result);
+ // set new type, or keep existing
+ if (node.getType() == null) {
+ node.setType(result);
+ } else {
+ result = node.getType();
+ }
+ // done
return result;
}
@@ -1446,10 +1427,57 @@ public class TypeAnalyzer implements DartCompilationPhase {
public Type visitCascadeExpression(DartCascadeExpression node) {
DartExpression target = node.getTarget();
Type type = nonVoidTypeOf(target);
+ node.setType(type);
+ inferCascadeType(node);
node.visitChildren(this);
return type;
}
+ /**
+ * Infers {@link Type} of {@link DartCascadeExpression} from context.
+ */
+ private void inferCascadeType(DartCascadeExpression node) {
+ // field declaration
+ if (node.getParent() instanceof DartField) {
+ DartField field = (DartField) node.getParent();
+ Type varType = field.getElement().getType();
+ setCascadeUnionType(node, varType);
+ }
+ // variable declaration
+ if (node.getParent() instanceof DartVariable) {
+ DartVariable var = (DartVariable) node.getParent();
+ Type varType = var.getElement().getType();
+ setCascadeUnionType(node, varType);
+ }
+ // assignment
+ if (node.getParent() instanceof DartBinaryExpression) {
+ DartBinaryExpression binary = (DartBinaryExpression) node.getParent();
+ if (binary.getOperator() == Token.ASSIGN && binary.getArg2() == node
+ && binary.getArg1() != null) {
+ Element leftElement = binary.getArg1().getElement();
+ if (leftElement != null) {
+ Type varType = leftElement.getType();
+ setCascadeUnionType(node, varType);
+ }
+ }
+ }
+ }
+
+ /**
+ * Sets for given {@link DartCascadeExpression} and its target {@link Type} which is union of
+ * existing type and "newType".
+ */
+ private void setCascadeUnionType(DartCascadeExpression node, Type newType) {
+ DartExpression target = node.getTarget();
+ Type type = node.getType();
+ if (isExclicitlySpecifiedType(newType) && types.isAssignable(type, newType)) {
+ Type unionType = getUnionType(type, newType);
+ unionType = Types.makeInferred(unionType);
+ node.setType(unionType);
+ target.setType(unionType);
+ }
+ }
+
@Override
public Type visitFunctionObjectInvocation(DartFunctionObjectInvocation node) {
ClassElement element = functionType.getElement();
@@ -3498,26 +3526,6 @@ public class TypeAnalyzer implements DartCompilationPhase {
}
return defaults;
}
-
- private int getNumRequiredParameters(List<VariableElement> parameters) {
- int numRequired = 0;
- for (VariableElement parameter : parameters) {
- if (!parameter.isNamed()) {
- numRequired++;
- }
- }
- return numRequired;
- }
-
- private List<VariableElement> getNamedParameters(List<VariableElement> parameters) {
- List<VariableElement> named = Lists.newArrayList();
- for (VariableElement v : parameters) {
- if (v.isNamed()) {
- named.add(v);
- }
- }
- return named;
- }
}
}
« 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