Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Map.getOrDefault method as PlatformDependent declaration with ref…
…ined signature - First parameter should have type of K instead of Any - Special bridge should return second parameter if a key has wrong type - Special bridge may throw an exception if defaultValue has wrong type #KT-13209 Fixed
- Loading branch information
Showing
15 changed files
with
353 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
compiler/testData/codegen/java8/box/mapGetOrDefault/noTypeSafeBridge.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// FULL_JDK | ||
// WITH_RUNTIME | ||
|
||
class A : MutableMap<Any, Any?> { | ||
override val entries: MutableSet<MutableMap.MutableEntry<Any, Any?>> | ||
get() = throw UnsupportedOperationException() | ||
override val keys: MutableSet<Any> | ||
get() = throw UnsupportedOperationException() | ||
override val values: MutableCollection<Any?> | ||
get() = throw UnsupportedOperationException() | ||
|
||
override fun clear() { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun put(key: Any, value: Any?): Any? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun putAll(from: Map<out Any, Any?>) { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun remove(key: Any): Any? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override val size: Int | ||
get() = throw UnsupportedOperationException() | ||
|
||
override fun containsKey(key: Any): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun containsValue(value: Any?): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun get(key: Any): Any? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun isEmpty(): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun getOrDefault(key: Any, defaultValue: Any?): Any? { | ||
if (key == "abc") return "cde" | ||
return defaultValue | ||
} | ||
} | ||
|
||
fun box(): String { | ||
val a = A() | ||
if (a.getOrDefault("abc", "xyz") != "cde") return "fail 1" | ||
if (a.getOrDefault("56", "123") != "123") return "fail 2" | ||
|
||
val mm = a as MutableMap<Any?, Any?> | ||
if (mm.getOrDefault("abc", "xyz") != "cde") return "fail 3" | ||
if (mm.getOrDefault("56", 123) != 123) return "fail 4" | ||
if (mm.getOrDefault(1, "456") != "456") return "fail 5" | ||
if (mm.getOrDefault(null, "qwe") != "qwe") return "fail 6" | ||
if (mm.getOrDefault("abc", null) != "cde") return "fail 7" | ||
|
||
return "OK" | ||
} |
74 changes: 74 additions & 0 deletions
74
compiler/testData/codegen/java8/box/mapGetOrDefault/typeSafeBridge.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// FULL_JDK | ||
// WITH_RUNTIME | ||
|
||
class A : MutableMap<String, String> { | ||
override val entries: MutableSet<MutableMap.MutableEntry<String, String>> | ||
get() = throw UnsupportedOperationException() | ||
override val keys: MutableSet<String> | ||
get() = throw UnsupportedOperationException() | ||
override val values: MutableCollection<String> | ||
get() = throw UnsupportedOperationException() | ||
|
||
override fun clear() { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun put(key: String, value: String): String? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun putAll(from: Map<out String, String>) { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun remove(key: String): String? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override val size: Int | ||
get() = throw UnsupportedOperationException() | ||
|
||
override fun containsKey(key: String): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun containsValue(value: String): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun get(key: String): String? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun isEmpty(): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun getOrDefault(key: String, defaultValue: String): String { | ||
if (key == "abc") return "cde" | ||
return defaultValue | ||
} | ||
} | ||
|
||
fun box(): String { | ||
val a = A() | ||
if (a.getOrDefault("abc", "xyz") != "cde") return "fail 1" | ||
if (a.getOrDefault("56", "123") != "123") return "fail 2" | ||
|
||
val mm = a as MutableMap<Any?, Any?> | ||
if (mm.getOrDefault("abc", "xyz") != "cde") return "fail 3" | ||
if (mm.getOrDefault("56", "123") != "123") return "fail 4" | ||
if (mm.getOrDefault(1, "456") != "456") return "fail 5" | ||
if (mm.getOrDefault(null, "qwe") != "qwe") return "fail 6" | ||
|
||
try { | ||
// This is a known problem, there's no way to implement type-safe bridge/barrier properly: | ||
// 'override fun getOrDefault(key: String, defaultValue: String): String' expects two strings, | ||
// and returning defaultValue if Int was received seems incorrect here | ||
mm.getOrDefault("abc", 123) | ||
return "fail 7" | ||
} catch (e: java.lang.ClassCastException) { | ||
} | ||
|
||
return "OK" | ||
} |
80 changes: 80 additions & 0 deletions
80
compiler/testData/codegen/java8/box/mapGetOrDefault/typeSafeBridgeNotNullAny.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// FULL_JDK | ||
// WITH_RUNTIME | ||
|
||
class A : MutableMap<Any, Any> { | ||
override val entries: MutableSet<MutableMap.MutableEntry<Any, Any>> | ||
get() = throw UnsupportedOperationException() | ||
override val keys: MutableSet<Any> | ||
get() = throw UnsupportedOperationException() | ||
override val values: MutableCollection<Any> | ||
get() = throw UnsupportedOperationException() | ||
|
||
override fun clear() { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun put(key: Any, value: Any): Any? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun putAll(from: Map<out Any, Any>) { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun remove(key: Any): Any? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override val size: Int | ||
get() = throw UnsupportedOperationException() | ||
|
||
override fun containsKey(key: Any): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun containsValue(value: Any): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun get(key: Any): Any? { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun isEmpty(): Boolean { | ||
throw UnsupportedOperationException() | ||
} | ||
|
||
override fun getOrDefault(key: Any, defaultValue: Any): Any { | ||
// this condition can not be true because of checkParameterIsNotNull checks in the begin of every method, but it's left here | ||
// to emphasize that we expect these parameters are not null | ||
if (key == null || defaultValue == null) { | ||
throw IllegalArgumentException("fail") | ||
} | ||
if (key == "abc") return "cde" | ||
return defaultValue | ||
} | ||
} | ||
|
||
fun box(): String { | ||
val a = A() | ||
if (a.getOrDefault("abc", "xyz") != "cde") return "fail 1" | ||
if (a.getOrDefault("56", "123") != "123") return "fail 2" | ||
|
||
val mm = a as MutableMap<Any?, Any?> | ||
if (mm.getOrDefault("abc", "xyz") != "cde") return "fail 3" | ||
if (mm.getOrDefault("56", 123) != 123) return "fail 4" | ||
if (mm.getOrDefault(1, "456") != "456") return "fail 5" | ||
if (mm.getOrDefault(null, "qwe") != "qwe") return "fail 6" | ||
|
||
try { | ||
// This is a known problem, there's no way to implement type-safe bridge/barrier properly: | ||
// 'override fun getOrDefault(key: Any, defaultValue: Any): Any' expects two not-nullable values, | ||
// and returning defaultValue if null was received seems incorrect here | ||
mm.getOrDefault("abc", null) | ||
return "fail 7" | ||
} catch (e: java.lang.IllegalArgumentException) { | ||
// Parameter specified as non-null is null | ||
} | ||
|
||
return "OK" | ||
} |
18 changes: 18 additions & 0 deletions
18
compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/getOrDefault.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
abstract class A : Map<Int, String> | ||
|
||
fun foo(x: Map<Int, String>, a: A, b: java.util.HashMap<Int, String>) { | ||
x.getOrDefault(1, "") | ||
x.getOrDefault(<!TYPE_MISMATCH!>""<!>, "") | ||
x.getOrDefault(1, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>) | ||
x.getOrDefault(<!TYPE_MISMATCH!>""<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>) | ||
|
||
a.getOrDefault(1, "") | ||
a.getOrDefault(<!TYPE_MISMATCH!>""<!>, "") | ||
a.getOrDefault(1, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>) | ||
a.getOrDefault(<!TYPE_MISMATCH!>""<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>) | ||
|
||
b.getOrDefault(1, "") | ||
b.getOrDefault(<!TYPE_MISMATCH!>""<!>, "") | ||
b.getOrDefault(1, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>) | ||
b.getOrDefault(<!TYPE_MISMATCH!>""<!>, <!CONSTANT_EXPECTED_TYPE_MISMATCH!>2<!>) | ||
} |
20 changes: 20 additions & 0 deletions
20
compiler/testData/diagnostics/testsWithJava8/targetedBuiltIns/getOrDefault.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package | ||
|
||
public fun foo(/*0*/ x: kotlin.collections.Map<kotlin.Int, kotlin.String>, /*1*/ a: A, /*2*/ b: java.util.HashMap<kotlin.Int, kotlin.String>): kotlin.Unit | ||
|
||
public abstract class A : kotlin.collections.Map<kotlin.Int, kotlin.String> { | ||
public constructor A() | ||
public abstract override /*1*/ /*fake_override*/ val entries: kotlin.collections.Set<kotlin.collections.Map.Entry<kotlin.Int, kotlin.String>> | ||
public abstract override /*1*/ /*fake_override*/ val keys: kotlin.collections.Set<kotlin.Int> | ||
public abstract override /*1*/ /*fake_override*/ val size: kotlin.Int | ||
public abstract override /*1*/ /*fake_override*/ val values: kotlin.collections.Collection<kotlin.String> | ||
public abstract override /*1*/ /*fake_override*/ fun containsKey(/*0*/ key: kotlin.Int): kotlin.Boolean | ||
public abstract override /*1*/ /*fake_override*/ fun containsValue(/*0*/ value: kotlin.String): kotlin.Boolean | ||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean | ||
public open override /*1*/ /*fake_override*/ fun forEach(/*0*/ p0: java.util.function.BiConsumer<in kotlin.Int!, in kotlin.String!>!): kotlin.Unit | ||
public abstract override /*1*/ /*fake_override*/ fun get(/*0*/ key: kotlin.Int): kotlin.String? | ||
@kotlin.internal.PlatformDependent() public open override /*1*/ /*fake_override*/ fun getOrDefault(/*0*/ key: kotlin.Int, /*1*/ defaultValue: kotlin.String): kotlin.String | ||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int | ||
public abstract override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean | ||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.