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

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

Issue 61163005: Fix a bug in the type inferrer. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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 | sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart
===================================================================
--- sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart (revision 30389)
+++ sdk/lib/_internal/compiler/implementation/inferrer/simple_types_inferrer.dart (working copy)
@@ -135,6 +135,7 @@
final Compiler compiler;
final V types;
final Map<Node, T> concreteTypes = new Map<Node, T>();
+ final Set<Element> generativeConstructorsExposingThis = new Set<Element>();
InferrerEngine(this.compiler, this.types);
@@ -372,6 +373,20 @@
&& element.getEnclosingClass().isNative()
&& element.isField();
}
+
+ void analyze(Element element);
+
+ bool checkIfExposesThis(Element element) {
+ element = element.implementation;
+ return generativeConstructorsExposingThis.contains(element);
+ }
+
+ void recordExposesThis(Element element, bool exposesThis) {
+ element = element.implementation;
+ if (exposesThis) {
+ generativeConstructorsExposingThis.add(element);
+ }
+ }
}
class SimpleTypeInferrerVisitor<T>
@@ -404,6 +419,11 @@
element, outermostElement, inferrer, compiler, handler);
}
+ void analyzeSuperConstructorCall(Element target) {
+ inferrer.analyze(target);
+ isThisExposed = isThisExposed || inferrer.checkIfExposesThis(target);
+ }
+
T run() {
var node = analyzedElement.parseNode(compiler);
if (analyzedElement.isField() && node.asSendSet() == null) {
@@ -469,7 +489,6 @@
visitingInitializers = true;
visit(node.initializers);
visitingInitializers = false;
- visit(node.body);
// For a generative constructor like: `Foo();`, we synthesize
// a call to the default super constructor (the one that takes
// no argument). Resolution ensures that such a constructor
@@ -480,8 +499,11 @@
Selector selector =
new Selector.callDefaultConstructor(analyzedElement.getLibrary());
FunctionElement target = cls.superclass.lookupConstructor(selector);
+ analyzeSuperConstructorCall(target);
synthesizeForwardingCall(analyzedElement, target);
}
+ visit(node.body);
+ inferrer.recordExposesThis(analyzedElement, isThisExposed);
}
if (!isConstructorRedirect) {
// Iterate over all instance fields, and give a null type to
@@ -584,13 +606,18 @@
bool isThisOrSuper(Node node) => node.isThis() || node.isSuper();
+ bool isInClassOrSubclass(Element element) {
+ ClassElement cls = outermostElement.getEnclosingClass();
+ ClassElement enclosing = element.getEnclosingClass();
+ return (enclosing == cls) || compiler.world.isSubclass(cls, enclosing);
+ }
+
void checkIfExposesThis(Selector selector) {
if (isThisExposed) return;
inferrer.forEachElementMatching(selector, (element) {
if (element.isField()) {
if (!selector.isSetter()
- && element.getEnclosingClass() ==
- outermostElement.getEnclosingClass()
+ && isInClassOrSubclass(element)
&& !element.modifiers.isFinal()
&& locals.fieldScope.readField(element) == null
&& element.parseNode(compiler).asSendSet() == null) {
@@ -798,10 +825,11 @@
}
T visitSuperSend(Send node) {
+ Element element = elements[node];
if (visitingInitializers) {
seenSuperConstructorCall = true;
+ analyzeSuperConstructorCall(element);
}
- Element element = elements[node];
Selector selector = elements.getSelector(node);
// TODO(ngeoffray): We could do better here if we knew what we
// are calling does not expose this.
@@ -846,14 +874,15 @@
}
T visitStaticSend(Send node) {
+ Element element = elements[node];
if (visitingInitializers) {
if (Initializers.isConstructorRedirect(node)) {
isConstructorRedirect = true;
} else if (Initializers.isSuperConstructorCall(node)) {
seenSuperConstructorCall = true;
+ analyzeSuperConstructorCall(element);
}
}
- Element element = elements[node];
if (element.isForeign(compiler)) {
return handleForeignSend(node);
}
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/inferrer/type_graph_inferrer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698