Don't assert that annotation class has constructor in AnnotationDeserializer
#KT-9758 Fixed
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.annotation.AnnotationTarget.*
|
||||||
|
|
||||||
|
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPE, EXPRESSION, FILE)
|
||||||
|
annotation class Ann(val s: String)
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
// Ha! Ann is no longer an annotation, it's an interface instead. But we shouldn't assert it anywhere in the compiler
|
||||||
|
interface Ann
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
fun bar() = Test().foo("ok")
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
public fun bar(): @test.Ann() kotlin.String
|
||||||
|
|
||||||
|
public interface Ann {
|
||||||
|
}
|
||||||
|
|
||||||
|
@test.Ann() public final class Test {
|
||||||
|
public constructor Test()
|
||||||
|
@test.Ann() public final fun foo(/*0*/ @test.Ann() s: @test.Ann() kotlin.String): @test.Ann() kotlin.String
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
@Ann("class")
|
||||||
|
class Test {
|
||||||
|
@Ann("function")
|
||||||
|
fun foo(@Ann("parameter") s: @Ann("parameter type") String): @Ann("return type") String = @Ann("expression") s
|
||||||
|
}
|
||||||
+11
-2
@@ -69,8 +69,10 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private File compileLibrary(@NotNull String sourcePath) {
|
private File compileLibrary(@NotNull String sourcePath, @NotNull String... extraClassPath) {
|
||||||
return MockLibraryUtil.compileLibraryToJar(new File(getTestDataDirectory(), sourcePath).getPath(), "customKotlinLib", false);
|
return MockLibraryUtil.compileLibraryToJar(
|
||||||
|
new File(getTestDataDirectory(), sourcePath).getPath(), "customKotlinLib", false, extraClassPath
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void doTestWithTxt(@NotNull File... extraClassPath) throws Exception {
|
private void doTestWithTxt(@NotNull File... extraClassPath) throws Exception {
|
||||||
@@ -341,4 +343,11 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
|||||||
assertEquals(null, debugInfo.get());
|
assertEquals(null, debugInfo.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testReplaceAnnotationClassWithInterface() throws Exception {
|
||||||
|
File library1 = compileLibrary("library-1");
|
||||||
|
File usage = compileLibrary("usage", library1.getPath());
|
||||||
|
File library2 = compileLibrary("library-2");
|
||||||
|
doTestWithTxt(usage, library2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ public final class DescriptorResolverUtils {
|
|||||||
@Nullable
|
@Nullable
|
||||||
public static ValueParameterDescriptor getAnnotationParameterByName(@NotNull Name name, @NotNull ClassDescriptor annotationClass) {
|
public static ValueParameterDescriptor getAnnotationParameterByName(@NotNull Name name, @NotNull ClassDescriptor annotationClass) {
|
||||||
Collection<ConstructorDescriptor> constructors = annotationClass.getConstructors();
|
Collection<ConstructorDescriptor> constructors = annotationClass.getConstructors();
|
||||||
assert constructors.size() == 1 : "Annotation class descriptor must have only one constructor";
|
if (constructors.size() != 1) return null;
|
||||||
|
|
||||||
for (ValueParameterDescriptor parameter : constructors.iterator().next().getValueParameters()) {
|
for (ValueParameterDescriptor parameter : constructors.iterator().next().getValueParameters()) {
|
||||||
if (parameter.getName().equals(name)) {
|
if (parameter.getName().equals(name)) {
|
||||||
|
|||||||
+10
-9
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
|
|||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
|
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
|
||||||
@@ -42,18 +43,18 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
|
|||||||
private val factory = ConstantValueFactory(builtIns)
|
private val factory = ConstantValueFactory(builtIns)
|
||||||
|
|
||||||
public fun deserializeAnnotation(proto: Annotation, nameResolver: NameResolver): AnnotationDescriptor {
|
public fun deserializeAnnotation(proto: Annotation, nameResolver: NameResolver): AnnotationDescriptor {
|
||||||
val annotationClass = resolveClass(nameResolver.getClassId(proto.getId()))
|
val annotationClass = resolveClass(nameResolver.getClassId(proto.id))
|
||||||
|
|
||||||
val arguments = if (proto.getArgumentCount() == 0 || ErrorUtils.isError(annotationClass)) {
|
var arguments = emptyMap<ValueParameterDescriptor, ConstantValue<*>>()
|
||||||
mapOf()
|
if (proto.argumentCount != 0 && !ErrorUtils.isError(annotationClass) && DescriptorUtils.isAnnotationClass(annotationClass)) {
|
||||||
}
|
val constructor = annotationClass.constructors.singleOrNull()
|
||||||
else {
|
if (constructor != null) {
|
||||||
val parameterByName = annotationClass.getConstructors().single().getValueParameters().toMap { it.getName() }
|
val parameterByName = constructor.valueParameters.toMapBy { it.name }
|
||||||
val arguments = proto.getArgumentList().map { resolveArgument(it, parameterByName, nameResolver) }.filterNotNull()
|
arguments = proto.argumentList.map { resolveArgument(it, parameterByName, nameResolver) }.filterNotNull().toMap()
|
||||||
arguments.toMap()
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments, SourceElement.NO_SOURCE)
|
return AnnotationDescriptorImpl(annotationClass.defaultType, arguments, SourceElement.NO_SOURCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resolveArgument(
|
private fun resolveArgument(
|
||||||
|
|||||||
Reference in New Issue
Block a user