[KT-4124] Use generated test to avoid duplication of test data of inner classes. Add support of classes contained within objects.
This commit is contained in:
@@ -1063,6 +1063,9 @@ fun main(args: Array<String>) {
|
||||
model("codegen/box/secondaryConstructors", targetBackend = TargetBackend.JS)
|
||||
}
|
||||
|
||||
testClass<AbstractNestedTypesTest>() {
|
||||
model("codegen/box/classes/inner", targetBackend = TargetBackend.JS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,19 +35,11 @@ public class NestedTypesTest extends SingleFileTranslationTest {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testInstantiateInDerived() throws Exception {
|
||||
public void testOuterCompanion() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testInstantiateInDerivedLabeled() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testInstantiateInSameClass() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
|
||||
public void testProperOuter() throws Exception {
|
||||
public void testOuterObject() throws Exception {
|
||||
checkFooBoxIsOk();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.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/classes/inner")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public class NestedTypesTestGenerated extends AbstractNestedTypesTest {
|
||||
public void testAllFilesPresentInInner() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/classes/inner"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("instantiateInDerived.kt")
|
||||
public void testInstantiateInDerived() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/inner/instantiateInDerived.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("instantiateInDerivedLabeled.kt")
|
||||
public void testInstantiateInDerivedLabeled() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/inner/instantiateInDerivedLabeled.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("instantiateInSameClass.kt")
|
||||
public void testInstantiateInSameClass() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/inner/instantiateInSameClass.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("kt6708.kt")
|
||||
public void testKt6708() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/inner/kt6708.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("properOuter.kt")
|
||||
public void testProperOuter() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/inner/properOuter.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("properSuperLinking.kt")
|
||||
public void testProperSuperLinking() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classes/inner/properSuperLinking.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
+2
@@ -51,3 +51,5 @@ abstract class AbstractInlineMultiModuleTest : MultipleModulesTranslationTest("i
|
||||
abstract class AbstractReservedWordTest : SingleFileTranslationTest("reservedWords/")
|
||||
|
||||
abstract class AbstractSecondaryConstructorTest : AbstractBlackBoxTest("secondaryConstructors/")
|
||||
|
||||
abstract class AbstractNestedTypesTest : AbstractBlackBoxTest("nestedTypes/")
|
||||
|
||||
+30
-4
@@ -60,6 +60,8 @@ public class TranslationContext {
|
||||
private final DeclarationDescriptor declarationDescriptor;
|
||||
@Nullable
|
||||
private final ClassDescriptor classDescriptor;
|
||||
@Nullable
|
||||
private final ClassDescriptor objectDescriptor;
|
||||
|
||||
@NotNull
|
||||
public static TranslationContext rootContext(@NotNull StaticContext staticContext, JsFunction rootFunction) {
|
||||
@@ -90,9 +92,16 @@ public class TranslationContext {
|
||||
&& !DescriptorUtils.isAnonymousObject(declarationDescriptor)
|
||||
&& !DescriptorUtils.isObject(declarationDescriptor)) {
|
||||
this.classDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.classDescriptor = parent != null ? parent.classDescriptor : null;
|
||||
}
|
||||
if (declarationDescriptor instanceof ClassDescriptor && DescriptorUtils.isObject(declarationDescriptor)) {
|
||||
this.objectDescriptor = (ClassDescriptor) declarationDescriptor;
|
||||
}
|
||||
else {
|
||||
this.objectDescriptor = parent != null ? parent.objectDescriptor : null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -126,7 +135,7 @@ public class TranslationContext {
|
||||
DynamicContext dynamicContext = DynamicContext.newContext(fun.getScope(), fun.getBody());
|
||||
UsageTracker usageTracker = new UsageTracker(this.usageTracker, descriptor, fun.getScope());
|
||||
return new TranslationContext(this, this.staticContext, dynamicContext, this.aliasingContext.inner(), usageTracker, this.definitionPlace,
|
||||
this.declarationDescriptor);
|
||||
descriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -341,9 +350,27 @@ public class TranslationContext {
|
||||
if (alias != null) {
|
||||
return alias;
|
||||
}
|
||||
if (DescriptorUtils.isObject(descriptor.getContainingDeclaration())) {
|
||||
if (isConstructorOrDirectScope(descriptor.getContainingDeclaration())) {
|
||||
return JsLiteral.THIS;
|
||||
}
|
||||
else {
|
||||
return getQualifiedReference(descriptor.getContainingDeclaration());
|
||||
}
|
||||
}
|
||||
return getDispatchReceiverPath(getNearestClass(descriptor));
|
||||
}
|
||||
|
||||
private boolean isConstructorOrDirectScope(DeclarationDescriptor descriptor) {
|
||||
if (descriptor == declarationDescriptor) {
|
||||
return true;
|
||||
}
|
||||
if (declarationDescriptor instanceof ConstructorDescriptor) {
|
||||
return descriptor == declarationDescriptor.getContainingDeclaration();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private JsExpression getDispatchReceiverPath(@Nullable ClassDescriptor cls) {
|
||||
if (cls != null) {
|
||||
@@ -396,8 +423,7 @@ public class TranslationContext {
|
||||
private static ClassDescriptor getNearestClass(@Nullable DeclarationDescriptor declaration) {
|
||||
while (declaration != null) {
|
||||
if (declaration instanceof ClassDescriptor) {
|
||||
if (!DescriptorUtils.isAnonymousObject(declaration)
|
||||
&& !DescriptorUtils.isObject(declaration)) {
|
||||
if (!DescriptorUtils.isAnonymousObject(declaration) && !DescriptorUtils.isObject(declaration)) {
|
||||
return (ClassDescriptor) declaration;
|
||||
}
|
||||
}
|
||||
|
||||
+31
-16
@@ -150,20 +150,11 @@ var Kotlin = {};
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {(Array|Object|null)=} bases
|
||||
* @param {(function(new: T, ?, ?, ?, ?, ?, ?, ?): T)|null=} constructor
|
||||
* @param {Object=} properties
|
||||
* @param {Object=} staticProperties
|
||||
* @returns {function(new: T): T}
|
||||
* @template T
|
||||
*/
|
||||
Kotlin.createClassNow = function (bases, constructor, properties, staticProperties) {
|
||||
Kotlin.doCreateClass = function (metadata, constructor) {
|
||||
if (constructor == null) {
|
||||
constructor = emptyFunction();
|
||||
}
|
||||
|
||||
var metadata = computeMetadata(bases, properties, staticProperties);
|
||||
metadata.type = Kotlin.TYPE.CLASS;
|
||||
copyProperties(constructor, metadata.staticMembers);
|
||||
|
||||
@@ -189,6 +180,19 @@ var Kotlin = {};
|
||||
return constructor;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {(Array|Object|null)=} bases
|
||||
* @param {(function(new: T, ?, ?, ?, ?, ?, ?, ?): T)|null=} constructor
|
||||
* @param {Object=} properties
|
||||
* @param {Object=} staticProperties
|
||||
* @returns {function(new: T): T}
|
||||
* @template T
|
||||
*/
|
||||
Kotlin.createClassNow = function (bases, constructor, properties, staticProperties) {
|
||||
var metadata = computeMetadata(bases, properties, staticProperties);
|
||||
return Kotlin.doCreateClass(metadata, constructor);
|
||||
};
|
||||
|
||||
Kotlin.defineInnerTypes = function(constructor, types) {
|
||||
for (var innerTypeName in types) {
|
||||
if (types.hasOwnProperty(innerTypeName)) {
|
||||
@@ -202,11 +206,20 @@ var Kotlin = {};
|
||||
}
|
||||
};
|
||||
|
||||
Kotlin.createObjectNow = function (bases, constructor, functions) {
|
||||
var noNameClass = Kotlin.createClassNow(bases, constructor, functions);
|
||||
Kotlin.createObjectNow = function (bases, constructor, functions, staticProperties) {
|
||||
var metadata = computeMetadata(bases, functions, staticProperties);
|
||||
var noNameClass = Kotlin.doCreateClass(metadata, constructor);
|
||||
var obj = new noNameClass();
|
||||
noNameClass.$metadata$.type = Kotlin.TYPE.OBJECT;
|
||||
return obj;
|
||||
for (var innerTypeName in metadata.types) {
|
||||
if (metadata.types.hasOwnProperty(innerTypeName)) {
|
||||
Object.defineProperty(obj, innerTypeName, {
|
||||
get : metadata.types[innerTypeName],
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
Kotlin.createTraitNow = function (bases, properties, staticProperties) {
|
||||
@@ -243,7 +256,8 @@ var Kotlin = {};
|
||||
*/
|
||||
Kotlin.createClass = function (basesFun, constructor, properties, staticProperties) {
|
||||
function $o() {
|
||||
var klass = Kotlin.createClassNow(getBases(basesFun), constructor, properties, staticProperties);
|
||||
var metadata = computeMetadata(getBases(basesFun), properties, staticProperties);
|
||||
var klass = Kotlin.doCreateClass(metadata, constructor);
|
||||
Object.defineProperty(this, $o.className, {value: klass});
|
||||
return klass;
|
||||
}
|
||||
@@ -313,11 +327,12 @@ var Kotlin = {};
|
||||
* @param {function()|null} basesFun
|
||||
* @param {(function(new: T): T)|null=} constructor
|
||||
* @param {Object=} functions
|
||||
* @param {Object=} staticProperties
|
||||
* @returns {Object}
|
||||
* @template T
|
||||
*/
|
||||
Kotlin.createObject = function (basesFun, constructor, functions) {
|
||||
return Kotlin.createObjectNow(getBases(basesFun), constructor, functions);
|
||||
Kotlin.createObject = function (basesFun, constructor, functions, staticProperties) {
|
||||
return Kotlin.createObjectNow(getBases(basesFun), constructor, functions, staticProperties);
|
||||
};
|
||||
|
||||
Kotlin.callGetter = function (thisObject, klass, propertyName) {
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
package foo
|
||||
|
||||
open class A(val value: String) {
|
||||
inner class B(val s: String) {
|
||||
val result = value + "_" + s
|
||||
}
|
||||
}
|
||||
|
||||
class C : A("fromC") {
|
||||
fun classReceiver() = B("OK")
|
||||
fun superReceiver() = super.B("OK")
|
||||
|
||||
fun newAReceiver() = A("fromA").B("OK")
|
||||
fun aReceiver(): B {
|
||||
val a = A("fromA")
|
||||
return a.B("OK")
|
||||
}
|
||||
|
||||
fun A.extReceiver() = this.B("OK")
|
||||
fun extReceiver() = A("fromA").extReceiver()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val receiver = C()
|
||||
var result = receiver.classReceiver().result
|
||||
if (result != "fromC_OK") return "fail 1: $result"
|
||||
|
||||
result = receiver.superReceiver().result
|
||||
if (result != "fromC_OK") return "fail 2: $result"
|
||||
|
||||
|
||||
result = receiver.aReceiver().result
|
||||
if (result != "fromA_OK") return "fail 3: $result"
|
||||
|
||||
result = receiver.newAReceiver().result
|
||||
if (result != "fromA_OK") return "fail 3: $result"
|
||||
|
||||
result = receiver.extReceiver().result
|
||||
if (result != "fromA_OK") return "fail 3: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package foo
|
||||
|
||||
open class A(val value: String) {
|
||||
inner class B(val s: String) {
|
||||
val result = value + "_" + s
|
||||
}
|
||||
}
|
||||
|
||||
class C : A("fromC") {
|
||||
|
||||
inner class X: A("fromX") {
|
||||
fun classReceiver() = B("OK")
|
||||
fun superReceiver() = super.B("OK")
|
||||
fun superXReceiver() = super@X.B("OK")
|
||||
fun superXCastReceiver() = (this@X as A).B("OK")
|
||||
|
||||
fun superCReceiver() = super@C.B("OK")
|
||||
fun superCCastReceiver() = (this@C as A).B("OK")
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val receiver = C().X()
|
||||
var result = receiver.classReceiver().result
|
||||
if (result != "fromX_OK") return "fail 1: $result"
|
||||
|
||||
result = receiver.superReceiver().result
|
||||
if (result != "fromX_OK") return "fail 2: $result"
|
||||
|
||||
result = receiver.superXReceiver().result
|
||||
if (result != "fromX_OK") return "fail 3: $result"
|
||||
|
||||
result = receiver.superXCastReceiver().result
|
||||
if (result != "fromX_OK") return "fail 4: $result"
|
||||
|
||||
|
||||
result = receiver.superCReceiver().result
|
||||
if (result != "fromC_OK") return "fail 5: $result"
|
||||
|
||||
result = receiver.superCCastReceiver().result
|
||||
if (result != "fromC_OK") return "fail 6: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package foo
|
||||
|
||||
class C(val value: String = "C") {
|
||||
|
||||
inner class B(val s: String) {
|
||||
val result = value + "_" + s
|
||||
}
|
||||
|
||||
fun classReceiver() = B("OK")
|
||||
|
||||
fun newCReceiver() = C("newC").B("OK")
|
||||
fun cReceiver(): B {
|
||||
val c = C("newC")
|
||||
return c.B("OK")
|
||||
}
|
||||
|
||||
fun C.extReceiver1() = this.B("OK")
|
||||
fun extReceiver() = C("newC").extReceiver1()
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val receiver = C()
|
||||
var result = receiver.classReceiver().result
|
||||
if (result != "C_OK") return "fail 1: $result"
|
||||
|
||||
result = receiver.cReceiver().result
|
||||
if (result != "newC_OK") return "fail 3: $result"
|
||||
|
||||
result = receiver.newCReceiver().result
|
||||
if (result != "newC_OK") return "fail 3: $result"
|
||||
|
||||
result = receiver.extReceiver().result
|
||||
if (result != "newC_OK") return "fail 3: $result"
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package foo
|
||||
|
||||
class A {
|
||||
inner class B {
|
||||
val x = foo();
|
||||
}
|
||||
|
||||
class C {
|
||||
val x = foo();
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun foo(): String {
|
||||
return "foo_result";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = A().B().x
|
||||
if (result != "foo_result") {
|
||||
return "fail1_" + result
|
||||
}
|
||||
result = A.C().x
|
||||
if (result != "foo_result") {
|
||||
return "fail2_" + result
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package foo
|
||||
|
||||
val q = "baz"
|
||||
|
||||
object A {
|
||||
val x = "foo"
|
||||
|
||||
class B {
|
||||
val y = x + "_bar"
|
||||
val z = q + "_bar"
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
var result = A.B().y
|
||||
if (result != "foo_bar") {
|
||||
return "failed1_" + result
|
||||
}
|
||||
result = A.B().z
|
||||
if (result != "baz_bar") {
|
||||
return "failed2_" + result
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
package foo
|
||||
|
||||
open class A(val s: String) {
|
||||
open inner class B(val s: String) {
|
||||
fun testB() = s + this@A.s
|
||||
}
|
||||
|
||||
open inner class C(): A("C") {
|
||||
fun testC() =
|
||||
B("B_").testB()
|
||||
}
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val res = A("A").C().testC()
|
||||
return if (res == "B_C") "OK" else res;
|
||||
}
|
||||
Reference in New Issue
Block a user