| 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 {
|
|
|