From b91ed1e02a41614967dc6c2211adc60b53059a8e Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 6 Sep 2016 15:04:56 +0300 Subject: [PATCH] KT-13544: support typealiases in JS backend --- .../box/typealias/typeAliasCompanion.kt | 9 +++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++ .../kotlin/generators/tests/GenerateTests.kt | 4 ++ .../semantics/TypeAliasesTestsGenerated.java | 67 +++++++++++++++++++ .../abstractClassesForGeneratedTests.kt | 2 + .../declaration/DeclarationBodyVisitor.java | 6 ++ .../expression/ExpressionVisitor.java | 6 ++ .../js/translate/utils/BindingUtils.java | 21 +++++- 8 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/typealias/typeAliasCompanion.kt create mode 100644 js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/TypeAliasesTestsGenerated.java diff --git a/compiler/testData/codegen/box/typealias/typeAliasCompanion.kt b/compiler/testData/codegen/box/typealias/typeAliasCompanion.kt new file mode 100644 index 00000000000..07efa97a0f0 --- /dev/null +++ b/compiler/testData/codegen/box/typealias/typeAliasCompanion.kt @@ -0,0 +1,9 @@ +class A { + companion object { + val result = "OK" + } +} + +typealias Alias = A.Companion + +fun box(): String = Alias.result diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8031d957e41..0a6012724ec 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -15550,6 +15550,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("typeAliasCompanion.kt") + public void testTypeAliasCompanion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasCompanion.kt"); + doTest(fileName); + } + @TestMetadata("typeAliasConstructor.kt") public void testTypeAliasConstructor() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructor.kt"); diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 1333dd4f8d5..6553c78f652 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -1205,6 +1205,10 @@ fun main(args: Array) { testClass() { model("codegen/boxInline/nonLocalReturns/", targetBackend = TargetBackend.JS) } + + testClass() { + model("codegen/box/typealias/", targetBackend = TargetBackend.JS) + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/TypeAliasesTestsGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/TypeAliasesTestsGenerated.java new file mode 100644 index 00000000000..ff55a083533 --- /dev/null +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/TypeAliasesTestsGenerated.java @@ -0,0 +1,67 @@ +/* + * 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.js.test.semantics; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/codegen/box/typealias") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class TypeAliasesTestsGenerated extends AbstractTypeAliasesTests { + public void testAllFilesPresentInTypealias() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/typealias"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("localTypeAlias.kt") + public void testLocalTypeAlias() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/localTypeAlias.kt"); + doTest(fileName); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/simple.kt"); + doTest(fileName); + } + + @TestMetadata("typeAliasCompanion.kt") + public void testTypeAliasCompanion() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasCompanion.kt"); + doTest(fileName); + } + + @TestMetadata("typeAliasConstructor.kt") + public void testTypeAliasConstructor() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasConstructor.kt"); + doTest(fileName); + } + + @TestMetadata("typeAliasObject.kt") + public void testTypeAliasObject() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/typealias/typeAliasObject.kt"); + doTest(fileName); + } +} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt index 850da232d22..c696faf631b 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/abstractClassesForGeneratedTests.kt @@ -68,3 +68,5 @@ abstract class AbstractRttiTest : SingleFileTranslationTest("rtti/") abstract class AbstractCastTest : SingleFileTranslationTest("expression/cast/") abstract class AbstractLightReflectionTest : SingleFileTranslationTest("reflection/light/") + +abstract class AbstractTypeAliasesTests : AbstractBlackBoxTest("typealiases/") diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java index b18f3796777..a79a00e62c7 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/declaration/DeclarationBodyVisitor.java @@ -142,4 +142,10 @@ public class DeclarationBodyVisitor extends TranslatorVisitor { } initializerStatements.add(statement); } + + @Override + public Void visitTypeAlias(@NotNull KtTypeAlias typeAlias, TranslationContext data) { + // Resolved by front-end, not used by backend + return null; + } } 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 fca66762e69..2950d825590 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 @@ -590,6 +590,12 @@ public final class ExpressionVisitor extends TranslatorVisitor { return JsEmpty.INSTANCE; } + @Override + public JsNode visitTypeAlias(@NotNull KtTypeAlias typeAlias, TranslationContext data) { + // Resolved by front-end, not used by backend + return JsEmpty.INSTANCE; + } + private static ClassTranslator.TranslationResult translateClassOrObject( @NotNull KtClassOrObject declaration, @NotNull ClassDescriptor descriptor, diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java index 567f6824f91..f350fefced9 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java +++ b/js/js.translator/src/org/jetbrains/kotlin/js/translate/utils/BindingUtils.java @@ -106,7 +106,7 @@ public final class BindingUtils { public static DeclarationDescriptor getDescriptorForReferenceExpression(@NotNull BindingContext context, @NotNull KtReferenceExpression reference) { if (BindingContextUtils.isExpressionWithValidReference(reference, context)) { - return BindingContextUtils.getNotNull(context, BindingContext.REFERENCE_TARGET, reference); + return resolveObjectViaTypeAlias(BindingContextUtils.getNotNull(context, BindingContext.REFERENCE_TARGET, reference)); } return null; } @@ -114,7 +114,24 @@ public final class BindingUtils { @Nullable private static DeclarationDescriptor getNullableDescriptorForReferenceExpression(@NotNull BindingContext context, @NotNull KtReferenceExpression reference) { - return context.get(BindingContext.REFERENCE_TARGET, reference); + DeclarationDescriptor descriptor = context.get(BindingContext.REFERENCE_TARGET, reference); + return descriptor != null ? resolveObjectViaTypeAlias(descriptor) : null; + } + + @NotNull + private static DeclarationDescriptor resolveObjectViaTypeAlias(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof TypeAliasDescriptor) { + ClassDescriptor classDescriptor = ((TypeAliasDescriptor) descriptor).getClassDescriptor(); + assert classDescriptor != null : "Class descriptor must be non-null in resolved typealias: " + descriptor; + if (classDescriptor.getKind() != ClassKind.OBJECT) { + classDescriptor = classDescriptor.getCompanionObjectDescriptor(); + assert classDescriptor != null : "Resolved typealias must have non-null class descriptor: " + descriptor; + } + return classDescriptor; + } + else { + return descriptor; + } } public static boolean isVariableReassignment(@NotNull BindingContext context, @NotNull KtExpression expression) {