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

Unified Diff: dart/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart

Issue 13866010: Correctly compile unresolved for-in loops. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Additional problems found during testing. Created 7 years, 8 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
Index: dart/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
diff --git a/dart/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/dart/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index c61db0c92dc74d31bc41cbc41db0a6383f410a24..6c923c022058b42a83fe765538adefd8b3cf5b9b 100644
--- a/dart/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/dart/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -179,11 +179,11 @@ class SimpleTypesInferrer extends TypesInferrer {
* of a field, these [Node] are initially discarded, and once the
* type is computed, we make sure these constraints are satisfied
* for that type. For example:
- *
+ *
* [: field++ ], or [: field += 42 :], the constraint is on the
* operator+, and we make sure that a typed selector with the found
* type returns that type.
- *
+ *
* [: field = other.field :], the constraint in on the [:field]
* getter selector, and we make sure that the getter selector
* returns that type.
@@ -265,7 +265,8 @@ class SimpleTypesInferrer extends TypesInferrer {
recompiles++;
recomputeWatch.start();
}
- bool changed = analyze(element);
+ bool changed =
+ compiler.withCurrentElement(element, () => analyze(element));
analyzed++;
if (wasAnalyzed) {
recomputeWatch.stop();
@@ -1199,7 +1200,7 @@ class SimpleTypeInferrerVisitor extends ResolvedVisitor<TypeMask> {
if (analyzedElement.isField()) {
return visit(node.asSendSet().arguments.head);
}
-
+
FunctionElement function = analyzedElement;
FunctionSignature signature = function.computeSignature(compiler);
signature.forEachOptionalParameter((element) {
@@ -1532,46 +1533,9 @@ class SimpleTypeInferrerVisitor extends ResolvedVisitor<TypeMask> {
}
} else if (op == '=') {
// [: foo = 42 :] or [: foo.bar = 42 :].
- ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
- if (Elements.isStaticOrTopLevelField(element)) {
- handleStaticSend(node, setterSelector, element, arguments);
- } else if (Elements.isUnresolved(element) || element.isSetter()) {
- handleDynamicSend(node, setterSelector, receiverType, arguments);
- } else if (element.isField()) {
- if (element.modifiers.isFinal()) {
- inferrer.recordFinalFieldType(
- node, outermostElement, element, rhsType);
- } else {
- locals.updateField(element, rhsType);
- if (visitingInitializers) {
- inferrer.recordNonFinalFieldElementType(node, element, rhsType);
- } else {
- handleDynamicSend(node, setterSelector, receiverType, arguments);
- }
- }
- } else if (Elements.isLocal(element)) {
- locals.update(element, rhsType);
- }
-
- if (!Elements.isLocal(element)) {
- // Recognize a constraint of the form [: field = other.field :].
- // Note that we check if the right hand side is a local to
- // recognize the situation [: var a = 42; this.a = a; :]. Our
- // constraint mechanism only works with members or top level
- // elements.
- var rhs = node.arguments.head;
- if (rhs.asSend() != null
- && rhs.isPropertyAccess
- && !Elements.isLocal(elements[rhs])
- && rhs.selector.source == node.selector.asIdentifier().source) {
- // TODO(ngeoffray): We should update selectors in the
- // element tree and find out if the typed selector still
- // applies to the receiver type.
- Selector constraint = elements.getSelector(rhs);
- inferrer.recordSetterConstraint(node, constraint);
- }
- }
- return rhsType;
+ return handlePlainAssignment(
+ node, element, setterSelector, receiverType, rhsType,
+ node.arguments.head);
} else {
// [: foo++ :] or [: foo += 1 :].
TypeMask getterType;
@@ -1622,6 +1586,55 @@ class SimpleTypeInferrerVisitor extends ResolvedVisitor<TypeMask> {
}
}
+ TypeMask handlePlainAssignment(Send node,
+ Element element,
+ Selector setterSelector,
+ TypeMask receiverType,
+ TypeMask rhsType,
+ Node rhs) {
+ ArgumentsTypes arguments = new ArgumentsTypes([rhsType], null);
+ if (Elements.isStaticOrTopLevelField(element)) {
+ handleStaticSend(node, setterSelector, element, arguments);
+ } else if (Elements.isUnresolved(element) || element.isSetter()) {
+ handleDynamicSend(node, setterSelector, receiverType, arguments);
+ } else if (element.isField()) {
+ if (element.modifiers.isFinal()) {
+ inferrer.recordFinalFieldType(
+ node, outermostElement, element, rhsType);
+ } else {
+ locals.updateField(element, rhsType);
+ if (visitingInitializers) {
+ inferrer.recordNonFinalFieldElementType(node, element, rhsType);
+ } else {
+ handleDynamicSend(node, setterSelector, receiverType, arguments);
+ }
+ }
+ } else if (Elements.isLocal(element)) {
+ locals.update(element, rhsType);
+ }
+
+ if (!Elements.isLocal(element)) {
+ // Recognize a constraint of the form [: field = other.field :].
+ // Note that we check if the right hand side is a local to
+ // recognize the situation [: var a = 42; this.a = a; :]. Our
+ // constraint mechanism only works with members or top level
+ // elements.
+ Send send = rhs.asSend();
+ if (send != null
+ && send.isPropertyAccess
+ && !Elements.isLocal(elements[rhs])
+ && send.selector.asIdentifier().source
+ == node.selector.asIdentifier().source) {
+ // TODO(ngeoffray): We should update selectors in the
+ // element tree and find out if the typed selector still
+ // applies to the receiver type.
+ Selector constraint = elements.getSelector(rhs);
+ inferrer.recordSetterConstraint(node, constraint);
+ }
+ }
+ return rhsType;
+ }
+
TypeMask visitIdentifier(Identifier node) {
if (node.isThis()) {
return thisType;
@@ -2006,24 +2019,24 @@ class SimpleTypeInferrerVisitor extends ResolvedVisitor<TypeMask> {
bool changed = false;
visit(node.expression);
if (!isThisExposed && node.expression.isThis()) {
- Selector iteratorSelector = elements.getIteratorSelector(node);
+ Selector iteratorSelector = compiler.iteratorSelector;
checkIfExposesThis(new TypedSelector(thisType, iteratorSelector));
TypeMask iteratorType = inferrer.typeOfSelector(iteratorSelector);
checkIfExposesThis(
- new TypedSelector(iteratorType, elements.getMoveNextSelector(node)));
+ new TypedSelector(iteratorType, compiler.moveNextSelector));
checkIfExposesThis(
- new TypedSelector(iteratorType, elements.getCurrentSelector(node)));
+ new TypedSelector(iteratorType, compiler.currentSelector));
}
- Element variable;
- if (node.declaredIdentifier.asSend() != null) {
- variable = elements[node.declaredIdentifier];
+ Element variable = elements[node.declaredIdentifier];
+ Selector selector = elements.getSelector(node.declaredIdentifier);
+ if (!Elements.isUnresolved(variable)) {
+ locals.update(variable, inferrer.dynamicType);
} else {
- assert(node.declaredIdentifier.asVariableDefinitions() != null);
- VariableDefinitions variableDefinitions = node.declaredIdentifier;
- variable = elements[variableDefinitions.definitions.nodes.head];
+ handlePlainAssignment(new Send(), variable, selector,
+ inferrer.dynamicType, inferrer.dynamicType,
+ node.expression);
}
- locals.update(variable, inferrer.dynamicType);
loopLevel++;
do {
LocalsHandler saved = new LocalsHandler.from(locals);

Powered by Google App Engine
This is Rietveld 408576698