Prohibit instance access before super call

- Before this change members just left unresolved as they were absent in the
  specific scope named scopeForSecondaryConstructorHeaderResolution that
  created just to prohibit such accesses.
- Now they are resolved the same way as other members, but diagnostic is
  repored by in-place injected CallChecker
- Drop obsolete type of class scope

 #KT-6995 Fixed
This commit is contained in:
Denis Zharkov
2015-03-26 18:02:30 +03:00
parent b939530a5c
commit 418034add3
50 changed files with 690 additions and 162 deletions
@@ -216,6 +216,16 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
ReceiverParameterDescriptor substitutedExpectedThis = null;
if (dispatchReceiverParameter != null) {
// When generating fake-overridden member it's dispatch receiver parameter has type of Base, and it's correct.
// E.g.
// class Base { fun foo() }
// class Derived : Base
// val x: Base
// if (x is Derived) {
// // `x` shouldn't be marked as smart-cast
// // but it would if fake-overridden `foo` had `Derived` as it's dispatch receiver parameter type
// x.foo()
// }
substitutedExpectedThis = dispatchReceiverParameter.substitute(substitutor);
if (substitutedExpectedThis == null) {
return null;
@@ -98,4 +98,29 @@ public fun ClassDescriptor.getSuperClassNotAny(): ClassDescriptor? {
public fun ClassDescriptor.getSuperClassOrAny(): ClassDescriptor = getSuperClassNotAny() ?: KotlinBuiltIns.getInstance().getAny()
public val ClassDescriptor.secondaryConstructors: List<ConstructorDescriptor>
get() = getConstructors().filterNot { it.isPrimary() }
get() = getConstructors().filterNot { it.isPrimary() }
/**
* Returns containing declaration of dispatch receiver for callable adjusted to fake-overridden cases
*
* open class A {
* fun foo() = 1
* }
* class B : A()
*
* for A.foo -> returns A (dispatch receiver parameter is A)
* for B.foo -> returns B (dispatch receiver parameter is still A, but it's fake-overridden in B, so it's containing declaration is B)
*
* class Outer {
* inner class Inner()
* }
*
* for constructor of Outer.Inner -> returns Outer (dispatch receiver parameter is Outer, but it's containing declaration is Inner)
*
*/
public fun CallableDescriptor.getOwnerForEffectiveDispatchReceiverParameter(): DeclarationDescriptor? {
if (this is CallableMemberDescriptor && getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
return getContainingDeclaration()
}
return getDispatchReceiverParameter()?.getContainingDeclaration()
}