JS: fix absence of temporary variable in secondary constructors. See KT-16377
This commit is contained in:
committed by
Alexey Andreev
parent
3b222f13f3
commit
86d1c7b7ec
@@ -2149,6 +2149,12 @@ public class BoxJsTestGenerated extends AbstractBoxJsTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("secondaryConstructorTemporaryVars.kt")
|
||||||
|
public void testSecondaryConstructorTemporaryVars() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/evaluationOrder/secondaryConstructorTemporaryVars.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("whenAsMinusArgument.kt")
|
@TestMetadata("whenAsMinusArgument.kt")
|
||||||
public void testWhenAsMinusArgument() throws Exception {
|
public void testWhenAsMinusArgument() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/evaluationOrder/whenAsMinusArgument.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("js/js.translator/testData/box/expression/evaluationOrder/whenAsMinusArgument.kt");
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.js.test.utils;
|
package org.jetbrains.kotlin.js.test.utils;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.text.StringUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.js.backend.ast.*;
|
import org.jetbrains.kotlin.js.backend.ast.*;
|
||||||
|
import org.jetbrains.kotlin.js.inline.util.CollectUtilsKt;
|
||||||
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata;
|
import org.jetbrains.kotlin.js.translate.expression.InlineMetadata;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -261,6 +263,28 @@ public class DirectiveTestUtils {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final DirectiveHandler HAS_NO_CAPTURED_VARS = new DirectiveHandler("HAS_NO_CAPTURED_VARS") {
|
||||||
|
@Override
|
||||||
|
void processEntry(@NotNull JsNode ast, @NotNull ArgumentsHelper arguments) throws Exception {
|
||||||
|
String functionName = arguments.getNamedArgument("function");
|
||||||
|
|
||||||
|
Set<String> except = new HashSet<String>();
|
||||||
|
String exceptString = arguments.findNamedArgument("except");
|
||||||
|
if (exceptString != null) {
|
||||||
|
for (String exceptId : StringUtil.split(exceptString, ";")) {
|
||||||
|
except.add(exceptId.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JsFunction function = AstSearchUtil.getFunction(ast, functionName);
|
||||||
|
Set<JsName> freeVars = CollectUtilsKt.collectFreeVariables(function);
|
||||||
|
for (JsName freeVar : freeVars) {
|
||||||
|
assertTrue("Function " + functionName + " captures free variable " + freeVar.getIdent(),
|
||||||
|
except.contains(freeVar.getIdent()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private static final List<DirectiveHandler> DIRECTIVE_HANDLERS = Arrays.asList(
|
private static final List<DirectiveHandler> DIRECTIVE_HANDLERS = Arrays.asList(
|
||||||
FUNCTION_CONTAINS_NO_CALLS,
|
FUNCTION_CONTAINS_NO_CALLS,
|
||||||
FUNCTION_NOT_CALLED,
|
FUNCTION_NOT_CALLED,
|
||||||
@@ -278,7 +302,8 @@ public class DirectiveTestUtils {
|
|||||||
COUNT_NULLS,
|
COUNT_NULLS,
|
||||||
NOT_REFERENCED,
|
NOT_REFERENCED,
|
||||||
HAS_INLINE_METADATA,
|
HAS_INLINE_METADATA,
|
||||||
HAS_NO_INLINE_METADATA
|
HAS_NO_INLINE_METADATA,
|
||||||
|
HAS_NO_CAPTURED_VARS
|
||||||
);
|
);
|
||||||
|
|
||||||
public static void processDirectives(@NotNull JsNode ast, @NotNull String sourceCode) throws Exception {
|
public static void processDirectives(@NotNull JsNode ast, @NotNull String sourceCode) throws Exception {
|
||||||
|
|||||||
+2
-1
@@ -217,13 +217,14 @@ class ClassTranslator private constructor(
|
|||||||
val constructorInitializer = context.getFunctionObject(constructorDescriptor)
|
val constructorInitializer = context.getFunctionObject(constructorDescriptor)
|
||||||
constructorInitializer.name = context.getInnerNameForDescriptor(constructorDescriptor)
|
constructorInitializer.name = context.getInnerNameForDescriptor(constructorDescriptor)
|
||||||
context.addDeclarationStatement(constructorInitializer.makeStmt())
|
context.addDeclarationStatement(constructorInitializer.makeStmt())
|
||||||
|
|
||||||
|
context = context.contextWithScope(constructorInitializer)
|
||||||
context.translateAndAliasParameters(constructorDescriptor, constructorInitializer.parameters)
|
context.translateAndAliasParameters(constructorDescriptor, constructorInitializer.parameters)
|
||||||
.translateFunction(constructor, constructorInitializer)
|
.translateFunction(constructor, constructorInitializer)
|
||||||
|
|
||||||
// Translate super/this call
|
// Translate super/this call
|
||||||
val superCallGenerators = mutableListOf<(MutableList<JsStatement>) -> Unit>()
|
val superCallGenerators = mutableListOf<(MutableList<JsStatement>) -> Unit>()
|
||||||
val referenceToClass = context.getInnerReference(classDescriptor)
|
val referenceToClass = context.getInnerReference(classDescriptor)
|
||||||
context = context.contextWithScope(constructorInitializer)
|
|
||||||
|
|
||||||
superCallGenerators += { it += FunctionBodyTranslator.setDefaultValueForArguments(constructorDescriptor, context) }
|
superCallGenerators += { it += FunctionBodyTranslator.setDefaultValueForArguments(constructorDescriptor, context) }
|
||||||
|
|
||||||
|
|||||||
Vendored
+22
@@ -0,0 +1,22 @@
|
|||||||
|
// HAS_NO_CAPTURED_VARS: function=A_init except=Kotlin;A
|
||||||
|
|
||||||
|
class A() {
|
||||||
|
var y: String? = null
|
||||||
|
var z: Any? = null
|
||||||
|
|
||||||
|
constructor(x: Any) : this() {
|
||||||
|
y = if (x == "foo") "!!!" else { z = x; ">>>" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val a = A("foo")
|
||||||
|
if (a.y != "!!!") return "fail1: ${a.y}"
|
||||||
|
if (a.z != null) return "fail2: ${a.z}"
|
||||||
|
|
||||||
|
val b = A(23)
|
||||||
|
if (b.y != ">>>") return "fail3: ${b.y}"
|
||||||
|
if (b.z != 23) return "fail4: ${b.z}"
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user