Deserialize annotations on value parameters of functions
This commit is contained in:
+7
-1
@@ -141,7 +141,7 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||||
final AnnotationVisitor v = memberVisitor.visitMethod(Name.guess(name), desc);
|
final MethodAnnotationVisitor v = memberVisitor.visitMethod(Name.guess(name), desc);
|
||||||
if (v == null) return null;
|
if (v == null) return null;
|
||||||
|
|
||||||
return new MethodVisitor(ASM4) {
|
return new MethodVisitor(ASM4) {
|
||||||
@@ -150,6 +150,12 @@ public class VirtualFileKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
return convertAnnotationVisitor(v, desc);
|
return convertAnnotationVisitor(v, desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public org.jetbrains.asm4.AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) {
|
||||||
|
AnnotationArgumentVisitor av = v.visitParameterAnnotation(parameter, classNameFromAsmDesc(desc));
|
||||||
|
return av == null ? null : convertAnnotationVisitor(av);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitEnd() {
|
public void visitEnd() {
|
||||||
v.visitEnd();
|
v.visitEnd();
|
||||||
|
|||||||
+26
-18
@@ -237,7 +237,7 @@ public class DescriptorDeserializer {
|
|||||||
local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
|
local.typeDeserializer.typeOrNull(proto.hasReceiverType() ? proto.getReceiverType() : null),
|
||||||
getExpectedThisObject(),
|
getExpectedThisObject(),
|
||||||
typeParameters,
|
typeParameters,
|
||||||
local.valueParameters(proto.getValueParameterList()),
|
local.valueParameters(proto),
|
||||||
local.typeDeserializer.type(proto.getReturnType()),
|
local.typeDeserializer.type(proto.getReturnType()),
|
||||||
modality(Flags.MODALITY.get(flags)),
|
modality(Flags.MODALITY.get(flags)),
|
||||||
visibility(Flags.VISIBILITY.get(flags)),
|
visibility(Flags.VISIBILITY.get(flags)),
|
||||||
@@ -265,7 +265,7 @@ public class DescriptorDeserializer {
|
|||||||
DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
|
DescriptorDeserializer local = createChildDeserializer(descriptor, Collections.<TypeParameter>emptyList(), typeParameters);
|
||||||
descriptor.initialize(
|
descriptor.initialize(
|
||||||
classDescriptor.getTypeConstructor().getParameters(),
|
classDescriptor.getTypeConstructor().getParameters(),
|
||||||
local.valueParameters(proto.getValueParameterList()),
|
local.valueParameters(proto),
|
||||||
visibility(Flags.VISIBILITY.get(proto.getFlags())),
|
visibility(Flags.VISIBILITY.get(proto.getFlags())),
|
||||||
DescriptorUtils.isConstructorOfStaticNestedClass(descriptor)
|
DescriptorUtils.isConstructorOfStaticNestedClass(descriptor)
|
||||||
);
|
);
|
||||||
@@ -384,29 +384,37 @@ public class DescriptorDeserializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<ValueParameterDescriptor> valueParameters(@NotNull List<Callable.ValueParameter> protos) {
|
private List<ValueParameterDescriptor> valueParameters(@NotNull Callable callable) {
|
||||||
|
DeclarationDescriptor containerOfCallable = containingDeclaration.getContainingDeclaration();
|
||||||
|
assert containerOfCallable instanceof ClassOrNamespaceDescriptor
|
||||||
|
: "Only members in classes or namespaces should be serialized: " + containerOfCallable;
|
||||||
|
ClassOrNamespaceDescriptor classOrNamespace = (ClassOrNamespaceDescriptor) containerOfCallable;
|
||||||
|
|
||||||
|
List<Callable.ValueParameter> protos = callable.getValueParameterList();
|
||||||
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(protos.size());
|
List<ValueParameterDescriptor> result = new ArrayList<ValueParameterDescriptor>(protos.size());
|
||||||
for (int i = 0; i < protos.size(); i++) {
|
for (int i = 0; i < protos.size(); i++) {
|
||||||
Callable.ValueParameter proto = protos.get(i);
|
Callable.ValueParameter proto = protos.get(i);
|
||||||
result.add(valueParameter(proto, i));
|
result.add(new ValueParameterDescriptorImpl(
|
||||||
|
containingDeclaration,
|
||||||
|
i,
|
||||||
|
getAnnotations(classOrNamespace, callable, proto),
|
||||||
|
nameResolver.getName(proto.getName()),
|
||||||
|
typeDeserializer.type(proto.getType()),
|
||||||
|
Flags.DECLARES_DEFAULT_VALUE.get(proto.getFlags()),
|
||||||
|
typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ValueParameterDescriptor valueParameter(Callable.ValueParameter proto, int index) {
|
@NotNull
|
||||||
return new ValueParameterDescriptorImpl(
|
private List<AnnotationDescriptor> getAnnotations(
|
||||||
containingDeclaration,
|
@NotNull ClassOrNamespaceDescriptor classOrNamespace,
|
||||||
index,
|
@NotNull Callable callable,
|
||||||
getAnnotations(proto),
|
@NotNull Callable.ValueParameter valueParameter
|
||||||
nameResolver.getName(proto.getName()),
|
) {
|
||||||
typeDeserializer.type(proto.getType()),
|
return Flags.HAS_ANNOTATIONS.get(valueParameter.getFlags())
|
||||||
Flags.DECLARES_DEFAULT_VALUE.get(proto.getFlags()),
|
? annotationDeserializer.loadValueParameterAnnotations(classOrNamespace, callable, nameResolver, valueParameter)
|
||||||
typeDeserializer.typeOrNull(proto.hasVarargElementType() ? proto.getVarargElementType() : null));
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<AnnotationDescriptor> getAnnotations(Callable.ValueParameter proto) {
|
|
||||||
return Flags.HAS_ANNOTATIONS.get(proto.getFlags())
|
|
||||||
? annotationDeserializer.loadValueParameterAnnotations(proto)
|
|
||||||
: Collections.<AnnotationDescriptor>emptyList();
|
: Collections.<AnnotationDescriptor>emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-2
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
package org.jetbrains.jet.descriptors.serialization.descriptors;
|
package org.jetbrains.jet.descriptors.serialization.descriptors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -30,7 +46,12 @@ public interface AnnotationDeserializer {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
|
public List<AnnotationDescriptor> loadValueParameterAnnotations(
|
||||||
|
@NotNull ClassOrNamespaceDescriptor container,
|
||||||
|
@NotNull ProtoBuf.Callable callable,
|
||||||
|
@NotNull NameResolver nameResolver,
|
||||||
|
@NotNull ProtoBuf.Callable.ValueParameter proto
|
||||||
|
) {
|
||||||
return notSupported();
|
return notSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,5 +80,10 @@ public interface AnnotationDeserializer {
|
|||||||
);
|
);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto);
|
List<AnnotationDescriptor> loadValueParameterAnnotations(
|
||||||
|
@NotNull ClassOrNamespaceDescriptor container,
|
||||||
|
@NotNull ProtoBuf.Callable callable,
|
||||||
|
@NotNull NameResolver nameResolver,
|
||||||
|
@NotNull ProtoBuf.Callable.ValueParameter proto
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class A
|
||||||
|
annotation class B
|
||||||
|
|
||||||
|
class Class([A] val x: Int, [B] y: String)
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class A : jet.Annotation {
|
||||||
|
/*primary*/ public constructor A()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final annotation class B : jet.Annotation {
|
||||||
|
/*primary*/ public constructor B()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class Class {
|
||||||
|
/*primary*/ public constructor Class(/*0*/ test.A() x: jet.Int, /*1*/ test.B() y: jet.String)
|
||||||
|
test.A() internal final val x: jet.Int
|
||||||
|
internal final fun <get-x>(): jet.Int
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class A
|
||||||
|
annotation class B
|
||||||
|
|
||||||
|
enum class E([A] val x: String, [B] val y: Int)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class A : jet.Annotation {
|
||||||
|
/*primary*/ public constructor A()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final annotation class B : jet.Annotation {
|
||||||
|
/*primary*/ public constructor B()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final enum class E : jet.Enum<test.E> {
|
||||||
|
/*primary*/ private constructor E(/*0*/ test.A() x: jet.String, /*1*/ test.B() y: jet.Int)
|
||||||
|
test.A() internal final val x: jet.String
|
||||||
|
internal final fun <get-x>(): jet.String
|
||||||
|
test.B() internal final val y: jet.Int
|
||||||
|
internal final fun <get-y>(): jet.Int
|
||||||
|
public final override /*1*/ /*fake_override*/ fun name(): jet.String
|
||||||
|
public final override /*1*/ /*fake_override*/ fun ordinal(): jet.Int
|
||||||
|
|
||||||
|
internal class object <class-object-for-E> {
|
||||||
|
/*primary*/ private constructor <class-object-for-E>()
|
||||||
|
public final fun valueOf(/*0*/ value: jet.String): test.E
|
||||||
|
public final fun values(): jet.Array<test.E>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class A
|
||||||
|
|
||||||
|
fun Int.foo([A] x: Int) {}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal fun jet.Int.foo(/*0*/ test.A() x: jet.Int): jet.Unit
|
||||||
|
|
||||||
|
internal final annotation class A : jet.Annotation {
|
||||||
|
/*primary*/ public constructor A()
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
class Class {
|
||||||
|
fun String.foo([Anno] x: Int) = 42
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class Class {
|
||||||
|
/*primary*/ public constructor Class()
|
||||||
|
internal final fun jet.String.foo(/*0*/ test.Anno() x: jet.Int): jet.Int
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
class Class {
|
||||||
|
fun foo([Anno] x: String) {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class Class {
|
||||||
|
/*primary*/ public constructor Class()
|
||||||
|
internal final fun foo(/*0*/ test.Anno() x: jet.String): jet.Unit
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
fun foo([Anno] x: String) = 42
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal trait Trait {
|
||||||
|
internal open fun foo(/*0*/ test.Anno() x: jet.String): jet.Int
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class A
|
||||||
|
annotation class B
|
||||||
|
annotation class C
|
||||||
|
annotation class D
|
||||||
|
|
||||||
|
fun foo([A B] x: Int, [A C] y: Double, [B C D] z: String) {}
|
||||||
|
|
||||||
|
fun bar([A B C D] x: Int) {}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal fun bar(/*0*/ test.A() test.B() test.C() test.D() x: jet.Int): jet.Unit
|
||||||
|
internal fun foo(/*0*/ test.A() test.B() x: jet.Int, /*1*/ test.A() test.C() y: jet.Double, /*2*/ test.B() test.C() test.D() z: jet.String): jet.Unit
|
||||||
|
|
||||||
|
internal final annotation class A : jet.Annotation {
|
||||||
|
/*primary*/ public constructor A()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final annotation class B : jet.Annotation {
|
||||||
|
/*primary*/ public constructor B()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final annotation class C : jet.Annotation {
|
||||||
|
/*primary*/ public constructor C()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final annotation class D : jet.Annotation {
|
||||||
|
/*primary*/ public constructor D()
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
fun foo([Anno] x: Int) {}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal fun foo(/*0*/ test.Anno() x: jet.Int): jet.Unit
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
@@ -38,7 +38,7 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadKotlin/annotations")
|
@TestMetadata("compiler/testData/loadKotlin/annotations")
|
||||||
@InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class, Annotations.PropertiesWithoutBackingFields.class})
|
@InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class, Annotations.Parameters.class, Annotations.PropertiesWithoutBackingFields.class})
|
||||||
public static class Annotations extends AbstractLoadCompiledKotlinTest {
|
public static class Annotations extends AbstractLoadCompiledKotlinTest {
|
||||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
@@ -183,6 +183,54 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/loadKotlin/annotations/parameters")
|
||||||
|
public static class Parameters extends AbstractLoadCompiledKotlinTest {
|
||||||
|
public void testAllFilesPresentInParameters() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/parameters"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/Constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("EnumConstructor.kt")
|
||||||
|
public void testEnumConstructor() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/EnumConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ExtensionFunction.kt")
|
||||||
|
public void testExtensionFunction() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/ExtensionFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ExtensionFunctionInClass.kt")
|
||||||
|
public void testExtensionFunctionInClass() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/ExtensionFunctionInClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FunctionInClass.kt")
|
||||||
|
public void testFunctionInClass() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/FunctionInClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FunctionInTrait.kt")
|
||||||
|
public void testFunctionInTrait() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/FunctionInTrait.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ManyAnnotations.kt")
|
||||||
|
public void testManyAnnotations() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/ManyAnnotations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TopLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/parameters/TopLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields")
|
@TestMetadata("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields")
|
||||||
public static class PropertiesWithoutBackingFields extends AbstractLoadCompiledKotlinTest {
|
public static class PropertiesWithoutBackingFields extends AbstractLoadCompiledKotlinTest {
|
||||||
public void testAllFilesPresentInPropertiesWithoutBackingFields() throws Exception {
|
public void testAllFilesPresentInPropertiesWithoutBackingFields() throws Exception {
|
||||||
@@ -237,6 +285,7 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
suite.addTestSuite(ClassMembers.class);
|
suite.addTestSuite(ClassMembers.class);
|
||||||
suite.addTestSuite(Classes.class);
|
suite.addTestSuite(Classes.class);
|
||||||
suite.addTestSuite(PackageMembers.class);
|
suite.addTestSuite(PackageMembers.class);
|
||||||
|
suite.addTestSuite(Parameters.class);
|
||||||
suite.addTestSuite(PropertiesWithoutBackingFields.class);
|
suite.addTestSuite(PropertiesWithoutBackingFields.class);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|||||||
+50
-1
@@ -40,7 +40,7 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadKotlin/annotations")
|
@TestMetadata("compiler/testData/loadKotlin/annotations")
|
||||||
@InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class, Annotations.PropertiesWithoutBackingFields.class})
|
@InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class, Annotations.PackageMembers.class, Annotations.Parameters.class, Annotations.PropertiesWithoutBackingFields.class})
|
||||||
public static class Annotations extends AbstractLazyResolveNamespaceComparingTest {
|
public static class Annotations extends AbstractLazyResolveNamespaceComparingTest {
|
||||||
public void testAllFilesPresentInAnnotations() throws Exception {
|
public void testAllFilesPresentInAnnotations() throws Exception {
|
||||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true);
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
@@ -185,6 +185,54 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/loadKotlin/annotations/parameters")
|
||||||
|
public static class Parameters extends AbstractLazyResolveNamespaceComparingTest {
|
||||||
|
public void testAllFilesPresentInParameters() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/parameters"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Constructor.kt")
|
||||||
|
public void testConstructor() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/Constructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("EnumConstructor.kt")
|
||||||
|
public void testEnumConstructor() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/EnumConstructor.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ExtensionFunction.kt")
|
||||||
|
public void testExtensionFunction() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/ExtensionFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ExtensionFunctionInClass.kt")
|
||||||
|
public void testExtensionFunctionInClass() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/ExtensionFunctionInClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FunctionInClass.kt")
|
||||||
|
public void testFunctionInClass() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/FunctionInClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("FunctionInTrait.kt")
|
||||||
|
public void testFunctionInTrait() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/FunctionInTrait.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("ManyAnnotations.kt")
|
||||||
|
public void testManyAnnotations() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/ManyAnnotations.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TopLevelFunction.kt")
|
||||||
|
public void testTopLevelFunction() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/parameters/TopLevelFunction.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields")
|
@TestMetadata("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields")
|
||||||
public static class PropertiesWithoutBackingFields extends AbstractLazyResolveNamespaceComparingTest {
|
public static class PropertiesWithoutBackingFields extends AbstractLazyResolveNamespaceComparingTest {
|
||||||
public void testAllFilesPresentInPropertiesWithoutBackingFields() throws Exception {
|
public void testAllFilesPresentInPropertiesWithoutBackingFields() throws Exception {
|
||||||
@@ -239,6 +287,7 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
suite.addTestSuite(ClassMembers.class);
|
suite.addTestSuite(ClassMembers.class);
|
||||||
suite.addTestSuite(Classes.class);
|
suite.addTestSuite(Classes.class);
|
||||||
suite.addTestSuite(PackageMembers.class);
|
suite.addTestSuite(PackageMembers.class);
|
||||||
|
suite.addTestSuite(Parameters.class);
|
||||||
suite.addTestSuite(PropertiesWithoutBackingFields.class);
|
suite.addTestSuite(PropertiesWithoutBackingFields.class);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-19
@@ -233,6 +233,17 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
|||||||
MemberSignature signature = getCallableSignature(proto, nameResolver, kind);
|
MemberSignature signature = getCallableSignature(proto, nameResolver, kind);
|
||||||
if (signature == null) return Collections.emptyList();
|
if (signature == null) return Collections.emptyList();
|
||||||
|
|
||||||
|
return findClassAndLoadMemberAnnotations(container, proto, nameResolver, kind, signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private List<AnnotationDescriptor> findClassAndLoadMemberAnnotations(
|
||||||
|
@NotNull ClassOrNamespaceDescriptor container,
|
||||||
|
@NotNull ProtoBuf.Callable proto,
|
||||||
|
@NotNull NameResolver nameResolver,
|
||||||
|
@NotNull AnnotatedCallableKind kind,
|
||||||
|
@NotNull MemberSignature signature
|
||||||
|
) {
|
||||||
KotlinJvmBinaryClass kotlinClass = findClassWithMemberAnnotations(container, proto, nameResolver, kind);
|
KotlinJvmBinaryClass kotlinClass = findClassWithMemberAnnotations(container, proto, nameResolver, kind);
|
||||||
if (kotlinClass == null) {
|
if (kotlinClass == null) {
|
||||||
errorReporter.reportAnnotationLoadingError("Kotlin class for loading member annotations is not found: " + container, null);
|
errorReporter.reportAnnotationLoadingError("Kotlin class for loading member annotations is not found: " + container, null);
|
||||||
@@ -342,34 +353,54 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
|||||||
kotlinClass.loadMemberAnnotations(new KotlinJvmBinaryClass.MemberVisitor() {
|
kotlinClass.loadMemberAnnotations(new KotlinJvmBinaryClass.MemberVisitor() {
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public KotlinJvmBinaryClass.AnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc) {
|
public KotlinJvmBinaryClass.MethodAnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc) {
|
||||||
return annotationVisitor(MemberSignature.fromMethodNameAndDesc(name, desc));
|
return new AnnotationVisitorForMethod(MemberSignature.fromMethodNameAndDesc(name, desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc) {
|
public KotlinJvmBinaryClass.AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc) {
|
||||||
return annotationVisitor(MemberSignature.fromFieldNameAndDesc(name, desc));
|
return new MemberAnnotationVisitor(MemberSignature.fromFieldNameAndDesc(name, desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
class AnnotationVisitorForMethod extends MemberAnnotationVisitor implements KotlinJvmBinaryClass.MethodAnnotationVisitor {
|
||||||
private KotlinJvmBinaryClass.AnnotationVisitor annotationVisitor(@NotNull final MemberSignature signature) {
|
public AnnotationVisitorForMethod(@NotNull MemberSignature signature) {
|
||||||
return new KotlinJvmBinaryClass.AnnotationVisitor() {
|
super(signature);
|
||||||
private final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) {
|
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull JvmClassName className) {
|
||||||
return resolveAnnotation(className, result);
|
MemberSignature paramSignature = MemberSignature.fromMethodSignatureAndParameterIndex(signature, index);
|
||||||
|
List<AnnotationDescriptor> result = memberAnnotations.get(paramSignature);
|
||||||
|
if (result == null) {
|
||||||
|
result = new ArrayList<AnnotationDescriptor>();
|
||||||
|
memberAnnotations.put(paramSignature, result);
|
||||||
}
|
}
|
||||||
|
return resolveAnnotation(className, result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
class MemberAnnotationVisitor implements KotlinJvmBinaryClass.AnnotationVisitor {
|
||||||
public void visitEnd() {
|
private final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
|
||||||
if (!result.isEmpty()) {
|
protected final MemberSignature signature;
|
||||||
memberAnnotations.put(signature, result);
|
|
||||||
}
|
public MemberAnnotationVisitor(@NotNull MemberSignature signature) {
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public KotlinJvmBinaryClass.AnnotationArgumentVisitor visitAnnotation(@NotNull JvmClassName className) {
|
||||||
|
return resolveAnnotation(className, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
if (!result.isEmpty()) {
|
||||||
|
memberAnnotations.put(signature, result);
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -395,6 +426,11 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
|||||||
return new MemberSignature(name.asString() + "#" + desc);
|
return new MemberSignature(name.asString() + "#" + desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static MemberSignature fromMethodSignatureAndParameterIndex(@NotNull MemberSignature signature, int index) {
|
||||||
|
return new MemberSignature(signature.signature + "@" + index);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return signature.hashCode();
|
return signature.hashCode();
|
||||||
@@ -467,7 +503,23 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
|
public List<AnnotationDescriptor> loadValueParameterAnnotations(
|
||||||
throw new UnsupportedOperationException(); // TODO
|
@NotNull ClassOrNamespaceDescriptor container,
|
||||||
|
@NotNull ProtoBuf.Callable callable,
|
||||||
|
@NotNull NameResolver nameResolver,
|
||||||
|
@NotNull ProtoBuf.Callable.ValueParameter proto
|
||||||
|
) {
|
||||||
|
// Kind = FUNCTION because properties and getters don't have any value parameters, and property setters are not supported yet
|
||||||
|
// TODO: support annotations on property setter value parameters
|
||||||
|
MemberSignature methodSignature = getCallableSignature(callable, nameResolver, AnnotatedCallableKind.FUNCTION);
|
||||||
|
if (methodSignature != null) {
|
||||||
|
if (proto.hasExtension(JavaProtoBuf.index)) {
|
||||||
|
MemberSignature paramSignature =
|
||||||
|
MemberSignature.fromMethodSignatureAndParameterIndex(methodSignature, proto.getExtension(JavaProtoBuf.index));
|
||||||
|
return findClassAndLoadMemberAnnotations(container, callable, nameResolver, AnnotatedCallableKind.FUNCTION, paramSignature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-1
@@ -33,7 +33,7 @@ public interface KotlinJvmBinaryClass {
|
|||||||
// TODO: abstract signatures for methods and fields instead of ASM 'desc' strings?
|
// TODO: abstract signatures for methods and fields instead of ASM 'desc' strings?
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
AnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc);
|
MethodAnnotationVisitor visitMethod(@NotNull Name name, @NotNull String desc);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc);
|
AnnotationVisitor visitField(@NotNull Name name, @NotNull String desc);
|
||||||
@@ -46,6 +46,11 @@ public interface KotlinJvmBinaryClass {
|
|||||||
void visitEnd();
|
void visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MethodAnnotationVisitor extends AnnotationVisitor {
|
||||||
|
@Nullable
|
||||||
|
AnnotationArgumentVisitor visitParameterAnnotation(int index, @NotNull JvmClassName className);
|
||||||
|
}
|
||||||
|
|
||||||
interface AnnotationArgumentVisitor {
|
interface AnnotationArgumentVisitor {
|
||||||
// TODO: annotations, java.lang.Class
|
// TODO: annotations, java.lang.Class
|
||||||
void visit(@Nullable Name name, @Nullable Object value);
|
void visit(@Nullable Name name, @Nullable Object value);
|
||||||
|
|||||||
@@ -547,6 +547,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer {
|
|||||||
builder.append("/*").append(valueParameter.getIndex()).append("*/ ");
|
builder.append("/*").append(valueParameter.getIndex()).append("*/ ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderAnnotations(valueParameter, builder);
|
||||||
renderVariable(valueParameter, builder, topLevel);
|
renderVariable(valueParameter, builder, topLevel);
|
||||||
boolean withDefaultValue = debugMode ? valueParameter.declaresDefaultValue() : valueParameter.hasDefaultValue();
|
boolean withDefaultValue = debugMode ? valueParameter.declaresDefaultValue() : valueParameter.hasDefaultValue();
|
||||||
if (withDefaultValue) {
|
if (withDefaultValue) {
|
||||||
|
|||||||
Reference in New Issue
Block a user