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

Unified Diff: lib/compiler/implementation/closure.dart

Issue 10913081: Fix resolution of type parameters in static context, and the use of type parameters in closures. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 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
Index: lib/compiler/implementation/closure.dart
===================================================================
--- lib/compiler/implementation/closure.dart (revision 11862)
+++ lib/compiler/implementation/closure.dart (working copy)
@@ -179,7 +179,9 @@
// non-mutated variables.
Set<Element> mutatedVariables;
+ FunctionElement outermostFunctionElement;
FunctionElement currentFunctionElement;
+
// The closureData of the currentFunctionElement.
ClosureClassMap closureData;
@@ -250,16 +252,11 @@
}
void useLocal(Element element) {
- // TODO(floitsch): replace this with a general solution.
- Element functionElement = currentFunctionElement;
- if (functionElement.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
- ConstructorBodyElement body = functionElement;
- functionElement = body.constructor;
- }
// If the element is not declared in the current function and the element
// is not the closure itself we need to mark the element as free variable.
- if (element.enclosingElement != functionElement &&
- element != functionElement) {
+ if (insideClosure &&
floitsch 2012/09/05 13:50:34 As discussed: explain that this is not just an opt
ngeoffray 2012/09/05 15:36:11 Done.
+ element.enclosingElement != currentFunctionElement &&
+ element != currentFunctionElement) {
assert(closureData.freeVariableMapping[element] == null ||
closureData.freeVariableMapping[element] == element);
closureData.freeVariableMapping[element] = element;
@@ -346,6 +343,9 @@
}
visitNewExpression(NewExpression node) {
+ TypeAnnotation annotation = node.send.getTypeAnnotation();
+ DartType type = elements.getType(annotation);
+
bool hasTypeVariable(DartType type) {
if (type is TypeVariableType) {
return true;
@@ -359,14 +359,25 @@
}
return false;
}
- TypeAnnotation annotation = node.send.getTypeAnnotation();
- DartType type = elements.getType(annotation);
- if (hasTypeVariable(type)) {
- // Factories do not use [this] to get the type variables.
- if (closureData.thisElement !== null) {
- useLocal(closureData.thisElement);
+
+ void analyzeTypeVariables(DartType type) {
+ if (type is TypeVariableType) {
+ useLocal(type.element);
+ } else if (type is InterfaceType) {
+ InterfaceType ifcType = type;
+ for (DartType argument in ifcType.arguments) {
+ analyzeTypeVariables(argument);
+ }
}
}
+
+ if (outermostFunctionElement.isInstanceMember()
+ || outermostFunctionElement.isGenerativeConstructor()) {
+ if (hasTypeVariable(type)) useLocal(closureData.thisElement);
+ } else if (outermostFunctionElement.isFactoryConstructor()) {
+ analyzeTypeVariables(type);
+ }
+
node.visitChildren(this);
}
@@ -464,38 +475,31 @@
visitFunctionExpression(FunctionExpression node) {
Element element = elements[node];
- if (element.kind === ElementKind.PARAMETER) {
+ if (element.isParameter()) {
// TODO(ahe): This is a hack. This method should *not* call
// visitChildren.
return node.name.accept(this);
}
- bool isClosure = (closureData !== null);
- if (isClosure) closures.add(node);
-
bool oldInsideClosure = insideClosure;
FunctionElement oldFunctionElement = currentFunctionElement;
ClosureClassMap oldClosureData = closureData;
- insideClosure = isClosure;
- currentFunctionElement = elements[node];
+ insideClosure = outermostFunctionElement != null;
+ currentFunctionElement = element;
if (insideClosure) {
+ closures.add(node);
closureData = globalizeClosure(node, element);
} else {
+ outermostFunctionElement = element;
Element thisElement = null;
// TODO(floitsch): we should not need to look for generative constructors.
// At the moment we store only one ClosureData for both the factory and
// the body.
- if (element.isInstanceMember() ||
- element.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
+ if (element.isInstanceMember() || element.isGenerativeConstructor()) {
// TODO(floitsch): currently all variables are considered to be
floitsch 2012/09/05 13:50:34 Remove the TODO.
ngeoffray 2012/09/05 15:36:11 Done.
// declared in the GENERATIVE_CONSTRUCTOR. Including the 'this'.
- Element thisEnclosingElement = element;
- if (element.kind === ElementKind.GENERATIVE_CONSTRUCTOR_BODY) {
- ConstructorBodyElement body = element;
- thisEnclosingElement = body.constructor;
- }
- thisElement = new ThisElement(thisEnclosingElement);
+ thisElement = new ThisElement(element);
}
closureData = new ClosureClassMap(null, null, null, thisElement);
}
@@ -513,6 +517,15 @@
if (insideClosure) {
declareLocal(element);
}
+
+ if (currentFunctionElement.isFactoryConstructor()) {
+ // Declare the type parameters in the scope. Generative
+ // constructors just use 'this'.
+ ClassElement cls = currentFunctionElement.enclosingElement;
+ cls.typeVariables.forEach((TypeVariableType typeVariable) {
+ declareLocal(typeVariable.element);
+ });
+ }
// TODO(ahe): This is problematic. The backend should not repeat
// the work of the resolver. It is the resolver's job to create
« no previous file with comments | « no previous file | lib/compiler/implementation/elements/elements.dart » ('j') | lib/compiler/implementation/resolver.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698