KT-1152 Only allow annotation classes to be instantiated as annotations
#KT-1152 Fixed
This commit is contained in:
@@ -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;
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
|
||||
|
||||
boolean isSuccess();
|
||||
|
||||
boolean singleResult();
|
||||
boolean isSingleResult();
|
||||
|
||||
boolean isNothing();
|
||||
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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
|
||||
Reference in New Issue
Block a user