001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.resolve;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.kotlin.descriptors.*;
022 import org.jetbrains.kotlin.descriptors.annotations.*;
023 import org.jetbrains.kotlin.diagnostics.Errors;
024 import org.jetbrains.kotlin.psi.*;
025 import org.jetbrains.kotlin.resolve.calls.CallResolver;
026 import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
027 import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
028 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
029 import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
030 import org.jetbrains.kotlin.resolve.constants.ConstantValue;
031 import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
032 import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
033 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor;
034 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl;
035 import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
036 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
037 import org.jetbrains.kotlin.storage.StorageManager;
038 import org.jetbrains.kotlin.types.ErrorUtils;
039 import org.jetbrains.kotlin.types.KotlinType;
040
041 import javax.inject.Inject;
042 import java.util.ArrayList;
043 import java.util.List;
044
045 import static org.jetbrains.kotlin.diagnostics.Errors.NOT_AN_ANNOTATION_CLASS;
046 import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
047
048 public class AnnotationResolver {
049 @NotNull private final CallResolver callResolver;
050 @NotNull private final StorageManager storageManager;
051 @NotNull private TypeResolver typeResolver;
052 @NotNull private final ConstantExpressionEvaluator constantExpressionEvaluator;
053
054 public AnnotationResolver(
055 @NotNull CallResolver callResolver,
056 @NotNull ConstantExpressionEvaluator constantExpressionEvaluator,
057 @NotNull StorageManager storageManager
058 ) {
059 this.callResolver = callResolver;
060 this.constantExpressionEvaluator = constantExpressionEvaluator;
061 this.storageManager = storageManager;
062 }
063
064
065 // component dependency cycle
066 @Inject
067 public void setTypeResolver(@NotNull TypeResolver typeResolver) {
068 this.typeResolver = typeResolver;
069 }
070
071 @NotNull
072 public Annotations resolveAnnotationsWithoutArguments(
073 @NotNull LexicalScope scope,
074 @Nullable KtModifierList modifierList,
075 @NotNull BindingTrace trace
076 ) {
077 return resolveAnnotations(scope, modifierList, trace, false);
078 }
079
080 @NotNull
081 public Annotations resolveAnnotationsWithArguments(
082 @NotNull LexicalScope scope,
083 @Nullable KtModifierList modifierList,
084 @NotNull BindingTrace trace
085 ) {
086 return resolveAnnotations(scope, modifierList, trace, true);
087 }
088
089 @NotNull
090 public Annotations resolveAnnotationsWithoutArguments(
091 @NotNull LexicalScope scope,
092 @NotNull List<KtAnnotationEntry> annotationEntries,
093 @NotNull BindingTrace trace
094 ) {
095 return resolveAnnotationEntries(scope, annotationEntries, trace, false);
096 }
097
098 @NotNull
099 public Annotations resolveAnnotationsWithArguments(
100 @NotNull LexicalScope scope,
101 @NotNull List<KtAnnotationEntry> annotationEntries,
102 @NotNull BindingTrace trace
103 ) {
104 return resolveAnnotationEntries(scope, annotationEntries, trace, true);
105 }
106
107 private Annotations resolveAnnotations(
108 @NotNull LexicalScope scope,
109 @Nullable KtModifierList modifierList,
110 @NotNull BindingTrace trace,
111 boolean shouldResolveArguments
112 ) {
113 if (modifierList == null) {
114 return Annotations.Companion.getEMPTY();
115 }
116
117 return resolveAnnotationEntries(scope, modifierList.getAnnotationEntries(), trace, shouldResolveArguments);
118 }
119
120 private Annotations resolveAnnotationEntries(
121 @NotNull LexicalScope scope,
122 @NotNull List<KtAnnotationEntry> annotationEntryElements,
123 @NotNull BindingTrace trace,
124 boolean shouldResolveArguments
125 ) {
126 if (annotationEntryElements.isEmpty()) return Annotations.Companion.getEMPTY();
127 List<AnnotationWithTarget> result = new ArrayList<AnnotationWithTarget>(0);
128
129 for (KtAnnotationEntry entryElement : annotationEntryElements) {
130 AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement);
131 if (descriptor == null) {
132 descriptor = new LazyAnnotationDescriptor(new LazyAnnotationsContextImpl(this, storageManager, trace, scope), entryElement);
133 }
134 if (shouldResolveArguments) {
135 ForceResolveUtil.forceResolveAllContents(descriptor);
136 }
137
138 KtAnnotationUseSiteTarget target = entryElement.getUseSiteTarget();
139 if (target != null) {
140 result.add(new AnnotationWithTarget(descriptor, target.getAnnotationUseSiteTarget()));
141 }
142 else {
143 result.add(new AnnotationWithTarget(descriptor, null));
144 }
145 }
146 return AnnotationsImpl.create(result);
147 }
148
149 @NotNull
150 public KotlinType resolveAnnotationType(@NotNull LexicalScope scope, @NotNull KtAnnotationEntry entryElement, @NotNull BindingTrace trace) {
151 KtTypeReference typeReference = entryElement.getTypeReference();
152 if (typeReference == null) {
153 return ErrorUtils.createErrorType("No type reference: " + entryElement.getText());
154 }
155
156 KotlinType type = typeResolver.resolveType(scope, typeReference, trace, true);
157 if (!(type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
158 return ErrorUtils.createErrorType("Not an annotation: " + type);
159 }
160 return type;
161 }
162
163 public static void checkAnnotationType(
164 @NotNull KtAnnotationEntry entryElement,
165 @NotNull BindingTrace trace,
166 @NotNull OverloadResolutionResults<FunctionDescriptor> results
167 ) {
168 if (!results.isSingleResult()) return;
169 FunctionDescriptor descriptor = results.getResultingDescriptor();
170 if (!ErrorUtils.isError(descriptor)) {
171 if (descriptor instanceof ConstructorDescriptor) {
172 ConstructorDescriptor constructor = (ConstructorDescriptor)descriptor;
173 ClassDescriptor classDescriptor = constructor.getContainingDeclaration();
174 if (classDescriptor.getKind() != ClassKind.ANNOTATION_CLASS) {
175 trace.report(NOT_AN_ANNOTATION_CLASS.on(entryElement, classDescriptor));
176 }
177 }
178 else {
179 trace.report(NOT_AN_ANNOTATION_CLASS.on(entryElement, descriptor));
180 }
181 }
182 }
183
184 @NotNull
185 public OverloadResolutionResults<FunctionDescriptor> resolveAnnotationCall(
186 KtAnnotationEntry annotationEntry,
187 LexicalScope scope,
188 BindingTrace trace
189 ) {
190 return callResolver.resolveFunctionCall(
191 trace, scope,
192 CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, annotationEntry),
193 NO_EXPECTED_TYPE,
194 DataFlowInfo.EMPTY,
195 true
196 );
197 }
198
199 public static void reportUnsupportedAnnotationForTypeParameter(@NotNull KtTypeParameter jetTypeParameter, @NotNull BindingTrace trace) {
200 KtModifierList modifierList = jetTypeParameter.getModifierList();
201 if (modifierList == null) return;
202
203 for (KtAnnotationEntry annotationEntry : modifierList.getAnnotationEntries()) {
204 trace.report(Errors.UNSUPPORTED.on(annotationEntry, "Annotations for type parameters are not supported yet"));
205 }
206 }
207
208 @Nullable
209 public ConstantValue<?> getAnnotationArgumentValue(
210 @NotNull BindingTrace trace,
211 @NotNull ValueParameterDescriptor valueParameter,
212 @NotNull ResolvedValueArgument resolvedArgument
213 ) {
214 return constantExpressionEvaluator.getAnnotationArgumentValue(trace, valueParameter, resolvedArgument);
215 }
216 }