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.DataFlowInfoFactory;
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.storage.StorageManager;
037 import org.jetbrains.kotlin.types.ErrorUtils;
038 import org.jetbrains.kotlin.types.KotlinType;
039
040 import javax.inject.Inject;
041 import java.util.ArrayList;
042 import java.util.List;
043
044 import static org.jetbrains.kotlin.diagnostics.Errors.NOT_AN_ANNOTATION_CLASS;
045 import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
046
047 public class AnnotationResolver {
048 @NotNull private final CallResolver callResolver;
049 @NotNull private final StorageManager storageManager;
050 @NotNull private TypeResolver typeResolver;
051 @NotNull private final ConstantExpressionEvaluator constantExpressionEvaluator;
052
053 public AnnotationResolver(
054 @NotNull CallResolver callResolver,
055 @NotNull ConstantExpressionEvaluator constantExpressionEvaluator,
056 @NotNull StorageManager storageManager
057 ) {
058 this.callResolver = callResolver;
059 this.constantExpressionEvaluator = constantExpressionEvaluator;
060 this.storageManager = storageManager;
061 }
062
063
064 // component dependency cycle
065 @Inject
066 public void setTypeResolver(@NotNull TypeResolver typeResolver) {
067 this.typeResolver = typeResolver;
068 }
069
070 @NotNull
071 public Annotations resolveAnnotationsWithoutArguments(
072 @NotNull LexicalScope scope,
073 @Nullable KtModifierList modifierList,
074 @NotNull BindingTrace trace
075 ) {
076 return resolveAnnotations(scope, modifierList, trace, false);
077 }
078
079 @NotNull
080 public Annotations resolveAnnotationsWithArguments(
081 @NotNull LexicalScope scope,
082 @Nullable KtModifierList modifierList,
083 @NotNull BindingTrace trace
084 ) {
085 return resolveAnnotations(scope, modifierList, trace, true);
086 }
087
088 @NotNull
089 public Annotations resolveAnnotationsWithoutArguments(
090 @NotNull LexicalScope scope,
091 @NotNull List<KtAnnotationEntry> annotationEntries,
092 @NotNull BindingTrace trace
093 ) {
094 return resolveAnnotationEntries(scope, annotationEntries, trace, false);
095 }
096
097 @NotNull
098 public Annotations resolveAnnotationsWithArguments(
099 @NotNull LexicalScope scope,
100 @NotNull List<KtAnnotationEntry> annotationEntries,
101 @NotNull BindingTrace trace
102 ) {
103 return resolveAnnotationEntries(scope, annotationEntries, trace, true);
104 }
105
106 private Annotations resolveAnnotations(
107 @NotNull LexicalScope scope,
108 @Nullable KtModifierList modifierList,
109 @NotNull BindingTrace trace,
110 boolean shouldResolveArguments
111 ) {
112 if (modifierList == null) {
113 return Annotations.Companion.getEMPTY();
114 }
115
116 return resolveAnnotationEntries(scope, modifierList.getAnnotationEntries(), trace, shouldResolveArguments);
117 }
118
119 private Annotations resolveAnnotationEntries(
120 @NotNull LexicalScope scope,
121 @NotNull List<KtAnnotationEntry> annotationEntryElements,
122 @NotNull BindingTrace trace,
123 boolean shouldResolveArguments
124 ) {
125 if (annotationEntryElements.isEmpty()) return Annotations.Companion.getEMPTY();
126 List<AnnotationWithTarget> result = new ArrayList<AnnotationWithTarget>(0);
127
128 for (KtAnnotationEntry entryElement : annotationEntryElements) {
129 AnnotationDescriptor descriptor = trace.get(BindingContext.ANNOTATION, entryElement);
130 if (descriptor == null) {
131 descriptor = new LazyAnnotationDescriptor(new LazyAnnotationsContextImpl(this, storageManager, trace, scope), entryElement);
132 }
133 if (shouldResolveArguments) {
134 ForceResolveUtil.forceResolveAllContents(descriptor);
135 }
136
137 KtAnnotationUseSiteTarget target = entryElement.getUseSiteTarget();
138 if (target != null) {
139 result.add(new AnnotationWithTarget(descriptor, target.getAnnotationUseSiteTarget()));
140 }
141 else {
142 result.add(new AnnotationWithTarget(descriptor, null));
143 }
144 }
145 return AnnotationsImpl.create(result);
146 }
147
148 @NotNull
149 public KotlinType resolveAnnotationType(@NotNull LexicalScope scope, @NotNull KtAnnotationEntry entryElement, @NotNull BindingTrace trace) {
150 KtTypeReference typeReference = entryElement.getTypeReference();
151 if (typeReference == null) {
152 return ErrorUtils.createErrorType("No type reference: " + entryElement.getText());
153 }
154
155 KotlinType type = typeResolver.resolveType(scope, typeReference, trace, true);
156 if (!(type.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
157 return ErrorUtils.createErrorType("Not an annotation: " + type);
158 }
159 return type;
160 }
161
162 public static void checkAnnotationType(
163 @NotNull KtAnnotationEntry entryElement,
164 @NotNull BindingTrace trace,
165 @NotNull OverloadResolutionResults<FunctionDescriptor> results
166 ) {
167 if (!results.isSingleResult()) return;
168 FunctionDescriptor descriptor = results.getResultingDescriptor();
169 if (!ErrorUtils.isError(descriptor)) {
170 if (descriptor instanceof ConstructorDescriptor) {
171 ConstructorDescriptor constructor = (ConstructorDescriptor)descriptor;
172 ClassDescriptor classDescriptor = constructor.getContainingDeclaration();
173 if (classDescriptor.getKind() != ClassKind.ANNOTATION_CLASS) {
174 trace.report(NOT_AN_ANNOTATION_CLASS.on(entryElement, classDescriptor));
175 }
176 }
177 else {
178 trace.report(NOT_AN_ANNOTATION_CLASS.on(entryElement, descriptor));
179 }
180 }
181 }
182
183 @NotNull
184 public OverloadResolutionResults<FunctionDescriptor> resolveAnnotationCall(
185 KtAnnotationEntry annotationEntry,
186 LexicalScope scope,
187 BindingTrace trace
188 ) {
189 return callResolver.resolveFunctionCall(
190 trace, scope,
191 CallMaker.makeCall(null, null, annotationEntry),
192 NO_EXPECTED_TYPE,
193 DataFlowInfoFactory.EMPTY,
194 true
195 );
196 }
197
198 public static void reportUnsupportedAnnotationForTypeParameter(@NotNull KtTypeParameter jetTypeParameter, @NotNull BindingTrace trace) {
199 KtModifierList modifierList = jetTypeParameter.getModifierList();
200 if (modifierList == null) return;
201
202 for (KtAnnotationEntry annotationEntry : modifierList.getAnnotationEntries()) {
203 trace.report(Errors.UNSUPPORTED.on(annotationEntry, "Annotations for type parameters are not supported yet"));
204 }
205 }
206
207 @Nullable
208 public ConstantValue<?> getAnnotationArgumentValue(
209 @NotNull BindingTrace trace,
210 @NotNull ValueParameterDescriptor valueParameter,
211 @NotNull ResolvedValueArgument resolvedArgument
212 ) {
213 return constantExpressionEvaluator.getAnnotationArgumentValue(trace, valueParameter, resolvedArgument);
214 }
215 }