Extract evaluator from AnnotationResolver
This commit is contained in:
@@ -47,7 +47,6 @@ import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.COMPILE_TIME_INITIALIZER;
|
||||
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry;
|
||||
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
||||
|
||||
public class AnnotationResolver {
|
||||
@@ -206,7 +205,7 @@ public class AnnotationResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private void resolveAnnotationArgument(
|
||||
public static void resolveAnnotationArgument(
|
||||
@NotNull AnnotationDescriptorImpl annotationDescriptor,
|
||||
@NotNull ResolvedCall<? extends CallableDescriptor> call,
|
||||
@NotNull BindingTrace trace
|
||||
@@ -233,7 +232,7 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<CompileTimeConstant<?>> resolveValueArguments(
|
||||
private static List<CompileTimeConstant<?>> resolveValueArguments(
|
||||
@NotNull ResolvedValueArgument resolvedValueArgument,
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull BindingTrace trace
|
||||
@@ -252,115 +251,20 @@ public class AnnotationResolver {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public CompileTimeConstant<?> resolveExpressionToCompileTimeValue(
|
||||
public static CompileTimeConstant<?> resolveExpressionToCompileTimeValue(
|
||||
@NotNull JetExpression expression,
|
||||
@NotNull final JetType expectedType,
|
||||
@NotNull final BindingTrace trace
|
||||
@NotNull JetType expectedType,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
JetVisitor<CompileTimeConstant<?>, Void> visitor = new JetVisitor<CompileTimeConstant<?>, Void>() {
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitConstantExpression(@NotNull JetConstantExpression expression, Void nothing) {
|
||||
JetType type = expressionTypingServices.getType(JetScope.EMPTY, expression, expectedType, DataFlowInfo.EMPTY, trace);
|
||||
if (type == null) {
|
||||
// TODO:
|
||||
// trace.report(ANNOTATION_PARAMETER_SHOULD_BE_CONSTANT.on(expression));
|
||||
}
|
||||
return trace.get(BindingContext.COMPILE_TIME_VALUE, expression);
|
||||
}
|
||||
return expression.accept(new ConstantExpressionEvaluator(trace, expectedType), null);
|
||||
}
|
||||
|
||||
|
||||
// @Override
|
||||
// public CompileTimeConstant visitAnnotation(JetAnnotation annotation, Void nothing) {
|
||||
// super.visitAnnotation(annotation, null); // TODO
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public CompileTimeConstant visitAnnotationEntry(JetAnnotationEntry annotationEntry, Void nothing) {
|
||||
// return super.visitAnnotationEntry(annotationEntry, null); // TODO
|
||||
// }
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, Void nothing) {
|
||||
JetExpression innerExpression = expression.getExpression();
|
||||
if (innerExpression == null) return null;
|
||||
return innerExpression.accept(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, Void nothing) {
|
||||
return trace.get(BindingContext.COMPILE_TIME_VALUE, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, Void data) {
|
||||
DeclarationDescriptor descriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, expression);
|
||||
if (descriptor != null && isEnumEntry(descriptor)) {
|
||||
return new EnumValue((ClassDescriptor) descriptor);
|
||||
}
|
||||
|
||||
ResolvedCall<?> resolvedCall = trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression);
|
||||
if (resolvedCall != null) {
|
||||
CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor();
|
||||
if (callableDescriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) callableDescriptor;
|
||||
if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor)) {
|
||||
return trace.getBindingContext().get(COMPILE_TIME_INITIALIZER, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitQualifiedExpression(@NotNull JetQualifiedExpression expression, Void data) {
|
||||
JetExpression selectorExpression = expression.getSelectorExpression();
|
||||
if (selectorExpression != null) {
|
||||
return selectorExpression.accept(this, null);
|
||||
}
|
||||
return super.visitQualifiedExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitCallExpression(@NotNull JetCallExpression expression, Void data) {
|
||||
ResolvedCall<? extends CallableDescriptor> call =
|
||||
trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression());
|
||||
if (call != null) {
|
||||
CallableDescriptor resultingDescriptor = call.getResultingDescriptor();
|
||||
if (AnnotationUtils.isArrayMethodCall(call)) {
|
||||
JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType();
|
||||
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
||||
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
|
||||
arguments.addAll(resolveValueArguments(descriptorToArgument, type, trace));
|
||||
}
|
||||
return new ArrayValue(arguments, resultingDescriptor.getReturnType());
|
||||
}
|
||||
|
||||
if (resultingDescriptor instanceof ConstructorDescriptor) {
|
||||
JetType constructorReturnType = resultingDescriptor.getReturnType();
|
||||
assert constructorReturnType != null : "Constructor should have return type";
|
||||
if (DescriptorUtils.isAnnotationClass(constructorReturnType.getConstructor().getDeclarationDescriptor())) {
|
||||
AnnotationDescriptorImpl descriptor = new AnnotationDescriptorImpl();
|
||||
descriptor.setAnnotationType(constructorReturnType);
|
||||
resolveAnnotationArgument(descriptor, call, trace);
|
||||
return new AnnotationValue(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (AnnotationUtils.isJavaClassMethodCall(call)) {
|
||||
return new JavaClassValue(resultingDescriptor.getReturnType());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitJetElement(@NotNull JetElement element, Void nothing) {
|
||||
// TODO:
|
||||
//trace.report(ANNOTATION_PARAMETER_SHOULD_BE_CONSTANT.on(element));
|
||||
return null;
|
||||
}
|
||||
};
|
||||
return expression.accept(visitor, null);
|
||||
@NotNull
|
||||
public List<AnnotationDescriptor> getResolvedAnnotations(@Nullable JetModifierList modifierList, BindingTrace trace) {
|
||||
if (modifierList == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
return getResolvedAnnotations(modifierList.getAnnotationEntries(), trace);
|
||||
}
|
||||
|
||||
@SuppressWarnings("MethodMayBeStatic")
|
||||
|
||||
@@ -556,7 +556,7 @@ public class BodyResolver {
|
||||
JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer, context.getOuterDataFlowInfo(), trace);
|
||||
if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor)) {
|
||||
CompileTimeConstant<?> constant = annotationResolver.resolveExpressionToCompileTimeValue(initializer, expectedTypeForInitializer, trace);
|
||||
CompileTimeConstant<?> constant = AnnotationResolver.resolveExpressionToCompileTimeValue(initializer, expectedTypeForInitializer, trace);
|
||||
if (constant != null) {
|
||||
trace.record(BindingContext.COMPILE_TIME_INITIALIZER, propertyDescriptor, constant);
|
||||
}
|
||||
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* 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.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument;
|
||||
import org.jetbrains.jet.lang.resolve.constants.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
|
||||
import javax.rmi.CORBA.ClassDesc;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.COMPILE_TIME_INITIALIZER;
|
||||
|
||||
public class ConstantExpressionEvaluator extends JetVisitor<CompileTimeConstant<?>, Void> {
|
||||
@NotNull private final BindingTrace trace;
|
||||
@NotNull private final JetType expectedType;
|
||||
|
||||
public ConstantExpressionEvaluator(@NotNull BindingTrace trace, @NotNull JetType expectedType) {
|
||||
this.trace = trace;
|
||||
this.expectedType = expectedType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitConstantExpression(@NotNull JetConstantExpression expression, Void nothing) {
|
||||
return trace.get(BindingContext.COMPILE_TIME_VALUE, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitParenthesizedExpression(@NotNull JetParenthesizedExpression expression, Void nothing) {
|
||||
JetExpression innerExpression = expression.getExpression();
|
||||
if (innerExpression == null) return null;
|
||||
return innerExpression.accept(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitStringTemplateExpression(@NotNull JetStringTemplateExpression expression, Void nothing) {
|
||||
return trace.get(BindingContext.COMPILE_TIME_VALUE, expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitSimpleNameExpression(@NotNull JetSimpleNameExpression expression, Void data) {
|
||||
DeclarationDescriptor descriptor = trace.getBindingContext().get(BindingContext.REFERENCE_TARGET, expression);
|
||||
if (descriptor != null && DescriptorUtils.isEnumEntry(descriptor)) {
|
||||
return new EnumValue((ClassDescriptor) descriptor);
|
||||
}
|
||||
|
||||
ResolvedCall<? extends CallableDescriptor> resolvedCall =
|
||||
trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression);
|
||||
if (resolvedCall != null) {
|
||||
CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor();
|
||||
if (callableDescriptor instanceof PropertyDescriptor) {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) callableDescriptor;
|
||||
if (AnnotationUtils.isPropertyAcceptableAsAnnotationParameter(propertyDescriptor)) {
|
||||
return trace.getBindingContext().get(COMPILE_TIME_INITIALIZER, propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitQualifiedExpression(@NotNull JetQualifiedExpression expression, Void data) {
|
||||
JetExpression selectorExpression = expression.getSelectorExpression();
|
||||
if (selectorExpression != null) {
|
||||
return selectorExpression.accept(this, null);
|
||||
}
|
||||
return super.visitQualifiedExpression(expression, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitCallExpression(@NotNull JetCallExpression expression, Void data) {
|
||||
ResolvedCall<? extends CallableDescriptor> call =
|
||||
trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression());
|
||||
if (call != null) {
|
||||
CallableDescriptor resultingDescriptor = call.getResultingDescriptor();
|
||||
if (AnnotationUtils.isArrayMethodCall(call)) {
|
||||
JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType();
|
||||
List<CompileTimeConstant<?>> arguments = Lists.newArrayList();
|
||||
for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) {
|
||||
arguments.addAll(resolveArguments(descriptorToArgument.getArguments(), type, trace));
|
||||
}
|
||||
return new ArrayValue(arguments, resultingDescriptor.getReturnType());
|
||||
}
|
||||
|
||||
if (resultingDescriptor instanceof ConstructorDescriptor) {
|
||||
JetType constructorReturnType = resultingDescriptor.getReturnType();
|
||||
assert constructorReturnType != null : "Constructor should have return type";
|
||||
if (DescriptorUtils.isAnnotationClass(constructorReturnType.getConstructor().getDeclarationDescriptor())) {
|
||||
AnnotationDescriptorImpl descriptor = new AnnotationDescriptorImpl();
|
||||
descriptor.setAnnotationType(constructorReturnType);
|
||||
AnnotationResolver.resolveAnnotationArgument(descriptor, call, trace);
|
||||
return new AnnotationValue(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if (AnnotationUtils.isJavaClassMethodCall(call)) {
|
||||
return new JavaClassValue(resultingDescriptor.getReturnType());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<CompileTimeConstant<?>> resolveArguments(@NotNull List<ValueArgument> valueArguments, @NotNull JetType expectedType, @NotNull BindingTrace trace) {
|
||||
List<CompileTimeConstant<?>> constants = Lists.newArrayList();
|
||||
for (ValueArgument argument : valueArguments) {
|
||||
JetExpression argumentExpression = argument.getArgumentExpression();
|
||||
if (argumentExpression != null) {
|
||||
CompileTimeConstant<?> constant = argumentExpression.accept(new ConstantExpressionEvaluator(trace, expectedType), null);
|
||||
if (constant != null) {
|
||||
constants.add(constant);
|
||||
}
|
||||
}
|
||||
}
|
||||
return constants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompileTimeConstant<?> visitJetElement(@NotNull JetElement element, Void nothing) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -396,7 +396,7 @@ public class ExpressionTypingServices {
|
||||
getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), dataFlowInfo, trace);
|
||||
if (DescriptorUtils.isAnnotationClass(DescriptorUtils.getContainingClass(declaringScope))) {
|
||||
CompileTimeConstant<?> constant =
|
||||
annotationResolver.resolveExpressionToCompileTimeValue(defaultValue, valueParameterDescriptor.getType(), trace);
|
||||
AnnotationResolver.resolveExpressionToCompileTimeValue(defaultValue, valueParameterDescriptor.getType(), trace);
|
||||
if (constant != null) {
|
||||
trace.record(BindingContext.COMPILE_TIME_VALUE, defaultValue, constant);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user