Fix for KT-16614: Report inability to inline 1.8 bytecode into 1.6 bytecode as an error, no as an exception
This commit is contained in:
-1
@@ -66,7 +66,6 @@ public class AnonymousObjectTransformer extends ObjectTransformer<AnonymousObjec
|
||||
createClassReader().accept(new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, inliningContext.state);
|
||||
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces);
|
||||
if(CoroutineCodegenUtilKt.COROUTINE_IMPL_ASM_TYPE.getInternalName().equals(superName)) {
|
||||
inliningContext.setContinuation(true);
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.load.kotlin.incremental.components.IncrementalCache;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
||||
@@ -202,7 +203,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
MethodNode node = nodeAndSmap != null ? nodeAndSmap.getNode() : null;
|
||||
throw new CompilationException(
|
||||
"Couldn't inline method call '" + functionDescriptor.getName() + "' into\n" +
|
||||
contextDescriptor + "\n" +
|
||||
DescriptorRenderer.DEBUG_TEXT.render(contextDescriptor) + "\n" +
|
||||
(element != null ? element.getText() : "<no source>") +
|
||||
(generateNodeText ? ("\nCause: " + InlineCodegenUtil.getNodeText(node)) : ""),
|
||||
e, callElement
|
||||
@@ -321,7 +322,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
}
|
||||
});
|
||||
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId, state);
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), classId);
|
||||
}
|
||||
|
||||
assert callableDescriptor instanceof DeserializedCallableMemberDescriptor : "Not a deserialized function or proper: " + callableDescriptor;
|
||||
@@ -348,7 +349,7 @@ public class InlineCodegen extends CallGenerator {
|
||||
});
|
||||
|
||||
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId, state);
|
||||
return InlineCodegenUtil.getMethodNode(bytes, asmMethod.getName(), asmMethod.getDescriptor(), containerId);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -92,8 +92,7 @@ public class InlineCodegenUtil {
|
||||
byte[] classData,
|
||||
final String methodName,
|
||||
final String methodDescriptor,
|
||||
ClassId classId,
|
||||
final @NotNull GenerationState state
|
||||
ClassId classId
|
||||
) {
|
||||
ClassReader cr = new ClassReader(classData);
|
||||
final MethodNode[] node = new MethodNode[1];
|
||||
@@ -103,10 +102,6 @@ public class InlineCodegenUtil {
|
||||
lines[1] = Integer.MIN_VALUE;
|
||||
//noinspection PointlessBitwiseExpression
|
||||
cr.accept(new ClassVisitor(API) {
|
||||
@Override
|
||||
public void visit(int version, int access, @NotNull String name, String signature, String superName, String[] interfaces) {
|
||||
assertVersionNotGreaterThanGeneratedOne(version, name, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitSource(String source, String debug) {
|
||||
@@ -151,16 +146,6 @@ public class InlineCodegenUtil {
|
||||
return new SMAPAndMethodNode(node[0], smap);
|
||||
}
|
||||
|
||||
public static void assertVersionNotGreaterThanGeneratedOne(int version, String internalName, @NotNull GenerationState state) {
|
||||
// TODO: report a proper diagnostic
|
||||
if (version > state.getClassFileVersion() && !"true".equals(System.getProperty("kotlin.skip.bytecode.version.check"))) {
|
||||
throw new UnsupportedOperationException(
|
||||
"Cannot inline bytecode of class " + internalName + " which has version " + version + ". " +
|
||||
"This compiler can only inline Java 1.6 bytecode (version " + Opcodes.V1_6 + ")"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public static void initDefaultSourceMappingIfNeeded(
|
||||
@NotNull CodegenContext context, @NotNull MemberCodegen codegen, @NotNull GenerationState state
|
||||
) {
|
||||
|
||||
@@ -66,7 +66,6 @@ class WhenMappingTransformer(
|
||||
val fieldNode = transformationInfo.fieldNode
|
||||
classReader.accept(object : ClassVisitor(InlineCodegenUtil.API, classBuilder.visitor) {
|
||||
override fun visit(version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<String>) {
|
||||
InlineCodegenUtil.assertVersionNotGreaterThanGeneratedOne(version, name, state)
|
||||
classBuilder.defineClass(null, version, access, name, signature, superName, interfaces)
|
||||
}
|
||||
|
||||
|
||||
@@ -123,7 +123,8 @@ class GenerationState @JvmOverloads constructor(
|
||||
extraJvmDiagnosticsTrace.bindingContext.diagnostics
|
||||
}
|
||||
|
||||
val isJvm8Target: Boolean = configuration.get(JVMConfigurationKeys.JVM_TARGET) == JvmTarget.JVM_1_8
|
||||
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
||||
val isJvm8Target: Boolean = target == JvmTarget.JVM_1_8
|
||||
val isJvm8TargetWithDefaults: Boolean = isJvm8Target && configuration.getBoolean(JVMConfigurationKeys.JVM8_TARGET_WITH_DEFAULTS)
|
||||
val generateDefaultImplsForJvm8: Boolean = configuration.getBoolean(JVMConfigurationKeys.INTERFACE_COMPATIBILITY)
|
||||
|
||||
@@ -162,7 +163,7 @@ class GenerationState @JvmOverloads constructor(
|
||||
|
||||
val rootContext: CodegenContext<*> = RootContext(this)
|
||||
|
||||
val classFileVersion: Int = if (isJvm8Target) Opcodes.V1_8 else Opcodes.V1_6
|
||||
val classFileVersion: Int = target.bytecodeVersion
|
||||
|
||||
val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA)
|
||||
|
||||
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2017 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.resolve.jvm.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassOrPackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryPackageSourceElement
|
||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedCallableMemberDescriptor
|
||||
|
||||
class InlinePlatformCompatibilityChecker: CallChecker {
|
||||
|
||||
private val doCheck = doCheck()
|
||||
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (!doCheck) return
|
||||
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor as? CallableMemberDescriptor ?: return
|
||||
if (!InlineUtil.isInline(resultingDescriptor)) {
|
||||
if (resultingDescriptor is PropertyDescriptor && InlineUtil.isInline(resultingDescriptor.getter)) {
|
||||
//TODO: we should distinguish setter usage from getter one, now we could report wrong diagnostic on non-inline setter
|
||||
//var prop: Int
|
||||
// inline get
|
||||
// set
|
||||
//
|
||||
// prop - resolved call with property descriptor and we should report error
|
||||
// prop = 1 - resolved call with setter for whole expression and property descriptor for left part,
|
||||
// so we couldn't distinguish is this expression for setter or for getter and will report wrong diagnostic
|
||||
}
|
||||
else {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val propertyOrFun = DescriptorUtils.getDirectMember(resultingDescriptor)
|
||||
val inliningBytecodeVersion = getBytecodeVersionIfDeserializedDescriptor(propertyOrFun) ?: return
|
||||
|
||||
val compilingTarget = context.compilerConfiguration[JVMConfigurationKeys.JVM_TARGET] ?: JvmTarget.DEFAULT
|
||||
val compilingBytecodeVersion = compilingTarget.bytecodeVersion
|
||||
if (compilingBytecodeVersion < inliningBytecodeVersion) {
|
||||
context.trace.report(ErrorsJvm.INLINE_FROM_HIGHER_PLATFORM.on(reportOn, JvmTarget.getDescription(inliningBytecodeVersion), JvmTarget.getDescription(compilingBytecodeVersion)))
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
fun doCheck() = "true" != System.getProperty("kotlin.skip.bytecode.version.check")
|
||||
|
||||
fun getBytecodeVersionIfDeserializedDescriptor(funOrProperty: DeclarationDescriptor): Int? {
|
||||
if (funOrProperty !is DeserializedCallableMemberDescriptor) return null
|
||||
|
||||
val containingDeclaration = funOrProperty.containingDeclaration as ClassOrPackageFragmentDescriptor
|
||||
|
||||
val source = containingDeclaration.source
|
||||
val binaryClass =
|
||||
when (source) {
|
||||
is KotlinJvmBinarySourceElement -> source.binaryClass
|
||||
is KotlinJvmBinaryPackageSourceElement -> source.getContainingBinaryClass(funOrProperty)
|
||||
else -> null
|
||||
} as? FileBasedKotlinClass ?: return null
|
||||
|
||||
return binaryClass.classVersion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -115,6 +115,8 @@ public class DefaultErrorMessagesJvm implements DefaultErrorMessages.Extension {
|
||||
|
||||
MAP.put(ErrorsJvm.DEFAULT_METHOD_CALL_FROM_JAVA6_TARGET, "Super calls to Java default methods are deprecated in JVM target 1.6. Recompile with '-jvm-target 1.8'");
|
||||
MAP.put(ErrorsJvm.INTERFACE_STATIC_METHOD_CALL_FROM_JAVA6_TARGET, "Calls to static methods in Java interfaces are deprecated in JVM target 1.6. Recompile with '-jvm-target 1.8'");
|
||||
|
||||
MAP.put(ErrorsJvm.INLINE_FROM_HIGHER_PLATFORM, "Cannot inline bytecode built with {0} into bytecode that is being built with {1}. Please specify proper ''-jvm-target'' option", Renderers.TO_STRING, Renderers.TO_STRING);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -92,6 +92,8 @@ public interface ErrorsJvm {
|
||||
DiagnosticFactory0<PsiElement> DEFAULT_METHOD_CALL_FROM_JAVA6_TARGET = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> INTERFACE_STATIC_METHOD_CALL_FROM_JAVA6_TARGET = DiagnosticFactory0.create(WARNING);
|
||||
|
||||
DiagnosticFactory2<PsiElement, String, String> INLINE_FROM_HIGHER_PLATFORM = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
Object _initializer = new Object() {
|
||||
{
|
||||
|
||||
+3
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.container.useImpl
|
||||
import org.jetbrains.kotlin.container.useInstance
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.resolve.PlatformConfigurator
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.InlineCheckerWrapper
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.ReifiedTypeParameterSubstitutionChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.HeaderImplDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.MissingDependencyClassChecker
|
||||
@@ -55,7 +56,8 @@ object JvmPlatformConfigurator : PlatformConfigurator(
|
||||
UnsupportedSyntheticCallableReferenceChecker(),
|
||||
SuperCallWithDefaultArgumentsChecker(),
|
||||
ProtectedSyntheticExtensionCallChecker,
|
||||
ReifiedTypeParameterSubstitutionChecker()
|
||||
ReifiedTypeParameterSubstitutionChecker(),
|
||||
InlinePlatformCompatibilityChecker()
|
||||
),
|
||||
|
||||
additionalTypeCheckers = listOf(
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// JVM_TARGET: 1.8
|
||||
package a
|
||||
|
||||
inline fun inlineFun(p: () -> Unit) {
|
||||
p()
|
||||
}
|
||||
|
||||
var inlineGetter: Int
|
||||
inline get() = 1
|
||||
set(varue) {}
|
||||
|
||||
var inlineSetter: Int
|
||||
get() = 1
|
||||
inline set(varue) {}
|
||||
|
||||
var allInline: Int
|
||||
inline get() = 1
|
||||
inline set(varue) {}
|
||||
|
||||
|
||||
|
||||
class A {
|
||||
inline fun inlineFun(p: () -> Unit) {
|
||||
p()
|
||||
}
|
||||
|
||||
var inlineGetter: Int
|
||||
inline get() = 1
|
||||
set(varue) {}
|
||||
|
||||
var inlineSetter: Int
|
||||
get() = 1
|
||||
inline set(varue) {}
|
||||
|
||||
var allInline: Int
|
||||
inline get() = 1
|
||||
inline set(varue) {}
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:6:5: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
inlineFun {}
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:7:5: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
inlineGetter
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:8:5: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
inlineGetter = 1
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:11:5: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
inlineSetter = 1
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:13:5: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
allInline
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:14:5: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
allInline = 1
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:17:7: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
a.inlineFun {}
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:18:7: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
a.inlineGetter
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:19:7: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
a.inlineGetter = 1
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:22:7: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
a.inlineSetter = 1
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:24:7: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
a.allInline
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/wrongInlineTarget/source.kt:25:7: error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6. Please specify proper '-jvm-target' option
|
||||
a.allInline = 1
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package usage
|
||||
|
||||
import a.*
|
||||
|
||||
fun baz() {
|
||||
inlineFun {}
|
||||
inlineGetter
|
||||
inlineGetter = 1
|
||||
|
||||
inlineSetter
|
||||
inlineSetter = 1
|
||||
|
||||
allInline
|
||||
allInline = 1
|
||||
|
||||
val a = A()
|
||||
a.inlineFun {}
|
||||
a.inlineGetter
|
||||
a.inlineGetter = 1
|
||||
|
||||
a.inlineSetter
|
||||
a.inlineSetter = 1
|
||||
|
||||
a.allInline
|
||||
a.allInline = 1
|
||||
}
|
||||
|
||||
|
||||
@@ -83,13 +83,10 @@ class ReplCompilerJava8Test : TestCase() {
|
||||
val configuration = makeConfiguration().apply {
|
||||
put(JVMConfigurationKeys.JVM_TARGET, JvmTarget.JVM_1_6)
|
||||
}
|
||||
try {
|
||||
runTest(configuration)
|
||||
Assert.fail("Should fail due to bytecode incompatibility check")
|
||||
}
|
||||
catch (e: CompilationException) {
|
||||
Assert.assertTrue(e.message!!.contains("This compiler can only inline Java 1.6 bytecode (version 50)"))
|
||||
}
|
||||
|
||||
val result = runTest(configuration)
|
||||
Assert.assertTrue(result is ReplCompileResult.Error)
|
||||
Assert.assertTrue((result as ReplCompileResult.Error).message.contains("error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6"))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -98,11 +95,9 @@ class ReplCompilerJava8Test : TestCase() {
|
||||
val configuration = makeConfiguration()
|
||||
System.setProperty(KOTLIN_REPL_JVM_TARGET_PROPERTY, "1.6")
|
||||
try {
|
||||
runTest(configuration)
|
||||
Assert.fail("Should fail due to bytecode incompatibility check")
|
||||
}
|
||||
catch (e: CompilationException) {
|
||||
Assert.assertTrue(e.message!!.contains("This compiler can only inline Java 1.6 bytecode (version 50)"))
|
||||
val result = runTest(configuration)
|
||||
Assert.assertTrue(result is ReplCompileResult.Error)
|
||||
Assert.assertTrue((result as ReplCompileResult.Error).message.contains("error: cannot inline bytecode built with JVM target 1.8 into bytecode that is being built with JVM target 1.6"))
|
||||
}
|
||||
finally {
|
||||
System.clearProperty(KOTLIN_REPL_JVM_TARGET_PROPERTY)
|
||||
|
||||
+18
-4
@@ -89,15 +89,19 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
|
||||
@NotNull
|
||||
private File compileLibrary(@NotNull String sourcePath, @NotNull File... extraClassPath) {
|
||||
return compileLibrary(sourcePath, Collections.<String>emptyList(), extraClassPath);
|
||||
}
|
||||
|
||||
private File compileLibrary(@NotNull String sourcePath, List<String> additionalOptions, @NotNull File... extraClassPath) {
|
||||
File destination = new File(tmpdir, sourcePath + ".jar");
|
||||
compileLibrary(new K2JVMCompiler(), sourcePath, destination, extraClassPath);
|
||||
compileLibrary(new K2JVMCompiler(), sourcePath, destination, additionalOptions, extraClassPath);
|
||||
return destination;
|
||||
}
|
||||
|
||||
private void compileLibrary(
|
||||
@NotNull CLICompiler<?> compiler, @NotNull String sourcePath, @NotNull File destination, @NotNull File... extraClassPath
|
||||
@NotNull CLICompiler<?> compiler, @NotNull String sourcePath, @NotNull File destination, List<String> additionalOptions, @NotNull File... extraClassPath
|
||||
) {
|
||||
Pair<String, ExitCode> output = compileKotlin(compiler, sourcePath, destination, Collections.<String>emptyList(), extraClassPath);
|
||||
Pair<String, ExitCode> output = compileKotlin(compiler, sourcePath, destination, additionalOptions, extraClassPath);
|
||||
Assert.assertEquals(normalizeOutput(new Pair<String, ExitCode>("", ExitCode.OK)), normalizeOutput(output));
|
||||
}
|
||||
|
||||
@@ -324,7 +328,7 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
|
||||
try {
|
||||
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "true");
|
||||
compileLibrary(compiler, libraryName, destination);
|
||||
compileLibrary(compiler, libraryName, destination, Collections.<String>emptyList());
|
||||
}
|
||||
finally {
|
||||
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY);
|
||||
@@ -629,4 +633,14 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
|
||||
Pair<String, ExitCode> output = compileKotlin("source.kt", tmpdir, library1);
|
||||
KotlinTestUtils.assertEqualsToFile(new File(getTestDataDirectory(), "output.txt"), normalizeOutput(output));
|
||||
}
|
||||
|
||||
public void testWrongInlineTarget() throws Exception {
|
||||
File library = compileLibrary("library", Arrays.asList("-jvm-target", "1.8"));
|
||||
|
||||
Pair<String, ExitCode> outputMain = compileKotlin("source.kt", tmpdir, library);
|
||||
|
||||
KotlinTestUtils.assertEqualsToFile(
|
||||
new File(getTestDataDirectory(), "output.txt"), normalizeOutput(outputMain)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,17 +17,36 @@
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import org.jetbrains.kotlin.utils.DescriptionAware
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
|
||||
enum class JvmTarget(override val description: String) : DescriptionAware {
|
||||
JVM_1_6("1.6"),
|
||||
JVM_1_8("1.8"),
|
||||
;
|
||||
|
||||
val bytecodeVersion: Int
|
||||
get() = when(this) {
|
||||
JVM_1_6 -> Opcodes.V1_6
|
||||
JVM_1_8 -> Opcodes.V1_8
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val DEFAULT = JVM_1_6
|
||||
|
||||
@JvmStatic
|
||||
fun fromString(string: String) = values().find { it.description == string }
|
||||
|
||||
fun getDescription(bytecodeVersion: Int): String {
|
||||
val platformDescription = values().find { it.bytecodeVersion == bytecodeVersion }?.description ?:
|
||||
when (bytecodeVersion) {
|
||||
Opcodes.V1_7 -> "1.7"
|
||||
Opcodes.V1_8 + 1 -> "1.9"
|
||||
else -> null
|
||||
}
|
||||
|
||||
return if (platformDescription != null) "JVM target $platformDescription"
|
||||
else "JVM bytecode version $bytecodeVersion"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user