Fix wrong nullability enhancement for annotated java.lang.Object type

Effectively, this commit drops cached value for j.l.Object type
This cache was introduced when types were immutable, but they
became mutable after starting reading top-level TYPE_USE annotations,
that lead to changing shared JAVA_LANG_OBJECT_CLASSIFIER_TYPE instance

 #KT-20826 Fixed
This commit is contained in:
Denis Zharkov
2017-10-20 09:43:25 +03:00
parent 3c9ef6d319
commit da52716bfd
8 changed files with 69 additions and 26 deletions
@@ -16,14 +16,11 @@
package org.jetbrains.kotlin.load.java.structure.impl.classFiles
import com.intellij.psi.CommonClassNames
import com.intellij.util.containers.ContainerUtil
import org.jetbrains.kotlin.builtins.PrimitiveType
import org.jetbrains.kotlin.load.java.structure.JavaClassifierType
import org.jetbrains.kotlin.load.java.structure.JavaType
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameter
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
import org.jetbrains.kotlin.utils.compact
@@ -33,14 +30,11 @@ import java.text.StringCharacterIterator
/**
* Take a look at com.intellij.psi.impl.compiled.SignatureParsing
* NOTE: currently this class can simply be converted to an object, but there are postponed plans
* to introduce cached instance for java.lang.Object type that would require injected class finder.
* So please, do not convert it to object
*/
class BinaryClassSignatureParser(globalContext: ClassifierResolutionContext) {
companion object {
private val JAVA_LANG_OBJECT = ClassId.topLevel(FqName(CommonClassNames.JAVA_LANG_OBJECT))
}
private val JAVA_LANG_OBJECT_CLASSIFIER_TYPE: JavaClassifierType =
PlainJavaClassifierType({ globalContext.resolveClass(JAVA_LANG_OBJECT) }, emptyList())
class BinaryClassSignatureParser {
fun parseTypeParametersDeclaration(signature: CharacterIterator, context: ClassifierResolutionContext): List<JavaTypeParameter> {
if (signature.current() != '<') {
@@ -68,25 +62,14 @@ class BinaryClassSignatureParser(globalContext: ClassifierResolutionContext) {
val parameterName = name.toString()
// postpone list allocation till a second bound is seen; ignore sole Object bound
var bounds: MutableList<JavaClassifierType>? = null
var jlo = false
val bounds: MutableList<JavaClassifierType> = ContainerUtil.newSmartList()
while (signature.current() == ':') {
signature.next()
val bound = parseClassifierRefSignature(signature, context) ?: continue
if (bounds == null) {
if (JAVA_LANG_OBJECT_CLASSIFIER_TYPE === bound) {
jlo = true
continue
}
bounds = ContainerUtil.newSmartList()
if (jlo) {
bounds.add(JAVA_LANG_OBJECT_CLASSIFIER_TYPE)
}
}
bounds.add(bound)
}
return BinaryJavaTypeParameter(Name.identifier(parameterName), bounds ?: emptyList())
return BinaryJavaTypeParameter(Name.identifier(parameterName), bounds)
}
fun parseClassifierRefSignature(signature: CharacterIterator, context: ClassifierResolutionContext): JavaClassifierType? {
@@ -148,8 +131,6 @@ class BinaryClassSignatureParser(globalContext: ClassifierResolutionContext) {
}
signature.next()
if (canonicalName.toString() == "java/lang/Object") return JAVA_LANG_OBJECT_CLASSIFIER_TYPE
return PlainJavaClassifierType(
{ context.resolveByInternalName(canonicalName.toString()) },
argumentGroups.reversed().flattenTo(arrayListOf()).compact()