Dead code elimination
#KT-6602 Fixed #KT-6305 Fixed #KT-5656 Fixed
This commit is contained in:
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.codegen.optimization
|
||||||
|
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.common.OptimizationBasicInterpreter
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||||
|
|
||||||
|
public class DeadCodeEliminationMethodTransformer : MethodTransformer() {
|
||||||
|
override fun transform(internalClassName: String, methodNode: MethodNode) {
|
||||||
|
val frames = MethodTransformer.analyze(internalClassName, methodNode, OptimizationBasicInterpreter())
|
||||||
|
val insnList = methodNode.instructions
|
||||||
|
val insnsArray = insnList.toArray()
|
||||||
|
|
||||||
|
// Do not remove not meaningful nodes (labels/linenumbers) because they can be referred
|
||||||
|
// by try/catch blocks or local variables table
|
||||||
|
// We remove unneeded ones further after all optimizations by calling CommonPackage.prepareForEmitting(methodNode)
|
||||||
|
insnsArray.zip(frames).filter {
|
||||||
|
it.second == null && it.first.isMeaningful
|
||||||
|
}.forEach { insnList.remove(it.first) }
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
-2
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
import org.jetbrains.kotlin.codegen.inline.InlineCodegenUtil;
|
||||||
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantBoxingMethodTransformer;
|
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantBoxingMethodTransformer;
|
||||||
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantNullCheckMethodTransformer;
|
import org.jetbrains.kotlin.codegen.optimization.boxing.RedundantNullCheckMethodTransformer;
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.common.CommonPackage;
|
||||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer;
|
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer;
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes;
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
@@ -35,8 +36,11 @@ import java.util.List;
|
|||||||
public class OptimizationMethodVisitor extends MethodVisitor {
|
public class OptimizationMethodVisitor extends MethodVisitor {
|
||||||
private static final int MEMORY_LIMIT_BY_METHOD_MB = 50;
|
private static final int MEMORY_LIMIT_BY_METHOD_MB = 50;
|
||||||
private static final MethodTransformer[] TRANSFORMERS = new MethodTransformer[]{
|
private static final MethodTransformer[] TRANSFORMERS = new MethodTransformer[]{
|
||||||
new RedundantNullCheckMethodTransformer(), new RedundantBoxingMethodTransformer(),
|
new RedundantNullCheckMethodTransformer(),
|
||||||
new RedundantGotoMethodTransformer(), new StoreStackBeforeInlineMethodTransformer()
|
new RedundantBoxingMethodTransformer(),
|
||||||
|
new DeadCodeEliminationMethodTransformer(),
|
||||||
|
new RedundantGotoMethodTransformer(),
|
||||||
|
new StoreStackBeforeInlineMethodTransformer()
|
||||||
};
|
};
|
||||||
|
|
||||||
private final MethodNode methodNode;
|
private final MethodNode methodNode;
|
||||||
@@ -70,6 +74,7 @@ public class OptimizationMethodVisitor extends MethodVisitor {
|
|||||||
for (MethodTransformer transformer : TRANSFORMERS) {
|
for (MethodTransformer transformer : TRANSFORMERS) {
|
||||||
transformer.transform("fake", methodNode);
|
transformer.transform("fake", methodNode);
|
||||||
}
|
}
|
||||||
|
CommonPackage.prepareForEmitting(methodNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
methodNode.accept(new EndIgnoringMethodVisitorDecorator(Opcodes.ASM5, delegate));
|
methodNode.accept(new EndIgnoringMethodVisitorDecorator(Opcodes.ASM5, delegate));
|
||||||
|
|||||||
+1
-6
@@ -22,6 +22,7 @@ import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
|||||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.JumpInsnNode
|
||||||
|
import org.jetbrains.kotlin.codegen.optimization.common.isMeaningful
|
||||||
|
|
||||||
public class RedundantGotoMethodTransformer : MethodTransformer() {
|
public class RedundantGotoMethodTransformer : MethodTransformer() {
|
||||||
/**
|
/**
|
||||||
@@ -53,9 +54,3 @@ public class RedundantGotoMethodTransformer : MethodTransformer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val AbstractInsnNode.isMeaningful : Boolean get() =
|
|
||||||
when (this.getType()) {
|
|
||||||
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME -> false
|
|
||||||
else -> true
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,71 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2014 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.codegen.optimization.common
|
||||||
|
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||||
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
|
val AbstractInsnNode.isMeaningful : Boolean get() =
|
||||||
|
when (this.getType()) {
|
||||||
|
AbstractInsnNode.LABEL, AbstractInsnNode.LINE, AbstractInsnNode.FRAME -> false
|
||||||
|
else -> true
|
||||||
|
}
|
||||||
|
|
||||||
|
class InsnStream(val from: AbstractInsnNode, val to: AbstractInsnNode?) : Stream<AbstractInsnNode> {
|
||||||
|
override fun iterator(): Iterator<AbstractInsnNode> {
|
||||||
|
return object : Iterator<AbstractInsnNode> {
|
||||||
|
var current = from
|
||||||
|
override fun next(): AbstractInsnNode {
|
||||||
|
val result = current
|
||||||
|
current = current.getNext()
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
override fun hasNext() = current != to
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun MethodNode.prepareForEmitting() {
|
||||||
|
tryCatchBlocks = tryCatchBlocks.filter { tcb ->
|
||||||
|
InsnStream(tcb.start, tcb.end).any { insn ->
|
||||||
|
insn.isMeaningful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// local variables with live ranges starting after last meaningful instruction lead to VerifyError
|
||||||
|
localVariables = localVariables.filter { lv ->
|
||||||
|
InsnStream(lv.start, instructions.getLast()).any { insn ->
|
||||||
|
insn.isMeaningful
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We should remove linenumbers after last meaningful instruction
|
||||||
|
// because they point to index of non-existing instruction and it leads to VerifyError
|
||||||
|
var current = instructions.getLast()
|
||||||
|
while (!current.isMeaningful) {
|
||||||
|
val prev = current.getPrevious()
|
||||||
|
|
||||||
|
if (current.getType() == AbstractInsnNode.LINE) {
|
||||||
|
instructions.remove(current)
|
||||||
|
}
|
||||||
|
|
||||||
|
current = prev
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun foo(): Int {
|
||||||
|
return 1
|
||||||
|
// val xyz has empty live range because everything after return will be removed as dead
|
||||||
|
val xyz = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(1, foo())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
fun foo(x: Any?) {}
|
||||||
|
|
||||||
|
fun box() {
|
||||||
|
val x: Int? = 1
|
||||||
|
x!!
|
||||||
|
|
||||||
|
val z: Int? = if (1 == 1) x else null
|
||||||
|
z!!
|
||||||
|
|
||||||
|
foo(1 as java.lang.Integer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 IFNULL
|
||||||
|
// 1 IFNONNULL
|
||||||
|
// 1 throwNpe
|
||||||
|
// 0 ATHROW
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun foo() {
|
||||||
|
return
|
||||||
|
// val xyz has empty live range because everything after return will be removed as dead
|
||||||
|
val xyz = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 0 xyz
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
fun foo(value: Boolean): Int {
|
||||||
|
if (value)
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(1, foo(true))
|
||||||
|
assertEquals(2, foo(false))
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
3 return's are defined in functions
|
||||||
|
2 are from package facade
|
||||||
|
1 is from package clinit
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 6 RETURN
|
||||||
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeText")
|
@TestMetadata("compiler/testData/codegen/bytecodeText")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@InnerTestClasses({BytecodeTextTestGenerated.BoxingOptimization.class, BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Inline.class, BytecodeTextTestGenerated.LazyCodegen.class, BytecodeTextTestGenerated.LineNumbers.class, BytecodeTextTestGenerated.Statements.class, BytecodeTextTestGenerated.StaticFields.class, BytecodeTextTestGenerated.StoreStackBeforeInline.class, BytecodeTextTestGenerated.When.class, BytecodeTextTestGenerated.WhenEnumOptimization.class, BytecodeTextTestGenerated.WhenStringOptimization.class})
|
@InnerTestClasses({BytecodeTextTestGenerated.BoxingOptimization.class, BytecodeTextTestGenerated.Constants.class, BytecodeTextTestGenerated.DeadCodeElimination.class, BytecodeTextTestGenerated.DirectInvoke.class, BytecodeTextTestGenerated.Inline.class, BytecodeTextTestGenerated.LazyCodegen.class, BytecodeTextTestGenerated.LineNumbers.class, BytecodeTextTestGenerated.Statements.class, BytecodeTextTestGenerated.StaticFields.class, BytecodeTextTestGenerated.StoreStackBeforeInline.class, BytecodeTextTestGenerated.When.class, BytecodeTextTestGenerated.WhenEnumOptimization.class, BytecodeTextTestGenerated.WhenStringOptimization.class})
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||||
@TestMetadata("accessorForProtected.kt")
|
@TestMetadata("accessorForProtected.kt")
|
||||||
@@ -301,6 +301,33 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class DeadCodeElimination extends AbstractBytecodeTextTest {
|
||||||
|
public void testAllFilesPresentInDeadCodeElimination() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/deadCodeElimination"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("boxing.kt")
|
||||||
|
public void testBoxing() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination/boxing.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("emptyVariableRange.kt")
|
||||||
|
public void testEmptyVariableRange() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination/emptyVariableRange.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lastReturn.kt")
|
||||||
|
public void testLastReturn() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/deadCodeElimination/lastReturn.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/bytecodeText/directInvoke")
|
@TestMetadata("compiler/testData/codegen/bytecodeText/directInvoke")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
+16
-1
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
|||||||
@SuppressWarnings("all")
|
@SuppressWarnings("all")
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.Classes.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.LazyCodegen.class, BlackBoxWithStdlibCodegenTestGenerated.LocalFunInLambda.class, BlackBoxWithStdlibCodegenTestGenerated.MultiDeclForArray.class, BlackBoxWithStdlibCodegenTestGenerated.Native.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class})
|
@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, BlackBoxWithStdlibCodegenTestGenerated.Arrays.class, BlackBoxWithStdlibCodegenTestGenerated.BoxingOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.CallableReference.class, BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.Classes.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.DeadCodeElimination.class, BlackBoxWithStdlibCodegenTestGenerated.DefaultArguments.class, BlackBoxWithStdlibCodegenTestGenerated.Enum.class, BlackBoxWithStdlibCodegenTestGenerated.Evaluate.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.HashPMap.class, BlackBoxWithStdlibCodegenTestGenerated.Intrinsics.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.LazyCodegen.class, BlackBoxWithStdlibCodegenTestGenerated.LocalFunInLambda.class, BlackBoxWithStdlibCodegenTestGenerated.MultiDeclForArray.class, BlackBoxWithStdlibCodegenTestGenerated.Native.class, BlackBoxWithStdlibCodegenTestGenerated.NonLocalReturns.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformNames.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformStatic.class, BlackBoxWithStdlibCodegenTestGenerated.PlatformTypes.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Reflection.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Reified.class, BlackBoxWithStdlibCodegenTestGenerated.StoreStackBeforeInline.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class, BlackBoxWithStdlibCodegenTestGenerated.ToArray.class, BlackBoxWithStdlibCodegenTestGenerated.Vararg.class, BlackBoxWithStdlibCodegenTestGenerated.When.class, BlackBoxWithStdlibCodegenTestGenerated.WhenEnumOptimization.class, BlackBoxWithStdlibCodegenTestGenerated.WhenStringOptimization.class})
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||||
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
|
public void testAllFilesPresentInBoxWithStdlib() throws Exception {
|
||||||
@@ -1186,6 +1186,21 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/deadCodeElimination")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class DeadCodeElimination extends AbstractBlackBoxCodegenTest {
|
||||||
|
public void testAllFilesPresentInDeadCodeElimination() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/deadCodeElimination"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("emptyVariableRange.kt")
|
||||||
|
public void testEmptyVariableRange() throws Exception {
|
||||||
|
String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/deadCodeElimination/emptyVariableRange.kt");
|
||||||
|
doTestWithStdlib(fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/boxWithStdlib/defaultArguments")
|
@TestMetadata("compiler/testData/codegen/boxWithStdlib/defaultArguments")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@InnerTestClasses({DefaultArguments.Constructor.class})
|
@InnerTestClasses({DefaultArguments.Constructor.class})
|
||||||
|
|||||||
Reference in New Issue
Block a user