Deserialize annotations on class members
Make 'Callable' message of descriptors.proto extensible, extend it in java_descriptors.proto with a JVM signature of the member. This is needed in order for annotation deserializer to find out which member in the compiled bytecode corresponds to which descriptor in the hierarchy. Create a new module 'serialization.java' containing everything related to Java-specific serialization of descriptors. Add an extension point to DescriptorSerializer, allowing to perform platform-specific serialization on a callable
This commit is contained in:
Generated
+1
@@ -30,6 +30,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/preloader/preloader.iml" filepath="$PROJECT_DIR$/compiler/preloader/preloader.iml" group="compiler/cli" />
|
||||
<module fileurl="file://$PROJECT_DIR$/runtime/runtime.iml" filepath="$PROJECT_DIR$/runtime/runtime.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/frontend/serialization/serialization.iml" filepath="$PROJECT_DIR$/compiler/frontend/serialization/serialization.iml" group="compiler" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/frontend.java/serialization.java/serialization.java.iml" filepath="$PROJECT_DIR$/compiler/frontend.java/serialization.java/serialization.java.iml" group="compiler/java" />
|
||||
<module fileurl="file://$PROJECT_DIR$/compiler/util/util.iml" filepath="$PROJECT_DIR$/compiler/util/util.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<include name="compiler/frontend/src"/>
|
||||
<include name="compiler/frontend/serialization/src"/>
|
||||
<include name="compiler/frontend.java/src"/>
|
||||
<include name="compiler/frontend.java/serialization.java/src"/>
|
||||
<include name="compiler/backend/src"/>
|
||||
<include name="compiler/cli/src"/>
|
||||
<include name="compiler/cli/cli-common/src"/>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<orderEntry type="library" name="javax.inject" level="project" />
|
||||
<orderEntry type="module" module-name="serialization" />
|
||||
<orderEntry type="library" name="protobuf-java" level="project" />
|
||||
<orderEntry type="module" module-name="serialization.java" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
<orderEntry type="module" module-name="runtime" />
|
||||
<orderEntry type="library" name="javax.inject" level="project" />
|
||||
<orderEntry type="module" module-name="serialization" />
|
||||
<orderEntry type="module" module-name="serialization.java" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="protobuf-java" level="project" />
|
||||
<orderEntry type="module" module-name="serialization" />
|
||||
<orderEntry type="library" name="annotations" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
+29
@@ -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)
|
||||
}
|
||||
+44
@@ -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);
|
||||
}
|
||||
}
|
||||
+78
-39
@@ -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<AnnotationDescriptor> 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<AnnotationDescriptor> 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<AnnotationDescriptor> loadClassAnnotationsFromFile(@NotNull VirtualFile virtualFile) throws IOException {
|
||||
final List<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
|
||||
@@ -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<AnnotationDescriptor> result
|
||||
) {
|
||||
@Nullable
|
||||
private AnnotationVisitor resolveAnnotation(@NotNull String desc, @NotNull final List<AnnotationDescriptor> 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<AnnotationDescriptor> loadCallableAnnotations(@NotNull ProtoBuf.Callable callableProto) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
public List<AnnotationDescriptor> 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<String, List<AnnotationDescriptor>> memberAnnotations = loadMemberAnnotationsFromFile(file);
|
||||
|
||||
String signature = JavaProtoBufUtil.loadJavaSignature(callableProto);
|
||||
if (signature == null) return Collections.emptyList();
|
||||
|
||||
List<AnnotationDescriptor> annotations = memberAnnotations.get(signature);
|
||||
return annotations == null ? Collections.<AnnotationDescriptor>emptyList() : annotations;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw ExceptionUtils.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, List<AnnotationDescriptor>> loadMemberAnnotationsFromFile(@NotNull VirtualFile file) throws IOException {
|
||||
final Map<String, List<AnnotationDescriptor>> memberAnnotations = new HashMap<String, List<AnnotationDescriptor>>();
|
||||
|
||||
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<AnnotationDescriptor> result = new ArrayList<AnnotationDescriptor>();
|
||||
|
||||
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<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AnnotationDescriptor> loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -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
|
||||
|
||||
@@ -196,6 +196,8 @@ message Callable {
|
||||
repeated ValueParameter value_parameter = 7;
|
||||
|
||||
required Type return_type = 8;
|
||||
|
||||
extensions 100 to 199;
|
||||
}
|
||||
|
||||
enum Modality {
|
||||
|
||||
+3
-2
@@ -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) {
|
||||
|
||||
+10
-14
@@ -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<AnnotationDescriptor> annotations = getAnnotations(proto);
|
||||
List<AnnotationDescriptor> 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<TypeParameterDescriptor> typeParameters = new ArrayList<TypeParameterDescriptor>(proto.getTypeParameterCount());
|
||||
@@ -269,17 +267,15 @@ public class DescriptorDeserializer {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
private List<AnnotationDescriptor> getAnnotations(Callable proto) {
|
||||
return Flags.HAS_ANNOTATIONS.get(proto.getFlags())
|
||||
? annotationDeserializer.loadCallableAnnotations(proto)
|
||||
@NotNull
|
||||
private List<AnnotationDescriptor> 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.<AnnotationDescriptor>emptyList();
|
||||
}
|
||||
|
||||
private List<AnnotationDescriptor> getSetterAnnotations(Callable proto, int setterFlags) {
|
||||
return Flags.HAS_ANNOTATIONS.get(setterFlags) ? annotationDeserializer.loadSetterAnnotations(proto) : Collections
|
||||
.<AnnotationDescriptor>emptyList();
|
||||
}
|
||||
|
||||
private static CallableMemberDescriptor.Kind memberKind(Callable.MemberKind memberKind) {
|
||||
switch (memberKind) {
|
||||
case DECLARATION:
|
||||
|
||||
+2
@@ -212,6 +212,8 @@ public class DescriptorSerializer {
|
||||
|
||||
builder.setReturnType(local.type(getSerializableReturnType(descriptor.getReturnType())));
|
||||
|
||||
extension.serializeCallable(descriptor, builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
+21
-7
@@ -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<Callable> {
|
||||
|
||||
// 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<org.jetbrains.jet.descriptors.serialization.ProtoBuf.Callable>.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;
|
||||
}
|
||||
|
||||
|
||||
+4
@@ -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) {
|
||||
}
|
||||
}
|
||||
|
||||
+5
-16
@@ -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<AnnotationDescriptor> loadCallableAnnotations(
|
||||
@NotNull ProtoBuf.Callable callableProto
|
||||
@NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto
|
||||
) {
|
||||
return notSupported();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AnnotationDescriptor> loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
|
||||
return notSupported();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AnnotationDescriptor> loadValueParameterAnnotations(
|
||||
@NotNull ProtoBuf.Callable.ValueParameter parameterProto
|
||||
) {
|
||||
public List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto) {
|
||||
return notSupported();
|
||||
}
|
||||
|
||||
@@ -47,14 +40,10 @@ public interface AnnotationDeserializer {
|
||||
|
||||
@NotNull
|
||||
List<AnnotationDescriptor> loadCallableAnnotations(
|
||||
@NotNull ClassOrNamespaceDescriptor container,
|
||||
@NotNull ProtoBuf.Callable callableProto
|
||||
);
|
||||
|
||||
@NotNull
|
||||
List<AnnotationDescriptor> loadValueParameterAnnotations(
|
||||
@NotNull ProtoBuf.Callable.ValueParameter parameterProto
|
||||
);
|
||||
|
||||
@NotNull
|
||||
List<AnnotationDescriptor> loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto);
|
||||
List<AnnotationDescriptor> loadValueParameterAnnotations(@NotNull ProtoBuf.Callable.ValueParameter parameterProto);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package test
|
||||
|
||||
annotation class Anno
|
||||
|
||||
class Class {
|
||||
Anno fun foo() { }
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
+3
-7
@@ -70,13 +70,9 @@ public abstract class AbstractDescriptorSerializationTest extends KotlinTestWith
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AnnotationDescriptor> loadCallableAnnotations(@NotNull ProtoBuf.Callable callableProto) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public List<AnnotationDescriptor> loadSetterAnnotations(@NotNull ProtoBuf.Callable callableProto) {
|
||||
public List<AnnotationDescriptor> loadCallableAnnotations(
|
||||
@NotNull ClassOrNamespaceDescriptor container, @NotNull ProtoBuf.Callable callableProto
|
||||
) {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
|
||||
+15
-1
@@ -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;
|
||||
}
|
||||
|
||||
+3
-1
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+15
-1
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user