diff --git a/.idea/modules.xml b/.idea/modules.xml
index 4d1846a6f2a..05cd23eb300 100644
--- a/.idea/modules.xml
+++ b/.idea/modules.xml
@@ -30,6 +30,7 @@
+
diff --git a/build.xml b/build.xml
index 95fb1869d3e..8915bfb077f 100644
--- a/build.xml
+++ b/build.xml
@@ -26,6 +26,7 @@
+
diff --git a/compiler/backend/backend.iml b/compiler/backend/backend.iml
index d6c4b6e6622..0d10715226e 100644
--- a/compiler/backend/backend.iml
+++ b/compiler/backend/backend.iml
@@ -14,6 +14,7 @@
+
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
index 5071c5c067d..7f4e4f83e6e 100644
--- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java
@@ -41,9 +41,7 @@ import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter;
import org.jetbrains.jet.codegen.state.GenerationState;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.codegen.state.JetTypeMapperMode;
-import org.jetbrains.jet.descriptors.serialization.DescriptorSerializer;
-import org.jetbrains.jet.descriptors.serialization.NameSerializationUtil;
-import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
+import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
@@ -223,7 +221,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void writeKotlinInfo() {
AnnotationVisitor av = v.getVisitor().visitAnnotation(JvmStdlibNames.KOTLIN_INFO_CLASS.getDescriptor(), true);
- DescriptorSerializer serializer = new DescriptorSerializer();
+
+ DescriptorSerializer serializer = new DescriptorSerializer(new JavaSerializerExtension(typeMapper));
ProtoBuf.Class classProto = serializer.classProto(descriptor).build();
@@ -1844,5 +1843,4 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
-
}
diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java b/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java
new file mode 100644
index 00000000000..ec9617a7c14
--- /dev/null
+++ b/compiler/backend/src/org/jetbrains/jet/codegen/JavaSerializerExtension.java
@@ -0,0 +1,52 @@
+/*
+ * 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.codegen;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jet.codegen.signature.JvmMethodSignature;
+import org.jetbrains.jet.codegen.state.JetTypeMapper;
+import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
+import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
+import org.jetbrains.jet.descriptors.serialization.SerializerExtension;
+import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
+import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
+
+public class JavaSerializerExtension extends SerializerExtension {
+ private final JetTypeMapper typeMapper;
+
+ public JavaSerializerExtension(@NotNull JetTypeMapper typeMapper) {
+ this.typeMapper = typeMapper;
+ }
+
+ @Override
+ public void serializeCallable(@NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto) {
+ JvmMethodSignature signature = mapSignature(callable);
+ if (signature != null) {
+ JavaProtoBufUtil.saveJavaSignature(proto, signature.getAsmMethod().toString());
+ }
+ }
+
+ // TODO: this should be done upon generation of the member instead, because we don't know enough at this point to map correctly
+ @Nullable
+ private JvmMethodSignature mapSignature(@NotNull CallableMemberDescriptor descriptor) {
+ if (descriptor instanceof FunctionDescriptor) {
+ return typeMapper.mapSignature((FunctionDescriptor) descriptor);
+ }
+ return null;
+ }
+}
diff --git a/compiler/frontend.java/frontend.java.iml b/compiler/frontend.java/frontend.java.iml
index b979014c075..26f992661ef 100644
--- a/compiler/frontend.java/frontend.java.iml
+++ b/compiler/frontend.java/frontend.java.iml
@@ -13,6 +13,7 @@
+
diff --git a/compiler/frontend.java/serialization.java/serialization.java.iml b/compiler/frontend.java/serialization.java/serialization.java.iml
new file mode 100644
index 00000000000..0a493903138
--- /dev/null
+++ b/compiler/frontend.java/serialization.java/serialization.java.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/compiler/frontend.java/serialization.java/src/java_descriptors.proto b/compiler/frontend.java/serialization.java/src/java_descriptors.proto
new file mode 100644
index 00000000000..1248d0edd8e
--- /dev/null
+++ b/compiler/frontend.java/serialization.java/src/java_descriptors.proto
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+import "compiler/frontend/serialization/src/descriptors.proto";
+
+option java_outer_classname = "JavaProtoBuf";
+option optimize_for = LITE_RUNTIME;
+
+extend Callable {
+ optional string java_signature = 100;
+}
diff --git a/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java b/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java
new file mode 100644
index 00000000000..9e7df4210cc
--- /dev/null
+++ b/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBuf.java
@@ -0,0 +1,29 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: compiler/frontend.java/serialization.java/src/java_descriptors.proto
+
+package org.jetbrains.jet.descriptors.serialization;
+
+public final class JavaProtoBuf {
+ private JavaProtoBuf() {}
+ public static void registerAllExtensions(
+ com.google.protobuf.ExtensionRegistryLite registry) {
+ registry.add(org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.javaSignature);
+ }
+ public static final int JAVA_SIGNATURE_FIELD_NUMBER = 100;
+ public static final
+ com.google.protobuf.GeneratedMessageLite.GeneratedExtension<
+ org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable,
+ java.lang.String> javaSignature = com.google.protobuf.GeneratedMessageLite
+ .newSingularGeneratedExtension(
+ org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.getDefaultInstance(),
+ "",
+ null,
+ null,
+ 100,
+ com.google.protobuf.WireFormat.FieldType.STRING);
+
+ static {
+ }
+
+ // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java b/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java
new file mode 100644
index 00000000000..d5acb121547
--- /dev/null
+++ b/compiler/frontend.java/serialization.java/src/org/jetbrains/jet/descriptors/serialization/JavaProtoBufUtil.java
@@ -0,0 +1,44 @@
+/*
+ * 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;
+
+import com.google.protobuf.ExtensionRegistryLite;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import static org.jetbrains.jet.descriptors.serialization.JavaProtoBuf.javaSignature;
+
+public class JavaProtoBufUtil {
+ private JavaProtoBufUtil() {
+ }
+
+ @Nullable
+ public static String loadJavaSignature(@NotNull ProtoBuf.Callable callable) {
+ return callable.hasExtension(javaSignature) ? callable.getExtension(javaSignature) : null;
+ }
+
+ public static void saveJavaSignature(@NotNull ProtoBuf.Callable.Builder callable, @NotNull String signature) {
+ callable.setExtension(javaSignature, signature);
+ }
+
+ @NotNull
+ public static ClassData readJavaClassDataFrom(@NotNull byte[] data) {
+ ExtensionRegistryLite registry = ExtensionRegistryLite.newInstance();
+ JavaProtoBuf.registerAllExtensions(registry);
+ return ClassData.read(data, registry);
+ }
+}
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java
index bc236f3ec66..196fea06465 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/AnnotationDescriptorDeserializer.java
@@ -19,10 +19,9 @@ package org.jetbrains.jet.lang.resolve.java.resolver;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiClass;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.asm4.AnnotationVisitor;
-import org.jetbrains.asm4.ClassReader;
-import org.jetbrains.asm4.ClassVisitor;
-import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.asm4.*;
+import org.jetbrains.jet.descriptors.serialization.JavaProtoBufUtil;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.descriptors.serialization.descriptors.AnnotationDeserializer;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -38,8 +37,7 @@ import org.jetbrains.jet.utils.ExceptionUtils;
import javax.inject.Inject;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
import static org.jetbrains.asm4.ClassReader.*;
import static org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN;
@@ -62,20 +60,8 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
@NotNull
@Override
- public List loadClassAnnotations(
- @NotNull ClassDescriptor descriptor,
- @NotNull ProtoBuf.Class classProto
- ) {
- FqName fqName = kotlinFqNameToJavaFqName(naiveKotlinFqName(descriptor));
- PsiClass psiClass = psiClassFinder.findPsiClass(fqName, PsiClassFinder.RuntimeClassesHandleMode.IGNORE /* TODO: ?! */);
- if (psiClass == null) {
- throw new IllegalStateException("Psi class is not found for class: " + descriptor);
- }
- VirtualFile virtualFile = getVirtualFile(psiClass, fqName, (ClassOrNamespaceDescriptor) descriptor.getContainingDeclaration());
- if (virtualFile == null) {
- throw new IllegalStateException("Virtual file is not found for class: " + descriptor) ;
- }
-
+ public List loadClassAnnotations(@NotNull ClassDescriptor descriptor, @NotNull ProtoBuf.Class classProto) {
+ VirtualFile virtualFile = findVirtualFileByDescriptor(descriptor);
try {
return loadClassAnnotationsFromFile(virtualFile);
}
@@ -84,6 +70,20 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
}
}
+ @NotNull
+ private VirtualFile findVirtualFileByDescriptor(@NotNull ClassDescriptor descriptor) {
+ FqName fqName = kotlinFqNameToJavaFqName(naiveKotlinFqName(descriptor));
+ PsiClass psiClass = psiClassFinder.findPsiClass(fqName, PsiClassFinder.RuntimeClassesHandleMode.IGNORE /* TODO: ?! */);
+ if (psiClass == null) {
+ throw new IllegalStateException("Psi class is not found for class: " + descriptor);
+ }
+ VirtualFile virtualFile = getVirtualFile(psiClass, fqName, (ClassOrNamespaceDescriptor) descriptor.getContainingDeclaration());
+ if (virtualFile == null) {
+ throw new IllegalStateException("Virtual file is not found for class: " + descriptor) ;
+ }
+ return virtualFile;
+ }
+
@NotNull
private List loadClassAnnotationsFromFile(@NotNull VirtualFile virtualFile) throws IOException {
final List result = new ArrayList();
@@ -91,12 +91,7 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
new ClassReader(virtualFile.getInputStream()).accept(new ClassVisitor(Opcodes.ASM4) {
@Override
public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
- if (ignoreAnnotation(desc)) return null;
-
- FqName annotationFqName = convertJvmDescriptorToFqName(desc);
- ClassDescriptor annotationClass = javaClassResolver.resolveClass(annotationFqName, ERROR_IF_FOUND_IN_KOTLIN);
- assert annotationClass != null : "Annotation class is not found: " + desc;
- return resolveAnnotation(annotationClass, result);
+ return resolveAnnotation(desc, result);
}
}, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
@@ -115,11 +110,13 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
return new FqName(fqName);
}
- @NotNull
- private static AnnotationVisitor resolveAnnotation(
- @NotNull final ClassDescriptor annotationClass,
- @NotNull final List result
- ) {
+ @Nullable
+ private AnnotationVisitor resolveAnnotation(@NotNull String desc, @NotNull final List result) {
+ if (ignoreAnnotation(desc)) return null;
+
+ FqName annotationFqName = convertJvmDescriptorToFqName(desc);
+ final ClassDescriptor annotationClass = javaClassResolver.resolveClass(annotationFqName, ERROR_IF_FOUND_IN_KOTLIN);
+ assert annotationClass != null : "Annotation class is not found: " + desc;
final AnnotationDescriptor annotation = new AnnotationDescriptor();
annotation.setAnnotationType(annotationClass.getDefaultType());
@@ -146,8 +143,56 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
@NotNull
@Override
- public List loadCallableAnnotations(@NotNull ProtoBuf.Callable callableProto) {
- throw new UnsupportedOperationException(); // TODO
+ public List loadCallableAnnotations(
+ @NotNull ClassOrNamespaceDescriptor container,
+ @NotNull ProtoBuf.Callable callableProto
+ ) {
+ if (!(container instanceof ClassDescriptor)) return Collections.emptyList(); // TODO: NamespaceDescriptor
+
+ VirtualFile file = findVirtualFileByDescriptor((ClassDescriptor) container);
+
+ try {
+ // TODO: calculate this only once for each container
+ Map> memberAnnotations = loadMemberAnnotationsFromFile(file);
+
+ String signature = JavaProtoBufUtil.loadJavaSignature(callableProto);
+ if (signature == null) return Collections.emptyList();
+
+ List annotations = memberAnnotations.get(signature);
+ return annotations == null ? Collections.emptyList() : annotations;
+ }
+ catch (IOException e) {
+ throw ExceptionUtils.rethrow(e);
+ }
+ }
+
+ @NotNull
+ private Map> loadMemberAnnotationsFromFile(@NotNull VirtualFile file) throws IOException {
+ final Map> memberAnnotations = new HashMap>();
+
+ new ClassReader(file.getInputStream()).accept(new ClassVisitor(Opcodes.ASM4) {
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ final String methodSignature = name + desc;
+ final List result = new ArrayList();
+
+ return new MethodVisitor(Opcodes.ASM4) {
+ @Override
+ public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+ return resolveAnnotation(desc, result);
+ }
+
+ @Override
+ public void visitEnd() {
+ if (!result.isEmpty()) {
+ memberAnnotations.put(methodSignature, result);
+ }
+ }
+ };
+ }
+ }, SKIP_CODE | SKIP_DEBUG | SKIP_FRAMES);
+
+ return memberAnnotations;
}
@NotNull
@@ -155,10 +200,4 @@ public class AnnotationDescriptorDeserializer implements AnnotationDeserializer
public List loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
throw new UnsupportedOperationException(); // TODO
}
-
- @NotNull
- @Override
- public List loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
- throw new UnsupportedOperationException(); // TODO
- }
}
diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java
index 51dd2fa5dcf..61835dee81b 100644
--- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java
+++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/DeserializedDescriptorResolver.java
@@ -24,10 +24,7 @@ import org.jetbrains.asm4.AnnotationVisitor;
import org.jetbrains.asm4.ClassReader;
import org.jetbrains.asm4.ClassVisitor;
import org.jetbrains.asm4.Opcodes;
-import org.jetbrains.jet.descriptors.serialization.ClassData;
-import org.jetbrains.jet.descriptors.serialization.ClassId;
-import org.jetbrains.jet.descriptors.serialization.DescriptorFinder;
-import org.jetbrains.jet.descriptors.serialization.PackageData;
+import org.jetbrains.jet.descriptors.serialization.*;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedClassDescriptor;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedPackageMemberScope;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
@@ -141,7 +138,7 @@ public final class DeserializedDescriptorResolver {
private static ClassData readClassDataFromClassFile(@NotNull VirtualFile virtualFile) {
byte[] data = getKotlinInfoDataFromClassFile(virtualFile);
if (data == null) return null;
- return ClassData.read(data);
+ return JavaProtoBufUtil.readJavaClassDataFrom(data);
}
@Nullable
diff --git a/compiler/frontend/serialization/src/descriptors.proto b/compiler/frontend/serialization/src/descriptors.proto
index fa4bba55af6..544e674d7f3 100644
--- a/compiler/frontend/serialization/src/descriptors.proto
+++ b/compiler/frontend/serialization/src/descriptors.proto
@@ -196,6 +196,8 @@ message Callable {
repeated ValueParameter value_parameter = 7;
required Type return_type = 8;
+
+ extensions 100 to 199;
}
enum Modality {
diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ClassData.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ClassData.java
index 29ee4e5632d..c3afeb59107 100644
--- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ClassData.java
+++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ClassData.java
@@ -16,6 +16,7 @@
package org.jetbrains.jet.descriptors.serialization;
+import com.google.protobuf.ExtensionRegistryLite;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.utils.ExceptionUtils;
@@ -24,11 +25,11 @@ import java.io.IOException;
public final class ClassData {
@NotNull
- public static ClassData read(@NotNull byte[] bytes) {
+ public static ClassData read(@NotNull byte[] bytes, @NotNull ExtensionRegistryLite registry) {
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
NameResolver nameResolver = NameSerializationUtil.deserializeNameResolver(in);
- ProtoBuf.Class classProto = ProtoBuf.Class.parseFrom(in);
+ ProtoBuf.Class classProto = ProtoBuf.Class.parseFrom(in, registry);
return new ClassData(nameResolver, classProto);
}
catch (IOException e) {
diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java
index 7f980a492cb..e7209ff85e8 100644
--- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java
+++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorDeserializer.java
@@ -169,7 +169,7 @@ public class DescriptorDeserializer {
boolean isNotDefault = proto.hasSetterFlags() && Flags.IS_NOT_DEFAULT.get(setterFlags);
if (isNotDefault) {
setter = new PropertySetterDescriptorImpl(
- property, getSetterAnnotations(proto, setterFlags),
+ property, getAnnotations(proto, setterFlags),
modality(Flags.MODALITY.get(setterFlags)), visibility(Flags.VISIBILITY.get(setterFlags)),
isNotDefault, !isNotDefault, property.getKind()
);
@@ -192,13 +192,11 @@ public class DescriptorDeserializer {
private PropertyDescriptorImpl createPropertyDescriptor(@NotNull Callable proto) {
int flags = proto.getFlags();
Name name = nameResolver.getName(proto.getName());
- List annotations = getAnnotations(proto);
+ List annotations = getAnnotations(proto, proto.getFlags());
Visibility visibility = visibility(Flags.VISIBILITY.get(flags));
Callable.CallableKind callableKind = Flags.CALLABLE_KIND.get(flags);
if (callableKind == Callable.CallableKind.OBJECT_PROPERTY) {
- assert containingDeclaration instanceof ClassOrNamespaceDescriptor
- : "Properties for objects can only exist in class or namespace: " + name;
FqNameUnsafe fqName = DescriptorUtils.getFQName(containingDeclaration).child(name);
ClassId objectId = ClassId.fromFqNameAndContainingDeclaration(fqName, (ClassOrNamespaceDescriptor) containingDeclaration);
ClassDescriptor objectClass = typeDeserializer.getDescriptorFinder().findClass(objectId);
@@ -223,7 +221,7 @@ public class DescriptorDeserializer {
int flags = proto.getFlags();
SimpleFunctionDescriptorImpl function = new SimpleFunctionDescriptorImpl(
containingDeclaration,
- getAnnotations(proto),
+ getAnnotations(proto, proto.getFlags()),
nameResolver.getName(proto.getName()),
memberKind(Flags.MEMBER_KIND.get(flags))
);
@@ -254,7 +252,7 @@ public class DescriptorDeserializer {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;
ConstructorDescriptorImpl descriptor = new ConstructorDescriptorImpl(
classDescriptor,
- getAnnotations(proto),
+ getAnnotations(proto, proto.getFlags()),
// TODO: primary
true);
List typeParameters = new ArrayList(proto.getTypeParameterCount());
@@ -269,17 +267,15 @@ public class DescriptorDeserializer {
return descriptor;
}
- private List getAnnotations(Callable proto) {
- return Flags.HAS_ANNOTATIONS.get(proto.getFlags())
- ? annotationDeserializer.loadCallableAnnotations(proto)
+ @NotNull
+ private List getAnnotations(@NotNull Callable proto, int flags) {
+ assert containingDeclaration instanceof ClassOrNamespaceDescriptor
+ : "Only members in classes or namespaces should be serialized: " + containingDeclaration;
+ return Flags.HAS_ANNOTATIONS.get(flags)
+ ? annotationDeserializer.loadCallableAnnotations((ClassOrNamespaceDescriptor) containingDeclaration, proto)
: Collections.emptyList();
}
- private List getSetterAnnotations(Callable proto, int setterFlags) {
- return Flags.HAS_ANNOTATIONS.get(setterFlags) ? annotationDeserializer.loadSetterAnnotations(proto) : Collections
- .emptyList();
- }
-
private static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
switch (memberKind) {
case DECLARATION:
diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java
index b5a1c02f6c4..5414d89616f 100644
--- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java
+++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/DescriptorSerializer.java
@@ -212,6 +212,8 @@ public class DescriptorSerializer {
builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType())));
+ extension.serializeCallable(descriptor, builder);
+
return builder;
}
diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java
index ea21b87889a..a021c573aed 100644
--- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java
+++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/ProtoBuf.java
@@ -5262,8 +5262,9 @@ public final class ProtoBuf {
// @@protoc_insertion_point(class_scope:org.jetbrains.jet.descriptors.serialization.Package)
}
- public interface CallableOrBuilder
- extends com.google.protobuf.MessageLiteOrBuilder {
+ public interface CallableOrBuilder extends
+ com.google.protobuf.GeneratedMessageLite.
+ ExtendableMessageOrBuilder {
// optional int32 flags = 1;
boolean hasFlags();
@@ -5310,8 +5311,8 @@ public final class ProtoBuf {
org.jetbrains.jet.descriptors.serialization.ProtoBuf.Type getReturnType();
}
public static final class Callable extends
- com.google.protobuf.GeneratedMessageLite
- implements CallableOrBuilder {
+ com.google.protobuf.GeneratedMessageLite.ExtendableMessage<
+ Callable> implements CallableOrBuilder {
// Use Callable.newBuilder() to construct.
private Callable(Builder builder) {
super(builder);
@@ -6158,6 +6159,10 @@ public final class ProtoBuf {
memoizedIsInitialized = 0;
return false;
}
+ if (!extensionsAreInitialized()) {
+ memoizedIsInitialized = 0;
+ return false;
+ }
memoizedIsInitialized = 1;
return true;
}
@@ -6165,6 +6170,9 @@ public final class ProtoBuf {
public void writeTo(com.google.protobuf.CodedOutputStream output)
throws java.io.IOException {
getSerializedSize();
+ com.google.protobuf.GeneratedMessageLite
+ .ExtendableMessage.ExtensionWriter extensionWriter =
+ newExtensionWriter();
if (((bitField0_ & 0x00000001) == 0x00000001)) {
output.writeInt32(1, flags_);
}
@@ -6195,6 +6203,7 @@ public final class ProtoBuf {
if (((bitField0_ & 0x00000010) == 0x00000010)) {
output.writeInt32(11, setterParameterName_);
}
+ extensionWriter.writeUntil(200, output);
}
private int memoizedSerializedSize = -1;
@@ -6243,6 +6252,7 @@ public final class ProtoBuf {
size += com.google.protobuf.CodedOutputStream
.computeInt32Size(11, setterParameterName_);
}
+ size += extensionsSerializedSize();
memoizedSerializedSize = size;
return size;
}
@@ -6329,9 +6339,8 @@ public final class ProtoBuf {
public Builder toBuilder() { return newBuilder(this); }
public static final class Builder extends
- com.google.protobuf.GeneratedMessageLite.Builder<
- org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable, Builder>
- implements org.jetbrains.jet.descriptors.serialization.ProtoBuf.CallableOrBuilder {
+ com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<
+ org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable, Builder> implements org.jetbrains.jet.descriptors.serialization.ProtoBuf.CallableOrBuilder {
// Construct using org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable.newBuilder()
private Builder() {
maybeForceBuilderInitialization();
@@ -6490,6 +6499,7 @@ public final class ProtoBuf {
if (other.hasReturnType()) {
mergeReturnType(other.getReturnType());
}
+ this.mergeExtensionFields(other);
return this;
}
@@ -6524,6 +6534,10 @@ public final class ProtoBuf {
return false;
}
+ if (!extensionsAreInitialized()) {
+
+ return false;
+ }
return true;
}
diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java
index 7a10a3fb1c8..cb19039ca5c 100644
--- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java
+++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/SerializerExtension.java
@@ -17,6 +17,7 @@
package org.jetbrains.jet.descriptors.serialization;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
public abstract class SerializerExtension {
@@ -25,4 +26,7 @@ public abstract class SerializerExtension {
public boolean hasSupertypes(@NotNull ClassDescriptor descriptor) {
return true;
}
+
+ public void serializeCallable(@NotNull CallableMemberDescriptor callable, @NotNull ProtoBuf.Callable.Builder proto) {
+ }
}
diff --git a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java
index e26461ed511..a726690deda 100644
--- a/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java
+++ b/compiler/frontend/serialization/src/org/jetbrains/jet/descriptors/serialization/descriptors/AnnotationDeserializer.java
@@ -3,6 +3,7 @@ package org.jetbrains.jet.descriptors.serialization.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.descriptors.serialization.ProtoBuf;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
+import org.jetbrains.jet.lang.descriptors.ClassOrNamespaceDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import java.util.List;
@@ -18,22 +19,14 @@ public interface AnnotationDeserializer {
@NotNull
@Override
public List loadCallableAnnotations(
- @NotNull ProtoBuf.Callable callableProto
+ @NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto
) {
return notSupported();
}
@NotNull
@Override
- public List loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
- return notSupported();
- }
-
- @NotNull
- @Override
- public List loadValueParameterAnnotations(
- @NotNull ProtoBuf.Callable.ValueParameter parameterProto
- ) {
+ public List loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
return notSupported();
}
@@ -47,14 +40,10 @@ public interface AnnotationDeserializer {
@NotNull
List loadCallableAnnotations(
+ @NotNull ClassOrNamespaceDescriptor container,
@NotNull ProtoBuf.Callable callableProto
);
@NotNull
- List loadValueParameterAnnotations(
- @NotNull ProtoBuf.Callable.ValueParameter parameterProto
- );
-
- @NotNull
- List loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto);
+ List loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto);
}
diff --git a/compiler/testData/loadKotlin/annotations/classMembers/Function.kt b/compiler/testData/loadKotlin/annotations/classMembers/Function.kt
new file mode 100644
index 00000000000..ecb1631416f
--- /dev/null
+++ b/compiler/testData/loadKotlin/annotations/classMembers/Function.kt
@@ -0,0 +1,7 @@
+package test
+
+annotation class Anno
+
+class Class {
+ Anno fun foo() { }
+}
diff --git a/compiler/testData/loadKotlin/annotations/classMembers/Function.txt b/compiler/testData/loadKotlin/annotations/classMembers/Function.txt
new file mode 100644
index 00000000000..04d14bc8372
--- /dev/null
+++ b/compiler/testData/loadKotlin/annotations/classMembers/Function.txt
@@ -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()
+ test.Anno() internal final fun foo(): jet.Unit
+}
diff --git a/compiler/tests/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorSerializationTest.java b/compiler/tests/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorSerializationTest.java
index e7f42d5179a..5f8398843fa 100644
--- a/compiler/tests/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorSerializationTest.java
+++ b/compiler/tests/org/jetbrains/jet/descriptors/serialization/AbstractDescriptorSerializationTest.java
@@ -70,13 +70,9 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
@NotNull
@Override
- public List loadCallableAnnotations(@NotNull ProtoBuf.Callable callableProto) {
- throw new UnsupportedOperationException(); // TODO
- }
-
- @NotNull
- @Override
- public List loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
+ public List loadCallableAnnotations(
+ @NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto
+ ) {
throw new UnsupportedOperationException(); // TODO
}
diff --git a/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java b/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java
index 6de02405d5f..3baa7af4c19 100644
--- a/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java
+++ b/compiler/tests/org/jetbrains/jet/descriptors/serialization/DescriptorSerializationTestGenerated.java
@@ -38,12 +38,25 @@ public class DescriptorSerializationTestGenerated extends AbstractDescriptorSeri
}
@TestMetadata("compiler/testData/loadKotlin/annotations")
- @InnerTestClasses({Annotations.Classes.class})
+ @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class})
public static class Annotations extends AbstractDescriptorSerializationTest {
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);
}
+ @TestMetadata("compiler/testData/loadKotlin/annotations/classMembers")
+ public static class ClassMembers extends AbstractDescriptorSerializationTest {
+ public void testAllFilesPresentInClassMembers() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/classMembers"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("Function.kt")
+ public void testFunction() throws Exception {
+ doTest("compiler/testData/loadKotlin/annotations/classMembers/Function.kt");
+ }
+
+ }
+
@TestMetadata("compiler/testData/loadKotlin/annotations/classes")
public static class Classes extends AbstractDescriptorSerializationTest {
public void testAllFilesPresentInClasses() throws Exception {
@@ -95,6 +108,7 @@ public class DescriptorSerializationTestGenerated extends AbstractDescriptorSeri
public static Test innerSuite() {
TestSuite suite = new TestSuite("Annotations");
suite.addTestSuite(Annotations.class);
+ suite.addTestSuite(ClassMembers.class);
suite.addTestSuite(Classes.class);
return suite;
}
diff --git a/compiler/tests/org/jetbrains/jet/descriptors/serialization/KotlinInfoForClassTest.java b/compiler/tests/org/jetbrains/jet/descriptors/serialization/KotlinInfoForClassTest.java
index 2c486604b30..844f4cc9878 100644
--- a/compiler/tests/org/jetbrains/jet/descriptors/serialization/KotlinInfoForClassTest.java
+++ b/compiler/tests/org/jetbrains/jet/descriptors/serialization/KotlinInfoForClassTest.java
@@ -32,6 +32,8 @@ import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import java.io.IOException;
+import static com.google.protobuf.ExtensionRegistryLite.getEmptyRegistry;
+
public class KotlinInfoForClassTest extends CodegenTestCase {
public static final FqName NAMESPACE_NAME = new FqName("test");
public static final FqNameUnsafe CLASS_NAME = new FqNameUnsafe("A");
@@ -68,7 +70,7 @@ public class KotlinInfoForClassTest extends CodegenTestCase {
public KotlinInfoBasedDescriptorFinder(@NotNull KotlinInfo kotlinInfo) throws IOException {
super(new LockBasedStorageManager(), AnnotationDeserializer.UNSUPPORTED);
- this.classData = ClassData.read(kotlinInfo.data());
+ this.classData = ClassData.read(kotlinInfo.data(), getEmptyRegistry());
this.namespace = JetTestUtils.createTestNamespace(NAMESPACE_NAME.shortName());
}
diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java
index 8689c36abb5..14150f8a231 100644
--- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java
+++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java
@@ -38,12 +38,25 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
}
@TestMetadata("compiler/testData/loadKotlin/annotations")
- @InnerTestClasses({Annotations.Classes.class})
+ @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class})
public static class Annotations extends AbstractLoadCompiledKotlinTest {
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);
}
+ @TestMetadata("compiler/testData/loadKotlin/annotations/classMembers")
+ public static class ClassMembers extends AbstractLoadCompiledKotlinTest {
+ public void testAllFilesPresentInClassMembers() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/classMembers"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("Function.kt")
+ public void testFunction() throws Exception {
+ doTestWithAccessors("compiler/testData/loadKotlin/annotations/classMembers/Function.kt");
+ }
+
+ }
+
@TestMetadata("compiler/testData/loadKotlin/annotations/classes")
public static class Classes extends AbstractLoadCompiledKotlinTest {
public void testAllFilesPresentInClasses() throws Exception {
@@ -95,6 +108,7 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
public static Test innerSuite() {
TestSuite suite = new TestSuite("Annotations");
suite.addTestSuite(Annotations.class);
+ suite.addTestSuite(ClassMembers.class);
suite.addTestSuite(Classes.class);
return suite;
}
diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java
index b0e8dfcf556..667f1d70c4b 100644
--- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java
+++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java
@@ -40,12 +40,25 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
}
@TestMetadata("compiler/testData/loadKotlin/annotations")
- @InnerTestClasses({Annotations.Classes.class})
+ @InnerTestClasses({Annotations.ClassMembers.class, Annotations.Classes.class})
public static class Annotations extends AbstractLazyResolveNamespaceComparingTest {
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);
}
+ @TestMetadata("compiler/testData/loadKotlin/annotations/classMembers")
+ public static class ClassMembers extends AbstractLazyResolveNamespaceComparingTest {
+ public void testAllFilesPresentInClassMembers() throws Exception {
+ JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/annotations/classMembers"), Pattern.compile("^(.+)\\.kt$"), true);
+ }
+
+ @TestMetadata("Function.kt")
+ public void testFunction() throws Exception {
+ doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/annotations/classMembers/Function.kt");
+ }
+
+ }
+
@TestMetadata("compiler/testData/loadKotlin/annotations/classes")
public static class Classes extends AbstractLazyResolveNamespaceComparingTest {
public void testAllFilesPresentInClasses() throws Exception {
@@ -97,6 +110,7 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
public static Test innerSuite() {
TestSuite suite = new TestSuite("Annotations");
suite.addTestSuite(Annotations.class);
+ suite.addTestSuite(ClassMembers.class);
suite.addTestSuite(Classes.class);
return suite;
}