Index: pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
index e838943550a6319efe237a815a38853abbd3a4e2..48ae18195156335845eff5ffd7dc13d47e171ce7 100644 |
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart |
@@ -349,14 +349,18 @@ abstract class ElementTypeInformation extends TypeInformation { |
bool disableInferenceForClosures = true; |
factory ElementTypeInformation(Element element, TypeSystem types) { |
- if (element.isRegularParameter || element.isInitializingFormal) { |
+ if (element.isParameter) { |
ParameterElement parameter = element; |
- if (parameter.functionDeclaration.isInstanceMember) { |
+ if (parameter.functionDeclaration.isLocal) { |
+ return new ParameterTypeInformation._localFunction(element, types); |
+ } else if (parameter.functionDeclaration.isInstanceMember) { |
return new ParameterTypeInformation._instanceMember(element, types); |
} |
- return new ParameterTypeInformation._internal(element, types); |
+ return new ParameterTypeInformation._static(element, types); |
+ } else if (element.isLocal) { |
+ return new MemberTypeInformation._localFunction(element); |
} |
- return new MemberTypeInformation._internal(element); |
+ return new MemberTypeInformation._member(element); |
} |
ElementTypeInformation._internal(MemberTypeInformation context, this.element) |
@@ -406,6 +410,12 @@ class MemberTypeInformation extends ElementTypeInformation |
MemberTypeInformation._internal(Element element) |
: super._internal(null, element); |
+ MemberTypeInformation._member(MemberElement element) |
+ : this._internal(element); |
+ |
+ MemberTypeInformation._localFunction(LocalFunctionElement element) |
+ : this._internal(element); |
+ |
void addCall(Element caller, Spannable node) { |
assert(node is ast.Node || node is Element); |
_callers ??= <Element, Setlet<Spannable>>{}; |
@@ -587,16 +597,30 @@ class ParameterTypeInformation extends ElementTypeInformation { |
ParameterElement get element => super.element; |
FunctionElement get declaration => element.functionDeclaration; |
- ParameterTypeInformation._internal(ParameterElement element, TypeSystem types) |
- : super._internal( |
- types.getInferredTypeOf(element.functionDeclaration), element) { |
+ ParameterTypeInformation._internal( |
+ MemberTypeInformation context, ParameterElement parameter) |
+ : super._internal(context, parameter); |
+ |
+ factory ParameterTypeInformation._static( |
+ ParameterElement element, TypeSystem types) { |
assert(!element.functionDeclaration.isInstanceMember); |
+ MethodElement method = element.functionDeclaration; |
+ return new ParameterTypeInformation._internal( |
+ types.getInferredTypeOfMember(method), element); |
+ } |
+ |
+ factory ParameterTypeInformation._localFunction( |
+ ParameterElement element, TypeSystem types) { |
+ LocalFunctionElement localFunction = element.functionDeclaration; |
+ return new ParameterTypeInformation._internal( |
+ types.getInferredTypeOfLocalFunction(localFunction), element); |
} |
ParameterTypeInformation._instanceMember( |
ParameterElement element, TypeSystem types) |
: super._withAssignments( |
- types.getInferredTypeOf(element.functionDeclaration), |
+ types.getInferredTypeOfMember( |
+ element.functionDeclaration as MethodElement), |
element, |
new ParameterAssignments()) { |
assert(element.functionDeclaration.isInstanceMember); |
@@ -750,8 +774,12 @@ class StaticCallSiteTypeInformation extends CallSiteTypeInformation { |
: super(context, call, enclosing, selector, mask, arguments, inLoop); |
void addToGraph(InferrerEngine inferrer) { |
- MemberTypeInformation callee = |
- inferrer.types.getInferredTypeOf(calledElement); |
+ MemberTypeInformation callee; |
+ if (calledElement.isLocal) { |
+ callee = inferrer.types.getInferredTypeOfLocalFunction(calledElement); |
+ } else { |
+ callee = inferrer.types.getInferredTypeOfMember(calledElement); |
+ } |
callee.addCall(caller, call); |
callee.addUser(this); |
if (arguments != null) { |
@@ -773,9 +801,21 @@ class StaticCallSiteTypeInformation extends CallSiteTypeInformation { |
TypeMask computeType(InferrerEngine inferrer) { |
if (isSynthesized) { |
assert(arguments != null); |
- return inferrer.types.getInferredTypeOf(calledElement).type; |
+ if (calledElement.isLocal) { |
+ return inferrer.types |
+ .getInferredTypeOfLocalFunction(calledElement) |
+ .type; |
+ } else { |
+ return inferrer.types.getInferredTypeOfMember(calledElement).type; |
+ } |
} else { |
- return inferrer.typeOfElementWithSelector(calledElement, selector).type; |
+ if (calledElement.isLocal) { |
+ return inferrer |
+ .typeOfLocalFunctionWithSelector(calledElement, selector) |
+ .type; |
+ } else { |
+ return inferrer.typeOfMemberWithSelector(calledElement, selector).type; |
+ } |
} |
} |
@@ -786,14 +826,25 @@ class StaticCallSiteTypeInformation extends CallSiteTypeInformation { |
} |
bool hasStableType(InferrerEngine inferrer) { |
- return inferrer.types.getInferredTypeOf(calledElement).isStable && |
+ bool isStable; |
+ if (calledElement.isLocal) { |
+ isStable = |
+ inferrer.types.getInferredTypeOfLocalFunction(calledElement).isStable; |
+ } else { |
+ isStable = inferrer.types.getInferredTypeOfMember(calledElement).isStable; |
+ } |
+ return isStable && |
(arguments == null || arguments.every((info) => info.isStable)) && |
super.hasStableType(inferrer); |
} |
void removeAndClearReferences(InferrerEngine inferrer) { |
- ElementTypeInformation callee = |
- inferrer.types.getInferredTypeOf(calledElement); |
+ ElementTypeInformation callee; |
+ if (calledElement.isLocal) { |
+ callee = inferrer.types.getInferredTypeOfLocalFunction(calledElement); |
+ } else { |
+ callee = inferrer.types.getInferredTypeOfMember(calledElement); |
+ } |
callee.removeUser(this); |
if (arguments != null) { |
arguments.forEach((info) => info.removeUser(this)); |
@@ -828,7 +879,8 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
arguments.forEach((info) => info.addUser(this)); |
} |
for (MemberElement element in targets) { |
- MemberTypeInformation callee = inferrer.types.getInferredTypeOf(element); |
+ MemberTypeInformation callee = |
+ inferrer.types.getInferredTypeOfMember(element); |
callee.addCall(caller, call); |
callee.addUser(this); |
inferrer.updateParameterAssignments( |
@@ -1000,7 +1052,7 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
.forEach((MemberEntity _element) { |
MemberElement element = _element; |
MemberTypeInformation callee = |
- inferrer.types.getInferredTypeOf(element); |
+ inferrer.types.getInferredTypeOfMember(element); |
callee.addCall(caller, call); |
callee.addUser(this); |
inferrer.updateParameterAssignments( |
@@ -1014,7 +1066,7 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
.forEach((MemberEntity _element) { |
MemberElement element = _element; |
MemberTypeInformation callee = |
- inferrer.types.getInferredTypeOf(element); |
+ inferrer.types.getInferredTypeOfMember(element); |
callee.removeCall(caller, call); |
callee.removeUser(this); |
inferrer.updateParameterAssignments( |
@@ -1069,7 +1121,7 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
TypeInformation info = |
handleIntrisifiedSelector(selector, typeMask, inferrer); |
if (info != null) return info.type; |
- return inferrer.typeOfElementWithSelector(element, selector).type; |
+ return inferrer.typeOfMemberWithSelector(element, selector).type; |
} |
})); |
@@ -1091,7 +1143,7 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
for (MemberElement element in targets) { |
if (!oldTargets.contains(element)) { |
MemberTypeInformation callee = |
- inferrer.types.getInferredTypeOf(element); |
+ inferrer.types.getInferredTypeOfMember(element); |
callee.addCall(caller, call); |
inferrer.updateParameterAssignments( |
this, element, arguments, selector, mask, |
@@ -1104,7 +1156,8 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
void removeAndClearReferences(InferrerEngine inferrer) { |
for (MemberElement element in targets) { |
- ElementTypeInformation callee = inferrer.types.getInferredTypeOf(element); |
+ ElementTypeInformation callee = |
+ inferrer.types.getInferredTypeOfMember(element); |
callee.removeUser(this); |
} |
if (arguments != null) { |
@@ -1123,7 +1176,7 @@ class DynamicCallSiteTypeInformation extends CallSiteTypeInformation { |
return receiver.isStable && |
targets.every((_element) { |
MemberElement element = _element; |
- return inferrer.types.getInferredTypeOf(element).isStable; |
+ return inferrer.types.getInferredTypeOfMember(element).isStable; |
}) && |
(arguments == null || arguments.every((info) => info.isStable)) && |
super.hasStableType(inferrer); |