diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 133ccc22a8c..edabcbcf394 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -243,7 +243,7 @@ public class JavaDescriptorResolver { // Example: // class Kotlin() : Java() {} // abstract public class Java {} - if (!psiClass.isInterface() || psiClass.isAnnotationType()) { + if (!psiClass.isInterface()) { ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl( classData.classDescriptor, Collections.emptyList(), @@ -253,6 +253,47 @@ public class JavaDescriptorResolver { classData.classDescriptor.addConstructor(constructorDescriptor, null); semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor); } + if (psiClass.isAnnotationType()) { + // A constructor for an annotation type takes all the "methods" in the @interface as parameters + ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl( + classData.classDescriptor, + Collections.emptyList(), + false); + + List valueParameters = Lists.newArrayList(); + PsiMethod[] methods = psiClass.getMethods(); + for (int i = 0; i < methods.length; i++) { + PsiMethod method = methods[i]; + if (method instanceof PsiAnnotationMethod) { + PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod) method; + assert annotationMethod.getParameterList().getParameters().length == 0; + + PsiType returnType = annotationMethod.getReturnType(); + + // We take the following heuristical convention: + // if the last method of the @interface is an array, we convert it into a vararg + JetType varargElementType = null; + if (i == methods.length - 1 && (returnType instanceof PsiArrayType)) { + varargElementType = semanticServices.getTypeTransformer().transformToType(((PsiArrayType) returnType).getComponentType()); + } + + valueParameters.add(new ValueParameterDescriptorImpl( + constructorDescriptor, + i, + Collections.emptyList(), + method.getName(), + false, + semanticServices.getTypeTransformer().transformToType(returnType), + annotationMethod.getDefaultValue() != null, + varargElementType)); + } + } + + constructorDescriptor.initialize(typeParameters, valueParameters, Modality.FINAL, classData.classDescriptor.getVisibility()); + constructorDescriptor.setReturnType(classData.classDescriptor.getDefaultType()); + classData.classDescriptor.addConstructor(constructorDescriptor, null); + semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor); + } } else { for (PsiMethod psiConstructor : psiConstructors) { diff --git a/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.jet b/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.jet new file mode 100644 index 00000000000..54802945bca --- /dev/null +++ b/compiler/testData/diagnostics/tests/annotations/JavaAnnotationConstructors.jet @@ -0,0 +1,5 @@ +// +JDK +import java.lang.annotation.* + +annotation [java.lang.annotation.Retention(RetentionPolicy.CLASS)] class my +annotation Retention(RetentionPolicy.RUNTIME) Target(ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR) class my1