KT-1152 Only allow annotation classes to be instantiated as annotations

#KT-1152 Fixed
This commit is contained in:
Andrey Breslav
2012-03-28 19:40:45 +04:00
parent 25a972cd80
commit 0a42abc7c9
9 changed files with 47 additions and 24 deletions
@@ -448,6 +448,8 @@ public interface Errors {
DiagnosticFactory<JetExpression> DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED = DiagnosticFactory.create(WARNING, "This expression is treated as an argument to the function call on the previous line. " + DiagnosticFactory<JetExpression> DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED = DiagnosticFactory.create(WARNING, "This expression is treated as an argument to the function call on the previous line. " +
"Separate it with a semicolon (;) if it is not intended to be an argument."); "Separate it with a semicolon (;) if it is not intended to be an argument.");
DiagnosticFactory1<JetAnnotationEntry, String> NOT_AN_ANNOTATION_CLASS = DiagnosticFactory1.create(ERROR, "{0} is not an annotation class");
// This field is needed to make the Initializer class load (interfaces cannot have static initializers) // This field is needed to make the Initializer class load (interfaces cannot have static initializers)
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
@@ -19,9 +19,9 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver;
@@ -82,23 +82,36 @@ public class AnnotationResolver {
} }
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement, public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement,
@NotNull AnnotationDescriptor descriptor, BindingTrace trace) { @NotNull AnnotationDescriptor annotationDescriptor, BindingTrace trace) {
OverloadResolutionResults<FunctionDescriptor> results = resolveType(scope, entryElement, descriptor, trace); OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
resolveArguments(results, descriptor, trace); trace,
} scope,
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement),
@NotNull NO_EXPECTED_TYPE,
private OverloadResolutionResults<FunctionDescriptor> resolveType(@NotNull JetScope scope, DataFlowInfo.EMPTY);
@NotNull JetAnnotationEntry entryElement,
@NotNull AnnotationDescriptor descriptor, BindingTrace trace) {
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(trace, scope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement), NO_EXPECTED_TYPE, DataFlowInfo.EMPTY);
JetType annotationType = results.getResultingDescriptor().getReturnType();
if (results.isSuccess()) { if (results.isSuccess()) {
descriptor.setAnnotationType(annotationType); FunctionDescriptor descriptor = results.getResultingDescriptor();
} else { if (!ErrorUtils.isError(descriptor)) {
descriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type")); if (descriptor instanceof ConstructorDescriptor) {
ConstructorDescriptor constructor = (ConstructorDescriptor)descriptor;
ClassDescriptor classDescriptor = constructor.getContainingDeclaration();
if (classDescriptor.getKind() != ClassKind.ANNOTATION_CLASS) {
trace.report(Errors.NOT_AN_ANNOTATION_CLASS.on(entryElement, classDescriptor.getName()));
}
}
else {
trace.report(Errors.NOT_AN_ANNOTATION_CLASS.on(entryElement, descriptor.getName()));
}
}
}
if (results.isSuccess()) {
JetType annotationType = results.getResultingDescriptor().getReturnType();
annotationDescriptor.setAnnotationType(annotationType);
resolveArguments(results, annotationDescriptor, trace);
}
else {
annotationDescriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type"));
} }
return results;
} }
private void resolveArguments(@NotNull OverloadResolutionResults<FunctionDescriptor> results, private void resolveArguments(@NotNull OverloadResolutionResults<FunctionDescriptor> results,
@@ -276,7 +276,7 @@ public class CallResolver {
} }
if (traceForFirstNonemptyCandidateSet != null) { if (traceForFirstNonemptyCandidateSet != null) {
traceForFirstNonemptyCandidateSet.commit(); traceForFirstNonemptyCandidateSet.commit();
if (resultsForFirstNonemptyCandidateSet.singleResult()) { if (resultsForFirstNonemptyCandidateSet.isSingleResult()) {
debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall()); debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall());
} }
@@ -436,7 +436,7 @@ public class CallResolver {
} }
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates); OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates);
if (!results.singleResult()) { if (!results.isSingleResult()) {
checkTypesWithNoCallee(task.toBasic()); checkTypesWithNoCallee(task.toBasic());
} }
return results; return results;
@@ -57,7 +57,7 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
boolean isSuccess(); boolean isSuccess();
boolean singleResult(); boolean isSingleResult();
boolean isNothing(); boolean isNothing();
@@ -63,7 +63,7 @@ import java.util.Collections;
@Override @Override
@NotNull @NotNull
public ResolvedCallImpl<D> getResultingCall() { public ResolvedCallImpl<D> getResultingCall() {
assert singleResult(); assert isSingleResult();
return results.iterator().next(); return results.iterator().next();
} }
@@ -85,7 +85,7 @@ import java.util.Collections;
} }
@Override @Override
public boolean singleResult() { public boolean isSingleResult() {
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH; return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
} }
@@ -609,7 +609,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
checkSuper(receiver, resultingDescriptor, context.trace, selectorExpression); checkSuper(receiver, resultingDescriptor, context.trace, selectorExpression);
return resultingDescriptor.getType(); return resultingDescriptor.getType();
} }
if (resolutionResult.isAmbiguity() || resolutionResult.singleResult()) { if (resolutionResult.isAmbiguity() || resolutionResult.isSingleResult()) {
temporaryTrace.commit(); temporaryTrace.commit();
return null; return null;
} }
@@ -172,7 +172,7 @@ public class ExpressionTypingContext {
@Nullable @Nullable
public FunctionDescriptor resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) { public FunctionDescriptor resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) {
OverloadResolutionResults<FunctionDescriptor> results = expressionTypingServices.getCallResolver().resolveFunctionCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType, dataFlowInfo); OverloadResolutionResults<FunctionDescriptor> results = expressionTypingServices.getCallResolver().resolveFunctionCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType, dataFlowInfo);
return results.singleResult() ? results.getResultingDescriptor() : null; return results.isSingleResult() ? results.getResultingDescriptor() : null;
} }
@NotNull @NotNull
@@ -0,0 +1,5 @@
import java.util.ArrayList
<!NONE_APPLICABLE!>ArrayList<!><Int>(1, 1) fun b() {}
<!UNRESOLVED_REFERENCE!>Xoo<!>(<!UNRESOLVED_REFERENCE!>x<!>) fun c() {}
Deprecated(<!TOO_MANY_ARGUMENTS, UNRESOLVED_REFERENCE!>x<!>) fun a() {}
@@ -0,0 +1,3 @@
class Foo
<!NOT_AN_ANNOTATION_CLASS!>Foo<!> class Bar