Don't use external annotations in compiler

External annotations will be re-enabled in the IDE later.

This fixes LazyJavaAnnotations which was breaking the contract of Annotations:
findAnnotation(FqName) was looking for external annotations, while iterator()
did not. This resulted in some inconsistencies in the compiler and IDE tests.

The other way, i.e. making iterator() look up external annotations, would have
been too costly for the compiler and with no clear benefit at the moment.
This commit is contained in:
Alexander Udalov
2015-04-13 14:48:54 +03:00
parent fe602d34ce
commit 24bad39e76
8 changed files with 56 additions and 90 deletions
@@ -1,6 +0,0 @@
public final class WithPlatformTypes implements java.lang.Iterable<java.lang.String> {
public WithPlatformTypes(@org.jetbrains.annotations.NotNull java.lang.Iterable<java.lang.String> i) { /* compiled code */ }
@org.jetbrains.annotations.NotNull
public java.util.Iterator<java.lang.String> iterator() { /* compiled code */ }
}
@@ -1,3 +0,0 @@
// WithPlatformTypes
class WithPlatformTypes(i: java.lang.Iterable<String>) : java.lang.Iterable<String> by i
@@ -1,33 +1,32 @@
import java.sql.DriverManager import java.sql.DriverManager
fun getConnection(url: String?) { fun getConnection(url: String?) {
DriverManager.getConnection(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>url<!>) DriverManager.getConnection(url)
DriverManager.getConnection(url!!) : java.sql.Connection DriverManager.getConnection(url!!) : java.sql.Connection
} }
fun getConnection(url: String?, props: java.util.Properties?) { fun getConnection(url: String?, props: java.util.Properties?) {
DriverManager.getConnection(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>url<!>, props) DriverManager.getConnection(url, props)
DriverManager.getConnection(url!!, props) : java.sql.Connection DriverManager.getConnection(url!!, props) : java.sql.Connection
} }
fun getConnection(url: String?, user: String?, password: String?) { fun getConnection(url: String?, user: String?, password: String?) {
DriverManager.getConnection(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>url<!>, user!!, password!!) DriverManager.getConnection(url, user!!, password!!)
DriverManager.getConnection(url!!, user, password<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) DriverManager.getConnection(url!!, user, password<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
DriverManager.getConnection(url<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, user<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, password) DriverManager.getConnection(url<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, user<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, password)
DriverManager.getConnection(url<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, user<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, password<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) : java.sql.Connection DriverManager.getConnection(url<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, user<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>, password<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) : java.sql.Connection
} }
fun getDriver(url: String?) { fun getDriver(url: String?) {
DriverManager.getDriver(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>url<!>) DriverManager.getDriver(url)
DriverManager.getDriver(url!!) : java.sql.Driver DriverManager.getDriver(url!!) : java.sql.Driver
} }
fun registerDriver(driver: java.sql.Driver?) { fun registerDriver(driver: java.sql.Driver?) {
DriverManager.registerDriver(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>driver<!>) DriverManager.registerDriver(driver)
DriverManager.registerDriver(driver!!) DriverManager.registerDriver(driver!!)
} }
fun getDrivers() { fun getDrivers() {
// todo fix to java.util.Enumeration<java.sql.Driver> bug in compiler fixed DriverManager.getDrivers() : java.util.Enumeration<java.sql.Driver>
DriverManager.getDrivers() : java.util.Enumeration<*> }
}
@@ -1,5 +1,5 @@
fun executeQuery(statement: java.sql.Statement, cmd: String?) { fun executeQuery(statement: java.sql.Statement, cmd: String?) {
statement.executeQuery(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>cmd<!>) statement.executeQuery(cmd)
statement.executeQuery(cmd!!) : java.sql.ResultSet statement.executeQuery(cmd!!) : java.sql.ResultSet
} }
@@ -8,6 +8,6 @@ fun executeQuery(statement: java.sql.PreparedStatement) {
} }
fun executeUpdate(statement: java.sql.Statement, cmd: String?) { fun executeUpdate(statement: java.sql.Statement, cmd: String?) {
statement.executeUpdate(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>cmd<!>) statement.executeUpdate(cmd)
statement.executeUpdate(cmd!!) statement.executeUpdate(cmd!!)
} }
@@ -43,12 +43,6 @@ public class KotlinLightClassTestGenerated extends AbstractKotlinLightClassTest
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^(.+)\\.kt$"), true); JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/asJava/lightClasses/delegation"), Pattern.compile("^(.+)\\.kt$"), true);
} }
@TestMetadata("ExternalAnnotations.kt")
public void testExternalAnnotations() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/ExternalAnnotations.kt");
doTest(fileName);
}
@TestMetadata("Function.kt") @TestMetadata("Function.kt")
public void testFunction() throws Exception { public void testFunction() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/Function.kt"); String fileName = JetTestUtils.navigationMetadata("compiler/testData/asJava/lightClasses/delegation/Function.kt");
@@ -16,42 +16,27 @@
package org.jetbrains.kotlin.load.java.lazy package org.jetbrains.kotlin.load.java.lazy
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation
class LazyJavaAnnotations( class LazyJavaAnnotations(
c: LazyJavaResolverContext, private val c: LazyJavaResolverContext,
val annotationOwner: JavaAnnotationOwner, val annotationOwner: JavaAnnotationOwner
private val extraLookup: (FqName) -> JavaAnnotation? = { null }
) : Annotations { ) : Annotations {
private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues { private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues {
annotation: JavaAnnotation -> annotation: JavaAnnotation ->
c.resolveAnnotation(annotation) c.resolveAnnotation(annotation)
} }
override fun findAnnotation(fqName: FqName): AnnotationDescriptor? { override fun findAnnotation(fqName: FqName) = annotationOwner.findAnnotation(fqName)?.let(annotationDescriptors)
val jAnnotation = annotationOwner.findAnnotation(fqName) ?: extraLookup(fqName)
if (jAnnotation == null) return null
return annotationDescriptors(jAnnotation) override fun iterator() = annotationOwner.getAnnotations().sequence().map(annotationDescriptors).filterNotNull().iterator()
}
override fun iterator() = annotationOwner.getAnnotations().stream().map { annotationDescriptors(it) }.filterNotNull().iterator()
override fun isEmpty() = !iterator().hasNext() override fun isEmpty() = !iterator().hasNext()
} }
fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations
= LazyJavaAnnotations(this, annotationsOwner) { fqName -> externalAnnotationResolver.findExternalAnnotation(annotationsOwner, fqName) } = LazyJavaAnnotations(this, annotationsOwner)
private fun GlobalJavaResolverContext.hasAnnotation(owner: JavaAnnotationOwner, annotationFqName: FqName): Boolean
= owner.findAnnotation(annotationFqName) != null || externalAnnotationResolver.findExternalAnnotation(owner, annotationFqName) != null
fun GlobalJavaResolverContext.hasMutableAnnotation(owner: JavaAnnotationOwner): Boolean = hasAnnotation(owner, JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION)
fun GlobalJavaResolverContext.hasReadOnlyAnnotation(owner: JavaAnnotationOwner): Boolean = hasAnnotation(owner, JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION)
fun GlobalJavaResolverContext.hasNotNullAnnotation(owner: JavaAnnotationOwner): Boolean = hasAnnotation(owner, JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION)
@@ -16,36 +16,37 @@
package org.jetbrains.kotlin.load.java.lazy.descriptors package org.jetbrains.kotlin.load.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.load.java.lazy.hasNotNullAnnotation import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.load.java.components.ExternalSignatureResolver
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeAttributes import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeAttributes
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
import org.jetbrains.kotlin.load.java.structure.JavaField
import org.jetbrains.kotlin.load.java.structure.JavaMethod
import org.jetbrains.kotlin.load.java.structure.JavaValueParameter import org.jetbrains.kotlin.load.java.structure.JavaValueParameter
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addIfNotNull
import org.jetbrains.kotlin.utils.toReadOnlyList
import java.util.ArrayList import java.util.ArrayList
import java.util.LinkedHashSet import java.util.LinkedHashSet
import org.jetbrains.kotlin.types.JetType
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.load.java.components.ExternalSignatureResolver
import org.jetbrains.kotlin.utils.*
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindExclude.NonExtensions
public abstract class LazyJavaMemberScope( public abstract class LazyJavaMemberScope(
protected val c: LazyJavaResolverContext, protected val c: LazyJavaResolverContext,
@@ -167,26 +168,21 @@ public abstract class LazyJavaMemberScope(
jValueParameters: List<JavaValueParameter> jValueParameters: List<JavaValueParameter>
): ResolvedValueParameters { ): ResolvedValueParameters {
var synthesizedNames = false var synthesizedNames = false
val descriptors = jValueParameters.withIndices().map { pair -> val descriptors = jValueParameters.withIndex().map { pair ->
val (index, javaParameter) = pair val (index, javaParameter) = pair
val annotations = c.resolveAnnotations(javaParameter) val annotations = c.resolveAnnotations(javaParameter)
val typeUsage = LazyJavaTypeAttributes(c, javaParameter, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, annotations) val typeUsage = LazyJavaTypeAttributes(c, javaParameter, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, annotations)
val (outType, varargElementType) = val (outType, varargElementType) =
if (javaParameter.isVararg()) { if (javaParameter.isVararg()) {
val paramType = javaParameter.getType() val paramType = javaParameter.getType() as? JavaArrayType
assert (paramType is JavaArrayType) { "Vararg parameter should be an array: $paramType" } ?: throw AssertionError("Vararg parameter should be an array: $javaParameter")
val arrayType = c.typeResolver.transformArrayType(paramType as JavaArrayType, typeUsage, true) val outType = c.typeResolver.transformArrayType(paramType, typeUsage, true)
val outType = if (PLATFORM_TYPES) arrayType else TypeUtils.makeNotNullable(arrayType) outType to KotlinBuiltIns.getInstance().getArrayElementType(outType)
outType to KotlinBuiltIns.getInstance().getArrayElementType(outType) }
} else {
else { c.typeResolver.transformJavaType(javaParameter.getType(), typeUsage) to null
val jetType = c.typeResolver.transformJavaType(javaParameter.getType(), typeUsage) }
if (!PLATFORM_TYPES && jetType.isMarkedNullable() && c.hasNotNullAnnotation(javaParameter))
TypeUtils.makeNotNullable(jetType) to null
else
jetType to null
}
val name = if (function.getName().asString() == "equals" && val name = if (function.getName().asString() == "equals" &&
jValueParameters.size() == 1 && jValueParameters.size() == 1 &&
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.components.TypeUsage.* import org.jetbrains.kotlin.load.java.components.TypeUsage.*
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver
import org.jetbrains.kotlin.load.java.lazy.hasNotNullAnnotation
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.FLEXIBLE_UPPER_BOUND
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.INFLEXIBLE import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.INFLEXIBLE
@@ -379,7 +378,9 @@ class LazyJavaTypeAttributes(
TypeUsage.MEMBER_SIGNATURE_COVARIANT TypeUsage.MEMBER_SIGNATURE_COVARIANT
} }
override val isMarkedNotNull: Boolean by c.storageManager.createLazyValue { c.hasNotNullAnnotation(annotationOwner) } override val isMarkedNotNull: Boolean by c.storageManager.createLazyValue {
annotationOwner.findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null
}
} }
private fun Annotations.isMarkedReadOnly() = findAnnotation(JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null private fun Annotations.isMarkedReadOnly() = findAnnotation(JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null