Only create lazy annotations for descriptors from code

This commit is contained in:
Andrey Breslav
2014-04-02 13:53:08 +04:00
parent c57243035e
commit bb87a6bb59
4 changed files with 45 additions and 77 deletions
@@ -359,9 +359,10 @@ public class ConstantExpressionEvaluator private (val trace: BindingTrace) : Jet
if (resultingDescriptor is ConstructorDescriptor) { if (resultingDescriptor is ConstructorDescriptor) {
val classDescriptor: ClassDescriptor = resultingDescriptor.getContainingDeclaration() val classDescriptor: ClassDescriptor = resultingDescriptor.getContainingDeclaration()
if (DescriptorUtils.isAnnotationClass(classDescriptor)) { if (DescriptorUtils.isAnnotationClass(classDescriptor)) {
val descriptor = AnnotationDescriptorImpl() val descriptor = AnnotationDescriptorImpl(
descriptor.setAnnotationType(classDescriptor.getDefaultType()) classDescriptor.getDefaultType(),
AnnotationResolver.resolveAnnotationArguments(descriptor, call, trace) AnnotationResolver.resolveAnnotationArguments(call, trace)
)
return AnnotationValue(descriptor) return AnnotationValue(descriptor)
} }
} }
@@ -23,7 +23,10 @@ import kotlin.KotlinPackage;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationsImpl;
import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator; import org.jetbrains.jet.lang.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
@@ -48,6 +51,7 @@ import org.jetbrains.jet.storage.StorageManager;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -128,24 +132,17 @@ public class AnnotationResolver {
for (JetAnnotationEntry entryElement : annotationEntryElements) { for (JetAnnotationEntry entryElement : annotationEntryElements) {
AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement); AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement);
if (descriptor == null) { if (descriptor == null) {
if (TopDownAnalyzer.LAZY) { descriptor = new LazyAnnotationDescriptor(
descriptor = new LazyAnnotationDescriptor( new LazyAnnotationsContext(this, storageManager, trace) {
new LazyAnnotationsContext(this, storageManager, trace) {
@NotNull @NotNull
@Override @Override
public JetScope getScope() { public JetScope getScope() {
return scope; return scope;
} }
}, },
entryElement entryElement
); );
}
else {
descriptor = new AnnotationDescriptorImpl();
((AnnotationDescriptorImpl) descriptor).setAnnotationType(resolveAnnotationType(scope, entryElement));
trace.record(BindingContext.ANNOTATION, entryElement, descriptor);
}
} }
if (shouldResolveArguments) { if (shouldResolveArguments) {
resolveAnnotationArguments(entryElement, scope, trace); resolveAnnotationArguments(entryElement, scope, trace);
@@ -220,7 +217,7 @@ public class AnnotationResolver {
} }
} }
private void resolveAnnotationArguments( private static void resolveAnnotationArguments(
@NotNull JetAnnotationEntry annotationEntry, @NotNull JetAnnotationEntry annotationEntry,
@NotNull JetScope scope, @NotNull JetScope scope,
@NotNull BindingTrace trace @NotNull BindingTrace trace
@@ -228,47 +225,26 @@ public class AnnotationResolver {
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
if (annotationDescriptor instanceof LazyAnnotationDescriptor) { if (annotationDescriptor instanceof LazyAnnotationDescriptor) {
// TopDownAnalyzer.LAZY
((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents(); ((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents();
return;
}
AnnotationDescriptorImpl annotationDescriptorImpl = (AnnotationDescriptorImpl) annotationDescriptor;
if (annotationDescriptorImpl.areValueArgumentsResolved()) return;
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(annotationEntry, scope, trace);
if (results.isSingleResult()) {
checkAnnotationType(annotationEntry, trace, results);
resolveAnnotationArguments(annotationDescriptor, results.getResultingCall(), trace);
}
else {
annotationDescriptorImpl.markValueArgumentsResolved();
} }
} }
public static void resolveAnnotationArguments( @NotNull
@NotNull AnnotationDescriptor annotationDescriptor, public static Map<ValueParameterDescriptor, CompileTimeConstant<?>> resolveAnnotationArguments(
@NotNull ResolvedCall<?> resolvedCall, @NotNull ResolvedCall<?> resolvedCall,
@NotNull BindingTrace trace @NotNull BindingTrace trace
) { ) {
if (TopDownAnalyzer.LAZY && annotationDescriptor instanceof LazyAnnotationDescriptor) { Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = new HashMap<ValueParameterDescriptor, CompileTimeConstant<?>>();
((LazyAnnotationDescriptor) annotationDescriptor).forceResolveAllContents();
return;
}
AnnotationDescriptorImpl annotationDescriptorImpl = (AnnotationDescriptorImpl) annotationDescriptor;
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument : resolvedCall.getValueArguments().entrySet()) { for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument : resolvedCall.getValueArguments().entrySet()) {
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
ResolvedValueArgument resolvedArgument = descriptorToArgument.getValue(); ResolvedValueArgument resolvedArgument = descriptorToArgument.getValue();
CompileTimeConstant<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument); CompileTimeConstant<?> value = getAnnotationArgumentValue(trace, parameterDescriptor, resolvedArgument);
if (value != null) { if (value != null) {
annotationDescriptorImpl.setValueArgument(parameterDescriptor, value); arguments.put(parameterDescriptor, value);
} }
} }
return arguments;
annotationDescriptorImpl.markValueArgumentsResolved();
} }
@Nullable @Nullable
@@ -42,7 +42,9 @@ import org.jetbrains.jet.lang.types.ErrorUtils;
import javax.inject.Inject; import javax.inject.Inject;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind; import static org.jetbrains.jet.descriptors.serialization.descriptors.Deserializers.AnnotatedCallableKind;
import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature; import static org.jetbrains.jet.lang.resolve.kotlin.DescriptorDeserializersStorage.MemberSignature;
@@ -119,10 +121,10 @@ public class AnnotationDescriptorDeserializer extends BaseDescriptorDeserializer
if (JvmAnnotationNames.isSpecialAnnotation(className)) return null; if (JvmAnnotationNames.isSpecialAnnotation(className)) return null;
final ClassDescriptor annotationClass = resolveClass(className, classResolver); final ClassDescriptor annotationClass = resolveClass(className, classResolver);
final AnnotationDescriptorImpl annotation = new AnnotationDescriptorImpl();
annotation.setAnnotationType(annotationClass.getDefaultType());
return new KotlinJvmBinaryClass.AnnotationArgumentVisitor() { return new KotlinJvmBinaryClass.AnnotationArgumentVisitor() {
private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> arguments = new HashMap<ValueParameterDescriptor, CompileTimeConstant<?>>();
@Override @Override
public void visit(@Nullable Name name, @Nullable Object value) { public void visit(@Nullable Name name, @Nullable Object value) {
if (name != null) { if (name != null) {
@@ -157,14 +159,16 @@ public class AnnotationDescriptorDeserializer extends BaseDescriptorDeserializer
@Override @Override
public void visitEnd() { public void visitEnd() {
annotation.markValueArgumentsResolved(); result.add(new AnnotationDescriptorImpl(
result.add(annotation); annotationClass.getDefaultType(),
arguments
));
} }
private void setArgumentValueByName(@NotNull Name name, @NotNull CompileTimeConstant<?> argumentValue) { private void setArgumentValueByName(@NotNull Name name, @NotNull CompileTimeConstant<?> argumentValue) {
ValueParameterDescriptor parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass); ValueParameterDescriptor parameter = DescriptorResolverUtils.getAnnotationParameterByName(name, annotationClass);
if (parameter != null) { if (parameter != null) {
annotation.setValueArgument(parameter, argumentValue); arguments.put(parameter, argumentValue);
} }
} }
}; };
@@ -16,7 +16,6 @@
package org.jetbrains.jet.lang.descriptors.annotations; package org.jetbrains.jet.lang.descriptors.annotations;
import com.google.common.collect.Maps;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
@@ -28,9 +27,16 @@ import java.util.Collections;
import java.util.Map; import java.util.Map;
public class AnnotationDescriptorImpl implements AnnotationDescriptor { public class AnnotationDescriptorImpl implements AnnotationDescriptor {
private JetType annotationType; private final JetType annotationType;
private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> valueArguments = Maps.newHashMap(); private final Map<ValueParameterDescriptor, CompileTimeConstant<?>> valueArguments;
private boolean valueArgumentsResolved = false;
public AnnotationDescriptorImpl(
@NotNull JetType annotationType,
@NotNull Map<ValueParameterDescriptor, CompileTimeConstant<?>> valueArguments
) {
this.annotationType = annotationType;
this.valueArguments = Collections.unmodifiableMap(valueArguments);
}
@Override @Override
@NotNull @NotNull
@@ -47,26 +53,7 @@ public class AnnotationDescriptorImpl implements AnnotationDescriptor {
@Override @Override
@NotNull @NotNull
public Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments() { public Map<ValueParameterDescriptor, CompileTimeConstant<?>> getAllValueArguments() {
// TODO: this assertion does not hold now, but this whole class will be gone before long, so I'm not fixing it return valueArguments;
//assert valueArgumentsResolved : "Value arguments are not resolved yet for [" + getType() + "]";
return Collections.unmodifiableMap(valueArguments);
}
public void setAnnotationType(@NotNull JetType annotationType) {
this.annotationType = annotationType;
}
public void setValueArgument(@NotNull ValueParameterDescriptor name, @NotNull CompileTimeConstant<?> value) {
assert !valueArgumentsResolved : "Value arguments are already resolved for " + this;
valueArguments.put(name, value);
}
public void markValueArgumentsResolved() {
this.valueArgumentsResolved = true;
}
public boolean areValueArgumentsResolved() {
return valueArgumentsResolved;
} }
@Override @Override