annotations with parameters
This commit is contained in:
@@ -16,9 +16,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor;
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
|
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
|
||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.objectweb.asm.AnnotationVisitor;
|
import org.objectweb.asm.AnnotationVisitor;
|
||||||
@@ -28,6 +33,7 @@ import org.objectweb.asm.MethodVisitor;
|
|||||||
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
@@ -36,13 +42,32 @@ public abstract class AnnotationCodegen {
|
|||||||
public void genAnnotations(Annotated annotated, JetTypeMapper typeMapper) {
|
public void genAnnotations(Annotated annotated, JetTypeMapper typeMapper) {
|
||||||
if(annotated == null)
|
if(annotated == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
List<AnnotationDescriptor> annotations = annotated.getAnnotations();
|
if(!(annotated instanceof DeclarationDescriptor))
|
||||||
if(annotations == null)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (AnnotationDescriptor annotationDescriptor : annotations) {
|
BindingContext bindingContext = typeMapper.bindingContext;
|
||||||
List<CompileTimeConstant<?>> valueArguments = annotationDescriptor.getValueArguments();
|
PsiElement psiElement = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, (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();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(modifierList == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<JetAnnotationEntry> annotationEntries = modifierList.getAnnotationEntries();
|
||||||
|
for (JetAnnotationEntry annotationEntry : annotationEntries) {
|
||||||
|
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(BindingContext.RESOLVED_CALL, annotationEntry.getCalleeExpression());
|
||||||
|
assert resolvedCall != null;
|
||||||
|
|
||||||
|
AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry);
|
||||||
|
assert annotationDescriptor != null;
|
||||||
|
|
||||||
JetType type = annotationDescriptor.getType();
|
JetType type = annotationDescriptor.getType();
|
||||||
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
|
ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||||
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper);
|
RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper);
|
||||||
@@ -50,13 +75,13 @@ public abstract class AnnotationCodegen {
|
|||||||
String internalName = typeMapper.mapType(type).getDescriptor();
|
String internalName = typeMapper.mapType(type).getDescriptor();
|
||||||
AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME);
|
AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME);
|
||||||
|
|
||||||
if(!valueArguments.isEmpty()) {
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : resolvedCall.getValueArguments().entrySet()) {
|
||||||
// todo: temporary hack for intrinsics in stdlib
|
List<JetExpression> valueArguments = entry.getValue().getArgumentExpressions();
|
||||||
if(valueArguments.size()==1 && "Intrinsic".equals(annotationDescriptor.getType().getConstructor().getDeclarationDescriptor().getName())) {
|
assert valueArguments.size() == 1; // todo
|
||||||
annotationVisitor.visit("value", valueArguments.get(0).getValue());
|
CompileTimeConstant<?> compileTimeConstant = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, valueArguments.get(0));
|
||||||
}
|
assert compileTimeConstant != null;
|
||||||
else
|
|
||||||
throw new UnsupportedOperationException("Only annotations without values are supported by backend so far");
|
annotationVisitor.visit(entry.getKey().getName(), compileTimeConstant.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
annotationVisitor.visitEnd();
|
annotationVisitor.visitEnd();
|
||||||
@@ -100,11 +125,11 @@ public abstract class AnnotationCodegen {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AnnotationCodegen forField(final FieldVisitor mv) {
|
public static AnnotationCodegen forField(final FieldVisitor fv) {
|
||||||
return new AnnotationCodegen() {
|
return new AnnotationCodegen() {
|
||||||
@Override
|
@Override
|
||||||
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
AnnotationVisitor visitAnnotation(String descr, boolean visible) {
|
||||||
return mv.visitAnnotation(descr, visible);
|
return fv.visitAnnotation(descr, visible);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class JetModifierList extends JetElement {
|
|||||||
return findChildrenByType(JetNodeTypes.ANNOTATION);
|
return findChildrenByType(JetNodeTypes.ANNOTATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public List<JetAnnotationEntry> getAnnotationEntries() {
|
public List<JetAnnotationEntry> getAnnotationEntries() {
|
||||||
List<JetAnnotationEntry> entries = findChildrenByType(JetNodeTypes.ANNOTATION_ENTRY);
|
List<JetAnnotationEntry> entries = findChildrenByType(JetNodeTypes.ANNOTATION_ENTRY);
|
||||||
List<JetAnnotationEntry> answer = entries.isEmpty() ? null : Lists.newArrayList(entries);
|
List<JetAnnotationEntry> answer = entries.isEmpty() ? null : Lists.newArrayList(entries);
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ public class AnnotationResolver {
|
|||||||
for (JetAnnotationEntry entryElement : annotationEntryElements) {
|
for (JetAnnotationEntry entryElement : annotationEntryElements) {
|
||||||
AnnotationDescriptor descriptor = new AnnotationDescriptor();
|
AnnotationDescriptor descriptor = new AnnotationDescriptor();
|
||||||
resolveAnnotationStub(scope, entryElement, descriptor, trace);
|
resolveAnnotationStub(scope, entryElement, descriptor, trace);
|
||||||
|
trace.record(BindingContext.ANNOTATION, entryElement, descriptor);
|
||||||
result.add(descriptor);
|
result.add(descriptor);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user