Generate annotations from descriptors, not PSI

This commit is contained in:
Andrey Breslav
2014-12-22 17:24:07 +03:00
parent 830e4dfd98
commit 8ff5cf62cc
5 changed files with 31 additions and 56 deletions
@@ -16,21 +16,13 @@
package org.jetbrains.jet.codegen;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.codegen.state.JetTypeMapper;
import org.jetbrains.jet.descriptors.serialization.descriptors.DeserializedCallableMemberDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.psi.JetAnnotationEntry;
import org.jetbrains.jet.lang.psi.JetClass;
import org.jetbrains.jet.lang.psi.JetModifierList;
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.constants.StringValue;
import org.jetbrains.jet.lang.resolve.java.JvmAnnotationNames;
@@ -46,10 +38,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.*;
import static org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor.Kind.DELEGATION;
import static org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils.descriptorToDeclaration;
import static org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage.getResolvedCall;
public abstract class AnnotationCodegen {
public static final class JvmFlagAnnotation {
@@ -84,11 +72,9 @@ public abstract class AnnotationCodegen {
private static final AnnotationVisitor NO_ANNOTATION_VISITOR = new AnnotationVisitor(Opcodes.ASM5) {};
private final JetTypeMapper typeMapper;
private final BindingContext bindingContext;
private AnnotationCodegen(JetTypeMapper mapper) {
typeMapper = mapper;
bindingContext = typeMapper.getBindingContext();
}
/**
@@ -103,48 +89,12 @@ public abstract class AnnotationCodegen {
return;
}
PsiElement psiElement;
if (annotated instanceof CallableMemberDescriptor && ((CallableMemberDescriptor) annotated).getKind() == DELEGATION) {
psiElement = null;
}
else {
psiElement = descriptorToDeclaration((DeclarationDescriptor) annotated);
}
JetModifierList modifierList = null;
if (annotated instanceof ConstructorDescriptor && psiElement instanceof JetClass) {
modifierList = ((JetClass) psiElement).getPrimaryConstructorModifierList();
}
else if (psiElement instanceof JetModifierListOwner) {
modifierList = ((JetModifierListOwner) psiElement).getModifierList();
}
Set<String> annotationDescriptorsAlreadyPresent = new HashSet<String>();
if (modifierList == null) {
if (annotated instanceof CallableMemberDescriptor &&
JvmCodegenUtil.getDirectMember((CallableMemberDescriptor) annotated) instanceof DeserializedCallableMemberDescriptor) {
for (AnnotationDescriptor annotation : annotated.getAnnotations()) {
String descriptor = genAnnotation(annotation);
if (descriptor != null) {
annotationDescriptorsAlreadyPresent.add(descriptor);
}
}
}
}
else {
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
for (JetAnnotationEntry annotationEntry : annotationEntries) {
ResolvedCall<?> resolvedCall = getResolvedCall(annotationEntry, bindingContext);
if (resolvedCall == null) continue; // Skipping annotations if they are not resolved. Needed for JetLightClass generation
AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry);
if (annotationDescriptor == null) continue; // Skipping annotations if they are not resolved. Needed for JetLightClass generation
String descriptor = genAnnotation(annotationDescriptor);
if (descriptor != null) {
annotationDescriptorsAlreadyPresent.add(descriptor);
}
for (AnnotationDescriptor annotation : annotated.getAnnotations()) {
String descriptor = genAnnotation(annotation);
if (descriptor != null) {
annotationDescriptorsAlreadyPresent.add(descriptor);
}
}
@@ -0,0 +1,11 @@
package a
import java.lang.annotation.*
Retention(RetentionPolicy.RUNTIME)
annotation class Ann
trait Tr {
Ann
fun foo() {}
}
@@ -0,0 +1,9 @@
class C : a.Tr
fun main(args: Array<String>) {
val method = javaClass<C>().getDeclaredMethod("foo")
val annotations = method.getDeclaredAnnotations().joinToString("\n")
if (annotations != "@a.Ann()") {
throw AssertionError(annotations)
}
}
@@ -19,7 +19,6 @@ package org.jetbrains.jet.jvm.compiler;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.jet.JUnit3RunnerWithInners;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.test.InnerTestClasses;
import org.jetbrains.jet.test.TestMetadata;
import org.junit.runner.RunWith;
@@ -36,6 +35,12 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/compileKotlinAgainstKotlin"), Pattern.compile("^(.+)\\.A.kt$"), true);
}
@TestMetadata("AnnotationInTrait.A.kt")
public void testAnnotationInTrait() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/AnnotationInTrait.A.kt");
doTest(fileName);
}
@TestMetadata("ClassInObject.A.kt")
public void testClassInObject() throws Exception {
String fileName = JetTestUtils.navigationMetadata("compiler/testData/compileKotlinAgainstKotlin/ClassInObject.A.kt");
@@ -92,7 +92,7 @@ public class SimpleFunctionDescriptorImpl extends FunctionDescriptorImpl impleme
getAnnotations(),
getName(),
kind,
getSource()
SourceElement.NO_SOURCE
);
}