Resolve annotations arguments in body resolver

This commit is contained in:
Natalia.Ukhorskaya
2013-07-04 12:26:04 +04:00
parent 33ddd713b7
commit a5662fe906
15 changed files with 537 additions and 63 deletions
@@ -181,6 +181,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setAnnotationResolver(annotationResolver);
this.bodyResolver.setCallResolver(callResolver);
this.bodyResolver.setContext(topDownAnalysisContext);
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
@@ -23,12 +23,12 @@ import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.BodiesResolveContext;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver;
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
import org.jetbrains.jet.lang.resolve.calls.CandidateResolver;
@@ -49,12 +49,12 @@ public class InjectorForBodyResolve {
private final BindingTrace bindingTrace;
private final BodiesResolveContext bodiesResolveContext;
private final ModuleDescriptor moduleDescriptor;
private AnnotationResolver annotationResolver;
private CallResolver callResolver;
private ArgumentTypeResolver argumentTypeResolver;
private ExpressionTypingServices expressionTypingServices;
private CallExpressionResolver callExpressionResolver;
private DescriptorResolver descriptorResolver;
private AnnotationResolver annotationResolver;
private TypeResolver typeResolver;
private QualifiedExpressionResolver qualifiedExpressionResolver;
private CandidateResolver candidateResolver;
@@ -77,12 +77,12 @@ public class InjectorForBodyResolve {
this.bindingTrace = bindingTrace;
this.bodiesResolveContext = bodiesResolveContext;
this.moduleDescriptor = moduleDescriptor;
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
this.argumentTypeResolver = new ArgumentTypeResolver();
this.expressionTypingServices = new ExpressionTypingServices();
this.callExpressionResolver = new CallExpressionResolver();
this.descriptorResolver = new DescriptorResolver();
this.annotationResolver = new AnnotationResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
this.candidateResolver = new CandidateResolver();
@@ -91,6 +91,7 @@ public class InjectorForBodyResolve {
this.scriptBodyResolver = new ScriptBodyResolver();
this.topDownAnalysisContext = new TopDownAnalysisContext();
this.bodyResolver.setAnnotationResolver(annotationResolver);
this.bodyResolver.setCallResolver(callResolver);
this.bodyResolver.setContext(bodiesResolveContext);
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
@@ -101,6 +102,9 @@ public class InjectorForBodyResolve {
this.bodyResolver.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setTrace(bindingTrace);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setExpressionTypingServices(expressionTypingServices);
callResolver.setArgumentTypeResolver(argumentTypeResolver);
callResolver.setCandidateResolver(candidateResolver);
callResolver.setExpressionTypingServices(expressionTypingServices);
@@ -122,9 +126,6 @@ public class InjectorForBodyResolve {
descriptorResolver.setExpressionTypingServices(expressionTypingServices);
descriptorResolver.setTypeResolver(typeResolver);
annotationResolver.setCallResolver(callResolver);
annotationResolver.setExpressionTypingServices(expressionTypingServices);
typeResolver.setAnnotationResolver(annotationResolver);
typeResolver.setDescriptorResolver(descriptorResolver);
typeResolver.setModuleDescriptor(moduleDescriptor);
@@ -130,6 +130,7 @@ public class InjectorForTopDownAnalyzerBasic {
this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setAnnotationResolver(annotationResolver);
this.bodyResolver.setCallResolver(callResolver);
this.bodyResolver.setContext(topDownAnalysisContext);
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);
@@ -20,6 +20,7 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.Annotated;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
@@ -40,6 +41,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import static org.jetbrains.jet.lang.resolve.BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT;
import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
public class AnnotationResolver {
@@ -58,34 +60,56 @@ public class AnnotationResolver {
}
@NotNull
public List<AnnotationDescriptor> resolveAnnotations(@NotNull JetScope scope, @Nullable JetModifierList modifierList, BindingTrace trace) {
if (modifierList == null) {
return Collections.emptyList();
}
return resolveAnnotations(scope, modifierList.getAnnotationEntries(), trace);
public List<AnnotationDescriptor> resolveAnnotations(
@NotNull JetScope scope,
@Nullable JetModifierList modifierList,
@NotNull BindingTrace trace)
{
return resolveAnnotations(scope, modifierList, trace, false);
}
@NotNull
public List<AnnotationDescriptor> resolveAnnotations(@NotNull JetScope scope, @NotNull List<JetAnnotationEntry> annotationEntryElements, BindingTrace trace) {
public List<AnnotationDescriptor> resolveAnnotationsWithArguments(
@NotNull JetScope scope,
@Nullable JetModifierList modifierList,
@NotNull BindingTrace trace
) {
return resolveAnnotations(scope, modifierList, trace, true);
}
private List<AnnotationDescriptor> resolveAnnotations(
@NotNull JetScope scope,
@Nullable JetModifierList modifierList,
@NotNull BindingTrace trace,
boolean shouldResolveArguments
) {
if (modifierList == null) {
return Collections.emptyList();
}
List<JetAnnotationEntry> annotationEntryElements = modifierList.getAnnotationEntries();
if (annotationEntryElements.isEmpty()) return Collections.emptyList();
List<AnnotationDescriptor> result = Lists.newArrayList();
for (JetAnnotationEntry entryElement : annotationEntryElements) {
AnnotationDescriptor descriptor = new AnnotationDescriptor();
resolveAnnotationStub(scope, entryElement, descriptor, trace);
trace.record(BindingContext.ANNOTATION, entryElement, descriptor);
if (shouldResolveArguments) {
resolveAnnotationArguments(entryElement, scope, trace);
}
result.add(descriptor);
}
return result;
}
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement,
@NotNull AnnotationDescriptor annotationDescriptor, BindingTrace trace) {
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
trace,
scope,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, entryElement),
NO_EXPECTED_TYPE,
DataFlowInfo.EMPTY);
public void resolveAnnotationStub(
@NotNull JetScope scope,
@NotNull JetAnnotationEntry entryElement,
@NotNull AnnotationDescriptor annotationDescriptor,
@NotNull BindingTrace trace
) {
TemporaryBindingTrace temporaryBindingTrace = new TemporaryBindingTrace(trace, "Trace for resolve annotation type");
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(entryElement, scope, temporaryBindingTrace);
if (results.isSuccess()) {
FunctionDescriptor descriptor = results.getResultingDescriptor();
if (!ErrorUtils.isError(descriptor)) {
@@ -102,27 +126,64 @@ public class AnnotationResolver {
}
JetType annotationType = results.getResultingDescriptor().getReturnType();
annotationDescriptor.setAnnotationType(annotationType);
resolveArguments(results, annotationDescriptor, trace);
}
else {
annotationDescriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type"));
}
}
private void resolveArguments(@NotNull OverloadResolutionResults<FunctionDescriptor> results,
@NotNull AnnotationDescriptor descriptor, BindingTrace trace) {
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument :
results.getResultingCall().getValueArguments().entrySet()) {
// TODO: are varargs supported here?
List<ValueArgument> valueArguments = descriptorToArgument.getValue().getArguments();
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
for (ValueArgument argument : valueArguments) {
JetExpression argumentExpression = argument.getArgumentExpression();
if (argumentExpression != null) {
CompileTimeConstant<?> compileTimeConstant =
resolveAnnotationArgument(argumentExpression, parameterDescriptor.getType(), trace);
if (compileTimeConstant != null) {
descriptor.setValueArgument(parameterDescriptor, compileTimeConstant);
private OverloadResolutionResults<FunctionDescriptor> resolveAnnotationCall(
JetAnnotationEntry annotationEntry,
JetScope scope,
BindingTrace trace
) {
return callResolver.resolveFunctionCall(
trace, scope,
CallMaker.makeCall(ReceiverValue.NO_RECEIVER, null, annotationEntry),
NO_EXPECTED_TYPE,
DataFlowInfo.EMPTY);
}
public void resolveAnnotationsArguments(@NotNull JetScope scope, @Nullable JetModifierList modifierList, @NotNull BindingTrace trace) {
if (modifierList == null) {
return;
}
for (JetAnnotationEntry annotationEntry : modifierList.getAnnotationEntries()) {
resolveAnnotationArguments(annotationEntry, scope, trace);
}
}
public void resolveAnnotationsArguments(@NotNull Annotated descriptor, @NotNull BindingTrace trace, @NotNull JetScope scope) {
for (AnnotationDescriptor annotationDescriptor : descriptor.getAnnotations()) {
JetAnnotationEntry annotationEntry = trace.getBindingContext().get(ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT, annotationDescriptor);
assert annotationEntry != null : "Cannot find annotation entry: " + annotationDescriptor;
resolveAnnotationArguments(annotationEntry, scope, trace);
}
}
private void resolveAnnotationArguments(
@NotNull JetAnnotationEntry annotationEntry,
@NotNull JetScope scope,
@NotNull BindingTrace trace
) {
OverloadResolutionResults<FunctionDescriptor> results = resolveAnnotationCall(annotationEntry, scope, trace);
if (results.isSuccess()) {
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> descriptorToArgument :
results.getResultingCall().getValueArguments().entrySet()) {
// TODO: are varargs supported here?
List<ValueArgument> valueArguments = descriptorToArgument.getValue().getArguments();
ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey();
for (ValueArgument argument : valueArguments) {
JetExpression argumentExpression = argument.getArgumentExpression();
if (argumentExpression != null) {
CompileTimeConstant<?> compileTimeConstant =
resolveAnnotationArgument(argumentExpression, parameterDescriptor.getType(), trace);
if (compileTimeConstant != null) {
AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry);
assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText();
annotationDescriptor.setValueArgument(parameterDescriptor, compileTimeConstant);
}
}
}
}
@@ -130,7 +191,7 @@ public class AnnotationResolver {
}
@Nullable
public CompileTimeConstant<?> resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType, final BindingTrace trace) {
private CompileTimeConstant<?> resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType, final BindingTrace trace) {
JetVisitor<CompileTimeConstant<?>, Void> visitor = new JetVisitor<CompileTimeConstant<?>, Void>() {
@Override
public CompileTimeConstant<?> visitConstantExpression(JetConstantExpression expression, Void nothing) {
@@ -74,6 +74,8 @@ public class BodyResolver {
private ControlFlowAnalyzer controlFlowAnalyzer;
@NotNull
private DeclarationsChecker declarationsChecker;
@NotNull
private AnnotationResolver annotationResolver;
@Inject
public void setTopDownAnalysisParameters(@NotNull TopDownAnalysisParameters topDownAnalysisParameters) {
@@ -120,6 +122,11 @@ public class BodyResolver {
this.context = context;
}
@Inject
public void setAnnotationResolver(@NotNull AnnotationResolver annotationResolver) {
this.annotationResolver = annotationResolver;
}
private void resolveBehaviorDeclarationBodies(@NotNull BodiesResolveContext bodiesResolveContext) {
// Initialize context
context = bodiesResolveContext;
@@ -320,6 +327,12 @@ public class BodyResolver {
}
private void resolveClassAnnotations() {
for (Map.Entry<JetClass, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
resolveAnnotationArguments(entry.getValue().getScopeForSupertypeResolution(), entry.getKey());
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : context.getObjects().entrySet()) {
resolveAnnotationArguments(entry.getValue().getScopeForSupertypeResolution(), entry.getKey());
}
}
private void resolveAnonymousInitializers() {
@@ -367,7 +380,8 @@ public class BodyResolver {
parameterScope.addVariableDescriptor(valueParameterDescriptor);
}
parameterScope.changeLockLevel(WritableScope.LockLevel.READING);
checkDefaultParameterValues(klass.getPrimaryConstructorParameters(), unsubstitutedPrimaryConstructor.getValueParameters(), parameterScope);
resolveValueParameter(klass.getPrimaryConstructorParameters(), unsubstitutedPrimaryConstructor.getValueParameters(),
parameterScope);
}
}
}
@@ -402,6 +416,8 @@ public class BodyResolver {
resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberResolution(), propertyScope);
}
resolveAnnotationArguments(propertyScope, property);
resolvePropertyAccessors(property, propertyDescriptor);
processed.add(property);
}
@@ -429,6 +445,8 @@ public class BodyResolver {
resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, propertyScope, propertyScope);
}
resolveAnnotationArguments(propertyScope, property);
resolvePropertyAccessors(property, propertyDescriptor);
}
}
@@ -446,6 +464,7 @@ public class BodyResolver {
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
if (getter != null && getterDescriptor != null) {
JetScope accessorScope = makeScopeForPropertyAccessor(getter, propertyDescriptor);
resolveAnnotationArguments(accessorScope, getter);
resolveFunctionBody(fieldAccessTrackingTrace, getter, getterDescriptor, accessorScope);
}
@@ -453,6 +472,7 @@ public class BodyResolver {
PropertySetterDescriptor setterDescriptor = propertyDescriptor.getSetter();
if (setter != null && setterDescriptor != null) {
JetScope accessorScope = makeScopeForPropertyAccessor(setter, propertyDescriptor);
resolveAnnotationArguments(accessorScope, setter);
resolveFunctionBody(fieldAccessTrackingTrace, setter, setterDescriptor, accessorScope);
}
}
@@ -621,6 +641,7 @@ public class BodyResolver {
JetScope declaringScope = this.context.getDeclaringScopes().apply(declaration);
assert declaringScope != null;
resolveAnnotationArguments(declaringScope, declaration);
resolveFunctionBody(trace, declaration, descriptor, declaringScope);
assert descriptor.getReturnType() != null;
@@ -643,24 +664,43 @@ public class BodyResolver {
List<JetParameter> valueParameters = function.getValueParameters();
List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
checkDefaultParameterValues(valueParameters, valueParameterDescriptors, functionInnerScope);
resolveValueParameter(valueParameters, valueParameterDescriptors, functionInnerScope);
assert functionDescriptor.getReturnType() != null;
}
private void checkDefaultParameterValues(List<JetParameter> valueParameters, List<ValueParameterDescriptor> valueParameterDescriptors, JetScope declaringScope) {
private void resolveValueParameter(
@NotNull List<JetParameter> valueParameters,
@NotNull List<ValueParameterDescriptor> valueParameterDescriptors,
@NotNull JetScope declaringScope
) {
for (int i = 0; i < valueParameters.size(); i++) {
ValueParameterDescriptor valueParameterDescriptor = valueParameterDescriptors.get(i);
if (valueParameterDescriptor.hasDefaultValue()) {
JetParameter jetParameter = valueParameters.get(i);
JetExpression defaultValue = jetParameter.getDefaultValue();
if (defaultValue != null) {
expressionTypingServices.getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), DataFlowInfo.EMPTY, trace);
}
JetParameter jetParameter = valueParameters.get(i);
resolveAnnotationArguments(declaringScope, jetParameter);
resolveDefaultValue(declaringScope, valueParameterDescriptor, jetParameter);
}
}
private void resolveDefaultValue(
@NotNull JetScope declaringScope,
@NotNull ValueParameterDescriptor valueParameterDescriptor,
@NotNull JetParameter jetParameter
) {
if (valueParameterDescriptor.hasDefaultValue()) {
JetExpression defaultValue = jetParameter.getDefaultValue();
if (defaultValue != null) {
expressionTypingServices.getType(declaringScope, defaultValue, valueParameterDescriptor.getType(), DataFlowInfo.EMPTY, trace);
}
}
}
private void resolveAnnotationArguments(@NotNull JetScope scope, @NotNull JetModifierListOwner owner) {
annotationResolver.resolveAnnotationsArguments(scope, owner.getModifierList(), trace);
}
private static void computeDeferredType(JetType type) {
// handle type inference loop: function or property body contains a reference to itself
// fun f() = { f() }
@@ -125,7 +125,7 @@ public class DeclarationResolver {
private void resolveAnnotationsForClassOrObject(AnnotationResolver annotationResolver, JetClassOrObject jetClass, MutableClassDescriptor descriptor) {
JetModifierList modifierList = jetClass.getModifierList();
if (modifierList != null) {
descriptor.getAnnotations().addAll(annotationResolver.resolveAnnotations(descriptor.getScopeForSupertypeResolution(), modifierList.getAnnotationEntries(), trace));
descriptor.getAnnotations().addAll(annotationResolver.resolveAnnotations(descriptor.getScopeForSupertypeResolution(), modifierList, trace));
}
}
@@ -245,16 +245,39 @@ public class DescriptorResolver {
}
}
@NotNull
public SimpleFunctionDescriptor resolveFunctionDescriptorWithAnnotationArguments(
@NotNull DeclarationDescriptor containingDescriptor,
@NotNull JetScope scope,
@NotNull JetNamedFunction function,
@NotNull BindingTrace trace
) {
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace));
}
@NotNull
public SimpleFunctionDescriptor resolveFunctionDescriptor(
@NotNull DeclarationDescriptor containingDescriptor,
@NotNull JetScope scope,
@NotNull JetNamedFunction function,
@NotNull BindingTrace trace
) {
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace,
annotationResolver.resolveAnnotations(scope, function.getModifierList(), trace));
}
@NotNull
private SimpleFunctionDescriptor resolveFunctionDescriptor(
@NotNull DeclarationDescriptor containingDescriptor,
@NotNull final JetScope scope,
@NotNull final JetNamedFunction function,
@NotNull final BindingTrace trace
@NotNull final BindingTrace trace,
@NotNull List<AnnotationDescriptor> annotations
) {
final SimpleFunctionDescriptorImpl functionDescriptor = new SimpleFunctionDescriptorImpl(
containingDescriptor,
annotationResolver.resolveAnnotations(scope, function.getModifierList(), trace),
annotations,
JetPsiUtil.safeName(function.getName()),
CallableMemberDescriptor.Kind.DECLARATION
);
@@ -475,6 +498,26 @@ public class DescriptorResolver {
public MutableValueParameterDescriptor resolveValueParameterDescriptor(
JetScope scope, DeclarationDescriptor declarationDescriptor,
JetParameter valueParameter, int index, JetType type, BindingTrace trace
) {
return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
annotationResolver.resolveAnnotations(scope, valueParameter.getModifierList(), trace));
}
@NotNull
public MutableValueParameterDescriptor resolveValueParameterDescriptorWithAnnotationArguments(
JetScope scope, DeclarationDescriptor declarationDescriptor,
JetParameter valueParameter, int index, JetType type, BindingTrace trace
) {
return resolveValueParameterDescriptor(declarationDescriptor, valueParameter, index, type, trace,
annotationResolver.resolveAnnotationsWithArguments(scope, valueParameter.getModifierList(),
trace));
}
@NotNull
private MutableValueParameterDescriptor resolveValueParameterDescriptor(
DeclarationDescriptor declarationDescriptor,
JetParameter valueParameter, int index, JetType type, BindingTrace trace,
List<AnnotationDescriptor> annotations
) {
JetType varargElementType = null;
JetType variableType = type;
@@ -485,7 +528,7 @@ public class DescriptorResolver {
MutableValueParameterDescriptor valueParameterDescriptor = new ValueParameterDescriptorImpl(
declarationDescriptor,
index,
annotationResolver.resolveAnnotations(scope, valueParameter.getModifierList(), trace),
annotations,
JetPsiUtil.safeName(valueParameter.getName()),
variableType,
valueParameter.getDefaultValue() != null,
@@ -683,7 +726,7 @@ public class DescriptorResolver {
BindingTrace trace
) {
JetType type = resolveParameterType(scope, parameter, trace);
return resolveLocalVariableDescriptor(containingDeclaration, parameter, type, trace);
return resolveLocalVariableDescriptor(containingDeclaration, parameter, type, trace, scope);
}
private JetType resolveParameterType(JetScope scope, JetParameter parameter, BindingTrace trace) {
@@ -706,11 +749,12 @@ public class DescriptorResolver {
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetParameter parameter,
@NotNull JetType type,
BindingTrace trace
BindingTrace trace,
@NotNull JetScope scope
) {
VariableDescriptor variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
annotationResolver.getResolvedAnnotations(parameter.getModifierList(), trace),
annotationResolver.resolveAnnotationsWithArguments(scope, parameter.getModifierList(), trace),
JetPsiUtil.safeName(parameter.getName()),
type,
false);
@@ -729,7 +773,7 @@ public class DescriptorResolver {
if (JetPsiUtil.isScriptDeclaration(variable)) {
PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(
containingDeclaration,
annotationResolver.getResolvedAnnotations(variable.getModifierList(), trace),
annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
Modality.FINAL,
Visibilities.INTERNAL,
variable.isVar(),
@@ -747,7 +791,7 @@ public class DescriptorResolver {
}
else {
VariableDescriptorImpl variableDescriptor =
resolveLocalVariableDescriptorWithType(containingDeclaration, variable, null, trace);
resolveLocalVariableDescriptorWithType(scope, containingDeclaration, variable, null, trace);
JetType type =
getVariableType(variableDescriptor, scope, variable, dataFlowInfo, false, trace); // For a local variable the type must not be deferred
@@ -758,6 +802,7 @@ public class DescriptorResolver {
@NotNull
public VariableDescriptorImpl resolveLocalVariableDescriptorWithType(
@NotNull JetScope scope,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull JetVariableDeclaration variable,
@Nullable JetType type,
@@ -765,7 +810,7 @@ public class DescriptorResolver {
) {
VariableDescriptorImpl variableDescriptor = new LocalVariableDescriptor(
containingDeclaration,
annotationResolver.getResolvedAnnotations(variable.getModifierList(), trace),
annotationResolver.resolveAnnotationsWithArguments(scope, variable.getModifierList(), trace),
JetPsiUtil.safeName(variable.getName()),
type,
variable.isVar());
@@ -151,7 +151,7 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
Collection<JetNamedFunction> declarations = declarationProvider.getFunctionDeclarations(name);
for (JetNamedFunction functionDeclaration : declarations) {
JetScope resolutionScope = getScopeForMemberDeclarationResolution(functionDeclaration);
result.add(resolveSession.getInjector().getDescriptorResolver().resolveFunctionDescriptor(thisDescriptor, resolutionScope,
result.add(resolveSession.getInjector().getDescriptorResolver().resolveFunctionDescriptorWithAnnotationArguments(thisDescriptor, resolutionScope,
functionDeclaration,
resolveSession.getTrace()));
}
@@ -179,9 +179,12 @@ public abstract class AbstractLazyMemberScope<D extends DeclarationDescriptor, D
Collection<JetProperty> declarations = declarationProvider.getPropertyDeclarations(name);
for (JetProperty propertyDeclaration : declarations) {
JetScope resolutionScope = getScopeForMemberDeclarationResolution(propertyDeclaration);
result.add(resolveSession.getInjector().getDescriptorResolver().resolvePropertyDescriptor(thisDescriptor, resolutionScope,
propertyDeclaration,
resolveSession.getTrace()));
PropertyDescriptor propertyDescriptor =
resolveSession.getInjector().getDescriptorResolver().resolvePropertyDescriptor(thisDescriptor, resolutionScope,
propertyDeclaration,
resolveSession.getTrace());
result.add(propertyDescriptor);
resolveSession.getInjector().getAnnotationResolver().resolveAnnotationsArguments(propertyDescriptor, resolveSession.getTrace(), resolutionScope);
}
// Objects are also properties
@@ -231,7 +231,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
type = CANT_INFER_LAMBDA_PARAM_TYPE;
}
}
return context.expressionTypingServices.getDescriptorResolver().resolveValueParameterDescriptor(
return context.expressionTypingServices.getDescriptorResolver().resolveValueParameterDescriptorWithAnnotationArguments(
context.scope, functionDescriptor, declaredParameter, index, type, context.trace);
}
@@ -331,7 +331,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
if (expectedParameterType == null) {
expectedParameterType = ErrorUtils.createErrorType("Error");
}
variableDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType, context.trace);
variableDescriptor = context.expressionTypingServices.getDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType, context.trace, context.scope);
}
{
@@ -423,7 +423,7 @@ public class ExpressionTypingUtils {
componentType = ErrorUtils.createErrorType(componentName + "() return type");
}
VariableDescriptor variableDescriptor = context.expressionTypingServices.getDescriptorResolver().
resolveLocalVariableDescriptorWithType(writableScope.getContainingDeclaration(), entry, componentType, context.trace);
resolveLocalVariableDescriptorWithType(writableScope, writableScope.getContainingDeclaration(), entry, componentType, context.trace);
VariableDescriptor olderVariable = writableScope.getLocalVariable(variableDescriptor.getName());
checkVariableShadowing(context, variableDescriptor, olderVariable);
@@ -158,7 +158,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override
public JetTypeInfo visitNamedFunction(JetNamedFunction function, ExpressionTypingContext context) {
SimpleFunctionDescriptor functionDescriptor = context.expressionTypingServices.getDescriptorResolver().
resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function, context.trace);
resolveFunctionDescriptorWithAnnotationArguments(scope.getContainingDeclaration(), scope, function, context.trace);
scope.addFunctionDescriptor(functionDescriptor);
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace);
@@ -0,0 +1,39 @@
package test
ANNOTATION class MyClass {
ANNOTATION class object {
}
ANNOTATION var prop: Int = 1
[ANNOTATION] get
[ANNOTATION] set
ANNOTATION fun foo([ANNOTATION] param: Int) {
[ANNOTATION] class LocalClass { }
[ANNOTATION] object LocalObject { }
[ANNOTATION] fun localFun() {}
[ANNOTATION] var localVar: Int = 1
}
ANNOTATION class InnerClass {
}
}
ANNOTATION object MyObject {
}
ANNOTATION var topProp: Int = 1
[ANNOTATION] get
[ANNOTATION] set
ANNOTATION fun topFoo([ANNOTATION] param: Int) {
}
val funLiteral = {([ANNOTATION] a: Int) -> a }
annotation class AnnString(a: String)
annotation class AnnInt(a: Int)
@@ -0,0 +1,282 @@
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.resolve.annotation;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.JetTestUtils;
import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.TypeProjection;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AnnotationDescriptorResolveTest extends JetLiteFixture {
private static final String PATH = "compiler/testData/resolveAnnotations/testFile.kt";
private static final FqName NAMESPACE = new FqName("test");
private BindingContext context;
@Override
protected JetCoreEnvironment createEnvironment() {
return JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable());
}
public void testIntAnnotation() throws IOException {
String content = getContent("AnnInt(1)");
String expectedAnnotation = "AnnInt[a = 1.toInt()]";
doTest(content, expectedAnnotation);
}
public void testStringAnnotation() throws IOException {
String content = getContent("AnnString(\"test\")");
String expectedAnnotation = "AnnString[a = \"test\"]";
doTest(content, expectedAnnotation);
}
private void doTest(@NotNull String content, @NotNull String expectedAnnotation) {
NamespaceDescriptor test = getNamespaceDescriptor(content);
ClassDescriptor myClass = getClassDescriptor(test, "MyClass");
checkDescriptor(expectedAnnotation, myClass);
checkDescriptor(expectedAnnotation, getClassObjectDescriptor(myClass));
checkDescriptor(expectedAnnotation, getInnerClassDescriptor(myClass, "InnerClass"));
FunctionDescriptor foo = getFunctionDescriptor(myClass, "foo");
checkDescriptor(expectedAnnotation, foo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(foo, "param"));
checkDescriptor(expectedAnnotation, getLocalClassDescriptor("LocalClass"));
checkDescriptor(expectedAnnotation, getLocalObjectDescriptor("LocalObject"));
checkDescriptor(expectedAnnotation, getLocalFunDescriptor("localFun"));
checkDescriptor(expectedAnnotation, getLocalVarDescriptor("localVar"));
SimpleFunctionDescriptor anonymousFun = getAnonymousFunDescriptor();
if (anonymousFun instanceof AnonymousFunctionDescriptor) {
for (ValueParameterDescriptor descriptor : anonymousFun.getValueParameters()) {
checkDescriptor(expectedAnnotation, descriptor);
}
}
PropertyDescriptor prop = getPropertyDescriptor(myClass, "prop");
checkDescriptor(expectedAnnotation, prop);
checkDescriptor(expectedAnnotation, prop.getGetter());
checkDescriptor(expectedAnnotation, prop.getSetter());
FunctionDescriptor topFoo = getFunctionDescriptor(test, "topFoo");
checkDescriptor(expectedAnnotation, topFoo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(topFoo, "param"));
PropertyDescriptor topProp = getPropertyDescriptor(test, "topProp");
checkDescriptor(expectedAnnotation, topProp);
checkDescriptor(expectedAnnotation, topProp.getGetter());
checkDescriptor(expectedAnnotation, topProp.getSetter());
checkDescriptor(expectedAnnotation, getObjectDescriptor(test, "MyObject"));
}
@NotNull
private static FunctionDescriptor getFunctionDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name functionName = Name.identifier(name);
JetScope memberScope = namespaceDescriptor.getMemberScope();
Collection<FunctionDescriptor> functions = memberScope.getFunctions(functionName);
assert functions.size() == 1 : "Failed to find function " + functionName + " in class" + "." + namespaceDescriptor.getName();
return functions.iterator().next();
}
@NotNull
private static FunctionDescriptor getFunctionDescriptor(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
Name functionName = Name.identifier(name);
JetScope memberScope = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList());
Collection<FunctionDescriptor> functions = memberScope.getFunctions(functionName);
assert functions.size() == 1 : "Failed to find function " + functionName + " in class" + "." + classDescriptor.getName();
return functions.iterator().next();
}
@NotNull
private static PropertyDescriptor getPropertyDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name propertyName = Name.identifier(name);
JetScope memberScope = namespaceDescriptor.getMemberScope();
Collection<VariableDescriptor> properties = memberScope.getProperties(propertyName);
assert properties.size() == 1 : "Failed to find property " + propertyName + " in class " + namespaceDescriptor.getName();
return (PropertyDescriptor) properties.iterator().next();
}
@NotNull
private static PropertyDescriptor getPropertyDescriptor(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
Name propertyName = Name.identifier(name);
JetScope memberScope = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList());
Collection<VariableDescriptor> properties = memberScope.getProperties(propertyName);
assert properties.size() == 1 : "Failed to find property " + propertyName + " in class " + classDescriptor.getName();
return (PropertyDescriptor) properties.iterator().next();
}
@NotNull
private static ClassDescriptor getClassDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name className = Name.identifier(name);
ClassifierDescriptor aClass = namespaceDescriptor.getMemberScope().getClassifier(className);
assertNotNull("Failed to find class: " + namespaceDescriptor.getName() + "." + className, aClass);
assert aClass instanceof ClassDescriptor;
return (ClassDescriptor) aClass;
}
@NotNull
private static ClassDescriptor getObjectDescriptor(@NotNull NamespaceDescriptor namespaceDescriptor, @NotNull String name) {
Name className = Name.identifier(name);
ClassDescriptor aClass = namespaceDescriptor.getMemberScope().getObjectDescriptor(className);
assertNotNull("Failed to find class: " + namespaceDescriptor.getName() + "." + className, aClass);
return aClass;
}
@NotNull
private static ClassDescriptor getClassObjectDescriptor(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor objectDescriptor = classDescriptor.getClassObjectDescriptor();
assert objectDescriptor != null : "Cannot find class object for class " + classDescriptor.getName();
return objectDescriptor;
}
@NotNull
private static ClassDescriptor getInnerClassDescriptor(@NotNull ClassDescriptor classDescriptor, @NotNull String name) {
Name propertyName = Name.identifier(name);
JetScope memberScope = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList());
ClassifierDescriptor innerClass = memberScope.getClassifier(propertyName);
assert innerClass instanceof ClassDescriptor : "Failed to find inner class " +
propertyName +
" in class " +
classDescriptor.getName();
return (ClassDescriptor) innerClass;
}
@NotNull
private ClassDescriptor getLocalClassDescriptor(@NotNull String name) {
for (ClassDescriptor descriptor : context.getSliceContents(BindingContext.CLASS).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local class " + name);
return null;
}
@NotNull
private ClassDescriptor getLocalObjectDescriptor(@NotNull String name) {
for (ClassDescriptor descriptor : context.getSliceContents(BindingContext.OBJECT_DECLARATION_CLASS).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local object " + name);
return null;
}
@NotNull
private SimpleFunctionDescriptor getLocalFunDescriptor(@NotNull String name) {
for (SimpleFunctionDescriptor descriptor : context.getSliceContents(BindingContext.FUNCTION).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local fun " + name);
return null;
}
@NotNull
private VariableDescriptor getLocalVarDescriptor(@NotNull String name) {
for (VariableDescriptor descriptor : context.getSliceContents(BindingContext.VARIABLE).values()) {
if (descriptor.getName().asString().equals(name)) {
return descriptor;
}
}
fail("Failed to find local variable " + name);
return null;
}
@NotNull
private SimpleFunctionDescriptor getAnonymousFunDescriptor() {
for (SimpleFunctionDescriptor descriptor : context.getSliceContents(BindingContext.FUNCTION).values()) {
if (descriptor instanceof AnonymousFunctionDescriptor) {
return descriptor;
}
}
fail("Failed to find anonymous fun");
return null;
}
private static ValueParameterDescriptor findValueParameter(List<ValueParameterDescriptor> parameters, String name) {
for (ValueParameterDescriptor parameter : parameters) {
if (parameter.getName().asString().equals(name)) {
return parameter;
}
}
return null;
}
@NotNull
private static ValueParameterDescriptor getFunctionParameterDescriptor(
@NotNull FunctionDescriptor functionDescriptor,
@NotNull String name
) {
ValueParameterDescriptor parameter = findValueParameter(functionDescriptor.getValueParameters(), name);
assertNotNull("Cannot find function parameter with name " + name, parameter);
return parameter;
}
@NotNull
private NamespaceDescriptor getNamespaceDescriptor(@NotNull String content) {
JetFile ktFile = JetTestUtils.createFile("dummy.kt", content, getProject());
context = JetTestUtils.analyzeFile(ktFile).getBindingContext();
NamespaceDescriptor namespaceDescriptor = context.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, NAMESPACE);
assertNotNull("Failed to find namespace: " + NAMESPACE, namespaceDescriptor);
return namespaceDescriptor;
}
private static String getContent(@NotNull String annotationText) throws IOException {
File file = new File(PATH);
String content = JetTestUtils.doLoadFile(file).replaceAll("ANNOTATION", annotationText);
return content;
}
private static void checkDescriptor(String expectedAnnotation, DeclarationDescriptor member) {
String actual = StringUtil.join(member.getAnnotations(), new Function<AnnotationDescriptor, String>() {
@Override
public String fun(AnnotationDescriptor annotationDescriptor) {
return annotationDescriptor.toString();
}
}, " ");
assertEquals("Failed to resolve annotation descriptor for " + member.toString(), expectedAnnotation, actual);
}
}
@@ -130,6 +130,7 @@ public class InjectorForTopDownAnalyzerForJs {
this.topDownAnalysisContext.setTopDownAnalysisParameters(topDownAnalysisParameters);
this.bodyResolver.setAnnotationResolver(annotationResolver);
this.bodyResolver.setCallResolver(callResolver);
this.bodyResolver.setContext(topDownAnalysisContext);
this.bodyResolver.setControlFlowAnalyzer(controlFlowAnalyzer);