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. " +
"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)
@SuppressWarnings("UnusedDeclaration")
@@ -19,9 +19,9 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.*;
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.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
@@ -82,23 +82,36 @@ public class AnnotationResolver {
}
public void resolveAnnotationStub(@NotNull JetScope scope, @NotNull JetAnnotationEntry entryElement,
@NotNull AnnotationDescriptor descriptor, BindingTrace trace) {
OverloadResolutionResults<FunctionDescriptor> results = resolveType(scope, entryElement, descriptor, trace);
resolveArguments(results, descriptor, trace);
}
@NotNull
private OverloadResolutionResults<FunctionDescriptor> resolveType(@NotNull JetScope scope,
@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();
@NotNull AnnotationDescriptor annotationDescriptor, BindingTrace trace) {
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveFunctionCall(
trace,
scope,
CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, entryElement),
NO_EXPECTED_TYPE,
DataFlowInfo.EMPTY);
if (results.isSuccess()) {
descriptor.setAnnotationType(annotationType);
} else {
descriptor.setAnnotationType(ErrorUtils.createErrorType("Unresolved annotation type"));
FunctionDescriptor descriptor = results.getResultingDescriptor();
if (!ErrorUtils.isError(descriptor)) {
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,
@@ -276,7 +276,7 @@ public class CallResolver {
}
if (traceForFirstNonemptyCandidateSet != null) {
traceForFirstNonemptyCandidateSet.commit();
if (resultsForFirstNonemptyCandidateSet.singleResult()) {
if (resultsForFirstNonemptyCandidateSet.isSingleResult()) {
debugInfo.set(ResolutionDebugInfo.RESULT, resultsForFirstNonemptyCandidateSet.getResultingCall());
}
@@ -436,7 +436,7 @@ public class CallResolver {
}
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(task.trace, task.tracing, successfulCandidates, failedCandidates);
if (!results.singleResult()) {
if (!results.isSingleResult()) {
checkTypesWithNoCallee(task.toBasic());
}
return results;
@@ -57,7 +57,7 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
boolean isSuccess();
boolean singleResult();
boolean isSingleResult();
boolean isNothing();
@@ -63,7 +63,7 @@ import java.util.Collections;
@Override
@NotNull
public ResolvedCallImpl<D> getResultingCall() {
assert singleResult();
assert isSingleResult();
return results.iterator().next();
}
@@ -85,7 +85,7 @@ import java.util.Collections;
}
@Override
public boolean singleResult() {
public boolean isSingleResult() {
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
}
@@ -609,7 +609,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
checkSuper(receiver, resultingDescriptor, context.trace, selectorExpression);
return resultingDescriptor.getType();
}
if (resolutionResult.isAmbiguity() || resolutionResult.singleResult()) {
if (resolutionResult.isAmbiguity() || resolutionResult.isSingleResult()) {
temporaryTrace.commit();
return null;
}
@@ -172,7 +172,7 @@ public class ExpressionTypingContext {
@Nullable
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);
return results.singleResult() ? results.getResultingDescriptor() : null;
return results.isSingleResult() ? results.getResultingDescriptor() : null;
}
@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