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

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

Issue 23449018: Fix inferrer bug in the presence of synthesized constructors: we should always notify a call to the… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 3 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 | tests/language/inferrer_synthesized_constructor_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (revision 26984)
+++ sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart (working copy)
@@ -168,7 +168,7 @@
* Assignments on the element and the types inferred at
* these assignments.
*/
- Map<Node, TypeMask> get assignments => null;
+ Map<Spannable, TypeMask> get assignments => null;
/**
* Callers of an element.
@@ -204,7 +204,7 @@
}
}
- void addAssignment(Node node, TypeMask mask) {
+ void addAssignment(Spannable node, TypeMask mask) {
assignments[node] = mask;
}
@@ -223,7 +223,7 @@
}
class ParameterTypeInformation extends TypeInformation {
- Map<Node, TypeMask> assignments = new Map<Node, TypeMask>();
+ Map<Spannable, TypeMask> assignments = new Map<Spannable, TypeMask>();
TypeMask type;
TypeMask defaultType;
@@ -235,7 +235,7 @@
class FieldTypeInformation extends TypeInformation {
TypeMask type;
Map<Element, int> callers = new Map<Element, int>();
- Map<Node, TypeMask> assignments = new Map<Node, TypeMask>();
+ Map<Spannable, TypeMask> assignments = new Map<Spannable, TypeMask>();
int analyzeCount = 0;
void clear() {
@@ -387,7 +387,7 @@
* [constraint] is a field assignment constraint, as described in
* [InternalSimpleTypesInferrer].
*/
- void recordTypeOfNonFinalField(Node node,
+ void recordTypeOfNonFinalField(Spannable node,
Element field,
T type,
CallSite constraint);
@@ -410,7 +410,7 @@
void recordReturnType(Element element, T type);
/**
- * Registers that [caller] calls [callee] at node [node], with
+ * Registers that [caller] calls [callee] at location [node], with
* [selector], and [arguments]. Note that [selector] is null for
* forwarding constructors.
*
@@ -422,7 +422,7 @@
*
* [inLoop] tells whether the call happens in a loop.
*/
- void registerCalledElement(Node node,
+ void registerCalledElement(Spannable node,
Selector selector,
Element caller,
Element callee,
@@ -629,7 +629,7 @@
* returns that type.
*
*/
- Map<Node, CallSite> setterConstraints = new Map<Node, CallSite>();
+ Map<Spannable, CallSite> setterConstraints = new Map<Spannable, CallSite>();
/**
* The work list of the inferrer.
@@ -1187,7 +1187,7 @@
typeInformationOf(callee).addCaller(caller);
}
- bool addArguments(Node node,
+ bool addArguments(Spannable node,
FunctionElement element,
ArgumentsTypes arguments) {
FunctionTypeInformation info = typeInformationOf(element);
@@ -1235,7 +1235,7 @@
ParameterTypeInformation info = typeInformationOf(parameter);
TypeMask elementType;
- info.assignments.forEach((Node node, TypeMask mask) {
+ info.assignments.forEach((Spannable node, TypeMask mask) {
if (mask == null) {
// Now that we know we have analyzed the function holding
// [parameter], we have a default type for that [parameter].
@@ -1262,7 +1262,7 @@
* [arguments]. [constraint] is a setter constraint (see
* [setterConstraints] documentation).
*/
- void registerCalledElement(Node node,
+ void registerCalledElement(Spannable node,
Selector selector,
Element caller,
Element callee,
@@ -1441,7 +1441,7 @@
* Records an assignment to [element] with the given
* [argumentType].
*/
- void recordTypeOfNonFinalField(Node node,
+ void recordTypeOfNonFinalField(Spannable node,
Element element,
TypeMask argumentType,
CallSite constraint) {
@@ -1463,7 +1463,7 @@
Map<Node, TypeMask> assignments) {
List<CallSite> constraints = <CallSite>[];
TypeMask elementType;
- assignments.forEach((Node node, TypeMask mask) {
+ assignments.forEach((Spannable node, TypeMask mask) {
CallSite constraint = setterConstraints[node];
if (constraint != null) {
// If this update has a constraint, we collect it and don't
@@ -1678,14 +1678,12 @@
parameterType,
null);
}
- } else {
- locals.update(element, parameterType, node);
}
+ locals.update(element, parameterType, node);
});
if (analyzedElement.isSynthesized) {
- // Use the enclosing class of the synthesized constructor as
- // the location for the initialized fields.
- node = analyzedElement.enclosingElement.parseNode(compiler);
+ node = analyzedElement;
+ synthesizeForwardingCall(node, analyzedElement.targetConstructor);
} else {
visitingInitializers = true;
visit(node.initializers);
@@ -2240,40 +2238,45 @@
returnType = inferrer.addReturnTypeFor(analyzedElement, returnType, type);
}
+ void synthesizeForwardingCall(Spannable node, FunctionElement element) {
+ element = element.implementation;
+ FunctionElement function = analyzedElement;
+ FunctionSignature signature = function.computeSignature(compiler);
+ List<T> unnamed = <T>[];
+ Map<SourceString, T> named = new Map<SourceString, T>();
+ signature.forEachRequiredParameter((Element element) {
+ assert(locals.use(element) != null);
+ unnamed.add(locals.use(element));
+ });
+ signature.forEachOptionalParameter((Element element) {
+ if (signature.optionalParametersAreNamed) {
+ named[element.name] = locals.use(element);
+ } else {
+ unnamed.add(locals.use(element));
+ }
+ });
+ ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
+ inferrer.registerCalledElement(node,
+ null,
+ outermostElement,
+ element,
+ arguments,
+ null,
+ sideEffects,
+ inLoop);
+ }
+
T visitReturn(Return node) {
if (node.isRedirectingFactoryBody) {
Element element = elements[node.expression];
if (Elements.isErroneousElement(element)) {
recordReturnType(types.dynamicType);
} else {
- element = element.implementation;
// We don't create a selector for redirecting factories, and
// the send is just a property access. Therefore we must
// manually create the [ArgumentsTypes] of the call, and
// manually register [analyzedElement] as a caller of [element].
- FunctionElement function = analyzedElement;
- FunctionSignature signature = function.computeSignature(compiler);
- List<T> unnamed = <T>[];
- Map<SourceString, T> named = new Map<SourceString, T>();
- signature.forEachRequiredParameter((Element element) {
- unnamed.add(locals.use(element));
- });
- signature.forEachOptionalParameter((Element element) {
- if (signature.optionalParametersAreNamed) {
- named[element.name] = locals.use(element);
- } else {
- unnamed.add(locals.use(element));
- }
- });
- ArgumentsTypes arguments = new ArgumentsTypes<T>(unnamed, named);
- inferrer.registerCalledElement(node.expression,
- null,
- outermostElement,
- element,
- arguments,
- null,
- sideEffects,
- inLoop);
+ synthesizeForwardingCall(node.expression, element);
recordReturnType(inferrer.returnTypeOfElement(element));
}
} else {
« no previous file with comments | « no previous file | tests/language/inferrer_synthesized_constructor_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698