From a31027d2d3d3f3a885663c435b8ad3327bb16cfe Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 31 Jan 2012 16:43:20 +0400 Subject: [PATCH] Very basic stub implementation for annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 144 +++++++++++------- 1 file changed, 91 insertions(+), 53 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index 779286f8b02..8be22c486de 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -5,22 +5,24 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.psi.JetAnnotationEntry; -import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetModifierList; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import java.util.Collections; import java.util.List; +import java.util.Map; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; @@ -30,15 +32,21 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; public class AnnotationResolver { private final BindingTrace trace; -// private final JetTypeInferrer typeInferrer; + private final JetSemanticServices semanticServices; private final CallResolver callResolver; -// private final JetTypeInferrer.Services services; public AnnotationResolver(JetSemanticServices semanticServices, BindingTrace trace) { this.trace = trace; -// this.typeInferrer = new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices); -// this.services = typeInferrer.getServices(this.trace); this.callResolver = new CallResolver(semanticServices, DataFlowInfo.EMPTY); + this.semanticServices = semanticServices; + } + + @NotNull + public List resolveAnnotations(@NotNull JetScope scope, @Nullable JetModifierList modifierList) { + if (modifierList == null) { + return Collections.emptyList(); + } + return resolveAnnotations(scope, modifierList.getAnnotationEntries()); } @NotNull @@ -53,57 +61,95 @@ public class AnnotationResolver { return result; } - public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, @NotNull AnnotationDescriptor descriptor) { + public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, + @NotNull AnnotationDescriptor descriptor) { + OverloadResolutionResults results = resolveType(scope, entryElement, descriptor); + resolveArguments(results, descriptor); + } + + @NotNull + private OverloadResolutionResults resolveType(@NotNull JetScope scope, + @NotNull JetAnnotationEntry entryElement, + @NotNull AnnotationDescriptor descriptor) { OverloadResolutionResults results = callResolver.resolveCall(trace, scope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement), NO_EXPECTED_TYPE); + JetType annotationType = results.getResultingDescriptor().getReturnType(); if (results.isSuccess()) { - descriptor.setAnnotationType(results.getResultingDescriptor().getReturnType()); - } - else { + descriptor.setAnnotationType(annotationType); + } else { descriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type")); } + return results; } - @NotNull - public List resolveAnnotations(@NotNull JetScope scope, @Nullable JetModifierList modifierList) { - if (modifierList == null) { - return Collections.emptyList(); + private void resolveArguments(@NotNull OverloadResolutionResults results, + @NotNull AnnotationDescriptor descriptor) { + List> arguments = Lists.newArrayList(); + for (Map.Entry descriptorToArgument : + results.getResultingCall().getValueArguments().entrySet()) { + // TODO: are varargs supported here? + List argumentExpressions = descriptorToArgument.getValue().getArgumentExpressions(); + ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); + for (JetExpression argument : argumentExpressions) { + arguments.add(resolveAnnotationArgument(argument, parameterDescriptor.getOutType())); + } } - return resolveAnnotations(scope, modifierList.getAnnotationEntries()); + descriptor.setValueArguments(arguments); } - public CompileTimeConstant resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull JetType expectedType) { - final CompileTimeConstant[] result = new CompileTimeConstant[1]; -// expression.accept(new JetVisitorVoid() { -// @Override -// public void visitConstantExpression(JetConstantExpression expression) { -// JetType type = typeInferrer.getType(JetScope.EMPTY, expression, false, expectedType); -// if (type != null) { -// Object value = expression.getValue(); -// -// } -// } -// -// @Override -// public void visitAnnotation(JetAnnotation annotation) { -// super.visitAnnotation(annotation); // TODO -// } -// -// @Override -// public void visitAnnotationEntry(JetAnnotationEntry annotationEntry) { -// super.visitAnnotationEntry(annotationEntry); // TODO -// } -// -// @Override -// public void visitParenthesizedExpression(JetParenthesizedExpression expression) { -// expression.getExpression().accept(this); + @Nullable + public CompileTimeConstant resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType) { + JetVisitor, Void> visitor = new JetVisitor, Void>() { + @Override + public CompileTimeConstant visitConstantExpression(JetConstantExpression expression, Void nothing) { + ExpressionTypingServices typeInferrerServices = semanticServices.getTypeInferrerServices(trace); + JetType type = typeInferrerServices.getType(JetScope.EMPTY, expression, expectedType, DataFlowInfo.EMPTY); + if (type == null) { + // TODO: + // trace.report(ANNOTATION_PARAMETER_SHOULD_BE_CONSTANT.on(expression)); + } + return trace.get(BindingContext.COMPILE_TIME_VALUE, expression); + } + + + // @Override +// public CompileTimeConstant visitAnnotation(JetAnnotation annotation, Void nothing) { +// super.visitAnnotation(annotation, null); // TODO // } // // @Override -// public void visitJetElement(JetElement element) { -// trace.getErrorHandler().genericError(element.getNode(), "Not allowed as an annotation argument"); +// public CompileTimeConstant visitAnnotationEntry(JetAnnotationEntry annotationEntry, Void nothing) { +// return super.visitAnnotationEntry(annotationEntry, null); // TODO // } -// }); - return result[0]; + + @Override + public CompileTimeConstant visitParenthesizedExpression(JetParenthesizedExpression expression, Void nothing) { + JetExpression innerExpression = expression.getExpression(); + if (innerExpression == null) return null; + return innerExpression.accept(this, null); + } + + @Override + public CompileTimeConstant visitStringTemplateExpression(JetStringTemplateExpression expression, + Void nothing) { + return trace.get(BindingContext.COMPILE_TIME_VALUE, expression); + } + + @Override + public CompileTimeConstant visitJetElement(JetElement element, Void nothing) { + // TODO: + //trace.report(ANNOTATION_PARAMETER_SHOULD_BE_CONSTANT.on(element)); + return null; + } + }; + return expression.accept(visitor, null); + } + + @NotNull + public List createAnnotationStubs(@Nullable JetModifierList modifierList) { + if (modifierList == null) { + return Collections.emptyList(); + } + return createAnnotationStubs(modifierList.getAnnotationEntries()); } @NotNull @@ -116,12 +162,4 @@ public class AnnotationResolver { } return result; } - - @NotNull - public List createAnnotationStubs(@Nullable JetModifierList modifierList) { - if (modifierList == null) { - return Collections.emptyList(); - } - return createAnnotationStubs(modifierList.getAnnotationEntries()); - } } -- GitLab