Reformat and cleanup most JVM codegen test classes
This commit is contained in:
+3
-3
@@ -33,9 +33,9 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {
|
||||
|
||||
@Override
|
||||
protected void doMultiFileTest(
|
||||
@NotNull File wholeFile,
|
||||
@NotNull List<TestFile> files,
|
||||
@Nullable File javaFilesDir
|
||||
@NotNull File wholeFile,
|
||||
@NotNull List<TestFile> files,
|
||||
@Nullable File javaFilesDir
|
||||
) throws Exception {
|
||||
boolean isIgnored = IGNORE_EXPECTED_FAILURES && InTextDirectivesUtils.isIgnoredTarget(getBackend(), wholeFile);
|
||||
|
||||
|
||||
+1
-2
@@ -24,8 +24,7 @@ abstract class AbstractBlackBoxInlineCodegenTest : AbstractBlackBoxCodegenTest()
|
||||
try {
|
||||
InlineTestUtil.checkNoCallsToInline(initializedClassLoader.allGeneratedFiles.filterClassFiles(), myFiles.psiFiles)
|
||||
SMAPTestUtil.checkSMAP(files, generateClassesInFile().getClassFiles(), false)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
} catch (e: Throwable) {
|
||||
println(generateToText())
|
||||
throw e
|
||||
}
|
||||
|
||||
+4
-17
@@ -34,7 +34,7 @@ abstract class AbstractBytecodeListingTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
private fun isWithSignatures(wholeFile: File): Boolean =
|
||||
WITH_SIGNATURES.containsMatchIn(wholeFile.readText())
|
||||
WITH_SIGNATURES.containsMatchIn(wholeFile.readText())
|
||||
|
||||
companion object {
|
||||
private val WITH_SIGNATURES = Regex.fromLiteral("// WITH_SIGNATURES")
|
||||
@@ -132,13 +132,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
}
|
||||
}.toString()
|
||||
|
||||
override fun visitMethod(
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String,
|
||||
signature: String?,
|
||||
exceptions: Array<out String>?
|
||||
): MethodVisitor? {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor? {
|
||||
if (!filter.shouldWriteMethod(access, name, desc)) {
|
||||
return null
|
||||
}
|
||||
@@ -176,7 +170,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
}.joinToString()
|
||||
val signatureIfRequired = if (withSignatures) "<$signature> " else ""
|
||||
declarationsInsideClass.add(
|
||||
Declaration("${signatureIfRequired}method $name($parameterWithAnnotations): $returnType", methodAnnotations)
|
||||
Declaration("${signatureIfRequired}method $name($parameterWithAnnotations): $returnType", methodAnnotations)
|
||||
)
|
||||
super.visitEnd()
|
||||
}
|
||||
@@ -218,14 +212,7 @@ class BytecodeListingTextCollectingVisitor(val filter: Filter, val withSignature
|
||||
return super.visitAnnotation(desc, visible)
|
||||
}
|
||||
|
||||
override fun visit(
|
||||
version: Int,
|
||||
access: Int,
|
||||
name: String,
|
||||
signature: String?,
|
||||
superName: String?,
|
||||
interfaces: Array<out String>?
|
||||
) {
|
||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String?, interfaces: Array<out String>?) {
|
||||
className = name
|
||||
classAccess = access
|
||||
classSignature = signature
|
||||
|
||||
+19
-27
@@ -5,12 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import com.intellij.openapi.util.io.FileUtil
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind
|
||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
import org.jetbrains.kotlin.utils.rethrow
|
||||
import org.junit.Assert
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
@@ -18,24 +16,25 @@ import java.util.regex.Matcher
|
||||
import java.util.regex.Pattern
|
||||
|
||||
abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||
|
||||
@Throws(Exception::class)
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<CodegenTestCase.TestFile>, javaFilesDir: File?) {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.ALL, files, TestJdkKind.MOCK_JDK, javaFilesDir)
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(
|
||||
ConfigurationKind.ALL,
|
||||
files,
|
||||
TestJdkKind.MOCK_JDK,
|
||||
*listOfNotNull(javaFilesDir).toTypedArray()
|
||||
)
|
||||
loadMultiFiles(files)
|
||||
|
||||
if (isMultiFileTest(files) && !InTextDirectivesUtils.isDirectiveDefined(wholeFile.readText(), "TREAT_AS_ONE_FILE")) {
|
||||
doTestMultiFile(files)
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
val expected = readExpectedOccurrences(wholeFile.path)
|
||||
val actual = generateToText("helpers/")
|
||||
checkGeneratedTextAgainstExpectedOccurrences(actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
private fun doTestMultiFile(files: List<CodegenTestCase.TestFile>) {
|
||||
private fun doTestMultiFile(files: List<TestFile>) {
|
||||
val expectedOccurrencesByOutputFile = LinkedHashMap<String, List<OccurrenceInfo>>()
|
||||
for (file in files) {
|
||||
readExpectedOccurrencesForMultiFileTest(file, expectedOccurrencesByOutputFile)
|
||||
@@ -50,10 +49,9 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(Exception::class)
|
||||
protected fun readExpectedOccurrences(filename: String): List<OccurrenceInfo> {
|
||||
val result = ArrayList<OccurrenceInfo>()
|
||||
val lines = FileUtil.loadFile(File(filename), Charsets.UTF_8.name(), true).split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
val lines = File(filename).readLines().dropLastWhile(String::isEmpty)
|
||||
|
||||
for (line in lines) {
|
||||
val matcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
|
||||
@@ -80,7 +78,7 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||
private val AT_OUTPUT_FILE_PATTERN = Pattern.compile("^\\s*//\\s*@(.*):$")
|
||||
private val EXPECTED_OCCURRENCES_PATTERN = Pattern.compile("^\\s*//\\s*(\\d+)\\s*(.*)$")
|
||||
|
||||
private fun isMultiFileTest(files: List<CodegenTestCase.TestFile>): Boolean {
|
||||
private fun isMultiFileTest(files: List<TestFile>): Boolean {
|
||||
var kotlinFiles = 0
|
||||
for (file in files) {
|
||||
if (file.name.endsWith(".kt")) {
|
||||
@@ -90,8 +88,7 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||
return kotlinFiles > 1
|
||||
}
|
||||
|
||||
fun checkGeneratedTextAgainstExpectedOccurrences(text: String,
|
||||
expectedOccurrences: List<OccurrenceInfo>) {
|
||||
fun checkGeneratedTextAgainstExpectedOccurrences(text: String, expectedOccurrences: List<OccurrenceInfo>) {
|
||||
val expected = StringBuilder()
|
||||
val actual = StringBuilder()
|
||||
|
||||
@@ -102,10 +99,9 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||
|
||||
try {
|
||||
Assert.assertEquals(text, expected.toString(), actual.toString())
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
} catch (e: Throwable) {
|
||||
println(text)
|
||||
throw rethrow(e)
|
||||
throw e
|
||||
}
|
||||
|
||||
}
|
||||
@@ -121,27 +117,23 @@ abstract class AbstractBytecodeTextTest : CodegenTestCase() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun readExpectedOccurrencesForMultiFileTest(
|
||||
file: CodegenTestCase.TestFile,
|
||||
occurrenceMap: MutableMap<String, List<OccurrenceInfo>>) {
|
||||
private fun readExpectedOccurrencesForMultiFileTest(file: TestFile, occurrenceMap: MutableMap<String, List<OccurrenceInfo>>) {
|
||||
var currentOccurrenceInfos: MutableList<OccurrenceInfo>? = null
|
||||
for (line in file.content.split("\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()) {
|
||||
val atOutputFileMatcher = AT_OUTPUT_FILE_PATTERN.matcher(line)
|
||||
if (atOutputFileMatcher.matches()) {
|
||||
val outputFileName = atOutputFileMatcher.group(1)
|
||||
if (occurrenceMap.containsKey(outputFileName)) {
|
||||
throw AssertionError(
|
||||
file.name + ": Expected occurrences for output file " + outputFileName + " were already provided")
|
||||
throw AssertionError("${file.name}: Expected occurrences for output file $outputFileName were already provided")
|
||||
}
|
||||
currentOccurrenceInfos = ArrayList<OccurrenceInfo>()
|
||||
occurrenceMap.put(outputFileName, currentOccurrenceInfos)
|
||||
currentOccurrenceInfos = ArrayList()
|
||||
occurrenceMap[outputFileName] = currentOccurrenceInfos
|
||||
}
|
||||
|
||||
val expectedOccurrencesMatcher = EXPECTED_OCCURRENCES_PATTERN.matcher(line)
|
||||
if (expectedOccurrencesMatcher.matches()) {
|
||||
if (currentOccurrenceInfos == null) {
|
||||
throw AssertionError(
|
||||
file.name + ": Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations")
|
||||
throw AssertionError("${file.name}: Should specify output file with '// @<OUTPUT_FILE_NAME>:' before expectations")
|
||||
}
|
||||
val occurrenceInfo = parseOccurrenceInfo(expectedOccurrencesMatcher)
|
||||
currentOccurrenceInfos.add(occurrenceInfo)
|
||||
|
||||
+1
-2
@@ -26,8 +26,7 @@ abstract class AbstractCompileKotlinAgainstInlineKotlinTest : AbstractCompileKot
|
||||
val sourceFiles = factory1.inputFiles + factory2.inputFiles
|
||||
InlineTestUtil.checkNoCallsToInline(allGeneratedFiles.filterClassFiles(), sourceFiles)
|
||||
SMAPTestUtil.checkSMAP(files, allGeneratedFiles.filterClassFiles(), true)
|
||||
}
|
||||
catch (e: Throwable) {
|
||||
} catch (e: Throwable) {
|
||||
println("FIRST:\n\n${factory1.createText()}\n\nSECOND:\n\n${factory2.createText()}")
|
||||
throw e
|
||||
}
|
||||
|
||||
+2
-2
@@ -49,13 +49,13 @@ public abstract class AbstractCompileKotlinAgainstKotlinTest extends CodegenTest
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) throws Exception {
|
||||
protected void doMultiFileTest(@NotNull File wholeFile, @NotNull List<TestFile> files, @Nullable File javaFilesDir) {
|
||||
assert javaFilesDir == null : ".java files are not supported yet in this test";
|
||||
doTwoFileTest(files);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Pair<ClassFileFactory, ClassFileFactory> doTwoFileTest(@NotNull List<TestFile> files) throws Exception {
|
||||
protected Pair<ClassFileFactory, ClassFileFactory> doTwoFileTest(@NotNull List<TestFile> files) {
|
||||
// Note that it may be beneficial to improve this test to handle many files, compiling them successively against all previous
|
||||
assert files.size() == 2 || (files.size() == 3 && files.get(2).name.equals("CoroutineUtil.kt")) : "There should be exactly two files in this test";
|
||||
TestFile fileA = files.get(0);
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ abstract class AbstractDumpDeclarationsTest : CodegenTestCase() {
|
||||
|
||||
override fun doMultiFileTest(wholeFile: File, files: List<TestFile>, javaFilesDir: File?) {
|
||||
val expectedResult = KotlinTestUtils.replaceExtension(wholeFile, "json")
|
||||
dumpToFile = KotlinTestUtils.tmpDirForTest(this).resolve(name + ".json")
|
||||
dumpToFile = KotlinTestUtils.tmpDirForTest(this).resolve("$name.json")
|
||||
compile(files, null)
|
||||
classFileFactory.generationState.destroy()
|
||||
KotlinTestUtils.assertEqualsToFile(expectedResult, dumpToFile.readText()) {
|
||||
|
||||
+6
-6
@@ -34,10 +34,10 @@ abstract class AbstractLightAnalysisModeTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
val fullTxt = compileWithFullAnalysis(files, javaFilesDir)
|
||||
.replace("final enum class", "enum class")
|
||||
.replace("final enum class", "enum class")
|
||||
|
||||
val liteTxt = compileWithLightAnalysis(wholeFile, files, javaFilesDir)
|
||||
.replace("@synthetic.kotlin.jvm.GeneratedByJvmOverloads ", "")
|
||||
.replace("@synthetic.kotlin.jvm.GeneratedByJvmOverloads ", "")
|
||||
|
||||
assertEquals(fullTxt, liteTxt)
|
||||
}
|
||||
@@ -53,7 +53,7 @@ abstract class AbstractLightAnalysisModeTest : CodegenTestCase() {
|
||||
assert(!relativePath.startsWith(".."))
|
||||
|
||||
val configuration = createConfiguration(
|
||||
configurationKind, getJdkKind(files), listOf(getAnnotationsJar()), javaFilesDir?.let(::listOf).orEmpty(), files
|
||||
configurationKind, getJdkKind(files), listOf(getAnnotationsJar()), javaFilesDir?.let(::listOf).orEmpty(), files
|
||||
)
|
||||
val environment = KotlinCoreEnvironment.createForTests(testRootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
AnalysisHandlerExtension.registerExtension(environment.project, PartialAnalysisHandlerExtension())
|
||||
@@ -65,14 +65,14 @@ abstract class AbstractLightAnalysisModeTest : CodegenTestCase() {
|
||||
}
|
||||
|
||||
protected fun compileWithFullAnalysis(
|
||||
files: List<TestFile>,
|
||||
javaSourceDir: File?
|
||||
files: List<TestFile>,
|
||||
javaSourceDir: File?
|
||||
): String {
|
||||
compile(files, javaSourceDir)
|
||||
classFileFactory.getClassFiles()
|
||||
|
||||
val classInternalNames = classFileFactory.generationState.bindingContext
|
||||
.getSliceContents(CodegenBinding.ASM_TYPE).map { it.value.internalName to it.key }.toMap()
|
||||
.getSliceContents(CodegenBinding.ASM_TYPE).map { it.value.internalName to it.key }.toMap()
|
||||
|
||||
return BytecodeListingTextCollectingVisitor.getText(classFileFactory, object : ListAnalysisFilter() {
|
||||
override fun shouldWriteClass(access: Int, name: String): Boolean {
|
||||
|
||||
@@ -29,7 +29,7 @@ import kotlin.collections.ArrayList
|
||||
abstract class AbstractLineNumberTest : CodegenTestCase() {
|
||||
|
||||
override fun doMultiFileTest(
|
||||
wholeFile: File, files: MutableList<CodegenTestCase.TestFile>, javaFilesDir: File?
|
||||
wholeFile: File, files: MutableList<TestFile>, javaFilesDir: File?
|
||||
) {
|
||||
val isCustomTest = wholeFile.parentFile.name.equals("custom", ignoreCase = true)
|
||||
if (!isCustomTest) {
|
||||
@@ -159,7 +159,7 @@ abstract class AbstractLineNumberTest : CodegenTestCase() {
|
||||
private val TEST_LINE_NUMBER_PATTERN = Pattern.compile("^.*test.$LINE_NUMBER_FUN\\(\\).*$")
|
||||
|
||||
private fun createLineNumberDeclaration() =
|
||||
CodegenTestCase.TestFile(
|
||||
TestFile(
|
||||
"$LINE_NUMBER_FUN.kt",
|
||||
"package test;\n\npublic fun $LINE_NUMBER_FUN(): Int = 0\n"
|
||||
)
|
||||
|
||||
-3
@@ -21,13 +21,10 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.test.ConfigurationKind;
|
||||
import org.jetbrains.kotlin.test.TestJdkKind;
|
||||
import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.kotlin.script.ScriptTestUtilKt.loadScriptingPlugin;
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@ import org.jetbrains.org.objectweb.asm.util.TraceMethodVisitor;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -82,7 +81,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
private static final String DEFAULT_TEST_FILE_NAME = "a_test";
|
||||
private static final String DEFAULT_JVM_TARGET_FOR_TEST = "kotlin.test.default.jvm.target";
|
||||
private static final String JAVA_COMPILATION_TARGET = "kotlin.test.java.compilation.target";
|
||||
public static final String RUN_BOX_TEST_IN_SEPARATE_PROCESS_PORT = "kotlin.test.box.in.separate.process.port";
|
||||
private static final String RUN_BOX_TEST_IN_SEPARATE_PROCESS_PORT = "kotlin.test.box.in.separate.process.port";
|
||||
|
||||
protected KotlinCoreEnvironment myEnvironment;
|
||||
protected CodegenTestFiles myFiles;
|
||||
@@ -90,7 +89,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
protected GeneratedClassLoader initializedClassLoader;
|
||||
protected File javaClassesOutputDirectory = null;
|
||||
protected List<File> additionalDependencies = null;
|
||||
protected String coroutinesPackage;
|
||||
protected String coroutinesPackage = "";
|
||||
|
||||
protected ConfigurationKind configurationKind = ConfigurationKind.JDK_ONLY;
|
||||
private final String defaultJvmTarget = System.getProperty(DEFAULT_JVM_TARGET_FOR_TEST);
|
||||
@@ -99,7 +98,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
|
||||
protected final void createEnvironmentWithMockJdkAndIdeaAnnotations(
|
||||
@NotNull ConfigurationKind configurationKind,
|
||||
@Nullable File... javaSourceRoots
|
||||
@NotNull File... javaSourceRoots
|
||||
) {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(configurationKind, Collections.emptyList(), TestJdkKind.MOCK_JDK, javaSourceRoots);
|
||||
}
|
||||
@@ -118,7 +117,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
@NotNull ConfigurationKind configurationKind,
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull TestJdkKind testJdkKind,
|
||||
@Nullable File... javaSourceRoots
|
||||
@NotNull File... javaSourceRoots
|
||||
) {
|
||||
if (myEnvironment != null) {
|
||||
throw new IllegalStateException("must not set up myEnvironment twice");
|
||||
@@ -161,7 +160,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
updateConfigurationByDirectivesInTestFiles(testFilesWithConfigurationDirectives, configuration, "");
|
||||
}
|
||||
|
||||
protected static void updateConfigurationByDirectivesInTestFiles(
|
||||
private static void updateConfigurationByDirectivesInTestFiles(
|
||||
@NotNull List<TestFile> testFilesWithConfigurationDirectives,
|
||||
@NotNull CompilerConfiguration configuration,
|
||||
@NotNull String coroutinesPackage
|
||||
@@ -306,12 +305,6 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
coroutinesPackage = "";
|
||||
super.setUp();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
myFiles = null;
|
||||
@@ -343,7 +336,8 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
assert myFiles == null : "Should not initialize myFiles twice";
|
||||
myFiles = CodegenTestFiles.create(file.getName(), content, myEnvironment.getProject());
|
||||
return content;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
@@ -512,44 +506,46 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected ClassFileFactory generateClassesInFile(boolean reportProblems) {
|
||||
if (classFileFactory == null) {
|
||||
try {
|
||||
GenerationState generationState = GenerationUtils.compileFiles(
|
||||
myFiles.getPsiFiles(), myEnvironment, getClassBuilderFactory(),
|
||||
new NoScopeRecordCliBindingTrace()
|
||||
);
|
||||
classFileFactory = generationState.getFactory();
|
||||
private ClassFileFactory generateClassesInFile(boolean reportProblems) {
|
||||
if (classFileFactory != null) return classFileFactory;
|
||||
|
||||
if (verifyWithDex() && DxChecker.RUN_DX_CHECKER) {
|
||||
DxChecker.check(classFileFactory);
|
||||
}
|
||||
try {
|
||||
GenerationState generationState = GenerationUtils.compileFiles(
|
||||
myFiles.getPsiFiles(), myEnvironment, getClassBuilderFactory(),
|
||||
new NoScopeRecordCliBindingTrace()
|
||||
);
|
||||
classFileFactory = generationState.getFactory();
|
||||
|
||||
if (verifyWithDex() && DxChecker.RUN_DX_CHECKER) {
|
||||
DxChecker.check(classFileFactory);
|
||||
}
|
||||
catch (TestsCompiletimeError e) {
|
||||
if (reportProblems) {
|
||||
e.getOriginal().printStackTrace();
|
||||
System.err.println("Generating instructions as text...");
|
||||
try {
|
||||
if (classFileFactory == null) {
|
||||
System.err.println("Cannot generate text: exception was thrown during generation");
|
||||
}
|
||||
else {
|
||||
System.err.println(classFileFactory.createText());
|
||||
}
|
||||
}
|
||||
catch (TestsCompiletimeError e) {
|
||||
if (reportProblems) {
|
||||
e.getOriginal().printStackTrace();
|
||||
System.err.println("Generating instructions as text...");
|
||||
try {
|
||||
if (classFileFactory == null) {
|
||||
System.err.println("Cannot generate text: exception was thrown during generation");
|
||||
}
|
||||
catch (Throwable e1) {
|
||||
System.err.println("Exception thrown while trying to generate text, the actual exception follows:");
|
||||
e1.printStackTrace();
|
||||
System.err.println("-----------------------------------------------------------------------------");
|
||||
else {
|
||||
System.err.println(classFileFactory.createText());
|
||||
}
|
||||
System.err.println("See exceptions above");
|
||||
} else {
|
||||
System.err.println("Compilation failure");
|
||||
}
|
||||
throw e;
|
||||
} catch (Throwable e) {
|
||||
throw new TestsCompilerError(e);
|
||||
catch (Throwable e1) {
|
||||
System.err.println("Exception thrown while trying to generate text, the actual exception follows:");
|
||||
e1.printStackTrace();
|
||||
System.err.println("-----------------------------------------------------------------------------");
|
||||
}
|
||||
System.err.println("See exceptions above");
|
||||
}
|
||||
else {
|
||||
System.err.println("Compilation failure");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
throw new TestsCompilerError(e);
|
||||
}
|
||||
return classFileFactory;
|
||||
}
|
||||
@@ -558,7 +554,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static boolean verifyAllFilesWithAsm(ClassFileFactory factory, ClassLoader loader, boolean reportProblems) {
|
||||
private static boolean verifyAllFilesWithAsm(ClassFileFactory factory, ClassLoader loader, boolean reportProblems) {
|
||||
boolean noErrors = true;
|
||||
for (OutputFile file : ClassFileUtilsKt.getClassFiles(factory)) {
|
||||
noErrors &= verifyWithAsm(file, loader, reportProblems);
|
||||
@@ -607,7 +603,8 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
Class<?> aClass = generateFacadeClass();
|
||||
try {
|
||||
return findTheOnlyMethod(aClass);
|
||||
} catch (Error e) {
|
||||
}
|
||||
catch (Error e) {
|
||||
System.out.println(generateToText());
|
||||
throw e;
|
||||
}
|
||||
@@ -618,22 +615,11 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
return findDeclaredMethodByName(generateFacadeClass(), name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings("unchecked")
|
||||
public Class<? extends Annotation> loadAnnotationClassQuietly(@NotNull String fqName) {
|
||||
try {
|
||||
return (Class<? extends Annotation>) initializedClassLoader.loadClass(fqName);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw ExceptionUtilsKt.rethrow(e);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateConfiguration(@NotNull CompilerConfiguration configuration) {
|
||||
|
||||
}
|
||||
|
||||
protected ClassBuilderFactory getClassBuilderFactory(){
|
||||
protected ClassBuilderFactory getClassBuilderFactory() {
|
||||
return ClassBuilderFactories.TEST;
|
||||
}
|
||||
|
||||
@@ -641,7 +627,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
|
||||
}
|
||||
|
||||
protected void setCustomDefaultJvmTarget(CompilerConfiguration configuration) {
|
||||
private void setCustomDefaultJvmTarget(CompilerConfiguration configuration) {
|
||||
JvmTarget target = configuration.get(JVMConfigurationKeys.JVM_TARGET);
|
||||
if (target == null && defaultJvmTarget != null) {
|
||||
JvmTarget value = JvmTarget.fromString(defaultJvmTarget);
|
||||
@@ -663,8 +649,8 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
boolean reportProblems
|
||||
) {
|
||||
configurationKind = extractConfigurationKind(files);
|
||||
boolean loadAndroidAnnotations = files.stream().anyMatch(it ->
|
||||
InTextDirectivesUtils.isDirectiveDefined(it.content, "ANDROID_ANNOTATIONS")
|
||||
boolean loadAndroidAnnotations = files.stream().anyMatch(
|
||||
it -> InTextDirectivesUtils.isDirectiveDefined(it.content, "ANDROID_ANNOTATIONS")
|
||||
);
|
||||
|
||||
List<String> javacOptions = extractJavacOptions(files);
|
||||
@@ -744,7 +730,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
return javacOptions;
|
||||
}
|
||||
|
||||
protected void updateJavacOptions(List<String> javacOptions) {
|
||||
private void updateJavacOptions(List<String> javacOptions) {
|
||||
if (javaCompilationTarget != null && !javacOptions.contains("-target")) {
|
||||
javacOptions.add("-source");
|
||||
javacOptions.add(javaCompilationTarget);
|
||||
@@ -832,9 +818,9 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
}
|
||||
|
||||
protected void doMultiFileTest(
|
||||
@NotNull File wholeFile,
|
||||
@NotNull List<TestFile> files,
|
||||
@Nullable File javaFilesDir
|
||||
@NotNull File wholeFile,
|
||||
@NotNull List<TestFile> files,
|
||||
@Nullable File javaFilesDir
|
||||
) throws Exception {
|
||||
throw new UnsupportedOperationException("Multi-file test cases are not supported in this test");
|
||||
}
|
||||
@@ -843,7 +829,7 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
throws IOException, InvocationTargetException, IllegalAccessException {
|
||||
Class<?> aClass = getGeneratedClass(classLoader, className);
|
||||
Method method = getBoxMethodOrNull(aClass);
|
||||
assertTrue("Can't find box method in " + aClass,method != null);
|
||||
assertNotNull("Can't find box method in " + aClass, method);
|
||||
callBoxMethodAndCheckResult(classLoader, aClass, method);
|
||||
}
|
||||
|
||||
@@ -876,7 +862,8 @@ public abstract class CodegenTestCase extends KtUsefulTestCase {
|
||||
List<URL> classPath = extractUrls(classLoader);
|
||||
if (classLoader instanceof GeneratedClassLoader) {
|
||||
File outDir = KotlinTestUtils.tmpDirForTest(this);
|
||||
SimpleOutputFileCollection currentOutput = new SimpleOutputFileCollection(((GeneratedClassLoader) classLoader).getAllGeneratedFiles());
|
||||
SimpleOutputFileCollection currentOutput =
|
||||
new SimpleOutputFileCollection(((GeneratedClassLoader) classLoader).getAllGeneratedFiles());
|
||||
writeAllTo(currentOutput, outDir);
|
||||
classPath.add(0, outDir.toURI().toURL());
|
||||
}
|
||||
|
||||
@@ -127,7 +127,8 @@ public class CodegenTestFiles {
|
||||
String[] values = valueString.split(" ");
|
||||
|
||||
scriptParameterValues.add(values);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
scriptParameterValues.add(ArrayUtil.EMPTY_STRING_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,15 +39,17 @@ import java.util.List;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
public class CodegenTestUtil {
|
||||
private CodegenTestUtil() {}
|
||||
private CodegenTestUtil() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static ClassFileFactory generateFiles(@NotNull KotlinCoreEnvironment environment, @NotNull CodegenTestFiles files) {
|
||||
return GenerationUtils.compileFiles(files.getPsiFiles(), environment).getFactory();
|
||||
}
|
||||
|
||||
public static void assertThrows(@NotNull Method foo, @NotNull Class<? extends Throwable> exceptionClass,
|
||||
@Nullable Object instance, @NotNull Object... args) throws IllegalAccessException {
|
||||
public static void assertThrows(
|
||||
@NotNull Method foo, @NotNull Class<? extends Throwable> exceptionClass, @Nullable Object instance, @NotNull Object... args
|
||||
) throws IllegalAccessException {
|
||||
boolean caught = false;
|
||||
try {
|
||||
foo.invoke(instance, args);
|
||||
|
||||
@@ -46,10 +46,6 @@ object GenerationUtils {
|
||||
writeAllTo(output)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun compileFile(ktFile: KtFile, environment: KotlinCoreEnvironment): ClassFileFactory =
|
||||
compileFiles(listOf(ktFile), environment).factory
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
fun compileFiles(
|
||||
|
||||
@@ -35,7 +35,7 @@ object InlineTestUtil {
|
||||
fun checkNoCallsToInline(outputFiles: Iterable<OutputFile>, sourceFiles: List<KtFile>) {
|
||||
val inlineInfo = obtainInlineInfo(outputFiles)
|
||||
val inlineMethods = inlineInfo.inlineMethods
|
||||
assert(!inlineMethods.isEmpty()) { "There are no inline methods" }
|
||||
assert(inlineMethods.isNotEmpty()) { "There are no inline methods" }
|
||||
|
||||
val notInlinedCalls = checkInlineMethodNotInvoked(outputFiles, inlineMethods)
|
||||
assert(notInlinedCalls.isEmpty()) { "All inline methods should be inlined but:\n" + notInlinedCalls.joinToString("\n") }
|
||||
@@ -48,7 +48,7 @@ object InlineTestUtil {
|
||||
val notInlinedParameters = checkParametersInlined(outputFiles, inlineInfo, sourceFiles)
|
||||
assert(notInlinedParameters.isEmpty()) {
|
||||
"All inline parameters should be inlined but:\n${notInlinedParameters.joinToString("\n")}\n" +
|
||||
"but if you have not inlined lambdas or anonymous objects enable NO_CHECK_LAMBDA_INLINING directive"
|
||||
"but if you have not inlined lambdas or anonymous objects enable NO_CHECK_LAMBDA_INLINING directive"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,9 @@ object InlineTestUtil {
|
||||
val inlineFunctions = inlineFunctionsJvmNames(binaryClass.classHeader)
|
||||
|
||||
val classVisitor = object : ClassVisitorWithName() {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
|
||||
override fun visitMethod(
|
||||
access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?
|
||||
): MethodVisitor? {
|
||||
if (name + desc in inlineFunctions) {
|
||||
inlineMethods.add(MethodInfo(className, name, desc))
|
||||
}
|
||||
@@ -70,7 +72,7 @@ object InlineTestUtil {
|
||||
}
|
||||
|
||||
ClassReader(file.asByteArray()).accept(classVisitor, 0)
|
||||
binaryClasses.put(classVisitor.className, binaryClass)
|
||||
binaryClasses[classVisitor.className] = binaryClass
|
||||
}
|
||||
|
||||
return InlineInfo(inlineMethods, binaryClasses)
|
||||
@@ -84,9 +86,11 @@ object InlineTestUtil {
|
||||
|
||||
//if inline function creates anonymous object then do not try to check that all lambdas are inlined
|
||||
val classVisitor = object : ClassVisitorWithName() {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
|
||||
override fun visitMethod(
|
||||
access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?
|
||||
): MethodVisitor? {
|
||||
if (name + desc in inlineFunctions) {
|
||||
return object: MethodNodeWithAnonymousObjectCheck(inlineInfo, access, name, desc, signature, exceptions) {
|
||||
return object : MethodNodeWithAnonymousObjectCheck(inlineInfo, access, name, desc, signature, exceptions) {
|
||||
override fun onAnonymousConstructorCallOrSingletonAccess(owner: String) {
|
||||
doLambdaInliningCheck = false
|
||||
}
|
||||
@@ -126,7 +130,9 @@ object InlineTestUtil {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
|
||||
override fun visitMethod(
|
||||
access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?
|
||||
): MethodVisitor? {
|
||||
if (skipMethodsOfThisClass) {
|
||||
return null
|
||||
}
|
||||
@@ -160,11 +166,13 @@ object InlineTestUtil {
|
||||
return notInlined
|
||||
}
|
||||
|
||||
private fun checkParametersInlined(outputFiles: Iterable<OutputFile>, inlineInfo: InlineInfo, sourceFiles: List<KtFile>): ArrayList<NotInlinedParameter> {
|
||||
private fun checkParametersInlined(
|
||||
outputFiles: Iterable<OutputFile>, inlineInfo: InlineInfo, sourceFiles: List<KtFile>
|
||||
): ArrayList<NotInlinedParameter> {
|
||||
val skipMethods =
|
||||
sourceFiles.flatMap {
|
||||
InTextDirectivesUtils.findLinesWithPrefixesRemoved(it.text, "// SKIP_INLINE_CHECK_IN: ")
|
||||
}.toSet()
|
||||
sourceFiles.flatMap {
|
||||
InTextDirectivesUtils.findLinesWithPrefixesRemoved(it.text, "// SKIP_INLINE_CHECK_IN: ")
|
||||
}.toSet()
|
||||
|
||||
val inlinedMethods = inlineInfo.inlineMethods
|
||||
val notInlinedParameters = ArrayList<NotInlinedParameter>()
|
||||
@@ -172,7 +180,9 @@ object InlineTestUtil {
|
||||
if (!isClassOrPackagePartKind(loadBinaryClass(file))) continue
|
||||
|
||||
ClassReader(file.asByteArray()).accept(object : ClassVisitorWithName() {
|
||||
override fun visitMethod(access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?): MethodVisitor? {
|
||||
override fun visitMethod(
|
||||
access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?
|
||||
): MethodVisitor? {
|
||||
val declaration = MethodInfo(className, name, desc)
|
||||
|
||||
//do not check anonymous object creation in inline functions and in package facades
|
||||
@@ -184,7 +194,7 @@ object InlineTestUtil {
|
||||
return null
|
||||
}
|
||||
|
||||
return object: MethodNodeWithAnonymousObjectCheck(inlineInfo, access, name, desc, signature, exceptions) {
|
||||
return object : MethodNodeWithAnonymousObjectCheck(inlineInfo, access, name, desc, signature, exceptions) {
|
||||
override fun onAnonymousConstructorCallOrSingletonAccess(owner: String) {
|
||||
val fromCall = MethodInfo(className, this.name, this.desc)
|
||||
notInlinedParameters.add(NotInlinedParameter(owner, fromCall))
|
||||
@@ -201,29 +211,27 @@ object InlineTestUtil {
|
||||
if (classInternalName.startsWith("kotlin/jvm/internal/"))
|
||||
return true
|
||||
|
||||
return isClassOrPackagePartKind(inlineInfo.binaryClasses[classInternalName]!!)
|
||||
return isClassOrPackagePartKind(inlineInfo.binaryClasses.getValue(classInternalName))
|
||||
}
|
||||
|
||||
private fun isClassOrPackagePartKind(klass: KotlinJvmBinaryClass): Boolean {
|
||||
return klass.classHeader.kind == KotlinClassHeader.Kind.CLASS && !klass.classId.isLocal
|
||||
|| klass.classHeader.kind == KotlinClassHeader.Kind.FILE_FACADE /*single file facade equals to package part*/
|
||||
|| klass.classHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART
|
||||
|| klass.classHeader.kind == KotlinClassHeader.Kind.FILE_FACADE /*single file facade equals to package part*/
|
||||
|| klass.classHeader.kind == KotlinClassHeader.Kind.MULTIFILE_CLASS_PART
|
||||
}
|
||||
|
||||
private fun loadBinaryClass(file: OutputFile): KotlinJvmBinaryClass {
|
||||
val klass = FileBasedKotlinClass.create(file.asByteArray()) {
|
||||
className, classVersion, classHeader, innerClasses ->
|
||||
private fun loadBinaryClass(file: OutputFile): KotlinJvmBinaryClass =
|
||||
FileBasedKotlinClass.create<FileBasedKotlinClass>(file.asByteArray()) { className, classVersion, classHeader, innerClasses ->
|
||||
object : FileBasedKotlinClass(className, classVersion, classHeader, innerClasses) {
|
||||
override val location: String
|
||||
get() = throw UnsupportedOperationException()
|
||||
|
||||
override fun getFileContents(): ByteArray = throw UnsupportedOperationException()
|
||||
override fun hashCode(): Int = throw UnsupportedOperationException()
|
||||
override fun equals(other: Any?): Boolean = throw UnsupportedOperationException()
|
||||
override fun toString(): String = throw UnsupportedOperationException()
|
||||
}
|
||||
}!!
|
||||
return klass
|
||||
}
|
||||
|
||||
private class InlineInfo(val inlineMethods: Set<MethodInfo>, val binaryClasses: Map<String, KotlinJvmBinaryClass>)
|
||||
|
||||
@@ -242,9 +250,11 @@ object InlineTestUtil {
|
||||
}
|
||||
}
|
||||
|
||||
private abstract class MethodNodeWithAnonymousObjectCheck(val inlineInfo: InlineInfo, access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?) : MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions) {
|
||||
private abstract class MethodNodeWithAnonymousObjectCheck(
|
||||
val inlineInfo: InlineInfo, access: Int, name: String, desc: String, signature: String?, exceptions: Array<String>?
|
||||
) : MethodNode(Opcodes.API_VERSION, access, name, desc, signature, exceptions) {
|
||||
private fun isInlineParameterLikeOwner(owner: String) =
|
||||
"$" in owner && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo)
|
||||
"$" in owner && !isTopLevelOrInnerOrPackageClass(owner, inlineInfo)
|
||||
|
||||
override fun visitMethodInsn(opcode: Int, owner: String, name: String, desc: String, itf: Boolean) {
|
||||
if ("<init>" == name && isInlineParameterLikeOwner(owner)) {
|
||||
|
||||
@@ -41,7 +41,7 @@ object SMAPTestUtil {
|
||||
}
|
||||
}, 0)
|
||||
|
||||
SMAPAndFile.SMAPAndFile(debugInfo, outputFile.sourceFiles.single(), outputFile.relativePath)
|
||||
SMAPAndFile(debugInfo, outputFile.sourceFiles.single(), outputFile.relativePath)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,10 @@ object SMAPTestUtil {
|
||||
}
|
||||
|
||||
private fun checkExtension(file: CodegenTestCase.TestFile, separateCompilation: Boolean) =
|
||||
file.name.run { endsWith(".smap") || if (separateCompilation) endsWith(".smap-separate-compilation") else endsWith(".smap-nonseparate-compilation") }
|
||||
file.name.run {
|
||||
endsWith(".smap") ||
|
||||
if (separateCompilation) endsWith(".smap-separate-compilation") else endsWith(".smap-nonseparate-compilation")
|
||||
}
|
||||
|
||||
fun checkSMAP(inputFiles: List<CodegenTestCase.TestFile>, outputFiles: Iterable<OutputFile>, separateCompilation: Boolean) {
|
||||
if (!GENERATE_SMAP) return
|
||||
@@ -71,15 +74,15 @@ object SMAPTestUtil {
|
||||
val compiledData = compiledSmaps.groupBy {
|
||||
it.sourceFile
|
||||
}.map {
|
||||
val smap = it.value.sortedByDescending { it.outputFile }.mapNotNull { it.smap }.joinToString("\n")
|
||||
val smap = it.value.sortedByDescending(SMAPAndFile::outputFile).mapNotNull(SMAPAndFile::smap).joinToString("\n")
|
||||
SMAPAndFile(if (smap.isNotEmpty()) smap else null, it.key, "NOT_SORTED")
|
||||
}.associateBy { it.sourceFile }
|
||||
|
||||
for (source in sourceData) {
|
||||
val ktFileName = "/" + source.sourceFile.
|
||||
replace(".smap-nonseparate-compilation", ".kt").
|
||||
replace(".smap-separate-compilation", ".kt").
|
||||
replace(".smap", ".kt")
|
||||
val ktFileName = "/" + source.sourceFile
|
||||
.replace(".smap-nonseparate-compilation", ".kt")
|
||||
.replace(".smap-separate-compilation", ".kt")
|
||||
.replace(".smap", ".kt")
|
||||
val data = compiledData[ktFileName]
|
||||
Assert.assertEquals("Smap data differs for $ktFileName", normalize(source.smap), normalize(data?.smap))
|
||||
}
|
||||
@@ -90,37 +93,32 @@ object SMAPTestUtil {
|
||||
private fun checkNoConflictMappings(compiledSmap: List<SMAPAndFile>?) {
|
||||
if (compiledSmap == null) return
|
||||
|
||||
compiledSmap.mapNotNull { it.smap }.forEach {
|
||||
val smap = SMAPParser.parse(it)
|
||||
val conflictingLines = smap.fileMappings.flatMap {
|
||||
fileMapping ->
|
||||
fileMapping.lineMappings.flatMap {
|
||||
lineMapping: RangeMapping ->
|
||||
compiledSmap.mapNotNull(SMAPAndFile::smap).forEach { smapString ->
|
||||
val smap = SMAPParser.parse(smapString)
|
||||
val conflictingLines = smap.fileMappings.flatMap { fileMapping ->
|
||||
fileMapping.lineMappings.flatMap { lineMapping: RangeMapping ->
|
||||
lineMapping.toRange.keysToMap { lineMapping }.entries
|
||||
}
|
||||
}.groupBy { it.key }.entries.filter { it.value.size != 1 }
|
||||
|
||||
|
||||
Assert.assertTrue(
|
||||
conflictingLines.joinToString(separator = "\n") {
|
||||
"Conflicting mapping for line ${it.key} in ${it.value.joinToString { it.toString() }} "
|
||||
},
|
||||
conflictingLines.isEmpty()
|
||||
conflictingLines.joinToString(separator = "\n") {
|
||||
"Conflicting mapping for line ${it.key} in ${it.value.joinToString(transform = Any::toString)}"
|
||||
},
|
||||
conflictingLines.isEmpty()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun normalize(text: String?) =
|
||||
text?.let { StringUtil.convertLineSeparators(it.trim()) }
|
||||
text?.let { StringUtil.convertLineSeparators(it.trim()) }
|
||||
|
||||
private class SMAPAndFile(val smap: String?, val sourceFile: String, val outputFile: String) {
|
||||
companion object {
|
||||
fun SMAPAndFile(smap: String?, sourceFile: File, outputFile: String) =
|
||||
SMAPAndFile(smap, getPath(sourceFile), outputFile)
|
||||
constructor(smap: String?, sourceFile: File, outputFile: String) : this(smap, getPath(sourceFile), outputFile)
|
||||
|
||||
fun getPath(file: File): String {
|
||||
return getPath(file.canonicalPath)
|
||||
}
|
||||
companion object {
|
||||
fun getPath(file: File): String =
|
||||
getPath(file.canonicalPath)
|
||||
|
||||
fun getPath(canonicalPath: String): String {
|
||||
//There are some problems with disk name on windows cause LightVirtualFile return it without disk name
|
||||
|
||||
+1
-1
@@ -20,6 +20,6 @@ import org.jetbrains.kotlin.codegen.AbstractBlackBoxCodegenTest
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
|
||||
abstract class AbstractIrBlackBoxInlineCodegenTest: AbstractBlackBoxCodegenTest() {
|
||||
abstract class AbstractIrBlackBoxInlineCodegenTest : AbstractBlackBoxCodegenTest() {
|
||||
override fun updateConfiguration(configuration: CompilerConfiguration) = configuration.put(JVMConfigurationKeys.IR, true)
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen
|
||||
|
||||
import junit.framework.TestCase
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.utils.rethrow
|
||||
import java.lang.reflect.Method
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
|
||||
@@ -28,17 +25,13 @@ fun clearReflectionCache(classLoader: ClassLoader) {
|
||||
val klass = classLoader.loadClass(JvmAbi.REFLECTION_FACTORY_IMPL.asSingleFqName().asString())
|
||||
val method = klass.getDeclaredMethod("clearCaches")
|
||||
method.invoke(null)
|
||||
}
|
||||
catch (e: ClassNotFoundException) {
|
||||
} catch (e: ClassNotFoundException) {
|
||||
// This is OK for a test without kotlin-reflect in the dependencies
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun ClassLoader?.extractUrls(): List<URL> {
|
||||
return (this as? URLClassLoader)?.let {
|
||||
it.urLs.toList() + it.parent.extractUrls()
|
||||
} ?: emptyList()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user