KT-9377 Support is-checks for read-only collections
Marker interfaces for mutable Kotlin collections and related classes.
This commit is contained in:
@@ -45,6 +45,8 @@ import org.jetbrains.kotlin.load.java.JvmAbi;
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames;
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass;
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.KotlinClass;
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor;
|
||||||
|
import org.jetbrains.kotlin.name.FqName;
|
||||||
|
import org.jetbrains.kotlin.name.FqNameUnsafe;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import org.jetbrains.kotlin.psi.*;
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
@@ -296,6 +298,27 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> KOTLIN_MARKER_INTERFACES = new HashMap<String, String>();
|
||||||
|
static {
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterator", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.Iterable", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.Collection", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.List", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.ListIterator", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.Set", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.Map", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.Map.Entry", "kotlin/jvm/internal/KMappedMarker");
|
||||||
|
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableIterator", "kotlin/jvm/internal/KMutableIterator");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableIterable", "kotlin/jvm/internal/KMutableIterable");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableCollection", "kotlin/jvm/internal/KMutableCollection");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableList", "kotlin/jvm/internal/KMutableList");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableListIterator", "kotlin/jvm/internal/KMutableListIterator");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableSet", "kotlin/jvm/internal/KMutableSet");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableMap", "kotlin/jvm/internal/KMutableMap");
|
||||||
|
KOTLIN_MARKER_INTERFACES.put("kotlin.MutableMap.MutableEntry", "kotlin/jvm/internal/KMutableMap$Entry");
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JvmClassSignature signature() {
|
private JvmClassSignature signature() {
|
||||||
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
|
BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
|
||||||
@@ -313,15 +336,31 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
sw.writeSuperclassEnd();
|
sw.writeSuperclassEnd();
|
||||||
|
|
||||||
LinkedHashSet<String> superInterfaces = new LinkedHashSet<String>();
|
LinkedHashSet<String> superInterfaces = new LinkedHashSet<String>();
|
||||||
|
Set<String> kotlinMarkerInterfaces = new LinkedHashSet<String>();
|
||||||
|
|
||||||
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
|
for (JetType supertype : descriptor.getTypeConstructor().getSupertypes()) {
|
||||||
if (isJvmInterface(supertype.getConstructor().getDeclarationDescriptor())) {
|
if (isJvmInterface(supertype.getConstructor().getDeclarationDescriptor())) {
|
||||||
sw.writeInterface();
|
sw.writeInterface();
|
||||||
Type jvmName = typeMapper.mapSupertype(supertype, sw);
|
Type jvmInterfaceType = typeMapper.mapSupertype(supertype, sw);
|
||||||
sw.writeInterfaceEnd();
|
sw.writeInterfaceEnd();
|
||||||
superInterfaces.add(jvmName.getInternalName());
|
String jvmInterfaceInternalName = jvmInterfaceType.getInternalName();
|
||||||
|
superInterfaces.add(jvmInterfaceInternalName);
|
||||||
|
|
||||||
|
String kotlinInterfaceName = DescriptorUtils.getFqName(supertype.getConstructor().getDeclarationDescriptor()).asString();
|
||||||
|
String kotlinMarkerInterfaceInternalName = KOTLIN_MARKER_INTERFACES.get(kotlinInterfaceName);
|
||||||
|
if (kotlinMarkerInterfaceInternalName != null) {
|
||||||
|
kotlinMarkerInterfaces.add(kotlinMarkerInterfaceInternalName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (String kotlinMarkerInterface : kotlinMarkerInterfaces) {
|
||||||
|
sw.writeInterface();
|
||||||
|
sw.writeAsmType(Type.getObjectType(kotlinMarkerInterface));
|
||||||
|
sw.writeInterfaceEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
superInterfaces.addAll(kotlinMarkerInterfaces);
|
||||||
|
|
||||||
return new JvmClassSignature(classAsmType.getInternalName(), superClassAsmType.getInternalName(),
|
return new JvmClassSignature(classAsmType.getInternalName(), superClassAsmType.getInternalName(),
|
||||||
new ArrayList<String>(superInterfaces), sw.makeJavaGenericSignature());
|
new ArrayList<String>(superInterfaces), sw.makeJavaGenericSignature());
|
||||||
|
|||||||
+57
@@ -0,0 +1,57 @@
|
|||||||
|
import kotlin.reflect.jvm.*
|
||||||
|
|
||||||
|
abstract class Itr : Iterator<String>
|
||||||
|
abstract class MItr : MutableIterator<String>
|
||||||
|
abstract class LItr : ListIterator<String>
|
||||||
|
abstract class MLItr : MutableListIterator<String>
|
||||||
|
abstract class It : Iterable<String>
|
||||||
|
abstract class MIt : MutableIterable<String>
|
||||||
|
abstract class C : Collection<String>
|
||||||
|
abstract class MC : MutableCollection<String>
|
||||||
|
abstract class L : List<String>
|
||||||
|
abstract class ML : MutableList<String>
|
||||||
|
abstract class S : Set<String>
|
||||||
|
abstract class MS : MutableSet<String>
|
||||||
|
abstract class M : Map<String, String>
|
||||||
|
abstract class MM : MutableMap<String, String>
|
||||||
|
abstract class ME : Map.Entry<String, String>
|
||||||
|
abstract class MME : MutableMap.MutableEntry<String, String>
|
||||||
|
|
||||||
|
abstract class L2 : L()
|
||||||
|
abstract class ML2 : ML()
|
||||||
|
|
||||||
|
abstract class Weird : Iterator<String>, MutableList<String>
|
||||||
|
|
||||||
|
fun expectInterfaces(jClass: Class<*>, expectedInterfaceNames: Set<String>) {
|
||||||
|
val actualInterfaceNames = jClass.getInterfaces().mapTo(linkedSetOf<String>()) { it.name }
|
||||||
|
|
||||||
|
assert(actualInterfaceNames == expectedInterfaceNames) {
|
||||||
|
"${jClass.name}: interfaces: expected: $expectedInterfaceNames; actual: $actualInterfaceNames"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
expectInterfaces(Itr::class.java, setOf("java.util.Iterator", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MItr::class.java, setOf("java.util.Iterator", "kotlin.jvm.internal.KMutableIterator"))
|
||||||
|
expectInterfaces(LItr::class.java, setOf("java.util.ListIterator", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MLItr::class.java, setOf("java.util.ListIterator", "kotlin.jvm.internal.KMutableListIterator"))
|
||||||
|
expectInterfaces(It::class.java, setOf("java.lang.Iterable", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MIt::class.java, setOf("java.lang.Iterable", "kotlin.jvm.internal.KMutableIterable"))
|
||||||
|
expectInterfaces(C::class.java, setOf("java.util.Collection", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MC::class.java, setOf("java.util.Collection", "kotlin.jvm.internal.KMutableCollection"))
|
||||||
|
expectInterfaces(L::class.java, setOf("java.util.List", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(ML::class.java, setOf("java.util.List", "kotlin.jvm.internal.KMutableList"))
|
||||||
|
expectInterfaces(S::class.java, setOf("java.util.Set", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MS::class.java, setOf("java.util.Set", "kotlin.jvm.internal.KMutableSet"))
|
||||||
|
expectInterfaces(M::class.java, setOf("java.util.Map", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MM::class.java, setOf("java.util.Map", "kotlin.jvm.internal.KMutableMap"))
|
||||||
|
expectInterfaces(ME::class.java, setOf("java.util.Map\$Entry", "kotlin.jvm.internal.KMappedMarker"))
|
||||||
|
expectInterfaces(MME::class.java, setOf("java.util.Map\$Entry", "kotlin.jvm.internal.KMutableMap\$Entry"))
|
||||||
|
expectInterfaces(L2::class.java, setOf<String>())
|
||||||
|
expectInterfaces(ML2::class.java, setOf<String>())
|
||||||
|
expectInterfaces(Weird::class.java,
|
||||||
|
setOf("java.util.Iterator", "kotlin.jvm.internal.KMappedMarker",
|
||||||
|
"java.util.List", "kotlin.jvm.internal.KMutableList"))
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+6
@@ -954,6 +954,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/classes/kt8011.kt");
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/classes/kt8011.kt");
|
||||||
doTestWithStdlib(fileName);
|
doTestWithStdlib(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("mutabilityMarkerInterfaces.kt")
|
||||||
|
public void testMutabilityMarkerInterfaces() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/classes/mutabilityMarkerInterfaces.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/controlStructures")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/controlStructures")
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMappedMarker {
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableCollection extends KMutableIterable {
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableIterable extends KMappedMarker {
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableIterator extends KMappedMarker {
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableList extends KMutableCollection {
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableListIterator extends KMutableIterator {
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableMap extends KMappedMarker {
|
||||||
|
interface Entry extends KMappedMarker {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal;
|
||||||
|
|
||||||
|
public interface KMutableSet extends KMutableCollection {
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user