Put type enhancement improvements under the compiler flag
This commit is contained in:
@@ -137,6 +137,7 @@ fun StorageComponentContainer.configureJavaSpecificComponents(
|
||||
JavaResolverSettings.create(
|
||||
isReleaseCoroutines = languageVersionSettings.supportsFeature(LanguageFeature.ReleaseCoroutines),
|
||||
correctNullabilityForNotNullTypeParameter = languageVersionSettings.supportsFeature(LanguageFeature.ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated),
|
||||
enhancementImprovements = languageVersionSettings.supportsFeature(LanguageFeature.ImprovementsAroundTypeEnhancement),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE: -ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class Basic_DisabledImprovements {
|
||||
public interface G<@NotNull T> {
|
||||
<@NotNull R> void foo(R r);
|
||||
}
|
||||
|
||||
public interface G1<T, E extends T, @NotNull X> {
|
||||
<R, @Nullable _A extends R> void foo(R r);
|
||||
}
|
||||
|
||||
<R, @NotNull _A extends R, @Nullable K> void foo(R r) {
|
||||
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
// !LANGUAGE: -ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class Basic_DisabledImprovements<T extends @NotNull Object> {
|
||||
interface G<T> extends G2<@NotNull T, @NotNull String> { }
|
||||
|
||||
interface G2<A, B> { }
|
||||
|
||||
static class A {
|
||||
class B<A, B> {}
|
||||
}
|
||||
|
||||
public interface MyClass<TT> {
|
||||
void f1(G<@NotNull String> p);
|
||||
G2<@Nullable String, @NotNull Integer> f2();
|
||||
<T extends @NotNull Object> void f3(@NotNull T x);
|
||||
void f4(G<@NotNull String @Nullable []> p);
|
||||
void f5(G<@NotNull ?> p);
|
||||
void f6(G<@NotNull ? extends @Nullable Object> p);
|
||||
void f7(G<@NotNull A.B<?, ?>> p);
|
||||
G<Basic_DisabledImprovements.@Nullable A.B<?, ?>> f81();
|
||||
G<Basic_DisabledImprovements.A.@Nullable B<?, ?>> f9();
|
||||
<T extends @NotNull Object, K extends G<@NotNull String []>> void f10(T p);
|
||||
}
|
||||
|
||||
Basic_DisabledImprovements(G<@NotNull String> p) { }
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package test
|
||||
|
||||
public open class Basic_DisabledImprovements</*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!> {
|
||||
public/*package*/ constructor Basic_DisabledImprovements</*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!>(/*0*/ p0: test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.NotNull kotlin.String!>!)
|
||||
|
||||
public/*package*/ open class A {
|
||||
public/*package*/ constructor A()
|
||||
|
||||
public/*package*/ open inner class B</*0*/ A : kotlin.Any!, /*1*/ B : kotlin.Any!> {
|
||||
public/*package*/ constructor B</*0*/ A : kotlin.Any!, /*1*/ B : kotlin.Any!>()
|
||||
}
|
||||
}
|
||||
|
||||
public/*package*/ interface G</*0*/ T : kotlin.Any!> : test.Basic_DisabledImprovements.G2<@org.jetbrains.annotations.NotNull T!, @org.jetbrains.annotations.NotNull kotlin.String!> {
|
||||
}
|
||||
|
||||
public/*package*/ interface G2</*0*/ A : kotlin.Any!, /*1*/ B : kotlin.Any!> {
|
||||
}
|
||||
|
||||
public interface MyClass</*0*/ TT : kotlin.Any!> {
|
||||
public abstract fun f1(/*0*/ p0: test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.NotNull kotlin.String!>!): kotlin.Unit
|
||||
public abstract fun </*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!, /*1*/ K : test.Basic_DisabledImprovements.G<kotlin.Array<(out) @org.jetbrains.annotations.NotNull kotlin.String!>!>!> f10(/*0*/ p0: T!): kotlin.Unit
|
||||
public abstract fun f2(): test.Basic_DisabledImprovements.G2<@org.jetbrains.annotations.Nullable kotlin.String!, @org.jetbrains.annotations.NotNull kotlin.Int!>!
|
||||
public abstract fun </*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!> f3(/*0*/ @org.jetbrains.annotations.NotNull p0: @org.jetbrains.annotations.NotNull T): kotlin.Unit
|
||||
public abstract fun f4(/*0*/ p0: test.Basic_DisabledImprovements.G<(@org.jetbrains.annotations.Nullable kotlin.Array<@org.jetbrains.annotations.NotNull kotlin.String!>..@org.jetbrains.annotations.Nullable kotlin.Array<out @org.jetbrains.annotations.NotNull kotlin.String!>?)>!): kotlin.Unit
|
||||
public abstract fun f5(/*0*/ p0: test.Basic_DisabledImprovements.G<*>!): kotlin.Unit
|
||||
public abstract fun f6(/*0*/ p0: test.Basic_DisabledImprovements.G<out @org.jetbrains.annotations.Nullable kotlin.Any!>!): kotlin.Unit
|
||||
public abstract fun f7(/*0*/ p0: test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.NotNull test.Basic_DisabledImprovements.A.B<*, *>!>!): kotlin.Unit
|
||||
public abstract fun f81(): test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.Nullable test.Basic_DisabledImprovements.A.B<*, *>!>!
|
||||
public abstract fun f9(): test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.Nullable test.Basic_DisabledImprovements.A.B<*, *>!>!
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+2
@@ -1,3 +1,5 @@
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE:
|
||||
|
||||
package test;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class Basic_DisabledImprovements {
|
||||
public interface G<@NotNull T> {
|
||||
<@NotNull R> void foo(R r);
|
||||
}
|
||||
|
||||
public interface G1<T, E extends T, @NotNull X> {
|
||||
<R, @Nullable _A extends R> void foo(R r);
|
||||
}
|
||||
|
||||
<R, @NotNull _A extends R, @Nullable K> void foo(R r) {
|
||||
|
||||
}
|
||||
}
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
// !LANGUAGE: -ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
import org.jetbrains.annotations.*;
|
||||
|
||||
public class Basic_DisabledImprovements<T extends @NotNull Object> {
|
||||
interface G<T> extends G2<@NotNull T, @NotNull String> { }
|
||||
|
||||
interface G2<A, B> { }
|
||||
|
||||
static class A {
|
||||
class B<A, B> {}
|
||||
}
|
||||
|
||||
public interface MyClass<TT> {
|
||||
void f1(G<@NotNull String> p);
|
||||
G2<@Nullable String, @NotNull Integer> f2();
|
||||
<T extends @NotNull Object> void f3(@NotNull T x);
|
||||
void f4(G<@NotNull String @Nullable []> p);
|
||||
void f5(G<@NotNull ?> p);
|
||||
void f6(G<@NotNull ? extends @Nullable Object> p);
|
||||
void f7(G<@NotNull A.B<?, ?>> p);
|
||||
G<Basic_DisabledImprovements.@Nullable A.B<?, ?>> f81();
|
||||
G<Basic_DisabledImprovements.A.@Nullable B<?, ?>> f9();
|
||||
<T extends @NotNull Object, K extends G<@NotNull String []>> void f10(T p);
|
||||
}
|
||||
|
||||
Basic_DisabledImprovements(G<@NotNull String> p) { }
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package test
|
||||
|
||||
public open class Basic_DisabledImprovements</*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!> {
|
||||
public/*package*/ constructor Basic_DisabledImprovements</*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!>(/*0*/ p: test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.NotNull kotlin.String>!)
|
||||
|
||||
public/*package*/ open class A {
|
||||
public/*package*/ constructor A()
|
||||
|
||||
public/*package*/ open inner class B</*0*/ A : kotlin.Any!, /*1*/ B : kotlin.Any!> {
|
||||
public/*package*/ constructor B</*0*/ A : kotlin.Any!, /*1*/ B : kotlin.Any!>()
|
||||
}
|
||||
}
|
||||
|
||||
public/*package*/ interface G</*0*/ T : kotlin.Any!> : test.Basic_DisabledImprovements.G2<@org.jetbrains.annotations.NotNull T!, @org.jetbrains.annotations.NotNull kotlin.String!> {
|
||||
}
|
||||
|
||||
public/*package*/ interface G2</*0*/ A : kotlin.Any!, /*1*/ B : kotlin.Any!> {
|
||||
}
|
||||
|
||||
public interface MyClass</*0*/ TT : kotlin.Any!> {
|
||||
public abstract fun f1(/*0*/ p: test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.NotNull kotlin.String>!): kotlin.Unit
|
||||
public abstract fun </*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!, /*1*/ K : test.Basic_DisabledImprovements.G<kotlin.Array<(out) @org.jetbrains.annotations.NotNull kotlin.String!>!>!> f10(/*0*/ p: T!): kotlin.Unit
|
||||
public abstract fun f2(): test.Basic_DisabledImprovements.G2<@org.jetbrains.annotations.Nullable kotlin.String?, @org.jetbrains.annotations.NotNull kotlin.Int>!
|
||||
public abstract fun </*0*/ T : @org.jetbrains.annotations.NotNull kotlin.Any!> f3(/*0*/ @org.jetbrains.annotations.NotNull x: @org.jetbrains.annotations.NotNull T): kotlin.Unit
|
||||
public abstract fun f4(/*0*/ p: test.Basic_DisabledImprovements.G<(@org.jetbrains.annotations.Nullable kotlin.Array<@org.jetbrains.annotations.NotNull kotlin.String!>..@org.jetbrains.annotations.Nullable kotlin.Array<out @org.jetbrains.annotations.NotNull kotlin.String!>?)>!): kotlin.Unit
|
||||
public abstract fun f5(/*0*/ p: test.Basic_DisabledImprovements.G<*>!): kotlin.Unit
|
||||
public abstract fun f6(/*0*/ p: test.Basic_DisabledImprovements.G<out @org.jetbrains.annotations.Nullable kotlin.Any?>!): kotlin.Unit
|
||||
public abstract fun f7(/*0*/ p: test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.NotNull test.Basic_DisabledImprovements.A.B<*, *>>!): kotlin.Unit
|
||||
public abstract fun f8(): test.Basic_DisabledImprovements.G<test.Basic_DisabledImprovements.A.B<*, *>!>!
|
||||
public abstract fun f9(): test.Basic_DisabledImprovements.G<@org.jetbrains.annotations.Nullable test.Basic_DisabledImprovements.A.B<*, *>?>!
|
||||
}
|
||||
}
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+1
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
// JAVAC_EXPECTED_FILE
|
||||
// !LANGUAGE: +ImprovementsAroundTypeEnhancement
|
||||
|
||||
package test;
|
||||
|
||||
|
||||
+16
-7
@@ -41,6 +41,7 @@ import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt.parseLanguageVersionSettings;
|
||||
import static org.jetbrains.kotlin.jvm.compiler.LoadDescriptorUtil.*;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.compileKotlinWithJava;
|
||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.newConfiguration;
|
||||
@@ -85,7 +86,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
|
||||
List<File> javaSources = FileUtil.findFilesByMask(Pattern.compile(".+\\.java"), sourcesDir);
|
||||
Pair<PackageViewDescriptor, BindingContext> binaryPackageAndContext = compileJavaAndLoadTestPackageAndBindingContextFromBinary(
|
||||
javaSources, tmpdir, ConfigurationKind.JDK_ONLY
|
||||
javaSources, tmpdir, ConfigurationKind.JDK_ONLY, null
|
||||
);
|
||||
|
||||
checkJavaPackage(expectedFile, binaryPackageAndContext.first, binaryPackageAndContext.second, COMPARATOR_CONFIGURATION);
|
||||
@@ -175,7 +176,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
|
||||
public static void updateConfigurationWithDirectives(String content, CompilerConfiguration configuration) {
|
||||
Directives directives = KotlinTestUtils.parseDirectives(content);
|
||||
LanguageVersionSettings languageVersionSettings = CompilerTestLanguageVersionSettingsKt.parseLanguageVersionSettings(directives);
|
||||
LanguageVersionSettings languageVersionSettings = parseLanguageVersionSettings(directives);
|
||||
if (languageVersionSettings == null) {
|
||||
languageVersionSettings = CompilerTestLanguageVersionSettingsKt.defaultLanguageVersionSettings();
|
||||
}
|
||||
@@ -274,9 +275,12 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
assertTrue(testPackageDir.mkdir());
|
||||
FileUtil.copy(originalJavaFile, new File(testPackageDir, originalJavaFile.getName()));
|
||||
|
||||
Directives directives = KotlinTestUtils.parseDirectives(FileUtil.loadFile(originalJavaFile));
|
||||
LanguageVersionSettings languageVersionSettings = parseLanguageVersionSettings(directives);
|
||||
|
||||
Pair<PackageViewDescriptor, BindingContext> javaPackageAndContext = loadTestPackageAndBindingContextFromJavaRoot(
|
||||
tmpdir, getTestRootDisposable(), getJdkKind(), ConfigurationKind.JDK_ONLY, false,
|
||||
false, useJavacWrapper(), withForeignAnnotations(), null);
|
||||
false, useJavacWrapper(), withForeignAnnotations(), languageVersionSettings);
|
||||
|
||||
checkJavaPackage(
|
||||
expectedFile, javaPackageAndContext.first, javaPackageAndContext.second,
|
||||
@@ -289,9 +293,10 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
File compiledDir = new File(tmpdir, "compiled");
|
||||
assertTrue(srcDir.mkdir());
|
||||
assertTrue(compiledDir.mkdir());
|
||||
String fileContent = FileUtil.loadFile(new File(javaFileName));
|
||||
|
||||
List<File> srcFiles = TestFiles.createTestFiles(
|
||||
new File(javaFileName).getName(), FileUtil.loadFile(new File(javaFileName), true),
|
||||
new File(javaFileName).getName(), fileContent,
|
||||
new TestFiles.TestFileFactoryNoModules<File>() {
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -307,8 +312,11 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
}
|
||||
});
|
||||
|
||||
Directives directives = KotlinTestUtils.parseDirectives(fileContent);
|
||||
LanguageVersionSettings languageVersionSettings = parseLanguageVersionSettings(directives);
|
||||
|
||||
Pair<PackageViewDescriptor, BindingContext> javaPackageAndContext = compileJavaAndLoadTestPackageAndBindingContextFromBinary(
|
||||
srcFiles, compiledDir, ConfigurationKind.ALL
|
||||
srcFiles, compiledDir, ConfigurationKind.ALL, languageVersionSettings
|
||||
);
|
||||
|
||||
|
||||
@@ -329,11 +337,12 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir {
|
||||
private Pair<PackageViewDescriptor, BindingContext> compileJavaAndLoadTestPackageAndBindingContextFromBinary(
|
||||
@NotNull Collection<File> javaFiles,
|
||||
@NotNull File outDir,
|
||||
@NotNull ConfigurationKind configurationKind
|
||||
@NotNull ConfigurationKind configurationKind,
|
||||
@Nullable LanguageVersionSettings explicitLanguageVersionSettings
|
||||
) throws IOException {
|
||||
compileJavaWithAnnotationsJar(javaFiles, outDir, getAdditionalJavacArgs(), getJdkHomeForJavac(), withForeignAnnotations());
|
||||
return loadTestPackageAndBindingContextFromJavaRoot(outDir, getTestRootDisposable(), getJdkKind(), configurationKind, true,
|
||||
usePsiClassFilesReading(), useJavacWrapper(), withForeignAnnotations(), null,
|
||||
usePsiClassFilesReading(), useJavacWrapper(), withForeignAnnotations(), explicitLanguageVersionSettings,
|
||||
getExtraClasspath(), this::configureEnvironment);
|
||||
}
|
||||
|
||||
|
||||
@@ -145,6 +145,20 @@ enum class LanguageFeature(
|
||||
AllowSealedInheritorsInDifferentFilesOfSamePackage(KOTLIN_1_5),
|
||||
SealedInterfaces(KOTLIN_1_5),
|
||||
|
||||
/*
|
||||
* Improvements include the following:
|
||||
* - taking into account for type enhancement freshly supported type use annotations: KT-11454
|
||||
* - use annotations in the type parameter position to enhance corresponding types: KT-11454
|
||||
* - proper support of the type enhancement of the annotated java arrays: KT-24392
|
||||
* - proper support of the type enhancement of the annotated java varargs' elements: KT-18768
|
||||
* - type enhancement based on annotated bounds of type parameters
|
||||
* - type enhancement within type arguments of the base classes and interfaces
|
||||
* - support type enhancement based on type use annotations on java fields
|
||||
* - preference of a type use annotation to annotation of another type: KT-24392
|
||||
* (if @NotNull has TYPE_USE and METHOD target, then `@NotNull Integer []` -> `Array<Int>..Array<out Int>?` instead of `Array<Int>..Array<out Int>`)
|
||||
*/
|
||||
ImprovementsAroundTypeEnhancement(KOTLIN_1_6),
|
||||
|
||||
// Temporarily disabled, see KT-27084/KT-22379
|
||||
SoundSmartcastFromLoopConditionForLoopAssignedVariables(sinceVersion = null, kind = BUG_FIX),
|
||||
|
||||
@@ -162,6 +176,7 @@ enum class LanguageFeature(
|
||||
MultiPlatformProjects(sinceVersion = null, defaultState = State.DISABLED),
|
||||
|
||||
NewInference(sinceVersion = KOTLIN_1_4),
|
||||
|
||||
// In the next block, features can be enabled only along with new inference
|
||||
SamConversionForKotlinFunctions(sinceVersion = KOTLIN_1_4),
|
||||
SamConversionPerArgument(sinceVersion = KOTLIN_1_4),
|
||||
@@ -263,6 +278,7 @@ enum class LanguageVersion(val major: Int, val minor: Int) : DescriptionAware {
|
||||
KOTLIN_1_3(1, 3),
|
||||
KOTLIN_1_4(1, 4),
|
||||
KOTLIN_1_5(1, 5),
|
||||
KOTLIN_1_6(1, 6),
|
||||
;
|
||||
|
||||
val isStable: Boolean
|
||||
|
||||
@@ -25,10 +25,11 @@ import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class LazyJavaAnnotations(
|
||||
private val c: LazyJavaResolverContext,
|
||||
private val annotationOwner: JavaAnnotationOwner
|
||||
private val annotationOwner: JavaAnnotationOwner,
|
||||
private val areAnnotationsFreshlySupported: Boolean = false
|
||||
) : Annotations {
|
||||
private val annotationDescriptors = c.components.storageManager.createMemoizedFunctionWithNullableValues { annotation: JavaAnnotation ->
|
||||
JavaAnnotationMapper.mapOrResolveJavaAnnotation(annotation, c)
|
||||
JavaAnnotationMapper.mapOrResolveJavaAnnotation(annotation, c, areAnnotationsFreshlySupported)
|
||||
}
|
||||
|
||||
override fun findAnnotation(fqName: FqName) =
|
||||
|
||||
@@ -31,8 +31,6 @@ import org.jetbrains.kotlin.load.java.components.SignaturePropagator
|
||||
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver
|
||||
import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
|
||||
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
|
||||
@@ -42,7 +40,6 @@ import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
|
||||
import java.util.*
|
||||
|
||||
class JavaResolverComponents(
|
||||
val storageManager: StorageManager,
|
||||
@@ -84,6 +81,7 @@ class JavaResolverComponents(
|
||||
interface JavaResolverSettings {
|
||||
val isReleaseCoroutines: Boolean
|
||||
val correctNullabilityForNotNullTypeParameter: Boolean
|
||||
val enhancementImprovements: Boolean
|
||||
|
||||
object Default : JavaResolverSettings {
|
||||
override val isReleaseCoroutines: Boolean
|
||||
@@ -91,16 +89,21 @@ interface JavaResolverSettings {
|
||||
|
||||
override val correctNullabilityForNotNullTypeParameter: Boolean
|
||||
get() = false
|
||||
|
||||
override val enhancementImprovements: Boolean
|
||||
get() = false
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun create(
|
||||
isReleaseCoroutines: Boolean,
|
||||
correctNullabilityForNotNullTypeParameter: Boolean
|
||||
correctNullabilityForNotNullTypeParameter: Boolean,
|
||||
enhancementImprovements: Boolean,
|
||||
): JavaResolverSettings =
|
||||
object : JavaResolverSettings {
|
||||
override val isReleaseCoroutines get() = isReleaseCoroutines
|
||||
override val correctNullabilityForNotNullTypeParameter get() = correctNullabilityForNotNullTypeParameter
|
||||
override val enhancementImprovements get() = enhancementImprovements
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -172,9 +175,11 @@ private fun LazyJavaResolverContext.extractDefaultNullabilityQualifier(
|
||||
return null
|
||||
}
|
||||
|
||||
val areImprovementsEnabled = components.settings.typeEnhancementImprovements
|
||||
|
||||
val nullabilityQualifier =
|
||||
components.signatureEnhancement.extractNullability(typeQualifier)?.copy(isForWarningOnly = jsr305State.isWarning)
|
||||
?: return null
|
||||
components.signatureEnhancement.extractNullability(typeQualifier, areImprovementsEnabled, typeParameterBounds = false)
|
||||
?.copy(isForWarningOnly = jsr305State.isWarning) ?: return null
|
||||
|
||||
return JavaDefaultQualifiers(nullabilityQualifier, applicability)
|
||||
}
|
||||
|
||||
+5
-1
@@ -208,7 +208,11 @@ class LazyJavaClassDescriptor(
|
||||
|
||||
for (javaType in javaTypes) {
|
||||
val kotlinType = c.typeResolver.transformJavaType(javaType, TypeUsage.SUPERTYPE.toAttributes())
|
||||
val enhancedKotlinType = c.components.signatureEnhancement.enhanceSuperType(kotlinType, c)
|
||||
val areImprovementsEnabled = c.components.settings.typeEnhancementImprovements
|
||||
val enhancedKotlinType = if (areImprovementsEnabled) {
|
||||
c.components.signatureEnhancement.enhanceSuperType(kotlinType, c)
|
||||
} else kotlinType
|
||||
|
||||
if (enhancedKotlinType.constructor.declarationDescriptor is NotFoundClasses.MockClassDescriptor) {
|
||||
incomplete.add(javaType)
|
||||
}
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ class JavaTypeResolver(
|
||||
fun transformArrayType(arrayType: JavaArrayType, attr: JavaTypeAttributes, isVararg: Boolean = false): KotlinType {
|
||||
val javaComponentType = arrayType.componentType
|
||||
val primitiveType = (javaComponentType as? JavaPrimitiveType)?.type
|
||||
val annotations = LazyJavaAnnotations(c, arrayType)
|
||||
val annotations = LazyJavaAnnotations(c, arrayType, areAnnotationsFreshlySupported = true)
|
||||
|
||||
if (primitiveType != null) {
|
||||
val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType)
|
||||
|
||||
+42
-25
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.load.java.*
|
||||
import org.jetbrains.kotlin.load.java.descriptors.*
|
||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||
import org.jetbrains.kotlin.load.java.lazy.copyWithNewDefaultTypeQualifiers
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaAnnotationDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
|
||||
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
|
||||
@@ -52,21 +53,25 @@ class SignatureEnhancement(
|
||||
private val typeEnhancement: JavaTypeEnhancement
|
||||
) {
|
||||
|
||||
private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? {
|
||||
private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(isForWarningOnly: Boolean): NullabilityQualifierWithMigrationStatus? {
|
||||
val enumValue = firstArgument() as? EnumValue
|
||||
// if no argument is specified, use default value: NOT_NULL
|
||||
?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
|
||||
?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
|
||||
|
||||
return when (enumValue.enumEntryName.asString()) {
|
||||
"ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
|
||||
"MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
|
||||
"UNKNOWN" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY)
|
||||
"ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
|
||||
"MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
|
||||
"UNKNOWN" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY, isForWarningOnly)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
fun extractNullability(annotationDescriptor: AnnotationDescriptor): NullabilityQualifierWithMigrationStatus? {
|
||||
extractNullabilityFromKnownAnnotations(annotationDescriptor)?.let { return it }
|
||||
fun extractNullability(
|
||||
annotationDescriptor: AnnotationDescriptor,
|
||||
areImprovementsEnabled: Boolean,
|
||||
typeParameterBounds: Boolean
|
||||
): NullabilityQualifierWithMigrationStatus? {
|
||||
extractNullabilityFromKnownAnnotations(annotationDescriptor, areImprovementsEnabled, typeParameterBounds)?.let { return it }
|
||||
|
||||
val typeQualifierAnnotation =
|
||||
annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor)
|
||||
@@ -75,18 +80,23 @@ class SignatureEnhancement(
|
||||
val jsr305State = annotationTypeQualifierResolver.resolveJsr305AnnotationState(annotationDescriptor)
|
||||
if (jsr305State.isIgnore) return null
|
||||
|
||||
return extractNullabilityFromKnownAnnotations(typeQualifierAnnotation)?.copy(isForWarningOnly = jsr305State.isWarning)
|
||||
return extractNullabilityFromKnownAnnotations(typeQualifierAnnotation, areImprovementsEnabled, typeParameterBounds)
|
||||
?.copy(isForWarningOnly = jsr305State.isWarning)
|
||||
}
|
||||
|
||||
private fun extractNullabilityFromKnownAnnotations(
|
||||
annotationDescriptor: AnnotationDescriptor
|
||||
annotationDescriptor: AnnotationDescriptor,
|
||||
areImprovementsEnabled: Boolean,
|
||||
typeParameterBounds: Boolean
|
||||
): NullabilityQualifierWithMigrationStatus? {
|
||||
val annotationFqName = annotationDescriptor.fqName ?: return null
|
||||
val isForWarningOnly = annotationDescriptor is LazyJavaAnnotationDescriptor
|
||||
&& (annotationDescriptor.isFreshlySupportedTypeUseAnnotation || typeParameterBounds)
|
||||
&& !areImprovementsEnabled
|
||||
|
||||
val migrationStatus =
|
||||
jspecifyMigrationStatus(annotationFqName)
|
||||
?: commonMigrationStatus(annotationFqName, annotationDescriptor)
|
||||
?: return null
|
||||
val migrationStatus = jspecifyMigrationStatus(annotationFqName)
|
||||
?: commonMigrationStatus(annotationFqName, annotationDescriptor, isForWarningOnly)
|
||||
?: return null
|
||||
|
||||
return if (!migrationStatus.isForWarningOnly
|
||||
&& annotationDescriptor is PossiblyExternalAnnotationDescriptor
|
||||
@@ -111,17 +121,18 @@ class SignatureEnhancement(
|
||||
|
||||
private fun commonMigrationStatus(
|
||||
annotationFqName: FqName,
|
||||
annotationDescriptor: AnnotationDescriptor
|
||||
annotationDescriptor: AnnotationDescriptor,
|
||||
isForWarningOnly: Boolean = false
|
||||
): NullabilityQualifierWithMigrationStatus? = when {
|
||||
annotationFqName in NULLABLE_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
|
||||
annotationFqName in NOT_NULL_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
|
||||
annotationFqName == JAVAX_NONNULL_ANNOTATION -> annotationDescriptor.extractNullabilityTypeFromArgument()
|
||||
annotationFqName in NULLABLE_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
|
||||
annotationFqName in NOT_NULL_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
|
||||
annotationFqName == JAVAX_NONNULL_ANNOTATION -> annotationDescriptor.extractNullabilityTypeFromArgument(isForWarningOnly)
|
||||
|
||||
annotationFqName == COMPATQUAL_NULLABLE_ANNOTATION && javaTypeEnhancementState.enableCompatqualCheckerFrameworkAnnotations ->
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
|
||||
|
||||
annotationFqName == COMPATQUAL_NONNULL_ANNOTATION && javaTypeEnhancementState.enableCompatqualCheckerFrameworkAnnotations ->
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
|
||||
|
||||
annotationFqName == ANDROIDX_RECENTLY_NON_NULL_ANNOTATION -> NullabilityQualifierWithMigrationStatus(
|
||||
NullabilityQualifier.NOT_NULL,
|
||||
@@ -326,10 +337,10 @@ class SignatureEnhancement(
|
||||
typeParameterForArgument: TypeParameterDescriptor?,
|
||||
isFromStarProjection: Boolean
|
||||
): JavaTypeQualifiers {
|
||||
val areImprovementsEnabled = containerContext.components.settings.typeEnhancementImprovements
|
||||
|
||||
val composedAnnotation =
|
||||
if (isHeadTypeConstructor && typeContainer is TypeParameterDescriptor) {
|
||||
composeAnnotations(typeContainer.annotations, annotations)
|
||||
} else if (isHeadTypeConstructor && typeContainer != null) {
|
||||
if (isHeadTypeConstructor && typeContainer != null && typeContainer !is TypeParameterDescriptor && areImprovementsEnabled) {
|
||||
val filteredContainerAnnotations = typeContainer.annotations.filter {
|
||||
val (_, targets) = annotationTypeQualifierResolver.resolveAnnotation(it) ?: return@filter false
|
||||
/*
|
||||
@@ -343,6 +354,8 @@ class SignatureEnhancement(
|
||||
AnnotationQualifierApplicabilityType.TYPE_USE !in targets
|
||||
}
|
||||
composeAnnotations(Annotations.create(filteredContainerAnnotations), annotations)
|
||||
} else if (isHeadTypeConstructor && typeContainer != null) {
|
||||
composeAnnotations(typeContainer.annotations, annotations)
|
||||
} else annotations
|
||||
|
||||
fun <T : Any> List<FqName>.ifPresent(qualifier: T) =
|
||||
@@ -361,7 +374,8 @@ class SignatureEnhancement(
|
||||
val (nullabilityFromBoundsForTypeBasedOnTypeParameter, isTypeParameterWithNotNullableBounds) =
|
||||
nullabilityInfoBoundsForTypeParameterUsage()
|
||||
|
||||
val annotationsNullability = composedAnnotation.extractNullability()?.takeUnless { isFromStarProjection }
|
||||
val annotationsNullability = composedAnnotation.extractNullability(areImprovementsEnabled, typeParameterBounds)
|
||||
?.takeUnless { isFromStarProjection }
|
||||
val nullabilityInfo =
|
||||
annotationsNullability
|
||||
?: computeNullabilityInfoInTheAbsenceOfExplicitAnnotation(
|
||||
@@ -452,8 +466,11 @@ class SignatureEnhancement(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Annotations.extractNullability(): NullabilityQualifierWithMigrationStatus? =
|
||||
this.firstNotNullResult { extractNullability(it) }
|
||||
private fun Annotations.extractNullability(
|
||||
areImprovementsEnabled: Boolean,
|
||||
typeParameterBounds: Boolean
|
||||
): NullabilityQualifierWithMigrationStatus? =
|
||||
this.firstNotNullResult { extractNullability(it, areImprovementsEnabled, typeParameterBounds) }
|
||||
|
||||
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user