[KJS FE] Allow using typeOf with non-reified type parameters

#KT-38771 fixed
This commit is contained in:
Zalim Bashorov
2020-07-08 16:20:23 +03:00
parent 9d362875da
commit ca37c6bfe6
15 changed files with 92 additions and 109 deletions
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -16,7 +16,14 @@ fun <X> test() = typeOf<Container<X>>()
fun box(): String {
val type = test<Any>()
val x = type.arguments.single().type!!.classifier as KTypeParameter
assertEquals("kotlin.Any?", x.upperBounds.joinToString())
val expected = className("kotlin", "Any?")
assertEquals(expected, x.upperBounds.joinToString())
return "OK"
}
fun className(qualifier: String, name: String): String {
val isJS = 1 as Any is Double
return if (isJS) name else "$qualifier.$name"
}
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -36,7 +36,12 @@ fun box(): String {
assertEquals(c.x1, c.x2)
assertEquals(c.x1.hashCode(), c.x2.hashCode())
assertNotEquals(c.x1, c.xFun)
if (!isJS) {
assertNotEquals(c.x1, c.xFun)
}
assertNotEquals(c.x1, c.y)
return "OK"
}
val isJS = 1 as Any is Double
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -22,6 +22,10 @@ fun box(): String {
assertEquals(createX<Any>(), createX<Any>())
assertEquals(createX<Any>().hashCode(), createX<Any>().hashCode())
assertNotEquals(createX<Any>(), createOtherX<Any>())
if (!isJS) {
assertNotEquals(createX<Any>(), createOtherX<Any>())
}
return "OK"
}
val isJS = 1 as Any is Double
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -16,7 +16,13 @@ class C<X> {
}
fun box(): String {
assertEquals("test.Container<X>", C<Any>().notNull().toString())
assertEquals("test.Container<X?>", C<Any>().nullable().toString())
val fqn = className("test", "Container")
assertEquals("$fqn<X>", C<Any>().notNull().toString())
assertEquals("$fqn<X?>", C<Any>().nullable().toString())
return "OK"
}
fun className(qualifier: String, name: String): String {
val isJS = 1 as Any is Double
return if (isJS) name else "$qualifier.$name"
}
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -14,7 +14,13 @@ fun <X1> notNull() = typeOf<Container<X1>>()
fun <X2> nullable() = typeOf<Container<X2?>>()
fun box(): String {
assertEquals("test.Container<X1>", notNull<Any>().toString())
assertEquals("test.Container<X2?>", nullable<Any>().toString())
val fqn = className("test", "Container")
assertEquals("$fqn<X1>", notNull<Any>().toString())
assertEquals("$fqn<X2?>", nullable<Any>().toString())
return "OK"
}
fun className(qualifier: String, name: String): String {
val isJS = 1 as Any is Double
return if (isJS) name else "$qualifier.$name"
}
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -14,7 +14,13 @@ val <X1> X1.notNull get() = typeOf<Container<X1>>()
val <X2> X2.nullable get() = typeOf<Container<X2?>>()
fun box(): String {
assertEquals("test.Container<X1>", "".notNull.toString())
assertEquals("test.Container<X2?>", "".nullable.toString())
val fqn = className("test", "Container")
assertEquals("$fqn<X1>", "".notNull.toString())
assertEquals("$fqn<X2?>", "".nullable.toString())
return "OK"
}
fun className(qualifier: String, name: String): String {
val isJS = 1 as Any is Double
return if (isJS) name else "$qualifier.$name"
}
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -25,16 +25,22 @@ fun box(): String {
assertEquals(KVariance.OUT, c.getOut().variance)
assertEquals(false, c.getInv().isReified)
val y = getY<Any, Any>()
assertEquals(false, y.isReified)
val x = y.upperBounds.single().classifier as KTypeParameter
assertEquals(true, x.isReified)
assertEquals(KVariance.INVARIANT, x.variance)
if (!isJS) {
val y = getY<Any, Any>()
assertEquals(false, y.isReified)
val x = y.upperBounds.single().classifier as KTypeParameter
assertEquals(true, x.isReified)
assertEquals(KVariance.INVARIANT, x.variance)
assertEquals("X", x.toString())
}
assertEquals("INV", c.getInv().toString())
assertEquals("in IN", c.getIn().toString())
assertEquals("out OUT", c.getOut().toString())
assertEquals("X", x.toString())
if (!isJS) {
assertEquals("in IN", c.getIn().toString())
assertEquals("out OUT", c.getOut().toString())
}
return "OK"
}
val isJS = 1 as Any is Double
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -1,7 +1,7 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// IGNORE_BACKEND: JS, JS_IR, NATIVE
// IGNORE_BACKEND: JS_IR_ES6
// IGNORE_BACKEND: NATIVE
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME
package test
@@ -16,16 +16,25 @@ fun <X, Y, Z> test() where X : Y?, Y : List<Z>, Z : Set<String>
fun box(): String {
val type = test<MutableList<Set<String>>?, MutableList<Set<String>>, Set<String>>()
assertEquals("test.Container<X>", type.toString())
val containerNmae = className("test", "Container")
assertEquals("$containerNmae<X>", type.toString())
val x = type.arguments.single().type!!.classifier as KTypeParameter
assertEquals("Y?", x.upperBounds.joinToString())
val y = x.upperBounds.single().classifier as KTypeParameter
assertEquals("kotlin.collections.List<Z>", y.upperBounds.joinToString())
val listName = className("kotlin.collections", "List")
assertEquals("$listName<Z>", y.upperBounds.joinToString())
val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter
assertEquals("kotlin.collections.Set<kotlin.String>", z.upperBounds.joinToString())
val setName = className("kotlin.collections", "Set")
val stringName = className("kotlin", "String")
assertEquals("$setName<$stringName>", z.upperBounds.joinToString())
return "OK"
}
fun className(qualifier: String, name: String): String {
val isJS = 1 as Any is Double
return if (isJS) name else "$qualifier.$name"
}
@@ -16,7 +16,7 @@ inline fun <reified T> T.causeBug() {
T::class
Array<T>(1) { x }
// Non-reified type parameters with recursive bounds are not yet supported
// Non-reified type parameters with recursive bounds are not yet supported, see Z from class Something
// typeOf<T>()
}
@@ -1,35 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
// !LANGUAGE: +ProhibitNonReifiedArraysAsReifiedTypeArguments
import kotlin.reflect.typeOf
inline fun <X, reified Y, Z : Y> test1() {
<!UNSUPPORTED!>typeOf<!><<!TYPE_PARAMETER_AS_REIFIED!>X<!>>()
<!UNSUPPORTED!>typeOf<!><List<X>>()
<!UNSUPPORTED!>typeOf<!><<!TYPE_PARAMETER_AS_REIFIED_ARRAY!>Array<X?><!>>()
typeOf<Y>()
<!UNSUPPORTED!>typeOf<!><<!TYPE_PARAMETER_AS_REIFIED!>Z<!>>()
<!UNSUPPORTED!>typeOf<!><List<Z>?>()
<!UNSUPPORTED!>typeOf<!><<!TYPE_PARAMETER_AS_REIFIED_ARRAY!>Array<Z><!>>()
}
class Test2<W> {
fun test2() {
<!UNSUPPORTED!>typeOf<!><<!TYPE_PARAMETER_AS_REIFIED!>W<!>>()
<!UNSUPPORTED!>typeOf<!><List<W?>>()
<!UNSUPPORTED!>typeOf<!><<!TYPE_PARAMETER_AS_REIFIED_ARRAY!>Array<W><!>>()
}
}
inline fun <reified U> f() {
typeOf<U>()
}
fun <T> test3() {
// We don't report anything here because we can't know in frontend how the corresponding type parameter is used in f
f<List<T>>()
}
@@ -1,13 +0,0 @@
package
public inline fun </*0*/ reified U> f(): kotlin.Unit
public inline fun </*0*/ X, /*1*/ reified Y, /*2*/ Z : Y> test1(): kotlin.Unit
public fun </*0*/ T> test3(): kotlin.Unit
public final class Test2</*0*/ W> {
public constructor Test2</*0*/ W>()
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 final fun test2(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1122,10 +1122,5 @@ public class DiagnosticsTestWithJsStdLibGenerated extends AbstractDiagnosticsTes
public void testReflectionApi() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJsStdLib/reflection/reflectionApi.kt");
}
@TestMetadata("typeOfWithNonReifiedParameter.kt")
public void testTypeOfWithNonReifiedParameter() throws Exception {
runTest("compiler/testData/diagnostics/testsWithJsStdLib/reflection/typeOfWithNonReifiedParameter.kt");
}
}
}
@@ -1,17 +1,6 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.resolve
@@ -23,7 +12,6 @@ import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor
import org.jetbrains.kotlin.js.naming.NameSuggestion
import org.jetbrains.kotlin.js.resolve.diagnostics.*
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
import org.jetbrains.kotlin.resolve.calls.checkers.TypeOfChecker
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
import org.jetbrains.kotlin.types.DynamicTypesAllowed
@@ -43,7 +31,6 @@ object JsPlatformConfigurator : PlatformConfiguratorBase(
JsModuleCallChecker,
JsDynamicCallChecker,
JsDefinedExternallyCallChecker,
TypeOfChecker,
),
identifierChecker = JsIdentifierChecker
) {