KT-6077 Compiler does not issue error on unsafe access to ArrayList with nullable values

#KT-6077 Fixed
This commit is contained in:
Andrey Breslav
2014-10-21 13:49:14 +04:00
parent 7b89771953
commit a14eefcea3
13 changed files with 184 additions and 6 deletions
@@ -4,5 +4,6 @@ trait Foo
fun test() {
var nullable: Foo? = null
val foo: Collection<Foo> = java.util.Collections.singleton(nullable)
val foo: Collection<Foo> = <!TYPE_MISMATCH!>java.util.Collections.singleton(nullable)<!>
val foo1: Collection<Foo> = java.util.Collections.singleton(nullable!!)
}
@@ -0,0 +1,9 @@
import java.util.ArrayList
fun foo() {
val list = ArrayList<String?>()
for (s in list) {
s<!UNSAFE_CALL!>.<!>length
}
}
@@ -0,0 +1,3 @@
package
internal fun foo(): kotlin.Unit
@@ -0,0 +1,3 @@
package test
class C: java.util.ArrayList<String>()
@@ -0,0 +1,45 @@
package test
internal final class C : java.util.ArrayList<kotlin.String> {
/*primary*/ public constructor C()
invisible_fake final override /*1*/ /*fake_override*/ var elementData: kotlin.Array<(out) kotlin.Any!>!
protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int
invisible_fake final override /*1*/ /*fake_override*/ var size: kotlin.Int
public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String!): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: (kotlin.MutableCollection<out kotlin.String!>..kotlin.Collection<kotlin.String!>?)): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: (kotlin.MutableCollection<out kotlin.String!>..kotlin.Collection<kotlin.String!>?)): kotlin.Boolean
invisible_fake open override /*1*/ /*fake_override*/ fun batchRemove(/*0*/ p0: (kotlin.MutableCollection<out kotlin.Any?>..kotlin.Collection<kotlin.Any?>?), /*1*/ p1: kotlin.Boolean): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any!
public open override /*1*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.Any!): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun containsAll(/*0*/ c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean
invisible_fake open override /*1*/ /*fake_override*/ fun elementData(/*0*/ p0: kotlin.Int): kotlin.String!
public open override /*1*/ /*fake_override*/ fun ensureCapacity(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun ensureCapacityInternal(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun fastRemove(/*0*/ p0: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String!
invisible_fake open override /*1*/ /*fake_override*/ fun grow(/*0*/ p0: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any!): kotlin.Int
public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun iterator(): kotlin.(Mutable)Iterator<kotlin.String!>!
public open override /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.Any!): kotlin.Int
public open override /*1*/ /*fake_override*/ fun listIterator(): kotlin.(Mutable)ListIterator<kotlin.String!>!
public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.(Mutable)ListIterator<kotlin.String!>!
invisible_fake open override /*1*/ /*fake_override*/ fun outOfBoundsMsg(/*0*/ p0: kotlin.Int): kotlin.String!
invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheck(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheckForAdd(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun readObject(/*0*/ p0: java.io.ObjectInputStream!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any!): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ index: kotlin.Int): kotlin.String!
public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: (kotlin.MutableCollection<out kotlin.Any?>..kotlin.Collection<kotlin.Any?>?)): kotlin.Boolean
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: (kotlin.MutableCollection<out kotlin.Any?>..kotlin.Collection<kotlin.Any?>?)): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String!): kotlin.String!
public open override /*1*/ /*fake_override*/ fun size(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.(Mutable)List<kotlin.String!>!
public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public open override /*1*/ /*fake_override*/ fun </*0*/ T> toArray(/*0*/ a: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
public open override /*1*/ /*fake_override*/ fun trimToSize(): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun writeObject(/*0*/ p0: java.io.ObjectOutputStream!): kotlin.Unit
}
@@ -0,0 +1,3 @@
package test
class C: java.util.ArrayList<String?>()
@@ -0,0 +1,45 @@
package test
internal final class C : java.util.ArrayList<kotlin.String?> {
/*primary*/ public constructor C()
invisible_fake final override /*1*/ /*fake_override*/ var elementData: kotlin.Array<(out) kotlin.Any!>!
protected/*protected and package*/ final override /*1*/ /*fake_override*/ var modCount: kotlin.Int
invisible_fake final override /*1*/ /*fake_override*/ var size: kotlin.Int
public open override /*1*/ /*fake_override*/ fun add(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String?): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun add(/*0*/ e: kotlin.String?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ c: (kotlin.MutableCollection<out kotlin.String?>..kotlin.Collection<kotlin.String?>?)): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun addAll(/*0*/ index: kotlin.Int, /*1*/ c: (kotlin.MutableCollection<out kotlin.String?>..kotlin.Collection<kotlin.String?>?)): kotlin.Boolean
invisible_fake open override /*1*/ /*fake_override*/ fun batchRemove(/*0*/ p0: (kotlin.MutableCollection<out kotlin.Any?>..kotlin.Collection<kotlin.Any?>?), /*1*/ p1: kotlin.Boolean): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun clear(): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun clone(): kotlin.Any!
public open override /*1*/ /*fake_override*/ fun contains(/*0*/ o: kotlin.Any!): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun containsAll(/*0*/ c: kotlin.Collection<kotlin.Any?>): kotlin.Boolean
invisible_fake open override /*1*/ /*fake_override*/ fun elementData(/*0*/ p0: kotlin.Int): kotlin.String?
public open override /*1*/ /*fake_override*/ fun ensureCapacity(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun ensureCapacityInternal(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun fastRemove(/*0*/ p0: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun get(/*0*/ index: kotlin.Int): kotlin.String?
invisible_fake open override /*1*/ /*fake_override*/ fun grow(/*0*/ p0: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun indexOf(/*0*/ o: kotlin.Any!): kotlin.Int
public open override /*1*/ /*fake_override*/ fun isEmpty(): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun iterator(): kotlin.(Mutable)Iterator<kotlin.String?>!
public open override /*1*/ /*fake_override*/ fun lastIndexOf(/*0*/ o: kotlin.Any!): kotlin.Int
public open override /*1*/ /*fake_override*/ fun listIterator(): kotlin.(Mutable)ListIterator<kotlin.String?>!
public open override /*1*/ /*fake_override*/ fun listIterator(/*0*/ index: kotlin.Int): kotlin.(Mutable)ListIterator<kotlin.String?>!
invisible_fake open override /*1*/ /*fake_override*/ fun outOfBoundsMsg(/*0*/ p0: kotlin.Int): kotlin.String!
invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheck(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun rangeCheckForAdd(/*0*/ p0: kotlin.Int): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun readObject(/*0*/ p0: java.io.ObjectInputStream!): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ o: kotlin.Any!): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun remove(/*0*/ index: kotlin.Int): kotlin.String?
public open override /*1*/ /*fake_override*/ fun removeAll(/*0*/ c: (kotlin.MutableCollection<out kotlin.Any?>..kotlin.Collection<kotlin.Any?>?)): kotlin.Boolean
protected/*protected and package*/ open override /*1*/ /*fake_override*/ fun removeRange(/*0*/ p0: kotlin.Int, /*1*/ p1: kotlin.Int): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun retainAll(/*0*/ c: (kotlin.MutableCollection<out kotlin.Any?>..kotlin.Collection<kotlin.Any?>?)): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun set(/*0*/ index: kotlin.Int, /*1*/ element: kotlin.String?): kotlin.String?
public open override /*1*/ /*fake_override*/ fun size(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun subList(/*0*/ fromIndex: kotlin.Int, /*1*/ toIndex: kotlin.Int): kotlin.(Mutable)List<kotlin.String?>!
public open override /*1*/ /*fake_override*/ fun toArray(): kotlin.Array<(out) kotlin.Any!>!
public open override /*1*/ /*fake_override*/ fun </*0*/ T> toArray(/*0*/ a: kotlin.Array<(out) T!>!): kotlin.Array<(out) T!>!
public open override /*1*/ /*fake_override*/ fun trimToSize(): kotlin.Unit
invisible_fake open override /*1*/ /*fake_override*/ fun writeObject(/*0*/ p0: java.io.ObjectOutputStream!): kotlin.Unit
}
@@ -7735,6 +7735,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("nullableTypeArgument.kt")
public void testNullableTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/nullableTypeArgument.kt");
doTest(fileName);
}
@TestMetadata("override.kt")
public void testOverride() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/override.kt");
@@ -106,7 +106,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
configurationKind);
PackageViewDescriptor packageFromSource = exhaust.getModuleDescriptor().getPackage(TEST_PACKAGE_FQNAME);
assert packageFromSource != null;
assert packageFromSource != null : "Package " + TEST_PACKAGE_FQNAME + " not found";
Assert.assertEquals("test", packageFromSource.getName().asString());
PackageViewDescriptor packageFromBinary = LoadDescriptorUtil.loadTestPackageAndBindingContextFromJavaRoot(
@@ -1795,7 +1795,7 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
@TestMetadata("compiler/testData/loadJava/compiledKotlin")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({CompiledKotlin.Annotations.class, CompiledKotlin.Class.class, CompiledKotlin.ClassFun.class, CompiledKotlin.ClassObject.class, CompiledKotlin.Constructor.class, CompiledKotlin.DataClass.class, CompiledKotlin.Enum.class, CompiledKotlin.FromLoadJava.class, CompiledKotlin.Fun.class, CompiledKotlin.Inline.class, CompiledKotlin.Prop.class, CompiledKotlin.Type.class, CompiledKotlin.Visibility.class})
@InnerTestClasses({CompiledKotlin.Annotations.class, CompiledKotlin.Class.class, CompiledKotlin.ClassFun.class, CompiledKotlin.ClassObject.class, CompiledKotlin.Constructor.class, CompiledKotlin.DataClass.class, CompiledKotlin.Enum.class, CompiledKotlin.FromLoadJava.class, CompiledKotlin.Fun.class, CompiledKotlin.Inline.class, CompiledKotlin.PlatformTypes.class, CompiledKotlin.Prop.class, CompiledKotlin.Type.class, CompiledKotlin.Visibility.class})
@RunWith(JUnit3RunnerWithInners.class)
public static class CompiledKotlin extends AbstractLoadJavaTest {
public void testAllFilesPresentInCompiledKotlin() throws Exception {
@@ -4119,6 +4119,27 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest {
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class PlatformTypes extends AbstractLoadJavaTest {
public void testAllFilesPresentInPlatformTypes() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/platformTypes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("notnullTypeArgument.kt")
public void testNotnullTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes/notnullTypeArgument.kt");
doTestCompiledKotlin(fileName);
}
@TestMetadata("nullableTypeArgument.kt")
public void testNullableTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes/nullableTypeArgument.kt");
doTestCompiledKotlin(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/prop")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Prop.DefaultAccessors.class})
@@ -33,7 +33,7 @@ import java.util.regex.Pattern;
public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyResolveRecursiveComparingTest {
@TestMetadata("compiler/testData/loadJava/compiledKotlin")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({CompiledKotlin.Annotations.class, CompiledKotlin.Class.class, CompiledKotlin.ClassFun.class, CompiledKotlin.ClassObject.class, CompiledKotlin.Constructor.class, CompiledKotlin.DataClass.class, CompiledKotlin.Enum.class, CompiledKotlin.FromLoadJava.class, CompiledKotlin.Fun.class, CompiledKotlin.Inline.class, CompiledKotlin.Prop.class, CompiledKotlin.Type.class, CompiledKotlin.Visibility.class})
@InnerTestClasses({CompiledKotlin.Annotations.class, CompiledKotlin.Class.class, CompiledKotlin.ClassFun.class, CompiledKotlin.ClassObject.class, CompiledKotlin.Constructor.class, CompiledKotlin.DataClass.class, CompiledKotlin.Enum.class, CompiledKotlin.FromLoadJava.class, CompiledKotlin.Fun.class, CompiledKotlin.Inline.class, CompiledKotlin.PlatformTypes.class, CompiledKotlin.Prop.class, CompiledKotlin.Type.class, CompiledKotlin.Visibility.class})
@RunWith(JUnit3RunnerWithInners.class)
public static class CompiledKotlin extends AbstractLazyResolveRecursiveComparingTest {
public void testAllFilesPresentInCompiledKotlin() throws Exception {
@@ -2357,6 +2357,27 @@ public class LazyResolveRecursiveComparingTestGenerated extends AbstractLazyReso
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class PlatformTypes extends AbstractLazyResolveRecursiveComparingTest {
public void testAllFilesPresentInPlatformTypes() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/platformTypes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("notnullTypeArgument.kt")
public void testNotnullTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes/notnullTypeArgument.kt");
doTest(fileName);
}
@TestMetadata("nullableTypeArgument.kt")
public void testNullableTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes/nullableTypeArgument.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/prop")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Prop.DefaultAccessors.class})
@@ -300,7 +300,7 @@ class LazyJavaTypeResolver(
override fun substitutionResult(replacement: JetType): JetType {
return if (replacement.isFlexible()) replacement
else create(TypeUtils.makeNotNullable(replacement), TypeUtils.makeNullable(replacement))
else create(replacement, TypeUtils.makeNullable(replacement))
}
override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
@SuppressWarnings("all")
@TestMetadata("compiler/testData/loadJava/compiledKotlin")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({LazyResolveByStubTestGenerated.Annotations.class, LazyResolveByStubTestGenerated.Class.class, LazyResolveByStubTestGenerated.ClassFun.class, LazyResolveByStubTestGenerated.ClassObject.class, LazyResolveByStubTestGenerated.Constructor.class, LazyResolveByStubTestGenerated.DataClass.class, LazyResolveByStubTestGenerated.Enum.class, LazyResolveByStubTestGenerated.FromLoadJava.class, LazyResolveByStubTestGenerated.Fun.class, LazyResolveByStubTestGenerated.Inline.class, LazyResolveByStubTestGenerated.Prop.class, LazyResolveByStubTestGenerated.Type.class, LazyResolveByStubTestGenerated.Visibility.class})
@InnerTestClasses({LazyResolveByStubTestGenerated.Annotations.class, LazyResolveByStubTestGenerated.Class.class, LazyResolveByStubTestGenerated.ClassFun.class, LazyResolveByStubTestGenerated.ClassObject.class, LazyResolveByStubTestGenerated.Constructor.class, LazyResolveByStubTestGenerated.DataClass.class, LazyResolveByStubTestGenerated.Enum.class, LazyResolveByStubTestGenerated.FromLoadJava.class, LazyResolveByStubTestGenerated.Fun.class, LazyResolveByStubTestGenerated.Inline.class, LazyResolveByStubTestGenerated.PlatformTypes.class, LazyResolveByStubTestGenerated.Prop.class, LazyResolveByStubTestGenerated.Type.class, LazyResolveByStubTestGenerated.Visibility.class})
@RunWith(JUnit3RunnerWithInners.class)
public class LazyResolveByStubTestGenerated extends AbstractLazyResolveByStubTest {
public void testAllFilesPresentInCompiledKotlin() throws Exception {
@@ -2354,6 +2354,27 @@ public class LazyResolveByStubTestGenerated extends AbstractLazyResolveByStubTes
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class PlatformTypes extends AbstractLazyResolveByStubTest {
public void testAllFilesPresentInPlatformTypes() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/loadJava/compiledKotlin/platformTypes"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("notnullTypeArgument.kt")
public void testNotnullTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes/notnullTypeArgument.kt");
doTest(fileName);
}
@TestMetadata("nullableTypeArgument.kt")
public void testNullableTypeArgument() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/loadJava/compiledKotlin/platformTypes/nullableTypeArgument.kt");
doTest(fileName);
}
}
@TestMetadata("compiler/testData/loadJava/compiledKotlin/prop")
@TestDataPath("$PROJECT_ROOT")
@InnerTestClasses({Prop.DefaultAccessors.class})