diff --git a/compiler/tests-common/org/jetbrains/kotlin/test/KotlinTestUtils.java b/compiler/tests-common/org/jetbrains/kotlin/test/KotlinTestUtils.java index 90622f8c135..4903fe927a1 100644 --- a/compiler/tests-common/org/jetbrains/kotlin/test/KotlinTestUtils.java +++ b/compiler/tests-common/org/jetbrains/kotlin/test/KotlinTestUtils.java @@ -110,7 +110,7 @@ public class KotlinTestUtils { * Several files may follow one module */ public static final Pattern FILE_OR_MODULE_PATTERN = Pattern.compile( - "(?://\\s*MODULE:\\s*([\\w\\d_\\-]+)(\\([\\w\\d_\\-]+(?:, [\\w\\d_\\-]+)*\\))?\\s*)?" + + "(?://\\s*MODULE:\\s*([\\w\\d_\\-]+)(\\([\\w\\d_\\-]+(?:,\\s*[\\w\\d_\\-]+)*\\))?\\s*)?" + "//\\s*FILE:\\s*(.*)$", Pattern.MULTILINE); public static final Pattern DIRECTIVE_PATTERN = Pattern.compile("^//\\s*!([\\w_]+)(:\\s*(.*)$)?", Pattern.MULTILINE); diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt index 8051bfc0a3e..fc6d0693d99 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/naming/NameSuggestion.kt @@ -66,6 +66,11 @@ class NameSuggestion { return suggest(descriptor.containingDeclaration!!) } + // Dynamic declarations always require stable names as defined in Kotlin source code + if (descriptor.isDynamic()) { + return SuggestedName(listOf(descriptor.name.asString()), true, descriptor, descriptor.containingDeclaration!!) + } + when (descriptor) { // Modules are root declarations, we don't produce declarations for them, therefore they can't clash is ModuleDescriptor -> return null @@ -94,8 +99,8 @@ class NameSuggestion { // Local functions and variables are always private with their own names as suggested names is CallableDescriptor -> if (DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) { - val name = getMangledName(getSuggestedName(descriptor), descriptor) - return SuggestedName(listOf(name.first), false, descriptor, descriptor.containingDeclaration) + val name = getNameForAnnotatedObject(descriptor) ?: getSuggestedName(descriptor) + return SuggestedName(listOf(name), false, descriptor, descriptor.containingDeclaration) } } @@ -103,11 +108,6 @@ class NameSuggestion { } private fun generateDefault(descriptor: DeclarationDescriptor): SuggestedName { - // Dynamic declarations always require stable names as defined in Kotlin source code - if (descriptor.isDynamic()) { - return SuggestedName(listOf(descriptor.name.asString()), true, descriptor, descriptor.containingDeclaration!!) - } - // For any non-local declaration suggest its own suggested name and put it in scope of its containing declaration. // For local declaration get a sequence for names of all containing functions and join their names with '$' symbol, // and use container of topmost function, i.e. @@ -146,7 +146,7 @@ class NameSuggestion { parts.reverse() val unmangledName = parts.joinToString("$") - val (id, stable) = getMangledName(unmangledName, descriptor) + val (id, stable) = mangleNameIfNecessary(unmangledName, descriptor) return SuggestedName(listOf(id), stable, descriptor, current) } @@ -168,7 +168,7 @@ class NameSuggestion { } companion object { - private fun getMangledName(baseName: String, descriptor: DeclarationDescriptor): Pair { + private fun mangleNameIfNecessary(baseName: String, descriptor: DeclarationDescriptor): NameAndStability { // If we have a callable descriptor (property or method) it can override method in a parent class. // Traverse to the topmost overridden method. // It does not matter which path to choose during traversal, since front-end must ensure @@ -182,20 +182,64 @@ class NameSuggestion { // If declaration is marked with either @native, @library or @JsName, return its stable name as is. val nativeName = getNameForAnnotatedObject(overriddenDescriptor) - if (nativeName != null) return Pair(nativeName, true) + if (nativeName != null) return NameAndStability(nativeName, true) - val stable = shouldBeStable(descriptor) - val finalName = when { - overriddenDescriptor is CallableDescriptor && stable -> { - getStableMangledName(baseName, getArgumentTypesAsString(overriddenDescriptor)) - } - shouldMangleUnstable(overriddenDescriptor) -> getPrivateMangledName(baseName, overriddenDescriptor as CallableDescriptor) - else -> baseName + return mangleRegularNameIfNecessary(baseName, overriddenDescriptor) + } + + private fun mangleRegularNameIfNecessary(baseName: String, descriptor: DeclarationDescriptor): NameAndStability { + if (descriptor is ClassOrPackageFragmentDescriptor) { + return NameAndStability(baseName, !DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) } - return Pair(finalName, stable) + fun regularAndUnstable() = NameAndStability(baseName, false) + + if (descriptor !is CallableMemberDescriptor) { + // Actually, only reified types get here, and it would be properly to put assertion here + // However, it's better to generate wrong code than crash + return regularAndUnstable() + } + + fun mangledAndStable() = NameAndStability(getStableMangledName(baseName, getArgumentTypesAsString(descriptor)), true) + fun mangledPrivate() = NameAndStability(getPrivateMangledName(baseName, descriptor), false) + + val containingDeclaration = descriptor.containingDeclaration + return when (containingDeclaration) { + is PackageFragmentDescriptor -> if (descriptor.visibility.isPublicAPI) mangledAndStable() else regularAndUnstable() + is ClassDescriptor -> { + // valueOf() is created in the library with a mangled name for every enum class + if (descriptor is FunctionDescriptor && descriptor.isEnumValueOfMethod()) return mangledAndStable() + + // Make all public declarations stable + if (descriptor.visibility == Visibilities.PUBLIC) return mangledAndStable() + + // Make all protected declarations of non-final public classes stable + if (descriptor.visibility == Visibilities.PROTECTED && + !containingDeclaration.isFinalClass && + containingDeclaration.visibility.isPublicAPI + ) { + return mangledAndStable() + } + + // Mangle (but make unstable) all non-public API of public classes + if (containingDeclaration.visibility.isPublicAPI && !containingDeclaration.isFinalClass) { + return mangledPrivate() + } + + regularAndUnstable() + } + else -> { + assert(containingDeclaration is CallableMemberDescriptor) { + "containingDeclaration for descriptor have unsupported type for mangling, " + + "descriptor: " + descriptor + ", containingDeclaration: " + containingDeclaration + } + regularAndUnstable() + } + } } + data class NameAndStability(val name: String, val stable: Boolean) + @JvmStatic fun getPrivateMangledName(baseName: String, descriptor: CallableDescriptor): String { val ownerName = descriptor.containingDeclaration.fqNameUnsafe.asString() return getStableMangledName(baseName, ownerName + ":" + getArgumentTypesAsString(descriptor)) @@ -214,67 +258,11 @@ class NameSuggestion { return argTypes.toString() } - // Sometimes private members of a class can clash with public members of subclasses, therefore we must - // mangle them - private fun shouldMangleUnstable(descriptor: DeclarationDescriptor): Boolean { - if (descriptor is ClassDescriptor) return false - if (DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) return false - - val containingClass = DescriptorUtils.getContainingClass(descriptor) - if (containingClass != null && descriptor is CallableMemberDescriptor && !descriptor.isOverridable) { - return containingClass.visibility.isPublicAPI - } - - return false - } - @JvmStatic fun getStableMangledName(suggestedName: String, forCalculateId: String): String { val suffix = if (forCalculateId.isEmpty()) "" else "_${mangledId(forCalculateId)}\$" return suggestedName + suffix } - private fun shouldBeStable(descriptor: DeclarationDescriptor): Boolean { - if (DescriptorUtils.isDescriptorWithLocalVisibility(descriptor)) return false - if (descriptor is ClassOrPackageFragmentDescriptor) return true - if (descriptor !is CallableMemberDescriptor) return false - - // Use stable mangling for overrides because we use stable mangling when any function inside a overridable declaration - // for avoid clashing names when inheritance. - if (DescriptorUtils.isOverride(descriptor)) return true - - val containingDeclaration = descriptor.containingDeclaration - if (isNativeObject(containingDeclaration) || isLibraryObject(containingDeclaration)) return true - - return when (containingDeclaration) { - is PackageFragmentDescriptor -> descriptor.visibility.isPublicAPI - is ClassDescriptor -> { - // Open (abstract) public methods of classes or final public methods of open (abstract) classes should be stable - if (containingDeclaration.modality == Modality.OPEN || containingDeclaration.modality == Modality.ABSTRACT) { - return descriptor.visibility.isPublicAPI - } - - // valueOf() is created in the library with a mangled name for every enum class - if (descriptor is FunctionDescriptor && descriptor.isEnumValueOfMethod()) return true - - // Don't use stable mangling when it inside a non-public class. - if (!containingDeclaration.visibility.isPublicAPI) return false - - // Ignore the `protected` visibility because it can be use outside a containing declaration - // only when the containing declaration is overridable. - if (descriptor.visibility === Visibilities.PUBLIC) return true - - return false - } - else -> { - assert(containingDeclaration is CallableMemberDescriptor) { - "containingDeclaration for descriptor have unsupported type for mangling, " + - "descriptor: " + descriptor + ", containingDeclaration: " + containingDeclaration - } - false - } - } - } - private fun mangledId(forCalculateId: String): String { val absHashCode = Math.abs(forCalculateId.hashCode()) return if (absHashCode != 0) Integer.toString(absHashCode, Character.MAX_RADIX) else "" diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt index c0a404da637..f09fdbcf88e 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt @@ -71,6 +71,7 @@ abstract class BasicBoxTest( val TEST_MODULE = "JS_TESTS" val DEFAULT_MODULE = "main" val TEST_FUNCTION = "box" + private val OLD_MODULE_SUFFIX = "-old" fun doTest(filePath: String) { val file = File(filePath) @@ -85,12 +86,13 @@ abstract class BasicBoxTest( val orderedModules = DFS.topologicalOrder(modules.values) { module -> module.dependencies.mapNotNull { modules[it] } } - val generatedJsFiles = orderedModules.asReversed().map { module -> + val generatedJsFiles = orderedModules.asReversed().mapNotNull { module -> val dependencies = module.dependencies.mapNotNull { modules[it]?.outputFileName(outputDir) + ".meta.js" } val outputFileName = module.outputFileName(outputDir) + ".js" generateJavaScriptFile(file.parent, module, outputFileName, dependencies, modules.size > 1) - outputFileName + + if (!module.name.endsWith(OLD_MODULE_SUFFIX)) outputFileName else null } val mainModuleName = if (TEST_MODULE in modules) TEST_MODULE else DEFAULT_MODULE val mainModule = modules[mainModuleName]!! @@ -247,7 +249,7 @@ abstract class BasicBoxTest( configuration.put(JSConfigurationKeys.LIBRARY_FILES, LibrarySourcesConfig.JS_STDLIB + dependencies) - configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name) + configuration.put(CommonConfigurationKeys.MODULE_NAME, module.name.removeSuffix(OLD_MODULE_SUFFIX)) configuration.put(JSConfigurationKeys.MODULE_KIND, module.moduleKind) configuration.put(JSConfigurationKeys.TARGET, EcmaVersion.v5) @@ -283,7 +285,7 @@ abstract class BasicBoxTest( (module ?: defaultModule).inliningDisabled = true } - val temporaryFile = File(tmpDir, fileName) + val temporaryFile = File(tmpDir, "${(module ?: defaultModule).name}/$fileName") KotlinTestUtils.mkdirs(temporaryFile.parentFile) temporaryFile.writeText(text, Charsets.UTF_8) diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleModulesTranslationTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleModulesTranslationTest.kt deleted file mode 100644 index b41fe1e2d8f..00000000000 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/MultipleModulesTranslationTest.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright 2010-2015 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 - -import com.intellij.openapi.util.io.FileUtil -import com.intellij.openapi.util.text.StringUtil -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.js.config.EcmaVersion -import org.jetbrains.kotlin.js.config.JSConfigurationKeys -import org.jetbrains.kotlin.js.config.JsConfig -import org.jetbrains.kotlin.js.facade.MainCallParameters -import org.jetbrains.kotlin.js.test.rhino.RhinoFunctionResultChecker -import org.jetbrains.kotlin.js.test.utils.JsTestUtils.getAllFilesInDir -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.serialization.js.ModuleKind -import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils -import java.io.File -import java.util.* - -abstract class MultipleModulesTranslationTest(main: String) : BasicTest(main) { - private val MAIN_MODULE_NAME: String = "main" - private val OLD_MODULE_SUFFIX = "-old" - private var dependencies: Map>? = null - protected var moduleKind = ModuleKind.PLAIN - - override fun checkFooBoxIsOkByPath(filePath: String) { - val dirName = getTestName(true) - dependencies = readModuleDependencies(filePath) - - // KT-7428: !! is necessary here - for ((moduleName, dependencies) in dependencies!!) { - translateModule(dirName, filePath, moduleName, dependencies) - } - - val filename = getInputFilePath(getModuleDirectoryName(dirName, MAIN_MODULE_NAME) + File.separator + MAIN_MODULE_NAME + ".kt") - val packageName = getPackageName(filename) - runMultiModuleTest(dirName, packageName, BasicTest.TEST_FUNCTION, "OK") - } - - private fun runMultiModuleTest(dirName: String, packageName: String, functionName: String, expectedResult: Any) { - val moduleDirectoryName = getModuleDirectoryName(dirName, MAIN_MODULE_NAME) - val checker = RhinoFunctionResultChecker(MAIN_MODULE_NAME, packageName, functionName, expectedResult) - runRhinoTests(moduleDirectoryName, BasicTest.DEFAULT_ECMA_VERSIONS, checker) - } - - private fun translateModule(dirName: String, pathToDir: String, moduleName: String, dependencies: List) { - val moduleDirectoryName = getModuleDirectoryName(dirName, moduleName) - val fullFilePaths = getAllFilesInDir(pathToDir + File.separator + moduleName) - - BasicTest.DEFAULT_ECMA_VERSIONS.forEach { version -> - val libraries = arrayListOf() - for (dependencyName in dependencies) { - val moduleDir = getModuleDirectoryName(dirName, dependencyName) - libraries.add(getMetaFileOutputPath(moduleDir, version)) - } - generateJavaScriptFiles(fullFilePaths, moduleDirectoryName, MainCallParameters.noCall(), version, - moduleName.removeSuffix(OLD_MODULE_SUFFIX), libraries) - } - } - - private fun getMetaFileOutputPath(moduleDirectoryName: String, version: EcmaVersion) = - KotlinJavascriptMetadataUtils.replaceSuffix(getOutputFilePath(moduleDirectoryName, version)) - - override fun setupConfig(configuration: CompilerConfiguration) { - val method = try { - javaClass.getMethod(name) - } - catch (e: NoSuchMethodException) { - return - } - - method.getAnnotation(WithModuleKind::class.java)?.let { moduleKind = it.value } - configuration.put(JSConfigurationKeys.MODULE_KIND, moduleKind) - } - - override fun shouldGenerateMetaInfo() = true - - override fun additionalJsFiles(ecmaVersion: EcmaVersion): List { - val result = mutableListOf(MODULE_EMULATION_FILE) - result += super.additionalJsFiles(ecmaVersion) - val dirName = getTestName(true) - assert(dependencies != null) { "dependencies should not be null" } - - for (moduleName in dependencies!!.keys.filter { !it.endsWith(OLD_MODULE_SUFFIX) }) { - if (moduleName != MAIN_MODULE_NAME && !moduleName.endsWith(OLD_MODULE_SUFFIX)) { - result.add(getOutputFilePath(getModuleDirectoryName(dirName, moduleName), ecmaVersion)) - } - } - - return result - } - - override fun translateFiles(jetFiles: MutableList, outputFile: File, mainCallParameters: MainCallParameters, - config: JsConfig) { - super.translateFiles(jetFiles, outputFile, mainCallParameters, config) - - if (config.moduleKind == ModuleKind.COMMON_JS) { - val content = FileUtil.loadFile(outputFile, true) - val wrappedContent = "__beginModule__();\n" + - "$content\n" + - "__endModule__(\"${StringUtil.escapeStringCharacters(config.moduleId)}\");" - FileUtil.writeToFile(outputFile, wrappedContent) - // TODO: it would be better to wrap output before JS file is actually written - } - } - - private fun readModuleDependencies(testDataDir: String): Map> { - val dependenciesTxt = upsearchFile(testDataDir, "dependencies.txt") - assert(dependenciesTxt.isFile) { "moduleDependencies should not be null" } - - val result = LinkedHashMap>() - for (line in dependenciesTxt.readLines()) { - val split = line.split("->") - val module = split[0] - val dependencies = if (split.size > 1) split[1] else "" - val dependencyList = dependencies.split(",").filterNot { it.isEmpty() } - - result[module] = dependencyList - } - - return result - } - - private fun upsearchFile(startingDir: String, name: String): File { - var dir: File? = File(startingDir) - var file = File(dir, name) - - while (dir != null && dir.isDirectory && !file.isFile) { - dir = dir.parentFile - file = File(dir, name) - } - - return file - } -} diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java index da7397dc0ed..c9c5d78c9dc 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/BoxJsTestGenerated.java @@ -2259,6 +2259,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("localInInitBlock.kt") + public void testLocalInInitBlock() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/function/localInInitBlock.kt"); + doTest(fileName); + } + @TestMetadata("loopClosure.kt") public void testLoopClosure() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/function/loopClosure.kt"); @@ -4978,6 +4984,18 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("privateInterfaceNameClash.kt") + public void testPrivateInterfaceNameClash() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/privateInterfaceNameClash.kt"); + doTest(fileName); + } + + @TestMetadata("privateNameClash.kt") + public void testPrivateNameClash() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/privateNameClash.kt"); + doTest(fileName); + } + @TestMetadata("useElementsFromDefaultPackageInAnotherModule.kt") public void testUseElementsFromDefaultPackageInAnotherModule() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/multiModule/useElementsFromDefaultPackageInAnotherModule.kt"); @@ -5305,6 +5323,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest { doTest(fileName); } + @TestMetadata("inheritanceInNativeClass.kt") + public void testInheritanceInNativeClass() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/inheritanceInNativeClass.kt"); + doTest(fileName); + } + @TestMetadata("kt1519.kt") public void testKt1519() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/native/kt1519.kt"); diff --git a/js/js.translator/testData/expression/function/cases/localInInitBlock.kt b/js/js.translator/testData/box/expression/function/localInInitBlock.kt similarity index 100% rename from js/js.translator/testData/expression/function/cases/localInInitBlock.kt rename to js/js.translator/testData/box/expression/function/localInInitBlock.kt diff --git a/js/js.translator/testData/box/inline/metadataForPublicFunction.kt b/js/js.translator/testData/box/inline/metadataForPublicFunction.kt index 0e4d7b68a72..7dedf267f1e 100644 --- a/js/js.translator/testData/box/inline/metadataForPublicFunction.kt +++ b/js/js.translator/testData/box/inline/metadataForPublicFunction.kt @@ -8,7 +8,7 @@ package foo // CHECK_HAS_INLINE_METADATA: apply_hiyix$ // CHECK_HAS_INLINE_METADATA: applyL_hiyix$ // CHECK_HAS_INLINE_METADATA: applyM_hiyix$ -// CHECK_HAS_NO_INLINE_METADATA: applyN_0 +// CHECK_HAS_NO_INLINE_METADATA: applyN_hiyix$ // CHECK_HAS_NO_INLINE_METADATA: applyO_hiyix$ inline diff --git a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/main/main.kt b/js/js.translator/testData/box/multiModule/privateInterfaceNameClash.kt similarity index 77% rename from js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/main/main.kt rename to js/js.translator/testData/box/multiModule/privateInterfaceNameClash.kt index 372c32cabd3..2318bb24c9e 100644 --- a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/main/main.kt +++ b/js/js.translator/testData/box/multiModule/privateInterfaceNameClash.kt @@ -1,3 +1,25 @@ +// MODULE: lib1 +// FILE: lib1.kt +package lib1 + +interface A { + private fun foo() = "A.foo" + + fun bar() = foo() +} + +// MODULE: lib2 +// FILE: lib2.kt +package lib2 + +interface B { + private fun foo() = "B.foo" + + fun bar() = foo() +} + +// MODULE: main(lib1,lib2) +// FILE: main.kt package main import lib1.A diff --git a/js/js.translator/testData/multiModule/cases/privateNameClash/main/main.kt b/js/js.translator/testData/box/multiModule/privateNameClash.kt similarity index 70% rename from js/js.translator/testData/multiModule/cases/privateNameClash/main/main.kt rename to js/js.translator/testData/box/multiModule/privateNameClash.kt index 32507f58bcc..b4cc23089d7 100644 --- a/js/js.translator/testData/multiModule/cases/privateNameClash/main/main.kt +++ b/js/js.translator/testData/box/multiModule/privateNameClash.kt @@ -1,3 +1,25 @@ +// MODULE: lib +// FILE: lib.kt +package lib + +open class A { + private val x = 23 + + fun foo() = x +} + +// MODULE: lib-old +// FILE: lib.kt +package lib + +open class A { + fun foo() = 12 +} + +inline fun check() = true + +// MODULE: main(lib-old) +// FILE: main.kt package main import lib.A @@ -14,10 +36,10 @@ class B : A() { // it won't report false positives eventually. So be patient and just update this test whenever you changed // algorithm of assigning unique identifiers. // Please, check that A.x and B.x have different JS names. -private fun checkJsNames(o: dynamic): Boolean = "x_i8qwny\$_0" in o && "x_dqqnpp\$_0" in o +private fun checkJsNames(o: dynamic): Boolean = "x_i8qwny\$_0" in o && "x_0" in o fun box(): String { - if (!check()) return "check failed: did not compile agains old library" + if (!check()) return "check failed: did not compile against old library" val a = A() if (a.foo() != 23) return "fail1: ${a.foo()}" diff --git a/js/js.translator/testData/box/native/inheritanceFromNativeClass.kt b/js/js.translator/testData/box/native/inheritanceFromNativeClass.kt index a8760a790b2..0084e1c7395 100644 --- a/js/js.translator/testData/box/native/inheritanceFromNativeClass.kt +++ b/js/js.translator/testData/box/native/inheritanceFromNativeClass.kt @@ -14,11 +14,9 @@ internal open class A(val a: Int) { internal class B(val b: Int) : A(b / 2) { override fun foo(i: Int): String = "B.foo($i: Int)" - fun boo(): String = "B.boo()" fun boo(i: String): String = "B.boo($i: String)" fun bar(i: String): String = "B.bar($i: String)" - fun bar(): String = "B.bar()" override fun baz(i: Int): String = "B.baz($i: Int)" fun bar(d: Double): String = "B.bar($d: Double)" } @@ -33,12 +31,10 @@ fun box(): String { if (b.foo(4) != "B.foo(4: Int)") return "b.foo(4) != \"B.foo(4: Int)\", it: ${b.foo(4)}" if (b.boo(434) != "A.boo(434)") return "b.boo(434) != \"A.boo(434)\", it: ${b.boo(434)}" - if (b.boo() != "B.boo()") return "b.boo() != \"B.boo()\", it: ${b.boo()}" if (b.boo("qlfj") != "B.boo(qlfj: String)") return "b.boo(\"qlfj\") != \"B.boo(qlfj: String)\", it: ${b.boo("qlfj")}" if (b.bar("apl") != "B.bar(apl: String)") return "b.bar(\"apl\") != \"B.bar(apl: String)\", it: ${b.bar("apl")}" if (b.baz(34) != "B.baz(34: Int)") return "b.baz(34) != \"B.baz(34: Int)\", it: ${b.baz(34)}" - if (b.bar() != "B.bar()") return "b.bar() != \"B.bar()\", it: ${b.bar()}" if (b.bar(2.213) != "B.bar(2.213: Double)") return "b.bar(2.213) != \"B.bar(2.213: Double)\", it: ${b.bar(2.213)}" val a: A = b diff --git a/js/js.translator/testData/box/native/inheritanceInNativeClass.js b/js/js.translator/testData/box/native/inheritanceInNativeClass.js new file mode 100644 index 00000000000..ac0cb0ed686 --- /dev/null +++ b/js/js.translator/testData/box/native/inheritanceInNativeClass.js @@ -0,0 +1,19 @@ +function createA() { + function ADerived() { + } + ADerived.prototype = Object.create(JS_TESTS.foo.A.prototype); + ADerived.prototype.foo_za3lpa$ = function(n) { + return 24; + }; + return new ADerived(); +} + +function createB() { + function BDerived() { + } + BDerived.prototype = Object.create(JS_TESTS.foo.B.prototype); + BDerived.prototype.bar_za3lpa$ = function(n) { + return this.foo_za3lpa$(n); + }; + return new BDerived(); +} \ No newline at end of file diff --git a/js/js.translator/testData/box/native/inheritanceInNativeClass.kt b/js/js.translator/testData/box/native/inheritanceInNativeClass.kt new file mode 100644 index 00000000000..115f104cca6 --- /dev/null +++ b/js/js.translator/testData/box/native/inheritanceInNativeClass.kt @@ -0,0 +1,27 @@ +package foo + +open class A { + open protected fun foo(n: Int) = 23 + + fun bar(n: Int) = foo(n) + 100 +} + +open class B { + protected fun foo(n: Int) = 42 + + open fun bar(n: Int) = 142 +} + +@native fun createA(): A + +@native fun createB(): B + +fun box(): String { + val a = createA() + if (a.bar(0) != 124) return "fail1: ${a.bar(0)}" + + val b = createB() + if (b.bar(0) != 42) return "fail2: ${b.bar(0)}" + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testData/box/native/passExtLambdaFromNative.js b/js/js.translator/testData/box/native/passExtLambdaFromNative.js index e55c955f4b5..e185f90ebc4 100644 --- a/js/js.translator/testData/box/native/passExtLambdaFromNative.js +++ b/js/js.translator/testData/box/native/passExtLambdaFromNative.js @@ -3,5 +3,5 @@ function A(v) { } function nativeBox(b) { - return b.bar_0(new A("foo"), function(i, s) { return "" + this.v + s + i }) + return b.bar_asnz92$(new A("foo"), function(i, s) { return "" + this.v + s + i }) } diff --git a/js/js.translator/testData/box/native/undefined.kt b/js/js.translator/testData/box/native/undefined.kt index 6802cb4ac4d..c742e9fb3d4 100644 --- a/js/js.translator/testData/box/native/undefined.kt +++ b/js/js.translator/testData/box/native/undefined.kt @@ -14,7 +14,7 @@ fun box(): String { val b: dynamic = object {val bar = ""} assertEquals(b.foo, undefined) - assertNotEquals(b.bar_0, undefined) + assertNotEquals(b.bar, undefined) return "OK" } \ No newline at end of file diff --git a/js/js.translator/testData/box/objectDeclaration/dontPolluteObject.kt b/js/js.translator/testData/box/objectDeclaration/dontPolluteObject.kt index e62446d681a..9349125a2b6 100644 --- a/js/js.translator/testData/box/objectDeclaration/dontPolluteObject.kt +++ b/js/js.translator/testData/box/objectDeclaration/dontPolluteObject.kt @@ -38,8 +38,8 @@ fun box(): String { assertEquals(listOf(), getOwnPropertyNames(emptyObjectExpr)) assertEquals(listOf(), keys(emptyObjectExpr)) - assertEquals(listOf("foo_0", "bar_0"), getOwnPropertyNames(someObjectExpr)) - assertEquals(listOf("foo_0", "bar_0"), keys(someObjectExpr)) + assertEquals(listOf("foo", "bar"), getOwnPropertyNames(someObjectExpr)) + assertEquals(listOf("foo", "bar"), keys(someObjectExpr)) return "OK" } diff --git a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/dependencies.txt b/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/dependencies.txt deleted file mode 100644 index f1f63b4136c..00000000000 --- a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/dependencies.txt +++ /dev/null @@ -1,3 +0,0 @@ -lib1-> -lib2-> -main->lib1,lib2 \ No newline at end of file diff --git a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/lib1/lib1.kt b/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/lib1/lib1.kt deleted file mode 100644 index 0f5a04047f3..00000000000 --- a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/lib1/lib1.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lib1 - -interface A { - private fun foo() = "A.foo" - - fun bar() = foo() -} \ No newline at end of file diff --git a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/lib2/lib2.kt b/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/lib2/lib2.kt deleted file mode 100644 index c6b1bc876dd..00000000000 --- a/js/js.translator/testData/multiModule/cases/privateInterfaceNameClash/lib2/lib2.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lib2 - -interface B { - private fun foo() = "B.foo" - - fun bar() = foo() -} \ No newline at end of file diff --git a/js/js.translator/testData/multiModule/cases/privateNameClash/dependencies.txt b/js/js.translator/testData/multiModule/cases/privateNameClash/dependencies.txt deleted file mode 100644 index 2011488bdff..00000000000 --- a/js/js.translator/testData/multiModule/cases/privateNameClash/dependencies.txt +++ /dev/null @@ -1,3 +0,0 @@ -lib-> -lib-old-> -main->lib-old \ No newline at end of file diff --git a/js/js.translator/testData/multiModule/cases/privateNameClash/lib-old/lib.kt b/js/js.translator/testData/multiModule/cases/privateNameClash/lib-old/lib.kt deleted file mode 100644 index 54969532846..00000000000 --- a/js/js.translator/testData/multiModule/cases/privateNameClash/lib-old/lib.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lib - -open class A { - fun foo() = 12 -} - -inline fun check() = true \ No newline at end of file diff --git a/js/js.translator/testData/multiModule/cases/privateNameClash/lib/lib.kt b/js/js.translator/testData/multiModule/cases/privateNameClash/lib/lib.kt deleted file mode 100644 index 3e338dffd6b..00000000000 --- a/js/js.translator/testData/multiModule/cases/privateNameClash/lib/lib.kt +++ /dev/null @@ -1,7 +0,0 @@ -package lib - -open class A { - private val x = 23 - - fun foo() = x -} \ No newline at end of file