Commit Graph

15 Commits

Author SHA1 Message Date
Paul Berry 017a1f4eff Revert "Fix forEachOverridePair in the case where the class in question is abstract."
This reverts commit e81deebfd8.

My reasoning in the above commit was wrong.  Consider the following code:

class A {
  void foo() {}
}
abstract class B extends A {
  void foo([x]);
}
class C extends B {}
main() {
  B b = new C();
  b.foo(42); // BAD: A.foo can't accept arguments.
}

To ensure soundness, this code needs to be disallowed, and the current
mechanism for doing that is to use forEachOverridePair.  Note that
forEachOverridePair is a bit of a misnomer; in addition to yielding
all pairs of methods (M1, M2) for which M1 overrides M2, it also
yields pairs of methods (M1, M2) for which the target class inherits
the concrete implementation M1, and M2 is part of the interface.
Technically this latter case is not an "override" but rather an
"implementation" (thanks to Lasse for pointing out this distinction).
However in both cases we need to do the same compile-time check to
ensure soundness: we need to check that the type of M1 is a subtype of
M2 (unless the check is suppressed by a "covariant" keyword).  Hence
it makes sense for forEachOverridePair to cover both cases.

To ensure that the above example is properly rejected, it is crucial
that some invocation of forEachOverridePair yield the pair (A.foo,
B.foo).  Prior to e81deebfd8,
forEachOverridePair(B) would not yield this pair, but
forEachOverridePair(C) would.  After
e81deebfd8, both calls yield this pair.

When I made e81deebfd8, I failed to
notice that forEachOverridePair(C) would yield the pair, so I thought
there was a problem.  So my "fix" was unnecessary.  And it created a
fresh problem: it meant that the following code would be disallowed:

class A {
  void foo() {}
}
abstract class B extends A {
  void foo([x]);
}
class C extends B {
  void foo([x]) {}
}
main() {
  B b = new C();
  b.foo(42); // OK: C.foo can accept an argument.
}

There is no a priori soundness reason for rejecting this code, and
according to Lasse, it has not yet been decided whether Dart 2.0 will
allow it.

This CL restores the old behavior.  Rather than remove the test case
in e81deebfd8, it modifies it to
demonstrate why the old behavior was correct.

R=scheglov@google.com

Review-Url: https://codereview.chromium.org/3004023002 .
2017-08-29 14:46:15 -07:00
Paul Berry e81deebfd8 Fix forEachOverridePair in the case where the class in question is abstract.
ClassHierarchy.forEachOverridePair contains special logic for unusual
cases like this one:

class A {
  void foo() {}
}
class B extends A {
  void foo();
}
main() {
  B b = new B();
  b.foo();
}

In this case, A.foo is considered to override B.foo (contrary to the
usual situation where the derived class method overrides the
superclass method).  The reasoning is that calling foo on a concrete
instance of B will cause A.foo to be executed (as illustrated in
main); therefore A.foo is callable via the interface of B.foo, thus in
a sense A.foo "overrides" B.foo.

The code contained a questionable optimization, however; it only
executed this special logic if the derived class was concrete.
Presuambly the reasoning was that if B were abstract, then a concrete
instance of B could never be created, so this situation could never
arise.

However, there is nothing to stop a concrete class from being derived
from B, e.g.:

class A {
  void foo() {}
}
abstract class B extends A {
  void foo();
}
class C extends B {}
main() {
  B b = new C();
  b.foo();
}

Now, calling foo on a concrete instance of C will cause A.foo to be
executed (as illustrated in main); therefore A.foo is callable via the
interface of B.foo, as before.  So we still need to report this as an
override pair even though B is abstract.

R=ahe@google.com, scheglov@google.com

Review-Url: https://codereview.chromium.org/2998383002 .
2017-08-28 11:48:59 -07:00
Paul Berry 41dcc04a80 Expose getInterfaceMembers method through ClassHierarchy.
The front end will need to use this method to iterate through the
interface of a class in order to determine when to create forwarding
stubs.

The functionality already exists; this CL merely exposes it and adds
tests.

R=scheglov@google.com

Review-Url: https://codereview.chromium.org/3003913002 .
2017-08-25 13:57:01 -07:00
Paul Berry be01632bc0 Fix type inference of getters that "override" setters and vice versa.
Normally getters and setters are considered distinct and unrelated by
the type inference algorithm.  However, if a getter has no declared
type and doesn't override anything, then we fall back on inferring its
type from an inherited setter, and vice versa.

R=sigmund@google.com

Review-Url: https://codereview.chromium.org/2946733003 .
2017-06-20 05:34:31 -07:00
Konstantin Shcheglov bcf179c9fa Add the 'crossGettersSetters' flag to ClassHierarchy.forEachOverridePair().
We need to be able to get 'overrides' of setters with getters and vise
versa to support top-level inference.

R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2941363002 .
2017-06-17 18:32:44 -07:00
Konstantin Shcheglov 5fe793ec4e Use ClassHierarchy.applyChanges() in MixinFullResolution.
So, we let the hierarchy to decide how to react to the changes, and
instance of which class hierarchy to create.

This makes initial compilation with Kernel Driver about 5% faster.

R=ahe@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2924333002 .
2017-06-08 14:00:51 -07:00
Konstantin Shcheglov 8ec1f95af6 Replace ClassHierarchy.classes with getOrderedClasses().
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2924713002 .
2017-06-05 20:23:13 -07:00
Konstantin Shcheglov 64ce51ce4b Fix the test and implement forEachOverridePair() for IncrementalClassHierarchy.
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2920323002 .
2017-06-05 13:11:29 -07:00
Konstantin Shcheglov 5cf61cb0dc Implement getInterfaceMember() for IncrementalClassHierarchy.
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2916383003 .
2017-06-03 18:52:00 -07:00
Konstantin Shcheglov 952687a64f Implement getDispatchTarget() in IncrementalClassHierarchy.
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2916403002 .
2017-06-02 13:58:26 -07:00
Konstantin Shcheglov 99363d42d0 Implement getClassicLeastUpperBound() in IncrementalClassHierarchy.
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2921083002 .
2017-06-02 13:46:58 -07:00
Konstantin Shcheglov c2b5ae00ce Implement getClassAsInstanceOf() and getTypeAsInstanceOf() for IncrementalClassHierarchy.
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2915263003 .
2017-06-02 11:54:47 -07:00
Konstantin Shcheglov 4301ce842a Implement IncrementalClassHierarchy.getRankedSuperclasses().
R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2916323002 .
2017-06-02 09:15:44 -07:00
Konstantin Shcheglov 65c1f5f8ab Start implementing IncrementalClassHierarchy.
Only getClassDepth() for now.

R=ahe@google.com, kmillikin@google.com, paulberry@google.com, sigmund@google.com
BUG=

Review-Url: https://codereview.chromium.org/2922533002 .
2017-06-01 15:01:51 -07:00
Paul Berry 29570728a3 Implement Dart 1.0 LUB algorithm (for interface types) in kernel.
Note: I intend to implement the full LUB algorithm (including strong
mode behaviors) in front_end, however this piece of the algorithm
makes sense to be in kernel so that it can take advantage of
_ClassInfo.

R=ahe@google.com, johnniwinther@google.com

Review-Url: https://codereview.chromium.org/2848083002 .
2017-05-01 11:25:47 -07:00