Suppot inlining default methods, inlining function into its default.

This commit is contained in:
Mikhael Bogdanov
2014-05-20 14:14:48 +04:00
parent b3fef4a7a0
commit 6ad2814b01
16 changed files with 276 additions and 91 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.jet.codegen;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.psi.JetExpression;
@@ -34,20 +35,28 @@ public interface CallGenerator {
@Override
public void genCall(
CallableMethod callableMethod,
ResolvedCall<?> resolvedCall, int mask,
ExpressionCodegen codegen
@NotNull CallableMethod callableMethod,
ResolvedCall<?> resolvedCall,
boolean callDefault,
@NotNull ExpressionCodegen codegen
) {
if (mask == 0) {
if (!callDefault) {
callableMethod.invokeWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
}
else {
callableMethod.invokeDefaultWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall, mask);
callableMethod.invokeDefaultWithNotNullAssertion(codegen.v, codegen.getState(), resolvedCall);
}
}
@Override
public void afterParameterPut(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor) {
public void genCallWithoutNullAssertion(
@NotNull CallableMethod method, @NotNull ExpressionCodegen codegen
) {
method.invokeWithoutAssertions(codegen.v);
}
@Override
public void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor) {
}
@@ -72,11 +81,20 @@ public interface CallGenerator {
) {
stackValue.put(stackValue.type, codegen.v);
}
@Override
public void putValueIfNeeded(
@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value
) {
value.put(value.type, codegen.v);
}
}
void genCall(CallableMethod callableMethod, ResolvedCall<?> resolvedCall, int mask, ExpressionCodegen codegen);
void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen);
void afterParameterPut(Type type, StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor);
void genCallWithoutNullAssertion(@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen);
void afterParameterPut(@NotNull Type type, StackValue stackValue, @NotNull ValueParameterDescriptor valueParameterDescriptor);
void genValueAndPut(
@NotNull ValueParameterDescriptor valueParameterDescriptor,
@@ -84,6 +102,8 @@ public interface CallGenerator {
@NotNull Type parameterType
);
void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value);
void putCapturedValueOnStack(
@NotNull StackValue stackValue,
@NotNull Type valueType, int paramIndex
@@ -128,14 +128,13 @@ public class CallableMethod implements Callable {
return generateCalleeType;
}
private void invokeDefault(InstructionAdapter v, int mask) {
private void invokeDefault(InstructionAdapter v) {
if (defaultImplOwner == null || defaultImplParam == null) {
throw new IllegalStateException();
}
Method method = getAsmMethod();
v.iconst(mask);
String desc = method.getDescriptor().replace(")", "I)");
if ("<init>".equals(method.getName())) {
v.visitMethodInsn(INVOKESPECIAL, defaultImplOwner.getInternalName(), "<init>", desc);
@@ -151,10 +150,9 @@ public class CallableMethod implements Callable {
public void invokeDefaultWithNotNullAssertion(
@NotNull InstructionAdapter v,
@NotNull GenerationState state,
@NotNull ResolvedCall resolvedCall,
int mask
@NotNull ResolvedCall resolvedCall
) {
invokeDefault(v, mask);
invokeDefault(v);
AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall);
}
@@ -175,7 +175,9 @@ public class ClosureCodegen extends ParentCodegenAwareImpl {
typeMapper.mapSignature(funDescriptor),
funDescriptor,
context.getContextKind(),
DefaultParameterValueLoader.DEFAULT);
DefaultParameterValueLoader.DEFAULT,
null);
cv.done();
}
@@ -2078,8 +2078,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
resolvedCall = ((VariableAsFunctionResolvedCall) resolvedCall).getFunctionCall();
}
assert callGenerator == defaultCallGenerator || !hasDefaultArguments(resolvedCall) && !tailRecursionCodegen.isTailRecursion(resolvedCall) :
"Method with defaults or tail recursive couldn't be inlined " + descriptor;
assert callGenerator == defaultCallGenerator || !tailRecursionCodegen.isTailRecursion(resolvedCall) :
"Tail recursive method couldn't be inlined " + descriptor;
int mask = pushMethodArgumentsWithCallReceiver(receiver, resolvedCall, callableMethod, false, callGenerator);
@@ -2088,10 +2088,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return;
}
callGenerator.genCall(callableMethod, resolvedCall, mask, this);
boolean callDefault = mask != 0;
if (callDefault) {
callGenerator.putValueIfNeeded(null, Type.INT_TYPE, StackValue.constant(mask, Type.INT_TYPE));
}
callGenerator.genCall(callableMethod, resolvedCall, callDefault, this);
}
protected CallGenerator getOrCreateCallGenerator(CallableDescriptor descriptor, JetElement callElement) {
@NotNull
protected CallGenerator getOrCreateCallGenerator(@NotNull CallableDescriptor descriptor, @Nullable JetElement callElement) {
boolean isInline = state.isInlineEnabled() &&
descriptor instanceof SimpleFunctionDescriptor &&
((SimpleFunctionDescriptor) descriptor).getInlineStrategy().isInline();
@@ -2328,22 +2334,6 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
return mask;
}
private static boolean hasDefaultArguments(@NotNull ResolvedCall<?> resolvedCall) {
List<ResolvedValueArgument> valueArguments = resolvedCall.getValueArgumentsByIndex();
CallableDescriptor fd = resolvedCall.getResultingDescriptor();
if (valueArguments == null) {
throw new IllegalStateException("Failed to arrange value arguments by index: " + resolvedCall.getResultingDescriptor());
}
for (ValueParameterDescriptor valueParameter : fd.getValueParameters()) {
ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex());
if (resolvedValueArgument instanceof DefaultValueArgument) {
return true;
}
}
return false;
}
public void genVarargs(ValueParameterDescriptor valueParameterDescriptor, VarargValueArgument valueArgument) {
JetType outType = valueParameterDescriptor.getType();
@@ -105,7 +105,7 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
}
generateDefaultIfNeeded(owner.intoFunction(functionDescriptor), method, functionDescriptor, kind,
DefaultParameterValueLoader.DEFAULT);
DefaultParameterValueLoader.DEFAULT, function);
}
public void generateMethod(
@@ -536,7 +536,8 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
@NotNull JvmMethodSignature signature,
@NotNull FunctionDescriptor functionDescriptor,
@NotNull OwnerKind kind,
@NotNull DefaultParameterValueLoader loadStrategy
@NotNull DefaultParameterValueLoader loadStrategy,
@Nullable JetNamedFunction function
) {
DeclarationDescriptor contextClass = owner.getContextDescriptor().getContainingDeclaration();
@@ -550,20 +551,14 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
return;
}
boolean isStatic = isStatic(kind);
Method jvmSignature = signature.getAsmMethod();
int flags = getVisibilityAccessFlag(functionDescriptor) | getDeprecatedAccessFlag(functionDescriptor);
Type ownerType = typeMapper.mapOwner(functionDescriptor, true);
String descriptor = jvmSignature.getDescriptor().replace(")", "I)");
boolean isConstructor = "<init>".equals(jvmSignature.getName());
if (!isStatic && !isConstructor) {
descriptor = descriptor.replace("(", "(" + ownerType.getDescriptor());
}
Method defaultMethod = new Method(isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor);
Method defaultMethod = typeMapper.mapDefaultMethod(functionDescriptor, kind, owner);
MethodVisitor mv = v.newMethod(null, flags | (isConstructor ? 0 : ACC_STATIC),
defaultMethod.getName(),
defaultMethod.getDescriptor(), null,
@@ -574,8 +569,9 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
mv.visitCode();
generateStaticDelegateMethodBody(mv, defaultMethod, (PackageFacadeContext) this.owner);
endVisit(mv, "default method delegation", callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
} else {
generateDefaultImpl(owner, signature, functionDescriptor, isStatic, mv, loadStrategy);
}
else {
generateDefaultImpl(owner, signature, functionDescriptor, isStatic(kind), mv, loadStrategy, function);
}
}
}
@@ -586,17 +582,32 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
@NotNull FunctionDescriptor functionDescriptor,
boolean aStatic,
@NotNull MethodVisitor mv,
@NotNull DefaultParameterValueLoader loadStrategy
@NotNull DefaultParameterValueLoader loadStrategy,
@Nullable JetNamedFunction function
) {
mv.visitCode();
generateDefaultImplBody(methodContext, signature, functionDescriptor, aStatic, mv, loadStrategy, function, getParentCodegen(), state);
endVisit(mv, "default method", callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
}
public static void generateDefaultImplBody(
@NotNull MethodContext methodContext,
@NotNull JvmMethodSignature signature,
@NotNull FunctionDescriptor functionDescriptor,
boolean aStatic,
@NotNull MethodVisitor mv,
@NotNull DefaultParameterValueLoader loadStrategy,
@Nullable JetNamedFunction function,
@NotNull MemberCodegen<?> parentCodegen,
@NotNull GenerationState state
) {
FrameMap frameMap = new FrameMap();
if (!aStatic) {
frameMap.enterTemp(OBJECT_TYPE);
}
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, getParentCodegen());
ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, signature.getReturnType(), methodContext, state, parentCodegen);
Type[] argTypes = signature.getAsmMethod().getArgumentTypes();
List<ValueParameterDescriptor> paramDescrs = functionDescriptor.getValueParameters();
@@ -616,14 +627,18 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
int maskIndex = frameMap.enterTemp(Type.INT_TYPE);
CallGenerator generator = codegen.getOrCreateCallGenerator(functionDescriptor, function);
InstructionAdapter iv = new InstructionAdapter(mv);
loadExplicitArgumentsOnStack(iv, OBJECT_TYPE, aStatic, signature);
generator.putHiddenParams();
for (int index = 0; index < paramDescrs.size(); index++) {
ValueParameterDescriptor parameterDescriptor = paramDescrs.get(index);
Type t = argTypes[countOfExtraVarsInMethodArgs + index];
int parameterIndex = frameMap.getIndex(parameterDescriptor);
if (parameterDescriptor.declaresDefaultValue()) {
iv.load(maskIndex, Type.INT_TYPE);
iv.iconst(1 << index);
@@ -633,28 +648,24 @@ public class FunctionCodegen extends ParentCodegenAwareImpl {
loadStrategy.putValueOnStack(parameterDescriptor, codegen);
int ind = frameMap.getIndex(parameterDescriptor);
iv.store(ind, t);
iv.store(parameterIndex, t);
iv.mark(loadArg);
}
iv.load(frameMap.getIndex(parameterDescriptor), t);
generator.putValueIfNeeded(parameterDescriptor, t, StackValue.local(parameterIndex, t));
}
CallableMethod method;
if (functionDescriptor instanceof ConstructorDescriptor) {
method = typeMapper.mapToCallableMethod((ConstructorDescriptor) functionDescriptor);
method = state.getTypeMapper().mapToCallableMethod((ConstructorDescriptor) functionDescriptor);
} else {
method = typeMapper.mapToCallableMethod(functionDescriptor, false, methodContext);
method = state.getTypeMapper().mapToCallableMethod(functionDescriptor, false, methodContext);
}
iv.visitMethodInsn(method.getInvokeOpcode(), method.getOwner().getInternalName(), method.getAsmMethod().getName(),
method.getAsmMethod().getDescriptor());
generator.genCallWithoutNullAssertion(method, codegen);
iv.areturn(signature.getReturnType());
endVisit(mv, "default method", callableDescriptorToDeclaration(state.getBindingContext(), functionDescriptor));
}
@@ -871,7 +871,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Type propertyType = typeMapper.mapType(property);
codegen.intermediateValueForProperty(property, false, null).put(propertyType, codegen.v);
}
}
},
null
);
}
}
@@ -1135,7 +1136,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
);
functionCodegen.generateDefaultIfNeeded(constructorContext, constructorSignature, constructorDescriptor,
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT);
OwnerKind.IMPLEMENTATION, DefaultParameterValueLoader.DEFAULT, null);
CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor);
FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v);
@@ -56,6 +56,7 @@ import java.util.*;
import static org.jetbrains.jet.codegen.AsmUtil.getMethodAsmFlags;
import static org.jetbrains.jet.codegen.AsmUtil.isPrimitive;
import static org.jetbrains.jet.codegen.AsmUtil.isStatic;
public class InlineCodegen implements CallGenerator {
private final GenerationState state;
@@ -105,15 +106,19 @@ public class InlineCodegen implements CallGenerator {
JvmCodegenUtil.isCallInsideSameModuleAsDeclared(functionDescriptor, codegen.getContext());
}
@Override
public void genCallWithoutNullAssertion(
@NotNull CallableMethod callableMethod, @NotNull ExpressionCodegen codegen
) {
genCall(callableMethod, null, false, codegen);
}
@Override
public void genCall(CallableMethod callableMethod, ResolvedCall<?> resolvedCall, int mask, ExpressionCodegen codegen) {
assert mask == 0 : "Default method invocation couldn't be inlined " + resolvedCall;
public void genCall(@NotNull CallableMethod callableMethod, @Nullable ResolvedCall<?> resolvedCall, boolean callDefault, @NotNull ExpressionCodegen codegen) {
MethodNode node = null;
try {
node = createMethodNode(callableMethod);
node = createMethodNode(callDefault);
endCall(inlineCall(node));
}
catch (CompilationException e) {
@@ -139,17 +144,21 @@ public class InlineCodegen implements CallGenerator {
}
@NotNull
private MethodNode createMethodNode(CallableMethod callableMethod)
throws ClassNotFoundException, IOException {
private MethodNode createMethodNode(boolean callDefault) throws ClassNotFoundException, IOException {
JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());
Method asmMethod;
if (callDefault) {
asmMethod = typeMapper.mapDefaultMethod(functionDescriptor, context.getContextKind(), context);
}
else {
asmMethod = jvmSignature.getAsmMethod();
}
MethodNode node;
if (functionDescriptor instanceof DeserializedSimpleFunctionDescriptor) {
VirtualFile file = InlineCodegenUtil.getVirtualFileForCallable((DeserializedSimpleFunctionDescriptor) functionDescriptor, state);
String methodDesc = callableMethod.getAsmMethod().getDescriptor();
DeclarationDescriptor parentDescriptor = functionDescriptor.getContainingDeclaration();
if (DescriptorUtils.isTrait(parentDescriptor)) {
methodDesc = "(" + typeMapper.mapType((ClassDescriptor) parentDescriptor).getDescriptor() + methodDesc.substring(1);
}
node = InlineCodegenUtil.getMethodNode(file.getInputStream(), functionDescriptor.getName().asString(), methodDesc);
node = InlineCodegenUtil.getMethodNode(file.getInputStream(), asmMethod.getName(), asmMethod.getDescriptor());
if (node == null) {
throw new RuntimeException("Couldn't obtain compiled function body for " + descriptorName(functionDescriptor));
@@ -162,25 +171,33 @@ public class InlineCodegen implements CallGenerator {
throw new RuntimeException("Couldn't find declaration for function " + descriptorName(functionDescriptor));
}
JvmMethodSignature jvmSignature = typeMapper.mapSignature(functionDescriptor, context.getContextKind());
Method asmMethod = jvmSignature.getAsmMethod();
node = new MethodNode(InlineCodegenUtil.API,
getMethodAsmFlags(functionDescriptor, context.getContextKind()),
getMethodAsmFlags(functionDescriptor, context.getContextKind()) | (callDefault ? Opcodes.ACC_STATIC : 0),
asmMethod.getName(),
asmMethod.getDescriptor(),
jvmSignature.getGenericsSignature(),
null);
//for maxLocals calculation
MethodVisitor adapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node);
FunctionCodegen.generateMethodBody(adapter, functionDescriptor, context.getParentContext().intoFunction(functionDescriptor),
jvmSignature,
new FunctionGenerationStrategy.FunctionDefault(state,
functionDescriptor,
(JetDeclarationWithBody) element),
codegen.getParentCodegen());
adapter.visitMaxs(-1, -1);
adapter.visitEnd();
MethodVisitor maxCalcAdapter = InlineCodegenUtil.wrapWithMaxLocalCalc(node);
MethodContext methodContext = context.getParentContext().intoFunction(functionDescriptor);
MemberCodegen<?> parentCodegen = codegen.getParentCodegen();
if (callDefault) {
boolean isStatic = isStatic(codegen.getContext().getContextKind());
FunctionCodegen.generateDefaultImplBody(
methodContext, jvmSignature, functionDescriptor, isStatic, maxCalcAdapter, DefaultParameterValueLoader.DEFAULT,
(JetNamedFunction) element, parentCodegen, state
);
}
else {
FunctionCodegen.generateMethodBody(
maxCalcAdapter, functionDescriptor, methodContext, jvmSignature,
new FunctionGenerationStrategy.FunctionDefault(state, functionDescriptor, (JetDeclarationWithBody) element),
parentCodegen
);
}
maxCalcAdapter.visitMaxs(-1, -1);
maxCalcAdapter.visitEnd();
}
return node;
}
@@ -240,11 +257,11 @@ public class InlineCodegen implements CallGenerator {
@Override
public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, ValueParameterDescriptor valueParameterDescriptor) {
public void afterParameterPut(@NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor) {
putCapturedInLocal(type, stackValue, valueParameterDescriptor, -1);
}
public void putCapturedInLocal(
private void putCapturedInLocal(
@NotNull Type type, @Nullable StackValue stackValue, @Nullable ValueParameterDescriptor valueParameterDescriptor, int capturedParamIndex
) {
if (!asFunctionInline && Type.VOID_TYPE != type) {
@@ -449,13 +466,18 @@ public class InlineCodegen implements CallGenerator {
rememberClosure((JetFunctionLiteralExpression) argumentExpression, parameterType);
} else {
StackValue value = codegen.gen(argumentExpression);
if (shouldPutValue(parameterType, value, valueParameterDescriptor)) {
value.put(parameterType, codegen.v);
}
afterParameterPut(parameterType, value, valueParameterDescriptor);
putValueIfNeeded(valueParameterDescriptor, parameterType, value);
}
}
@Override
public void putValueIfNeeded(@Nullable ValueParameterDescriptor valueParameterDescriptor, @NotNull Type parameterType, @NotNull StackValue value) {
if (shouldPutValue(parameterType, value, valueParameterDescriptor)) {
value.put(parameterType, codegen.v);
}
afterParameterPut(parameterType, value, valueParameterDescriptor);
}
@Override
public void putCapturedValueOnStack(
@NotNull StackValue stackValue, @NotNull Type valueType, int paramIndex
@@ -45,12 +45,12 @@ import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe;
import org.jetbrains.jet.lang.types.*;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.org.objectweb.asm.Type;
import org.jetbrains.org.objectweb.asm.commons.Method;
import java.util.ArrayList;
import java.util.List;
import static org.jetbrains.jet.codegen.AsmUtil.boxType;
import static org.jetbrains.jet.codegen.AsmUtil.getTraitImplThisParameterType;
import static org.jetbrains.jet.codegen.AsmUtil.*;
import static org.jetbrains.jet.codegen.JvmCodegenUtil.*;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.isVarCapturedInClosure;
@@ -582,6 +582,19 @@ public class JetTypeMapper {
return sw.makeJvmMethodSignature(mapFunctionName(f));
}
@NotNull
public Method mapDefaultMethod(@NotNull FunctionDescriptor functionDescriptor, @NotNull OwnerKind kind, @NotNull CodegenContext<?> context) {
Method jvmSignature = mapSignature(functionDescriptor, kind).getAsmMethod();
Type ownerType = mapOwner(functionDescriptor, isCallInsideSameModuleAsDeclared(functionDescriptor, context));
String descriptor = jvmSignature.getDescriptor().replace(")", "I)");
boolean isConstructor = "<init>".equals(jvmSignature.getName());
if (!isStatic(kind) && !isConstructor) {
descriptor = descriptor.replace("(", "(" + ownerType.getDescriptor());
}
return new Method(isConstructor ? "<init>" : jvmSignature.getName() + JvmAbi.DEFAULT_PARAMS_IMPL_SUFFIX, descriptor);
}
/**
* @return true iff a given function descriptor should be compiled to a method with boxed return type regardless of whether return type
* of that descriptor is nullable or not. This happens when a function returning a value of a primitive type overrides another function
@@ -0,0 +1,22 @@
import test.*
fun simple(): String {
val k = "K"
return simpleFun(lambda = {it + "O"}) + simpleFun("K", {k + it})
}
fun simpleR(): String {
val k = "K"
return simpleFunR({it + "O"}) + simpleFunR({k + it}, "K")
}
fun box(): String {
var result = simple()
if (result != "OOKK") return "fail1: ${result}"
result = simpleR()
if (result != "OOKK") return "fail2: ${result}"
return "OK"
}
@@ -0,0 +1,12 @@
package test
inline fun <T> simpleFun(arg: String = "O", lambda: (String) -> T): T {
return lambda(arg)
}
inline fun <T> simpleFunR(lambda: (String) -> T, arg: String = "O"): T {
return lambda(arg)
}
@@ -0,0 +1,26 @@
import test.*
fun testCompilation(arg: String = getStringInline()): String {
return arg
}
inline fun testCompilationInline(arg: String = getStringInline()): String {
return arg
}
fun box(): String {
var result = testCompilation()
if (result != "OK") return "fail1: ${result}"
result = testCompilation("OKOK")
if (result != "OKOK") return "fail2: ${result}"
result = testCompilationInline()
if (result != "OK") return "fail3: ${result}"
result = testCompilationInline("OKOK")
if (result != "OKOK") return "fail4: ${result}"
return "OK"
}
@@ -0,0 +1,5 @@
package test
inline fun getStringInline(): String {
return "OK"
}
@@ -0,0 +1,22 @@
import test.*
fun testCompilation(): String {
emptyFun()
emptyFun("K")
return "OK"
}
fun simple(): String {
return simpleFun() + simpleFun("K")
}
fun box(): String {
var result = testCompilation()
if (result != "OK") return "fail1: ${result}"
result = simple()
if (result != "OK") return "fail2: ${result}"
return "OK"
}
@@ -0,0 +1,11 @@
package test
inline fun emptyFun(arg: String = "O") {
}
inline fun simpleFun(arg: String = "O"): String {
val r = arg;
return r;
}
@@ -91,6 +91,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenT
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/closureChain");
}
@TestMetadata("defaultMethod")
public void testDefaultMethod() throws Exception {
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/defaultMethod");
}
@TestMetadata("extension")
public void testExtension() throws Exception {
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/extension");
@@ -126,6 +131,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenT
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/inlineChain");
}
@TestMetadata("inlineInDefaultParameter")
public void testInlineInDefaultParameter() throws Exception {
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/inlineInDefaultParameter");
}
@TestMetadata("lambdaClassClash")
public void testLambdaClassClash() throws Exception {
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/lambdaClassClash");
@@ -221,6 +231,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxCodegenT
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/simpleCapturingInPackage");
}
@TestMetadata("simpleDefaultMethod")
public void testSimpleDefaultMethod() throws Exception {
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/simpleDefaultMethod");
}
@TestMetadata("simpleDouble")
public void testSimpleDouble() throws Exception {
doTestMultiFileWithInlineCheck("compiler/testData/codegen/boxInline/simpleDouble");
@@ -91,6 +91,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/closureChain");
}
@TestMetadata("defaultMethod")
public void testDefaultMethod() throws Exception {
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/defaultMethod");
}
@TestMetadata("extension")
public void testExtension() throws Exception {
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/extension");
@@ -126,6 +131,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/inlineChain");
}
@TestMetadata("inlineInDefaultParameter")
public void testInlineInDefaultParameter() throws Exception {
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/inlineInDefaultParameter");
}
@TestMetadata("lambdaClassClash")
public void testLambdaClassClash() throws Exception {
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/lambdaClassClash");
@@ -221,6 +231,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/simpleCapturingInPackage");
}
@TestMetadata("simpleDefaultMethod")
public void testSimpleDefaultMethod() throws Exception {
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/simpleDefaultMethod");
}
@TestMetadata("simpleDouble")
public void testSimpleDouble() throws Exception {
doBoxTestWithInlineCheck("compiler/testData/codegen/boxInline/simpleDouble");