Skip to content

Commit

Permalink
Don't assert that annotation class has constructor in AnnotationDeser…
Browse files Browse the repository at this point in the history
…ializer

 #KT-9758 Fixed
  • Loading branch information
udalov committed Nov 5, 2015
1 parent 1a0c2e2 commit 748c0e7
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package test

fun bar() = Test().foo("ok")
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
@@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ private File getTestDataFileWithExtension(@NotNull String extension) {
}

@NotNull
private File compileLibrary(@NotNull String sourcePath) {
return MockLibraryUtil.compileLibraryToJar(new File(getTestDataDirectory(), sourcePath).getPath(), "customKotlinLib", false);
private File compileLibrary(@NotNull String sourcePath, @NotNull String... extraClassPath) {
return MockLibraryUtil.compileLibraryToJar(
new File(getTestDataDirectory(), sourcePath).getPath(), "customKotlinLib", false, extraClassPath
);
}

private void doTestWithTxt(@NotNull File... extraClassPath) throws Exception {
Expand Down Expand Up @@ -341,4 +343,11 @@ public void visitSource(String source, String debug) {
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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull Calla
@Nullable
public static ValueParameterDescriptor getAnnotationParameterByName(@NotNull Name name, @NotNull ClassDescriptor annotationClass) {
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()) {
if (parameter.getName().equals(name)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.ClassId
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.ConstantValue
import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory
Expand All @@ -42,18 +43,18 @@ public class AnnotationDeserializer(private val module: ModuleDescriptor) {
private val factory = ConstantValueFactory(builtIns)

public fun deserializeAnnotation(proto: Annotation, nameResolver: NameResolver): AnnotationDescriptor {
val annotationClass = resolveClass(nameResolver.getClassId(proto.getId()))

val arguments = if (proto.getArgumentCount() == 0 || ErrorUtils.isError(annotationClass)) {
mapOf()
}
else {
val parameterByName = annotationClass.getConstructors().single().getValueParameters().toMap { it.getName() }
val arguments = proto.getArgumentList().map { resolveArgument(it, parameterByName, nameResolver) }.filterNotNull()
arguments.toMap()
val annotationClass = resolveClass(nameResolver.getClassId(proto.id))

var arguments = emptyMap<ValueParameterDescriptor, ConstantValue<*>>()
if (proto.argumentCount != 0 && !ErrorUtils.isError(annotationClass) && DescriptorUtils.isAnnotationClass(annotationClass)) {
val constructor = annotationClass.constructors.singleOrNull()
if (constructor != null) {
val parameterByName = constructor.valueParameters.toMapBy { it.name }
arguments = proto.argumentList.map { resolveArgument(it, parameterByName, nameResolver) }.filterNotNull().toMap()
}
}

return AnnotationDescriptorImpl(annotationClass.getDefaultType(), arguments, SourceElement.NO_SOURCE)
return AnnotationDescriptorImpl(annotationClass.defaultType, arguments, SourceElement.NO_SOURCE)
}

private fun resolveArgument(
Expand Down

0 comments on commit 748c0e7

Please sign in to comment.