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 }