rewrite owner when copying FunctionDescriptor from supertype scope

that fixes invocation:

>>> StringBuilder.length()

that was compiled to

>>> invokevirtual CharSequence.length()

and now compiles to

>>> invokevirtual StringBuilder.length()

Essentially patch rewrites FunctionDescriptor.containingDeclaration
when FunctionDescriptor is copied to subclass scope.

FunctionDescriptor now has kind field that can be
* DECLARATION (for "real" function, maybe abstract)
* DELEGATION
* FAKE_OVERRIDE (created for functions from supertypes)

All tests pass although some parts of code are buggy and ugly.

Random comments about this patch:

* FunctionDescriptor.overrides point to function descriptors of supertype scopes

* Filling of memberScope with supertypes is moved to OverrideResolver

* ExpressionCodegen.intermediateValueForProperty must be rewritten

* Patch adds not nice REDECLARATION reports (see compiler/testData/diagnostics/tests/*).
  Will be fixed later.
This commit is contained in:
Stepan Koltsov
2012-02-10 20:36:40 +04:00
parent 41455a56c5
commit 4b94eb5e2b
46 changed files with 814 additions and 325 deletions
+8 -8
View File
@@ -11,7 +11,7 @@ fun f9(a : A?) {
a?.<error descr="Unresolved reference: bar">bar</error>()
if (a is B) {
<info descr="Automatically cast to B">a</info>.bar()
<info descr="Automatically cast to A">a</info>.foo()
<info descr="Automatically cast to B">a</info>.foo()
}
a?.foo()
a?.<error descr="Unresolved reference: bar">bar</error>()
@@ -26,7 +26,7 @@ fun f9(a : A?) {
return;
}
<info descr="Automatically cast to B">a</info>.bar()
<info descr="Automatically cast to A">a</info>.foo()
<info descr="Automatically cast to B">a</info>.foo()
}
fun f10(a : A?) {
@@ -77,7 +77,7 @@ fun f12(a : A?) {
b?.foo()
}
if (a is val b is B) {
<info descr="Automatically cast to A">b</info>.foo()
<info descr="Automatically cast to B">b</info>.foo()
<info descr="Automatically cast to B">a</info>.bar()
<info descr="Automatically cast to B">b</info>.bar()
}
@@ -85,7 +85,7 @@ fun f12(a : A?) {
fun f13(a : A?) {
if (a is val c is B) {
<info descr="Automatically cast to A">c</info>.foo()
<info descr="Automatically cast to B">c</info>.foo()
<info descr="Automatically cast to B">c</info>.bar()
}
else {
@@ -99,13 +99,13 @@ fun f13(a : A?) {
<error descr="Unresolved reference: c">c</error>.bar()
}
else {
<info descr="Automatically cast to A">a</info>.foo()
<info descr="Automatically cast to B">a</info>.foo()
<error descr="Unresolved reference: c">c</error>.bar()
}
a?.foo()
if (a is val c is B && <info descr="Automatically cast to A">a</info>.foo() == #() && <info descr="Automatically cast to B">c</info>.bar() == #()) {
<info descr="Automatically cast to A">c</info>.foo()
if (a is val c is B && <info descr="Automatically cast to B">a</info>.foo() == #() && <info descr="Automatically cast to B">c</info>.bar() == #()) {
<info descr="Automatically cast to B">c</info>.foo()
<info descr="Automatically cast to B">c</info>.bar()
}
else {
@@ -250,4 +250,4 @@ fun foo(var a: Any): Int {
return <error descr="[AUTOCAST_IMPOSSIBLE] Automatic cast to Int is impossible, because a could have changed since the is-check">a</error>
}
return 1
}
}