Kapt: Support import directive with aliases in "correctErrorTypes" mode (KT-21358)
This commit is contained in:
+10
-13
@@ -204,16 +204,12 @@ class ClassFileToSourceStubConverter(
|
||||
|
||||
for (importDirective in file.importDirectives) {
|
||||
// Qualified name should be valid Java fq-name
|
||||
val importedFqName = importDirective.importedFqName ?: continue
|
||||
val importedFqName = importDirective.importedFqName?.takeIf { it.pathSegments().size > 1 } ?: continue
|
||||
if (!isValidQualifiedName(importedFqName)) continue
|
||||
|
||||
val shortName = importedFqName.shortName()
|
||||
if (shortName.asString() == classDeclaration.simpleName.toString()) continue
|
||||
|
||||
// If alias is specified, it also should be valid Java name
|
||||
val aliasName = importDirective.aliasName
|
||||
if (aliasName != null /*TODO support aliases */ /*&& getValidIdentifierName(aliasName) == null*/) continue
|
||||
|
||||
val importedReference = getReferenceExpression(importDirective.importedReference)
|
||||
?.let { kaptContext.bindingContext[BindingContext.REFERENCE_TARGET, it] }
|
||||
|
||||
@@ -231,12 +227,6 @@ class ClassFileToSourceStubConverter(
|
||||
return JavacList.from(imports)
|
||||
}
|
||||
|
||||
private tailrec fun getReferenceExpression(expression: KtExpression?): KtReferenceExpression? = when (expression) {
|
||||
is KtReferenceExpression -> expression
|
||||
is KtQualifiedExpression -> getReferenceExpression(expression.selectorExpression)
|
||||
else -> null
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns false for the inner classes or if the origin for the class was not found.
|
||||
*/
|
||||
@@ -637,9 +627,10 @@ class ClassFileToSourceStubConverter(
|
||||
|
||||
if (type?.containsErrorTypes() == true) {
|
||||
val typeFromSource = ktTypeProvider()?.typeElement
|
||||
if (typeFromSource != null) {
|
||||
val ktFile = typeFromSource?.containingKtFile
|
||||
if (ktFile != null) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return ErrorTypeCorrector(this, kind).convert(typeFromSource, emptyMap()) as T
|
||||
return ErrorTypeCorrector(this, kind, ktFile).convert(typeFromSource, emptyMap()) as T
|
||||
}
|
||||
}
|
||||
|
||||
@@ -917,6 +908,12 @@ private fun Any?.isOfPrimiviteType(): Boolean = when(this) {
|
||||
private val ClassDescriptor.isNested: Boolean
|
||||
get() = containingDeclaration is ClassDescriptor
|
||||
|
||||
internal tailrec fun getReferenceExpression(expression: KtExpression?): KtReferenceExpression? = when (expression) {
|
||||
is KtReferenceExpression -> expression
|
||||
is KtQualifiedExpression -> getReferenceExpression(expression.selectorExpression)
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal fun getAnnotationValue(fqName: FqName, mods: JCTree.JCModifiers?): String? {
|
||||
val annotations = mods?.annotations ?: return null
|
||||
|
||||
|
||||
+29
-4
@@ -37,13 +37,30 @@ private typealias SubstitutionMap = Map<String, Pair<KtTypeParameter, KtTypeProj
|
||||
|
||||
class ErrorTypeCorrector(
|
||||
private val converter: ClassFileToSourceStubConverter,
|
||||
private val typeKind: TypeKind
|
||||
private val typeKind: TypeKind,
|
||||
file: KtFile
|
||||
) {
|
||||
private val defaultType = converter.treeMaker.FqName(Object::class.java.name)
|
||||
|
||||
private val bindingContext get() = converter.kaptContext.bindingContext
|
||||
private val treeMaker get() = converter.treeMaker
|
||||
|
||||
private val aliasedImports = mutableMapOf<String, JCTree.JCExpression>().apply {
|
||||
for (importDirective in file.importDirectives) {
|
||||
if (importDirective.isAllUnder) continue
|
||||
|
||||
val aliasName = importDirective.aliasName ?: continue
|
||||
val importedFqName = importDirective.importedFqName ?: continue
|
||||
|
||||
val importedReference = getReferenceExpression(importDirective.importedReference)
|
||||
?.let { bindingContext[BindingContext.REFERENCE_TARGET, it] }
|
||||
|
||||
if (importedReference is CallableDescriptor) continue
|
||||
|
||||
this[aliasName] = treeMaker.FqName(importedFqName)
|
||||
}
|
||||
}
|
||||
|
||||
enum class TypeKind {
|
||||
RETURN_TYPE, METHOD_PARAMETER_TYPE
|
||||
}
|
||||
@@ -85,9 +102,13 @@ class ErrorTypeCorrector(
|
||||
val referencedName = type.referencedName ?: return defaultType
|
||||
val qualifier = type.qualifier
|
||||
|
||||
if (qualifier == null && referencedName in substitutions) {
|
||||
val (typeParameter, projection) = substitutions.getValue(referencedName)
|
||||
return convertTypeProjection(projection, typeParameter.variance, emptyMap())
|
||||
if (qualifier == null) {
|
||||
if (referencedName in substitutions) {
|
||||
val (typeParameter, projection) = substitutions.getValue(referencedName)
|
||||
return convertTypeProjection(projection, typeParameter.variance, emptyMap())
|
||||
}
|
||||
|
||||
aliasedImports[referencedName]?.let { return it }
|
||||
}
|
||||
|
||||
baseExpression = when {
|
||||
@@ -155,6 +176,10 @@ class ErrorTypeCorrector(
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertTypeProjection() {
|
||||
|
||||
}
|
||||
|
||||
private fun convertFunctionType(type: KtFunctionType, substitutions: SubstitutionMap): JCTree.JCExpression {
|
||||
val receiverType = type.receiverTypeReference
|
||||
var parameterTypes = mapJList(type.parameters) { convert(it.typeReference, substitutions) }
|
||||
|
||||
+6
@@ -44,6 +44,12 @@ public class ClassFileToSourceStubConverterTestGenerated extends AbstractClassFi
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("aliasedImports.kt")
|
||||
public void testAliasedImports() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("plugins/kapt3/kapt3-compiler/testData/converter/aliasedImports.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInConverter() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("plugins/kapt3/kapt3-compiler/testData/converter"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// CORRECT_ERROR_TYPES
|
||||
// NO_VALIDATION
|
||||
|
||||
@file:Suppress("ENUM_ENTRY_AS_TYPE", "UNRESOLVED_REFERENCE")
|
||||
import java.util.Date as MyDate
|
||||
import java.util.concurrent.TimeUnit as MyTimeUnit
|
||||
import java.util.concurrent.TimeUnit.MICROSECONDS as MyMicroseconds
|
||||
import a.b.ABC as MyABC
|
||||
import bcd as MyBCD
|
||||
|
||||
class Test {
|
||||
lateinit var date: MyDate
|
||||
lateinit var timeUnit: MyTimeUnit
|
||||
lateinit var microseconds: MyMicroseconds
|
||||
|
||||
lateinit var abc: MyABC
|
||||
lateinit var bcd: MyBCD
|
||||
|
||||
class MyDate {
|
||||
lateinit var date2: MyDate
|
||||
}
|
||||
}
|
||||
|
||||
class Test2 {
|
||||
lateinit var date: MyDate
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeUnit.MICROSECONDS;
|
||||
import a.b.ABC;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@kapt.internal.KaptMetadata()
|
||||
public final class Test {
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public Test.MyDate date;
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public java.util.concurrent.TimeUnit timeUnit;
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public java.util.concurrent.TimeUnit microseconds;
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public a.b.ABC abc;
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public bcd bcd;
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getDate()LTest$MyDate;")
|
||||
public final Test.MyDate getDate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setDate(LTest$MyDate;)V")
|
||||
public final void setDate(@org.jetbrains.annotations.NotNull()
|
||||
Test.MyDate p0) {
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getTimeUnit()Ljava/util/concurrent/TimeUnit;")
|
||||
public final java.util.concurrent.TimeUnit getTimeUnit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setTimeUnit(Ljava/util/concurrent/TimeUnit;)V")
|
||||
public final void setTimeUnit(@org.jetbrains.annotations.NotNull()
|
||||
java.util.concurrent.TimeUnit p0) {
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getMicroseconds()Ljava/util/concurrent/TimeUnit;")
|
||||
public final java.util.concurrent.TimeUnit getMicroseconds() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setMicroseconds(Ljava/util/concurrent/TimeUnit;)V")
|
||||
public final void setMicroseconds(@org.jetbrains.annotations.NotNull()
|
||||
java.util.concurrent.TimeUnit p0) {
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getAbc()Lerror/NonExistentClass;")
|
||||
public final a.b.ABC getAbc() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setAbc(Lerror/NonExistentClass;)V")
|
||||
public final void setAbc(@org.jetbrains.annotations.NotNull()
|
||||
a.b.ABC p0) {
|
||||
}
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getBcd()Lerror/NonExistentClass;")
|
||||
public final bcd getBcd() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setBcd(Lerror/NonExistentClass;)V")
|
||||
public final void setBcd(@org.jetbrains.annotations.NotNull()
|
||||
bcd p0) {
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("<init>()V")
|
||||
public Test() {
|
||||
super();
|
||||
}
|
||||
|
||||
@kotlin.Metadata()
|
||||
public static final class MyDate {
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public Test.MyDate date2;
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getDate2()LTest$MyDate;")
|
||||
public final Test.MyDate getDate2() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setDate2(LTest$MyDate;)V")
|
||||
public final void setDate2(@org.jetbrains.annotations.NotNull()
|
||||
Test.MyDate p0) {
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("<init>()V")
|
||||
public MyDate() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeUnit.MICROSECONDS;
|
||||
import a.b.ABC;
|
||||
|
||||
@kotlin.Metadata()
|
||||
@kapt.internal.KaptMetadata()
|
||||
public final class Test2 {
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
public java.util.Date date;
|
||||
|
||||
@org.jetbrains.annotations.NotNull()
|
||||
@kapt.internal.KaptSignature("getDate()Ljava/util/Date;")
|
||||
public final java.util.Date getDate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("setDate(Ljava/util/Date;)V")
|
||||
public final void setDate(@org.jetbrains.annotations.NotNull()
|
||||
java.util.Date p0) {
|
||||
}
|
||||
|
||||
@kapt.internal.KaptSignature("<init>()V")
|
||||
public Test2() {
|
||||
super();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package kapt.internal;
|
||||
|
||||
public @interface KaptMetadata {
|
||||
|
||||
public java.lang.String value();
|
||||
}
|
||||
|
||||
////////////////////
|
||||
|
||||
package kapt.internal;
|
||||
|
||||
public @interface KaptSignature {
|
||||
|
||||
public java.lang.String value();
|
||||
}
|
||||
Reference in New Issue
Block a user