Check for exposed local classes (or objects) in type signatures

This commit is contained in:
Dmitry Petrov
2015-10-09 09:47:10 +03:00
parent cbf4e4a973
commit 7e51fb8521
22 changed files with 364 additions and 47 deletions
@@ -1,6 +1,6 @@
package p
class C(val y: Int) {
private class C(val y: Int) {
val initChild = { ->
object {
override fun toString(): String {
@@ -1,6 +1,7 @@
class One {
private class One {
val a1 = arrayOf(
object { val fy = "text"}
)}
)
}
fun box() = if (One().a1[0].fy == "text") "OK" else "fail"
@@ -16,13 +16,13 @@ class Foo {
privateProperty.f2()
}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected val protectedProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>protectedProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val internalProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>internalProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val internal2Property<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>internal2Property<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val publicProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>publicProperty<!><!> = object : MyClass(), MyTrait {}
private fun privateFunction() = object : MyClass(), MyTrait {}
@@ -32,13 +32,13 @@ class Foo {
privateFunction().f2()
}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected fun protectedFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>protectedFunction<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun internalFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>internalFunction<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun internal2Function()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>internal2Function<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun publicFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>publicFunction<!>()<!> = object : MyClass(), MyTrait {}
@@ -50,13 +50,13 @@ class Foo {
privatePropertyInner.f2()
}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected val protectedProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>protectedProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val internalProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>internalProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val internal2Property<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>internal2Property<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val publicProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>publicProperty<!><!> = object : MyClass(), MyTrait {}
private fun privateFunctionInner() = object : MyClass(), MyTrait {}
@@ -66,13 +66,13 @@ class Foo {
privateFunctionInner().f2()
}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected fun protectedFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>protected fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>protectedFunction<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun internalFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>internalFunction<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun internal2Function()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>internal2Function<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun publicFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>publicFunction<!>()<!> = object : MyClass(), MyTrait {}
}
@@ -90,21 +90,21 @@ class Foo {
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>private val packagePrivateProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!><!WRONG_MODIFIER_TARGET!>protected<!> val packageProtectedProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!><!WRONG_MODIFIER_TARGET!>protected<!> val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>packageProtectedProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val packageInternalProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>packageInternalProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val packageInternal2Property<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>packageInternal2Property<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val packagePublicProperty<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>packagePublicProperty<!><!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!><!WRONG_MODIFIER_TARGET!>protected<!> fun packageProtectedFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!><!WRONG_MODIFIER_TARGET!>protected<!> fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>packageProtectedFunction<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun packageInternalFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>packageInternalFunction<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun packageInternal2Function()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>internal fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>packageInternal2Function<!>()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun packagePublicFunction()<!> = object : MyClass(), MyTrait {}
<!AMBIGUOUS_ANONYMOUS_TYPE_INFERRED!>public fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>packagePublicFunction<!>()<!> = object : MyClass(), MyTrait {}
fun fooPackage() {
val packageLocalVar = object : MyClass(), MyTrait {}
+6 -6
View File
@@ -2,21 +2,21 @@ fun <T> run(f: () -> T): T {
return f()
}
// valid, A here is effectively Any
fun foo() = run {
// invalid, depends on local class
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>foo<!>() = run {
class A
A()
}
// valid, B here is also effectively Any
fun gav() = {
// invalid, depends on local class
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>gav<!>() = {
class B
B()
}
abstract class My
// valid, object literal here is also effectively Any
// valid, object literal here is effectively My
fun bar() = run {
object: My() {}
}
}
@@ -0,0 +1,64 @@
fun <T> run(f: () -> T): T {
return f()
}
class My<T>(val value: T)
open class Base
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid1<!>() = run {
class Local
My(Local())
}
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid2<!>() = My(object {})
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid3<!>() = My(object : Base() {})
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid4<!>() = run {
class Local
My(My(Local()))
}
fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid5<!>() = run {
fun invalid5a() = run {
class Local
Local()
}
My(invalid5a())
}
// Valid: effectively Any
fun valid1() = object {}
// Valid: effectively Base
fun valid2() = object : Base() {}
// Valid: explicit type argument
fun valid3() = My<Base>(object : Base() {})
// Valid: explicit type specified
fun valid4() : My<Base> = My(object : Base() {})
// Valid: local class denotable in local scope
fun valid5() = run {
class Local
fun valid5a() = My(Local())
My<Any>(valid5a())
}
// Valid: local class denotable in local scope
fun valid6() = run {
class Local
fun valid6a() = run {
fun valid6b() = My(Local())
valid6b()
}
My<Any>(valid6a())
}
// Valid: effectively My<Any>
fun valid7() = run {
class Local
My<My<*>>(My(Local()))
}
@@ -0,0 +1,30 @@
package
public fun invalid1(): My<invalid1.<anonymous>.Local>
public fun invalid2(): My<invalid2.<no name provided>>
public fun invalid3(): My<invalid3.<no name provided>>
public fun invalid4(): My<My<invalid4.<anonymous>.Local>>
public fun invalid5(): My<invalid5.<anonymous>.invalid5a.<anonymous>.Local>
public fun </*0*/ T> run(/*0*/ f: () -> T): T
public fun valid1(): kotlin.Any
public fun valid2(): Base
public fun valid3(): My<Base>
public fun valid4(): My<Base>
public fun valid5(): My<kotlin.Any>
public fun valid6(): My<kotlin.Any>
public fun valid7(): My<My<*>>
public open class Base {
public constructor Base()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class My</*0*/ T> {
public constructor My</*0*/ T>(/*0*/ value: T)
public final val value: T
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,24 @@
fun <T> run(f: () -> T): T = f()
class Something {
public val publicVal1 = object { override fun toString() = "!" }
protected val protectedVal1 = object { override fun toString() = "!" }
internal val internalVal1 = object { override fun toString() = "!" }
private val privateVal1 = object { override fun toString() = "!" }
public val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>publicVal2<!> = run { class A; A() }
protected val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>protectedVal2<!> = run { class A; A() }
internal val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>internalVal2<!> = run { class A; A() }
private val privateVal2 = run { class A; A() }
public fun publicFun1() = object { override fun toString() = "!" }
protected fun protectedFun1() = object { override fun toString() = "!" }
internal fun internalFun1() = object { override fun toString() = "!" }
private fun privateFun1() = object { override fun toString() = "!" }
public fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>publicFun2<!>() = run { class A; A() }
protected fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>protectedFun2<!>() = run { class A; A() }
internal fun <!FUNCTION_RETURN_TYPE_DEPENDS_ON_LOCAL_CLASS!>internalFun2<!>() = run { class A; A() }
private fun privateFun2() = run { class A; A() }
}
@@ -0,0 +1,26 @@
package
public fun </*0*/ T> run(/*0*/ f: () -> T): T
public final class Something {
public constructor Something()
internal final val internalVal1: kotlin.Any
internal final val internalVal2: Something.internalVal2.<anonymous>.A
private final val privateVal1: Something.privateVal1.<no name provided>
private final val privateVal2: Something.privateVal2.<anonymous>.A
protected final val protectedVal1: kotlin.Any
protected final val protectedVal2: Something.protectedVal2.<anonymous>.A
public final val publicVal1: kotlin.Any
public final val publicVal2: Something.publicVal2.<anonymous>.A
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
internal final fun internalFun1(): kotlin.Any
internal final fun internalFun2(): Something.internalFun2.<anonymous>.A
private final fun privateFun1(): Something.privateFun1.<no name provided>
private final fun privateFun2(): Something.privateFun2.<anonymous>.A
protected final fun protectedFun1(): kotlin.Any
protected final fun protectedFun2(): Something.protectedFun2.<anonymous>.A
public final fun publicFun1(): kotlin.Any
public final fun publicFun2(): Something.publicFun2.<anonymous>.A
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,64 @@
fun <T> run(f: () -> T): T {
return f()
}
class My<T>(val value: T)
open class Base
val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid1<!> = run {
class Local
My(Local())
}
val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid2<!> = My(object {})
val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid3<!> = My(object : Base() {})
val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid4<!> = run {
class Local
My(My(Local()))
}
val <!PROPERTY_TYPE_DEPENDS_ON_LOCAL_CLASS!>invalid5<!> = run {
fun invalid5a() = run {
class Local
Local()
}
My(invalid5a())
}
// Valid: effectively Any
val valid1 = object {}
// Valid: effectively Base
val valid2 = object : Base() {}
// Valid: explicit type argument
val valid3 = My<Base>(object : Base() {})
// Valid: explicit type specified
val valid4 : My<Base> = My(object : Base() {})
// Valid: local class denotable in local scope
val valid5 = run {
class Local
fun valid5a() = My(Local())
My<Any>(valid5a())
}
// Valid: local class denotable in local scope
val valid6 = run {
class Local
fun valid6a() = run {
fun valid6b() = My(Local())
valid6b()
}
My<Any>(valid6a())
}
// Valid: effectively My<Any>
val valid7 = run {
class Local
My<My<*>>(My(Local()))
}
@@ -0,0 +1,30 @@
package
public val invalid1: My<invalid1.<anonymous>.Local>
public val invalid2: My<invalid2.<no name provided>>
public val invalid3: My<invalid3.<no name provided>>
public val invalid4: My<My<invalid4.<anonymous>.Local>>
public val invalid5: My<invalid5.<anonymous>.invalid5a.<anonymous>.Local>
public val valid1: kotlin.Any
public val valid2: Base
public val valid3: My<Base>
public val valid4: My<Base>
public val valid5: My<kotlin.Any>
public val valid6: My<kotlin.Any>
public val valid7: My<My<*>>
public fun </*0*/ T> run(/*0*/ f: () -> T): T
public open class Base {
public constructor Base()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
public final class My</*0*/ T> {
public constructor My</*0*/ T>(/*0*/ value: T)
public final val value: T
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -6,12 +6,12 @@ fun <T> run(f: () -> T): T {
return f()
}
fun foo(a: Int) = run {
private fun foo(a: Int) = run {
class A
A()
}
fun foo() = run {
private fun foo() = run {
class A
A()
}
@@ -1,8 +1,8 @@
package
package p {
public fun foo(): p.foo.<anonymous>.A
public fun foo(/*0*/ a: kotlin.Int): p.foo.<anonymous>.A
private fun foo(): p.foo.<anonymous>.A
private fun foo(/*0*/ a: kotlin.Int): p.foo.<anonymous>.A
public fun </*0*/ T> run(/*0*/ f: () -> T): T
public fun test(): kotlin.Unit
}
@@ -6,14 +6,14 @@ fun <T> run(f: () -> T): T {
return f()
}
fun foo(a: Int) = run {
private fun foo(a: Int) = run {
object {
inner class A
fun foo() = A()
}.foo()
}
fun foo() = run {
private fun foo() = run {
object {
inner class A
fun foo() = A()
@@ -1,8 +1,8 @@
package
package p {
public fun foo(): p.foo.<anonymous>.<no name provided>.A
public fun foo(/*0*/ a: kotlin.Int): p.foo.<anonymous>.<no name provided>.A
private fun foo(): p.foo.<anonymous>.<no name provided>.A
private fun foo(/*0*/ a: kotlin.Int): p.foo.<anonymous>.<no name provided>.A
public fun </*0*/ T> run(/*0*/ f: () -> T): T
public fun test(): kotlin.Unit
}
@@ -6,14 +6,14 @@ fun <T> run(f: () -> T): T {
return f()
}
fun foo(a: Int) = run {
private fun foo(a: Int) = run {
class A {
inner class B
}
A().B()
}
fun foo() = run {
private fun foo() = run {
class A {
inner class B
}
@@ -1,8 +1,8 @@
package
package p {
public fun foo(): p.foo.<anonymous>.A.B
public fun foo(/*0*/ a: kotlin.Int): p.foo.<anonymous>.A.B
private fun foo(): p.foo.<anonymous>.A.B
private fun foo(/*0*/ a: kotlin.Int): p.foo.<anonymous>.A.B
public fun </*0*/ T> run(/*0*/ f: () -> T): T
public fun test(): kotlin.Unit
}