From c28b701ccffcf19e3d334e6f802486fc8f40e7b3 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Mon, 15 Feb 2016 18:34:20 +0300 Subject: [PATCH] JS: ignore annotation on expression when its retention is SOURCE #KT-8258 --- .../js/diagnosticForUnhandledElements.args | 4 -- .../cli/js/diagnosticForUnhandledElements.kt | 12 ----- .../cli/js/diagnosticForUnhandledElements.out | 4 -- .../unsupportedFeatures/annotations.kt | 40 +++++++++++++++ .../unsupportedFeatures/annotations.txt | 49 +++++++++++++++++++ ...sStdLibAndBackendCompilationGenerated.java | 17 ++++++- .../cli/KotlincExecutableTestGenerated.java | 8 +-- .../expression/ExpressionVisitor.java | 28 ++++++++++- .../js/translate/general/Translation.java | 5 +- 9 files changed, 135 insertions(+), 32 deletions(-) delete mode 100644 compiler/testData/cli/js/diagnosticForUnhandledElements.args delete mode 100644 compiler/testData/cli/js/diagnosticForUnhandledElements.kt delete mode 100644 compiler/testData/cli/js/diagnosticForUnhandledElements.out create mode 100644 compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.kt create mode 100644 compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.txt diff --git a/compiler/testData/cli/js/diagnosticForUnhandledElements.args b/compiler/testData/cli/js/diagnosticForUnhandledElements.args deleted file mode 100644 index 1f2d0cfb6f0..00000000000 --- a/compiler/testData/cli/js/diagnosticForUnhandledElements.args +++ /dev/null @@ -1,4 +0,0 @@ -$TESTDATA_DIR$/diagnosticForUnhandledElements.kt --no-stdlib --output -$TEMP_DIR$/out.js diff --git a/compiler/testData/cli/js/diagnosticForUnhandledElements.kt b/compiler/testData/cli/js/diagnosticForUnhandledElements.kt deleted file mode 100644 index 24ca9eec9c9..00000000000 --- a/compiler/testData/cli/js/diagnosticForUnhandledElements.kt +++ /dev/null @@ -1,12 +0,0 @@ -package foo - -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION) -annotation class fancy - -@fancy -class Foo { - @fancy - fun baz(@fancy foo : Int) : Int { - return (@fancy 1) - } -} diff --git a/compiler/testData/cli/js/diagnosticForUnhandledElements.out b/compiler/testData/cli/js/diagnosticForUnhandledElements.out deleted file mode 100644 index 808d4aef92a..00000000000 --- a/compiler/testData/cli/js/diagnosticForUnhandledElements.out +++ /dev/null @@ -1,4 +0,0 @@ -compiler/testData/cli/js/diagnosticForUnhandledElements.kt:10:17: error: cannot translate (not supported yet): '@fancy 1' - return (@fancy 1) - ^ -COMPILATION_ERROR diff --git a/compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.kt b/compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.kt new file mode 100644 index 00000000000..64b1aeeb9fb --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.kt @@ -0,0 +1,40 @@ +// !DIAGNOSTICS: -UNUSED_PARAMETER + +package foo + +@Retention(AnnotationRetention.SOURCE) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION) +annotation class AnnotationWithSourceRetention + +@Retention(AnnotationRetention.BINARY) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION) +annotation class AnnotationWithBinaryRetention + +@Retention(AnnotationRetention.RUNTIME) +@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION) +annotation class AnnotationWithRuntimeRetention + +@AnnotationWithSourceRetention +class TestSource { + @AnnotationWithSourceRetention + fun baz(@AnnotationWithSourceRetention foo : Int) : Int { + return (@AnnotationWithSourceRetention 1) + } +} + +@AnnotationWithBinaryRetention +class TestBinary { + @AnnotationWithBinaryRetention + fun baz(@AnnotationWithBinaryRetention foo : Int) : Int { + return (@AnnotationWithBinaryRetention 1) + } +} + +@AnnotationWithRuntimeRetention +class TestRuntime { + @AnnotationWithRuntimeRetention + fun baz(@AnnotationWithRuntimeRetention foo : Int) : Int { + return (@AnnotationWithRuntimeRetention 1) + } +} + diff --git a/compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.txt b/compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.txt new file mode 100644 index 00000000000..3e3461c01ef --- /dev/null +++ b/compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.txt @@ -0,0 +1,49 @@ +package + +package foo { + + @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION}) public final annotation class AnnotationWithBinaryRetention : kotlin.Annotation { + public constructor AnnotationWithBinaryRetention() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + @kotlin.annotation.Retention(value = AnnotationRetention.RUNTIME) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION}) public final annotation class AnnotationWithRuntimeRetention : kotlin.Annotation { + public constructor AnnotationWithRuntimeRetention() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + @kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION}) public final annotation class AnnotationWithSourceRetention : kotlin.Annotation { + public constructor AnnotationWithSourceRetention() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + @foo.AnnotationWithBinaryRetention() public final class TestBinary { + public constructor TestBinary() + @foo.AnnotationWithBinaryRetention() public final fun baz(/*0*/ @foo.AnnotationWithBinaryRetention() foo: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + @foo.AnnotationWithRuntimeRetention() public final class TestRuntime { + public constructor TestRuntime() + @foo.AnnotationWithRuntimeRetention() public final fun baz(/*0*/ @foo.AnnotationWithRuntimeRetention() foo: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } + + @foo.AnnotationWithSourceRetention() public final class TestSource { + public constructor TestSource() + @foo.AnnotationWithSourceRetention() public final fun baz(/*0*/ @foo.AnnotationWithSourceRetention() foo: kotlin.Int): kotlin.Int + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + } +} diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibAndBackendCompilationGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibAndBackendCompilationGenerated.java index 6177e48a42a..00cd9ca57bb 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibAndBackendCompilationGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithJsStdLibAndBackendCompilationGenerated.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -67,4 +67,19 @@ public class DiagnosticsTestWithJsStdLibAndBackendCompilationGenerated extends A doTest(fileName); } } + + @TestMetadata("compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class UnsupportedFeatures extends AbstractDiagnosticsTestWithJsStdLibAndBackendCompilation { + public void testAllFilesPresentInUnsupportedFeatures() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("annotations.kt") + public void testAnnotations() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithJsStdLibAndBackendCompilation/unsupportedFeatures/annotations.kt"); + doTest(fileName); + } + } } diff --git a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java index 38282e1031a..e9b708b6f50 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/KotlincExecutableTestGenerated.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -304,12 +304,6 @@ public class KotlincExecutableTestGenerated extends AbstractKotlincExecutableTes doJsTest(fileName); } - @TestMetadata("diagnosticForUnhandledElements.args") - public void testDiagnosticForUnhandledElements() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js/diagnosticForUnhandledElements.args"); - doJsTest(fileName); - } - @TestMetadata("diagnosticWhenReferenceToBuiltinsMember.args") public void testDiagnosticWhenReferenceToBuiltinsMember() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/js/diagnosticWhenReferenceToBuiltinsMember.args"); diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java index e205ae49f64..d834d0f8982 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/expression/ExpressionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -21,9 +21,12 @@ import com.google.dart.compiler.backend.js.ast.metadata.MetadataProperties; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.FunctionDescriptor; import org.jetbrains.kotlin.descriptors.VariableDescriptor; +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention; import org.jetbrains.kotlin.js.translate.context.Namer; import org.jetbrains.kotlin.js.translate.context.TranslationContext; import org.jetbrains.kotlin.js.translate.declaration.ClassTranslator; @@ -44,6 +47,7 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant; import org.jetbrains.kotlin.resolve.constants.ConstantValue; import org.jetbrains.kotlin.resolve.constants.NullValue; import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator; +import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt; import org.jetbrains.kotlin.resolve.inline.InlineUtil; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.TypeUtils; @@ -496,4 +500,26 @@ public final class ExpressionVisitor extends TranslatorVisitor { JsExpression value = ClassTranslator.generateClassCreation(expression, context); return newVar(name, value).source(expression); } + + @Override + public JsNode visitAnnotatedExpression(@NotNull KtAnnotatedExpression expression, TranslationContext context) { + for (KtAnnotationEntry entry : expression.getAnnotationEntries()) { + AnnotationDescriptor descriptor = context.bindingContext().get(BindingContext.ANNOTATION, entry); + if (descriptor == null) continue; + + ClassifierDescriptor classifierDescriptor = descriptor.getType().getConstructor().getDeclarationDescriptor(); + if (classifierDescriptor == null) continue; + + KotlinRetention retention = DescriptorUtilsKt.getAnnotationRetention(classifierDescriptor); + + if (retention == KotlinRetention.SOURCE) { + KtExpression baseExpression = expression.getBaseExpression(); + if (baseExpression == null) continue; + + return baseExpression.accept(this, context); + } + } + + return super.visitAnnotatedExpression(expression, context); + } } diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java index 398064ec7a3..2d0b53c9cc3 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/general/Translation.java @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2016 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. @@ -103,9 +103,8 @@ public final class Translation { return result; } - //NOTE: use with care @NotNull - public static JsNode doTranslateExpression(KtExpression expression, TranslationContext context) { + private static JsNode doTranslateExpression(KtExpression expression, TranslationContext context) { return expression.accept(new ExpressionVisitor(), context); }