Load annotations on properties declared in traits
This commit is contained in:
@@ -35,6 +35,7 @@ import java.util.List;
|
|||||||
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
|
import static org.jetbrains.asm4.Opcodes.ACC_STATIC;
|
||||||
import static org.jetbrains.asm4.Opcodes.RETURN;
|
import static org.jetbrains.asm4.Opcodes.RETURN;
|
||||||
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTopLevelOrInnerClass;
|
||||||
|
|
||||||
public abstract class ClassBodyCodegen extends MemberCodegen {
|
public abstract class ClassBodyCodegen extends MemberCodegen {
|
||||||
protected final JetClassOrObject myClass;
|
protected final JetClassOrObject myClass;
|
||||||
@@ -71,13 +72,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen {
|
|||||||
|
|
||||||
generateStaticInitializer();
|
generateStaticInitializer();
|
||||||
|
|
||||||
generateKotlinAnnotation();
|
if (state.getClassBuilderMode() == ClassBuilderMode.FULL && isTopLevelOrInnerClass(descriptor)) {
|
||||||
|
generateKotlinAnnotation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void generateDeclaration();
|
protected abstract void generateDeclaration();
|
||||||
|
|
||||||
protected void generateKotlinAnnotation() {
|
protected abstract void generateKotlinAnnotation();
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract void generateSyntheticParts();
|
protected abstract void generateSyntheticParts();
|
||||||
|
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
|
|||||||
|
|
||||||
if (owner instanceof NamespaceFacadeContext) {
|
if (owner instanceof NamespaceFacadeContext) {
|
||||||
Type ownerType = ((NamespaceFacadeContext) owner).getDelegateToClassType();
|
Type ownerType = ((NamespaceFacadeContext) owner).getDelegateToClassType();
|
||||||
v.getMemberMap().recordSrcClassNameForCallable(functionDescriptor, shortNameByAsmType(ownerType));
|
v.getMemberMap().recordImplClassNameForCallable(functionDescriptor, shortNameByAsmType(ownerType));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.getMemberMap().recordMethodOfDescriptor(functionDescriptor, asmMethod);
|
v.getMemberMap().recordMethodOfDescriptor(functionDescriptor, asmMethod);
|
||||||
|
|||||||
@@ -213,12 +213,6 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateKotlinAnnotation() {
|
protected void generateKotlinAnnotation() {
|
||||||
if (state.getClassBuilderMode() != ClassBuilderMode.FULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isTopLevelOrInnerClass(descriptor)) return;
|
|
||||||
|
|
||||||
DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(v.getMemberMap()));
|
DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(v.getMemberMap()));
|
||||||
|
|
||||||
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class JavaSerializerExtension extends SerializerExtension {
|
|||||||
@NotNull NameTable nameTable
|
@NotNull NameTable nameTable
|
||||||
) {
|
) {
|
||||||
saveSignature(callable, proto, nameTable);
|
saveSignature(callable, proto, nameTable);
|
||||||
saveSrcClassName(callable, proto, nameTable);
|
saveImplClassName(callable, proto, nameTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveSignature(
|
private void saveSignature(
|
||||||
@@ -91,14 +91,14 @@ public class JavaSerializerExtension extends SerializerExtension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveSrcClassName(
|
private void saveImplClassName(
|
||||||
@NotNull CallableMemberDescriptor callable,
|
@NotNull CallableMemberDescriptor callable,
|
||||||
@NotNull ProtoBuf.Callable.Builder proto,
|
@NotNull ProtoBuf.Callable.Builder proto,
|
||||||
@NotNull NameTable nameTable
|
@NotNull NameTable nameTable
|
||||||
) {
|
) {
|
||||||
String name = memberMap.getSrcClassNameOfCallable(callable);
|
String name = memberMap.getImplClassNameOfCallable(callable);
|
||||||
if (name != null) {
|
if (name != null) {
|
||||||
proto.setExtension(JavaProtoBuf.srcClassName, nameTable.getSimpleNameIndex(Name.identifier(name)));
|
proto.setExtension(JavaProtoBuf.implClassName, nameTable.getSimpleNameIndex(Name.identifier(name)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public final class MemberMap {
|
|||||||
private final Map<FunctionDescriptor, Method> methodForFunction = new HashMap<FunctionDescriptor, Method>();
|
private final Map<FunctionDescriptor, Method> methodForFunction = new HashMap<FunctionDescriptor, Method>();
|
||||||
private final Map<PropertyDescriptor, Pair<Type, String>> fieldForProperty = new HashMap<PropertyDescriptor, Pair<Type, String>>();
|
private final Map<PropertyDescriptor, Pair<Type, String>> fieldForProperty = new HashMap<PropertyDescriptor, Pair<Type, String>>();
|
||||||
private final Map<PropertyDescriptor, Method> syntheticMethodForProperty = new HashMap<PropertyDescriptor, Method>();
|
private final Map<PropertyDescriptor, Method> syntheticMethodForProperty = new HashMap<PropertyDescriptor, Method>();
|
||||||
private final Map<CallableMemberDescriptor, String> srcClassNameForCallable = new HashMap<CallableMemberDescriptor, String>();
|
private final Map<CallableMemberDescriptor, String> implClassNameForCallable = new HashMap<CallableMemberDescriptor, String>();
|
||||||
private final Set<PropertyDescriptor> staticFieldInOuterClass = new HashSet<PropertyDescriptor>();
|
private final Set<PropertyDescriptor> staticFieldInOuterClass = new HashSet<PropertyDescriptor>();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -50,8 +50,8 @@ public final class MemberMap {
|
|||||||
result.recordSyntheticMethodOfProperty(entry.getKey(), entry.getValue());
|
result.recordSyntheticMethodOfProperty(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<CallableMemberDescriptor, String> entry : map.srcClassNameForCallable.entrySet()) {
|
for (Map.Entry<CallableMemberDescriptor, String> entry : map.implClassNameForCallable.entrySet()) {
|
||||||
result.recordSrcClassNameForCallable(entry.getKey(), entry.getValue());
|
result.recordImplClassNameForCallable(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PropertyDescriptor property : map.staticFieldInOuterClass) {
|
for (PropertyDescriptor property : map.staticFieldInOuterClass) {
|
||||||
@@ -77,8 +77,8 @@ public final class MemberMap {
|
|||||||
assert old == null : "Duplicate synthetic method for property: " + descriptor + "; " + old;
|
assert old == null : "Duplicate synthetic method for property: " + descriptor + "; " + old;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recordSrcClassNameForCallable(@NotNull CallableMemberDescriptor descriptor, @NotNull String name) {
|
public void recordImplClassNameForCallable(@NotNull CallableMemberDescriptor descriptor, @NotNull String name) {
|
||||||
String old = srcClassNameForCallable.put(descriptor, name);
|
String old = implClassNameForCallable.put(descriptor, name);
|
||||||
assert old == null : "Duplicate src class name for callable: " + descriptor + "; " + old;
|
assert old == null : "Duplicate src class name for callable: " + descriptor + "; " + old;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +103,8 @@ public final class MemberMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public String getSrcClassNameOfCallable(@NotNull CallableMemberDescriptor descriptor) {
|
public String getImplClassNameOfCallable(@NotNull CallableMemberDescriptor descriptor) {
|
||||||
return srcClassNameForCallable.get(descriptor);
|
return implClassNameForCallable.get(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isStaticFieldInOuterClass(@NotNull PropertyDescriptor property) {
|
public boolean isStaticFieldInOuterClass(@NotNull PropertyDescriptor property) {
|
||||||
@@ -116,6 +116,6 @@ public final class MemberMap {
|
|||||||
return "Functions: " + methodForFunction.size() +
|
return "Functions: " + methodForFunction.size() +
|
||||||
", fields: " + fieldForProperty.size() +
|
", fields: " + fieldForProperty.size() +
|
||||||
", synthetic methods: " + syntheticMethodForProperty.size() +
|
", synthetic methods: " + syntheticMethodForProperty.size() +
|
||||||
", src class names: " + srcClassNameForCallable.size();
|
", impl class names: " + implClassNameForCallable.size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
|
|
||||||
if (context instanceof NamespaceFacadeContext) {
|
if (context instanceof NamespaceFacadeContext) {
|
||||||
Type ownerType = ((NamespaceFacadeContext) context).getDelegateToClassType();
|
Type ownerType = ((NamespaceFacadeContext) context).getDelegateToClassType();
|
||||||
v.getMemberMap().recordSrcClassNameForCallable(propertyDescriptor, shortNameByAsmType(ownerType));
|
v.getMemberMap().recordImplClassNameForCallable(propertyDescriptor, shortNameByAsmType(ownerType));
|
||||||
}
|
}
|
||||||
else if (kind != OwnerKind.TRAIT_IMPL) {
|
else if (kind != OwnerKind.TRAIT_IMPL) {
|
||||||
generateBackingField(p, propertyDescriptor);
|
generateBackingField(p, propertyDescriptor);
|
||||||
@@ -142,11 +142,16 @@ public class PropertyCodegen extends GenerationStateAware {
|
|||||||
AnnotationCodegen.forField(fieldVisitor, typeMapper).genAnnotations(propertyDescriptor);
|
AnnotationCodegen.forField(fieldVisitor, typeMapper).genAnnotations(propertyDescriptor);
|
||||||
}
|
}
|
||||||
else if (!propertyDescriptor.getAnnotations().isEmpty()) {
|
else if (!propertyDescriptor.getAnnotations().isEmpty()) {
|
||||||
if (!isTrait(context.getContextDescriptor())) {
|
Method method = getSyntheticMethodSignature(typeMapper, propertyDescriptor);
|
||||||
Method method = getSyntheticMethodSignature(typeMapper, propertyDescriptor);
|
DeclarationDescriptor descriptor = context.getContextDescriptor();
|
||||||
generateSyntheticMethodForAnnotatedProperty(v, typeMapper, propertyDescriptor, method);
|
if (isTrait(descriptor)) {
|
||||||
v.getMemberMap().recordSyntheticMethodOfProperty(propertyDescriptor, method);
|
Type tImplType = typeMapper.mapTraitImpl((ClassDescriptor) descriptor);
|
||||||
|
v.getMemberMap().recordImplClassNameForCallable(propertyDescriptor, shortNameByAsmType(tImplType));
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
generateSyntheticMethodForAnnotatedProperty(v, typeMapper, propertyDescriptor, method);
|
||||||
|
}
|
||||||
|
v.getMemberMap().recordSyntheticMethodOfProperty(propertyDescriptor, method);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package org.jetbrains.jet.codegen;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.asm4.AnnotationVisitor;
|
||||||
import org.jetbrains.asm4.commons.Method;
|
import org.jetbrains.asm4.commons.Method;
|
||||||
import org.jetbrains.jet.codegen.context.ClassContext;
|
import org.jetbrains.jet.codegen.context.ClassContext;
|
||||||
import org.jetbrains.jet.codegen.state.GenerationState;
|
import org.jetbrains.jet.codegen.state.GenerationState;
|
||||||
@@ -27,8 +28,11 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
|||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
import org.jetbrains.jet.lang.psi.JetProperty;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmAbi;
|
||||||
|
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
|
||||||
|
|
||||||
import static org.jetbrains.asm4.Opcodes.*;
|
import static org.jetbrains.asm4.Opcodes.*;
|
||||||
|
import static org.jetbrains.jet.codegen.AsmUtil.asmDescByFqNameWithoutInnerClasses;
|
||||||
|
|
||||||
public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
||||||
|
|
||||||
@@ -54,6 +58,14 @@ public class TraitImplBodyCodegen extends ClassBodyCodegen {
|
|||||||
v.visitSource(myClass.getContainingFile().getName(), null);
|
v.visitSource(myClass.getContainingFile().getName(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void generateKotlinAnnotation() {
|
||||||
|
AnnotationVisitor av =
|
||||||
|
v.getVisitor().visitAnnotation(asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_TRAIT_IMPL), true);
|
||||||
|
av.visit(JvmAnnotationNames.ABI_VERSION_FIELD_NAME, JvmAbi.VERSION);
|
||||||
|
av.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void generateSyntheticParts() {
|
protected void generateSyntheticParts() {
|
||||||
generateSyntheticMethodsForAnnotatedProperties();
|
generateSyntheticMethodsForAnnotatedProperties();
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
class Class {
|
||||||
|
trait Trait {
|
||||||
|
[Anno] val property: Int
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal final class Class {
|
||||||
|
/*primary*/ public constructor Class()
|
||||||
|
|
||||||
|
internal trait Trait {
|
||||||
|
test.Anno() internal abstract val property: jet.Int
|
||||||
|
internal abstract fun <get-property>(): jet.Int
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
[Anno] val property: Int
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal trait Trait {
|
||||||
|
test.Anno() internal abstract val property: jet.Int
|
||||||
|
internal abstract fun <get-property>(): jet.Int
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
annotation class Anno
|
||||||
|
|
||||||
|
trait Trait {
|
||||||
|
class object {
|
||||||
|
[Anno] val property: Int
|
||||||
|
get() = 42
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
package test
|
||||||
|
|
||||||
|
internal final annotation class Anno : jet.Annotation {
|
||||||
|
/*primary*/ public constructor Anno()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal trait Trait {
|
||||||
|
|
||||||
|
internal class object <class-object-for-Trait> {
|
||||||
|
/*primary*/ private constructor <class-object-for-Trait>()
|
||||||
|
test.Anno() internal final val property: jet.Int
|
||||||
|
internal final fun <get-property>(): jet.Int
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -209,11 +209,26 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
|||||||
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/ExtensionsWithSameNamePackage.kt");
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/ExtensionsWithSameNamePackage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NestedTrait.kt")
|
||||||
|
public void testNestedTrait() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/NestedTrait.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TopLevel.kt")
|
@TestMetadata("TopLevel.kt")
|
||||||
public void testTopLevel() throws Exception {
|
public void testTopLevel() throws Exception {
|
||||||
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/TopLevel.kt");
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/TopLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Trait.kt")
|
||||||
|
public void testTrait() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/Trait.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TraitClassObject.kt")
|
||||||
|
public void testTraitClassObject() throws Exception {
|
||||||
|
doTestWithAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/TraitClassObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test innerSuite() {
|
public static Test innerSuite() {
|
||||||
|
|||||||
+15
@@ -211,11 +211,26 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
|||||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/ExtensionsWithSameNamePackage.kt");
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/ExtensionsWithSameNamePackage.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("NestedTrait.kt")
|
||||||
|
public void testNestedTrait() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/NestedTrait.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TopLevel.kt")
|
@TestMetadata("TopLevel.kt")
|
||||||
public void testTopLevel() throws Exception {
|
public void testTopLevel() throws Exception {
|
||||||
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/TopLevel.kt");
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/TopLevel.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("Trait.kt")
|
||||||
|
public void testTrait() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/Trait.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TraitClassObject.kt")
|
||||||
|
public void testTraitClassObject() throws Exception {
|
||||||
|
doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/propertiesWithoutBackingFields/TraitClassObject.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Test innerSuite() {
|
public static Test innerSuite() {
|
||||||
|
|||||||
+3
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve.java;
|
|||||||
import jet.KotlinClass;
|
import jet.KotlinClass;
|
||||||
import jet.KotlinPackage;
|
import jet.KotlinPackage;
|
||||||
import jet.KotlinPackageFragment;
|
import jet.KotlinPackageFragment;
|
||||||
|
import jet.KotlinTraitImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqName;
|
import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils.fqNameByClass;
|
import static org.jetbrains.jet.lang.resolve.java.resolver.DescriptorResolverUtils.fqNameByClass;
|
||||||
@@ -30,6 +31,8 @@ public final class JvmAnnotationNames {
|
|||||||
|
|
||||||
public static final FqName KOTLIN_PACKAGE_FRAGMENT = fqNameByClass(KotlinPackageFragment.class);
|
public static final FqName KOTLIN_PACKAGE_FRAGMENT = fqNameByClass(KotlinPackageFragment.class);
|
||||||
|
|
||||||
|
public static final FqName KOTLIN_TRAIT_IMPL = fqNameByClass(KotlinTraitImpl.class);
|
||||||
|
|
||||||
public static final String ABI_VERSION_FIELD_NAME = "abiVersion";
|
public static final String ABI_VERSION_FIELD_NAME = "abiVersion";
|
||||||
|
|
||||||
public static final String DATA_FIELD_NAME = "data";
|
public static final String DATA_FIELD_NAME = "data";
|
||||||
|
|||||||
+29
-18
@@ -47,6 +47,8 @@ import javax.inject.Inject;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
|
||||||
|
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isTrait;
|
||||||
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
|
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.IGNORE_KOTLIN_SOURCES;
|
||||||
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
|
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.kotlinFqNameToJavaFqName;
|
||||||
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName;
|
import static org.jetbrains.jet.lang.resolve.kotlin.DeserializedResolverUtils.naiveKotlinFqName;
|
||||||
@@ -231,7 +233,7 @@ 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();
|
||||||
|
|
||||||
KotlinJvmBinaryClass kotlinClass = findClassWithMemberAnnotations(container, proto, nameResolver);
|
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);
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@@ -245,33 +247,42 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
|
|||||||
private KotlinJvmBinaryClass findClassWithMemberAnnotations(
|
private KotlinJvmBinaryClass findClassWithMemberAnnotations(
|
||||||
@NotNull ClassOrNamespaceDescriptor container,
|
@NotNull ClassOrNamespaceDescriptor container,
|
||||||
@NotNull ProtoBuf.Callable proto,
|
@NotNull ProtoBuf.Callable proto,
|
||||||
@NotNull NameResolver nameResolver
|
@NotNull NameResolver nameResolver,
|
||||||
|
@NotNull AnnotatedCallableKind kind
|
||||||
) {
|
) {
|
||||||
if (container instanceof NamespaceDescriptor) {
|
if (container instanceof NamespaceDescriptor) {
|
||||||
Name name = loadSrcClassName(proto, nameResolver);
|
return loadPackageFragmentClassFqName((NamespaceDescriptor) container, proto, nameResolver);
|
||||||
if (name != null) {
|
}
|
||||||
return kotlinClassFinder.find(getSrcClassFqName((NamespaceDescriptor) container, name));
|
else if (isClassObject(container) && isStaticFieldInOuter(proto)) {
|
||||||
|
// Backing fields of properties of a class object are generated in the outer class
|
||||||
|
return findKotlinClassByDescriptor((ClassOrNamespaceDescriptor) container.getContainingDeclaration());
|
||||||
|
}
|
||||||
|
else if (isTrait(container) && kind == AnnotatedCallableKind.PROPERTY) {
|
||||||
|
NamespaceDescriptor containingPackage = DescriptorUtils.getParentOfType(container, NamespaceDescriptor.class);
|
||||||
|
assert containingPackage != null : "Trait must have a namespace among his parents: " + container;
|
||||||
|
|
||||||
|
if (proto.hasExtension(JavaProtoBuf.implClassName)) {
|
||||||
|
Name tImplName = nameResolver.getName(proto.getExtension(JavaProtoBuf.implClassName));
|
||||||
|
return kotlinClassFinder.find(containingPackage.getFqName().child(tImplName));
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
else if (container instanceof ClassDescriptor && ((ClassDescriptor) container).getKind() == ClassKind.CLASS_OBJECT) {
|
|
||||||
// Backing fields of properties of a class object are generated in the outer class
|
|
||||||
if (isStaticFieldInOuter(proto)) {
|
|
||||||
return findKotlinClassByDescriptor((ClassOrNamespaceDescriptor) container.getContainingDeclaration());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return findKotlinClassByDescriptor(container);
|
return findKotlinClassByDescriptor(container);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
private static FqName getSrcClassFqName(@NotNull NamespaceDescriptor container, @NotNull Name name) {
|
|
||||||
return PackageClassUtils.getPackageClassFqName(DescriptorUtils.getFQName(container).toSafe()).parent().child(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static Name loadSrcClassName(@NotNull ProtoBuf.Callable proto, @NotNull NameResolver nameResolver) {
|
private KotlinJvmBinaryClass loadPackageFragmentClassFqName(
|
||||||
return proto.hasExtension(JavaProtoBuf.srcClassName) ? nameResolver.getName(proto.getExtension(JavaProtoBuf.srcClassName)) : null;
|
@NotNull NamespaceDescriptor container,
|
||||||
|
@NotNull ProtoBuf.Callable proto,
|
||||||
|
@NotNull NameResolver nameResolver
|
||||||
|
) {
|
||||||
|
if (proto.hasExtension(JavaProtoBuf.implClassName)) {
|
||||||
|
Name name = nameResolver.getName(proto.getExtension(JavaProtoBuf.implClassName));
|
||||||
|
FqName fqName = PackageClassUtils.getPackageClassFqName(container.getFqName()).parent().child(name);
|
||||||
|
return kotlinClassFinder.find(fqName);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isStaticFieldInOuter(@NotNull ProtoBuf.Callable proto) {
|
private static boolean isStaticFieldInOuter(@NotNull ProtoBuf.Callable proto) {
|
||||||
|
|||||||
+6
-3
@@ -38,6 +38,7 @@ import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.Annotat
|
|||||||
CLASS(JvmAnnotationNames.KOTLIN_CLASS),
|
CLASS(JvmAnnotationNames.KOTLIN_CLASS),
|
||||||
PACKAGE(JvmAnnotationNames.KOTLIN_PACKAGE),
|
PACKAGE(JvmAnnotationNames.KOTLIN_PACKAGE),
|
||||||
PACKAGE_FRAGMENT(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT),
|
PACKAGE_FRAGMENT(JvmAnnotationNames.KOTLIN_PACKAGE_FRAGMENT),
|
||||||
|
TRAIT_IMPL(JvmAnnotationNames.KOTLIN_TRAIT_IMPL),
|
||||||
OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION),
|
OLD_CLASS(JvmAnnotationNames.OLD_JET_CLASS_ANNOTATION),
|
||||||
OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION);
|
OLD_PACKAGE(JvmAnnotationNames.OLD_JET_PACKAGE_CLASS_ANNOTATION);
|
||||||
|
|
||||||
@@ -92,6 +93,8 @@ import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.Annotat
|
|||||||
return serializedDataHeader(SerializedDataHeader.Kind.PACKAGE);
|
return serializedDataHeader(SerializedDataHeader.Kind.PACKAGE);
|
||||||
case PACKAGE_FRAGMENT:
|
case PACKAGE_FRAGMENT:
|
||||||
return new PackageFragmentClassHeader(version);
|
return new PackageFragmentClassHeader(version);
|
||||||
|
case TRAIT_IMPL:
|
||||||
|
return new TraitImplClassHeader(version);
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown compatible HeaderType: " + foundType);
|
throw new UnsupportedOperationException("Unknown compatible HeaderType: " + foundType);
|
||||||
}
|
}
|
||||||
@@ -123,8 +126,8 @@ import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.Annotat
|
|||||||
if (newType == HeaderType.CLASS || newType == HeaderType.PACKAGE) {
|
if (newType == HeaderType.CLASS || newType == HeaderType.PACKAGE) {
|
||||||
return kotlinClassOrPackageVisitor(annotationClassName);
|
return kotlinClassOrPackageVisitor(annotationClassName);
|
||||||
}
|
}
|
||||||
else if (newType == HeaderType.PACKAGE_FRAGMENT) {
|
else if (newType == HeaderType.PACKAGE_FRAGMENT || newType == HeaderType.TRAIT_IMPL) {
|
||||||
return kotlinPackageFragmentVisitor(annotationClassName);
|
return annotationWithAbiVersionVisitor(annotationClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -198,7 +201,7 @@ import static org.jetbrains.jet.lang.resolve.kotlin.KotlinJvmBinaryClass.Annotat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private AnnotationArgumentVisitor kotlinPackageFragmentVisitor(@NotNull final JvmClassName annotationClassName) {
|
private AnnotationArgumentVisitor annotationWithAbiVersionVisitor(@NotNull final JvmClassName annotationClassName) {
|
||||||
return new AnnotationArgumentVisitor() {
|
return new AnnotationArgumentVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void visit(@Nullable Name name, @Nullable Object value) {
|
public void visit(@Nullable Name name, @Nullable Object value) {
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.lang.resolve.kotlin.header;
|
||||||
|
|
||||||
|
/* package */ class TraitImplClassHeader extends KotlinClassHeader {
|
||||||
|
protected TraitImplClassHeader(int version) {
|
||||||
|
super(version);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -74,6 +74,10 @@ extend Callable {
|
|||||||
|
|
||||||
optional JavaPropertySignature property_signature = 101;
|
optional JavaPropertySignature property_signature = 101;
|
||||||
|
|
||||||
// For top-level callables, short name of "...Package$src$..." class with the callable's body and annotations
|
// Package-less name of the class with the callable's body and annotations, if it differs from the class it's serialized into.
|
||||||
optional int32 src_class_name = 102;
|
// E.g. for a class "A/B/C$D" this would be "C$D".
|
||||||
|
// This is needed to find the class to load annotations from in the following cases:
|
||||||
|
// 1) annotations on top-level members are written to compiled package fragment classes
|
||||||
|
// 2) annotations on properties in traits are written to TImpl classes
|
||||||
|
optional int32 impl_class_name = 102;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -9,7 +9,7 @@ public final class JavaProtoBuf {
|
|||||||
com.google.protobuf.ExtensionRegistryLite registry) {
|
com.google.protobuf.ExtensionRegistryLite registry) {
|
||||||
registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.methodSignature);
|
registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.methodSignature);
|
||||||
registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.propertySignature);
|
registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.propertySignature);
|
||||||
registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.srcClassName);
|
registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.implClassName);
|
||||||
}
|
}
|
||||||
public interface JavaTypeOrBuilder
|
public interface JavaTypeOrBuilder
|
||||||
extends com.google.protobuf.MessageLiteOrBuilder {
|
extends com.google.protobuf.MessageLiteOrBuilder {
|
||||||
@@ -2825,14 +2825,14 @@ public final class JavaProtoBuf {
|
|||||||
null,
|
null,
|
||||||
101,
|
101,
|
||||||
com.google.protobuf.WireFormat.FieldType.MESSAGE);
|
com.google.protobuf.WireFormat.FieldType.MESSAGE);
|
||||||
public static final int SRC_CLASS_NAME_FIELD_NUMBER = 102;
|
public static final int IMPL_CLASS_NAME_FIELD_NUMBER = 102;
|
||||||
/**
|
/**
|
||||||
* <code>extend .org.jetbrains.jet.descriptors.serialization.Callable { ... }</code>
|
* <code>extend .org.jetbrains.jet.descriptors.serialization.Callable { ... }</code>
|
||||||
*/
|
*/
|
||||||
public static final
|
public static final
|
||||||
com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
|
com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
|
||||||
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable,
|
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable,
|
||||||
java.lang.Integer> srcClassName = com.google.protobuf.GeneratedMessageLite
|
java.lang.Integer> implClassName = com.google.protobuf.GeneratedMessageLite
|
||||||
.newSingularGeneratedExtension(
|
.newSingularGeneratedExtension(
|
||||||
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.getDefaultInstance(),
|
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.getDefaultInstance(),
|
||||||
0,
|
0,
|
||||||
|
|||||||
Reference in New Issue
Block a user