Diagnostics for illegal platform names

This commit is contained in:
Andrey Breslav
2014-06-10 18:51:23 +04:00
parent 14a6cdf458
commit f59ff5d8fe
5 changed files with 46 additions and 9 deletions
@@ -205,6 +205,8 @@ public interface Errors {
DiagnosticFactory2<JetDeclaration, CallableMemberDescriptor, String> CONFLICTING_OVERLOADS = DiagnosticFactory2.create(ERROR, DECLARATION);
DiagnosticFactory1<JetAnnotationEntry, String> ILLEGAL_PLATFORM_NAME = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition(
JetTokens.OPEN_KEYWORD));
@@ -419,6 +419,7 @@ public class DefaultErrorMessages {
RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES);
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' is already defined in {1}", COMPACT_WITH_MODIFIERS, STRING);
MAP.put(ILLEGAL_PLATFORM_NAME, "Illegal platform name: ''{0}''", STRING);
MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. The function 'invoke()' is not found", ELEMENT_TEXT, new Renderer<JetType>() {
@NotNull
@@ -28,7 +28,9 @@ 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.constants.*;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lexer.JetModifierKeywordToken;
import java.util.Collection;
@@ -36,6 +38,7 @@ import java.util.Collections;
import java.util.Map;
import static org.jetbrains.jet.lang.diagnostics.Errors.ILLEGAL_MODIFIER;
import static org.jetbrains.jet.lang.diagnostics.Errors.ILLEGAL_PLATFORM_NAME;
import static org.jetbrains.jet.lang.diagnostics.Errors.INAPPLICABLE_ANNOTATION;
import static org.jetbrains.jet.lexer.JetTokens.*;
@@ -152,15 +155,6 @@ public class ModifiersChecker {
}
private void checkPlatformNameApplicability(@NotNull DeclarationDescriptor descriptor) {
if (!DescriptorUtils.isTopLevelDeclaration(descriptor) || !(descriptor instanceof FunctionDescriptor)) {
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(new FqName("kotlin.platform.platformName"));
if (annotation != null) {
JetAnnotationEntry annotationEntry = trace.get(BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT, annotation);
if (annotationEntry != null) {
trace.report(INAPPLICABLE_ANNOTATION.on(annotationEntry));
}
}
}
if (descriptor instanceof PropertyDescriptor) {
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
if (propertyDescriptor.getGetter() != null) {
@@ -170,6 +164,27 @@ public class ModifiersChecker {
checkPlatformNameApplicability(propertyDescriptor.getSetter());
}
}
AnnotationDescriptor annotation = descriptor.getAnnotations().findAnnotation(new FqName("kotlin.platform.platformName"));
if (annotation == null) return;
JetAnnotationEntry annotationEntry = trace.get(BindingContext.ANNOTATION_DESCRIPTOR_TO_PSI_ELEMENT, annotation);
if (annotationEntry == null) return;
if (!DescriptorUtils.isTopLevelDeclaration(descriptor) || !(descriptor instanceof FunctionDescriptor)) {
trace.report(INAPPLICABLE_ANNOTATION.on(annotationEntry));
}
Collection<CompileTimeConstant<?>> values = annotation.getAllValueArguments().values();
if (!values.isEmpty()) {
CompileTimeConstant<?> name = values.iterator().next();
if (name instanceof StringValue) {
String value = ((StringValue) name).getValue();
if (value == null || !Name.isValidIdentifier(value)) {
trace.report(ILLEGAL_PLATFORM_NAME.on(annotationEntry, String.valueOf(value)));
}
}
}
}
private void checkCompatibility(@Nullable JetModifierList modifierList, Collection<JetModifierKeywordToken> availableModifiers, Collection<JetModifierKeywordToken>... availableCombinations) {
@@ -0,0 +1,14 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
import kotlin.platform.*
[<!ILLEGAL_PLATFORM_NAME!>platformName("")<!>]
fun foo(a: Any) {}
[<!ILLEGAL_PLATFORM_NAME!>platformName(".")<!>]
fun foo() {}
[<!ILLEGAL_PLATFORM_NAME!>platformName("/")<!>]
fun fooSlash() {}
[<!ILLEGAL_PLATFORM_NAME!>platformName("<")<!>]
fun fooLT() {}
@@ -55,6 +55,11 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("illegalPlatformName.kt")
public void testIllegalPlatformName() throws Exception {
doTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/illegalPlatformName.kt");
}
@TestMetadata("platformName.kt")
public void testPlatformName() throws Exception {
doTest("compiler/testData/diagnostics/testsWithStdLib/annotations/annotationApplicability/platformName.kt");