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.builtins.KotlinBuiltIns;
022 import org.jetbrains.kotlin.descriptors.*;
023 import org.jetbrains.kotlin.descriptors.annotations.*;
024 import org.jetbrains.kotlin.diagnostics.Errors;
025 import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
026 import org.jetbrains.kotlin.lexer.JetTokens;
027 import org.jetbrains.kotlin.psi.*;
028 import org.jetbrains.kotlin.resolve.annotations.*;
029 import org.jetbrains.kotlin.resolve.annotations.AnnotationsPackage;
030 import org.jetbrains.kotlin.resolve.calls.CallResolver;
031 import org.jetbrains.kotlin.resolve.calls.model.ResolvedValueArgument;
032 import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
033 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
034 import org.jetbrains.kotlin.resolve.calls.util.CallMaker;
035 import org.jetbrains.kotlin.resolve.constants.ConstantValue;
036 import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
037 import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil;
038 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationDescriptor;
039 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyAnnotationsContextImpl;
040 import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
041 import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
042 import org.jetbrains.kotlin.storage.StorageManager;
043 import org.jetbrains.kotlin.types.ErrorUtils;
044 import org.jetbrains.kotlin.types.JetType;
045
046 import javax.inject.Inject;
047 import java.util.ArrayList;
048 import java.util.List;
049
050 import static org.jetbrains.kotlin.diagnostics.Errors.NOT_AN_ANNOTATION_CLASS;
051 import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
052
053 public class AnnotationResolver {
054 @NotNull private final CallResolver callResolver;
055 @NotNull private final StorageManager storageManager;
056 @NotNull private TypeResolver typeResolver;
057 @NotNull private final ConstantExpressionEvaluator constantExpressionEvaluator;
058
059 @NotNull private final List<AnnotationDescriptor> modifiersAnnotations;
060
061 public AnnotationResolver(
062 @NotNull CallResolver callResolver,
063 @NotNull ConstantExpressionEvaluator constantExpressionEvaluator,
064 @NotNull StorageManager storageManager,
065 @NotNull KotlinBuiltIns kotlinBuiltIns
066 ) {
067 this.callResolver = callResolver;
068 this.constantExpressionEvaluator = constantExpressionEvaluator;
069 this.storageManager = storageManager;
070
071 modifiersAnnotations = AnnotationsPackage.buildMigrationAnnotationDescriptors(kotlinBuiltIns);
072 }
073
074
075 // component dependency cycle
076 @Inject
077 public void setTypeResolver(@NotNull TypeResolver typeResolver) {
078 this.typeResolver = typeResolver;
079 }
080
081 @NotNull
082 public Annotations resolveAnnotationsWithoutArguments(
083 @NotNull LexicalScope scope,
084 @Nullable JetModifierList modifierList,
085 @NotNull BindingTrace trace
086 ) {
087 return resolveAnnotations(scope, modifierList, trace, false);
088 }
089
090 @NotNull
091 public Annotations resolveAnnotationsWithArguments(
092 @NotNull LexicalScope scope,
093 @Nullable JetModifierList modifierList,
094 @NotNull BindingTrace trace
095 ) {
096 return resolveAnnotations(scope, modifierList, trace, true);
097 }
098
099 @NotNull
100 public Annotations resolveAnnotationsWithoutArguments(
101 @NotNull LexicalScope scope,
102 @NotNull List<JetAnnotationEntry> annotationEntries,
103 @NotNull BindingTrace trace
104 ) {
105 return resolveAnnotationEntries(scope, annotationEntries, trace, false);
106 }
107
108 @NotNull
109 public Annotations resolveAnnotationsWithArguments(
110 @NotNull LexicalScope scope,
111 @NotNull List<JetAnnotationEntry> annotationEntries,
112 @NotNull BindingTrace trace
113 ) {
114 return resolveAnnotationEntries(scope, annotationEntries, trace, true);
115 }
116
117 private Annotations resolveAnnotations(
118 @NotNull LexicalScope scope,
119 @Nullable JetModifierList modifierList,
120 @NotNull BindingTrace trace,
121 boolean shouldResolveArguments
122 ) {
123 if (modifierList == null) {
124 return Annotations.EMPTY;
125 }
126
127 List<JetAnnotationEntry> annotationEntryElements = modifierList.getAnnotationEntries();
128
129 return resolveAndAppendAnnotationsFromModifiers(
130 resolveAnnotationEntries(scope, annotationEntryElements, trace, shouldResolveArguments),
131 modifierList
132 );
133 }
134
135 @NotNull
136 public Annotations resolveAndAppendAnnotationsFromModifiers(
137 @NotNull Annotations annotations,
138 @NotNull JetModifierList modifierList
139 ) {
140 List<AnnotationDescriptor> annotationFromModifiers = new ArrayList<AnnotationDescriptor>();
141
142 for (int i = 0; i < JetTokens.ANNOTATION_MODIFIERS_KEYWORDS_ARRAY.length; i++) {
143 JetModifierKeywordToken modifier = JetTokens.ANNOTATION_MODIFIERS_KEYWORDS_ARRAY[i];
144 if (modifierList.hasModifier(modifier)) {
145 annotationFromModifiers.add(modifiersAnnotations.get(i));
146 }
147 }
148
149 if (annotationFromModifiers.isEmpty()) return annotations;
150
151 return new CompositeAnnotations(annotations, new AnnotationsImpl(annotationFromModifiers));
152 }
153
154 private Annotations resolveAnnotationEntries(
155 @NotNull LexicalScope scope,
156 @NotNull List<JetAnnotationEntry> annotationEntryElements,
157 @NotNull BindingTrace trace,
158 boolean shouldResolveArguments
159 ) {
160 if (annotationEntryElements.isEmpty()) return Annotations.EMPTY;
161 List<AnnotationWithTarget> result = new ArrayList<AnnotationWithTarget>(0);
162
163 for (JetAnnotationEntry entryElement : annotationEntryElements) {
164 AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement);
165 if (descriptor == null) {
166 descriptor = new LazyAnnotationDescriptor(new LazyAnnotationsContextImpl(this, storageManager, trace, scope), entryElement);
167 }
168 if (shouldResolveArguments) {
169 ForceResolveUtil.forceResolveAllContents(descriptor);
170 }
171
172 JetAnnotationUseSiteTarget target = entryElement.getUseSiteTarget();
173 if (target != null) {
174 result.add(new AnnotationWithTarget(descriptor, target.getAnnotationUseSiteTarget()));
175 }
176 else {
177 result.add(new AnnotationWithTarget(descriptor, null));
178 }
179 }
180 return AnnotationsImpl.create(result);
181 }
182
183 @NotNull
184 public JetType resolveAnnotationType(@NotNull LexicalScope scope, @NotNull JetAnnotationEntry entryElement) {
185 JetTypeReference typeReference = entryElement.getTypeReference();
186 if (typeReference == null) {
187 return ErrorUtils.createErrorType("No type reference: " + entryElement.getText());
188 }
189
190 JetType type = typeResolver.resolveType(scope, typeReference, new BindingTraceContext(), true);
191 if (!(type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
192 return ErrorUtils.createErrorType("Not an annotation: " + type);
193 }
194 return type;
195 }
196
197 public static void checkAnnotationType(
198 @NotNull JetAnnotationEntry entryElement,
199 @NotNull BindingTrace trace,
200 @NotNull OverloadResolutionResults<FunctionDescriptor> results
201 ) {
202 if (!results.isSingleResult()) return;
203 FunctionDescriptor descriptor = results.getResultingDescriptor();
204 if (!ErrorUtils.isError(descriptor)) {
205 if (descriptor instanceof ConstructorDescriptor) {
206 ConstructorDescriptor constructor = (ConstructorDescriptor)descriptor;
207 ClassDescriptor classDescriptor = constructor.getContainingDeclaration();
208 if (classDescriptor.getKind() != ClassKind.ANNOTATION_CLASS) {
209 trace.report(NOT_AN_ANNOTATION_CLASS.on(entryElement, classDescriptor));
210 }
211 }
212 else {
213 trace.report(NOT_AN_ANNOTATION_CLASS.on(entryElement, descriptor));
214 }
215 }
216 }
217
218 @NotNull
219 public OverloadResolutionResults<FunctionDescriptor> resolveAnnotationCall(
220 JetAnnotationEntry annotationEntry,
221 LexicalScope scope,
222 BindingTrace trace
223 ) {
224 return callResolver.resolveFunctionCall(
225 trace, scope,
226 CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, annotationEntry),
227 NO_EXPECTED_TYPE,
228 DataFlowInfo.EMPTY,
229 true
230 );
231 }
232
233 public static void reportUnsupportedAnnotationForTypeParameter(@NotNull JetTypeParameter jetTypeParameter, @NotNull BindingTrace trace) {
234 JetModifierList modifierList = jetTypeParameter.getModifierList();
235 if (modifierList == null) return;
236
237 for (JetAnnotationEntry annotationEntry : modifierList.getAnnotationEntries()) {
238 trace.report(Errors.UNSUPPORTED.on(annotationEntry, "Annotations for type parameters are not supported yet"));
239 }
240 }
241
242 @Nullable
243 public ConstantValue<?> getAnnotationArgumentValue(
244 @NotNull BindingTrace trace,
245 @NotNull ValueParameterDescriptor valueParameter,
246 @NotNull ResolvedValueArgument resolvedArgument
247 ) {
248 return constantExpressionEvaluator.getAnnotationArgumentValue(trace, valueParameter, resolvedArgument);
249 }
250 }