Vararg in constructor isn't loaded correctly from bytecode
#KT-3251 Fixed
This commit is contained in:
@@ -127,6 +127,51 @@ public class AsmUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isAbstract(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
return (functionDescriptor.getModality() == Modality.ABSTRACT
|
||||
|| isInterface(functionDescriptor.getContainingDeclaration()))
|
||||
&& !isStatic(kind)
|
||||
&& kind != OwnerKind.TRAIT_IMPL;
|
||||
}
|
||||
|
||||
public static boolean isStatic(OwnerKind kind) {
|
||||
return kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind;
|
||||
}
|
||||
|
||||
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
boolean isStatic = isStatic(kind);
|
||||
boolean isAbstract = isAbstract(functionDescriptor, kind);
|
||||
|
||||
int flags = getCommonCallableFlags(functionDescriptor);
|
||||
|
||||
if (functionDescriptor.getModality() == Modality.FINAL) {
|
||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||
if (!(containingDeclaration instanceof ClassDescriptor) ||
|
||||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) {
|
||||
flags |= ACC_FINAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (isStatic || kind == OwnerKind.TRAIT_IMPL) {
|
||||
flags |= ACC_STATIC;
|
||||
}
|
||||
|
||||
if (isAbstract) flags |= ACC_ABSTRACT;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static int getConstructorAsmFlags(FunctionDescriptor functionDescriptor) {
|
||||
return getCommonCallableFlags(functionDescriptor);
|
||||
}
|
||||
|
||||
private static int getCommonCallableFlags(FunctionDescriptor functionDescriptor) {
|
||||
int flags = getVisibilityAccessFlag(functionDescriptor);
|
||||
flags |= getVarargsFlag(functionDescriptor);
|
||||
flags |= getDeprecatedAccessFlag(functionDescriptor);
|
||||
return flags;
|
||||
}
|
||||
|
||||
//TODO: move mapping logic to front-end java
|
||||
public static int getVisibilityAccessFlag(@NotNull MemberDescriptor descriptor) {
|
||||
Integer specialCase = specialCaseVisibility(descriptor);
|
||||
@@ -175,6 +220,15 @@ public class AsmUtil {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private static int getVarargsFlag(FunctionDescriptor functionDescriptor) {
|
||||
if (!functionDescriptor.getValueParameters().isEmpty()
|
||||
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
|
||||
.getVarargElementType() != null) {
|
||||
return ACC_VARARGS;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Integer specialCaseVisibility(@NotNull MemberDescriptor memberDescriptor) {
|
||||
DeclarationDescriptor containingDeclaration = memberDescriptor.getContainingDeclaration();
|
||||
|
||||
@@ -338,50 +338,6 @@ public class FunctionCodegen extends GenerationStateAware {
|
||||
iv.areturn(asmMethod.getReturnType());
|
||||
}
|
||||
|
||||
private static boolean isAbstract(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
return (functionDescriptor.getModality() == Modality.ABSTRACT
|
||||
|| isInterface(functionDescriptor.getContainingDeclaration())
|
||||
)
|
||||
&& !isStatic(kind)
|
||||
&& kind != OwnerKind.TRAIT_IMPL;
|
||||
}
|
||||
|
||||
public static int getMethodAsmFlags(FunctionDescriptor functionDescriptor, OwnerKind kind) {
|
||||
boolean isStatic = isStatic(kind);
|
||||
boolean isAbstract = isAbstract(functionDescriptor, kind);
|
||||
|
||||
int flags = getVisibilityAccessFlag(functionDescriptor);
|
||||
|
||||
if (!functionDescriptor.getValueParameters().isEmpty()
|
||||
&& functionDescriptor.getValueParameters().get(functionDescriptor.getValueParameters().size() - 1)
|
||||
.getVarargElementType() != null) {
|
||||
flags |= ACC_VARARGS;
|
||||
}
|
||||
|
||||
if (functionDescriptor.getModality() == Modality.FINAL) {
|
||||
DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration();
|
||||
if (!(containingDeclaration instanceof ClassDescriptor) ||
|
||||
((ClassDescriptor) containingDeclaration).getKind() != ClassKind.TRAIT) {
|
||||
flags |= ACC_FINAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (isStatic || kind == OwnerKind.TRAIT_IMPL) {
|
||||
flags |= ACC_STATIC;
|
||||
}
|
||||
|
||||
if (isAbstract) flags |= ACC_ABSTRACT;
|
||||
|
||||
if (KotlinBuiltIns.getInstance().isDeprecated(functionDescriptor)) {
|
||||
flags |= ACC_DEPRECATED;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
private static boolean isStatic(OwnerKind kind) {
|
||||
return kind == OwnerKind.NAMESPACE || kind instanceof OwnerKind.StaticDelegateKind;
|
||||
}
|
||||
|
||||
public static void genJetAnnotations(
|
||||
@NotNull GenerationState state,
|
||||
@NotNull FunctionDescriptor functionDescriptor,
|
||||
|
||||
@@ -629,7 +629,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
|
||||
final String desc = "()" + componentType.getDescriptor();
|
||||
MethodVisitor mv = v.newMethod(myClass,
|
||||
FunctionCodegen.getMethodAsmFlags(function, OwnerKind.IMPLEMENTATION),
|
||||
AsmUtil.getMethodAsmFlags(function, OwnerKind.IMPLEMENTATION),
|
||||
function.getName().getName(),
|
||||
desc,
|
||||
null, null);
|
||||
@@ -654,7 +654,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
JvmMethodSignature methodSignature = typeMapper.mapSignature(function.getName(), function);
|
||||
final String methodDesc = methodSignature.getAsmMethod().getDescriptor();
|
||||
|
||||
MethodVisitor mv = v.newMethod(myClass, FunctionCodegen.getMethodAsmFlags(function, OwnerKind.IMPLEMENTATION),
|
||||
MethodVisitor mv = v.newMethod(myClass, AsmUtil.getMethodAsmFlags(function, OwnerKind.IMPLEMENTATION),
|
||||
function.getName().getName(), methodDesc,
|
||||
null, null);
|
||||
|
||||
@@ -931,7 +931,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
||||
final JvmMethodSignature constructorMethod = callableMethod.getSignature();
|
||||
|
||||
assert constructorDescriptor != null;
|
||||
int flags = getVisibilityAccessFlag(constructorDescriptor);
|
||||
int flags = getConstructorAsmFlags(constructorDescriptor);
|
||||
final MethodVisitor mv = v.newMethod(myClass, flags, constructorMethod.getName(), constructorMethod.getAsmMethod().getDescriptor(),
|
||||
constructorMethod.getGenericsSignature(), null);
|
||||
if (state.getClassBuilderMode() != ClassBuilderMode.SIGNATURES) {
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class A(vararg s: String) {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
fun main(args: Array<String>) {
|
||||
A()
|
||||
A("a")
|
||||
A("a", "b")
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package test
|
||||
|
||||
class A(vararg a: Int) {}
|
||||
@@ -0,0 +1,5 @@
|
||||
package test
|
||||
|
||||
internal final class A {
|
||||
/*primary*/ public constructor A(/*0*/ vararg a : jet.Int /*jet.IntArray*/)
|
||||
}
|
||||
+5
@@ -38,6 +38,11 @@ public class CompileKotlinAgainstKotlinTestGenerated extends AbstractCompileKotl
|
||||
doTest("compiler/testData/compileKotlinAgainstKotlin/ClassObjectMember.A.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorVararg.A.kt")
|
||||
public void testConstructorVararg_A() throws Exception {
|
||||
doTest("compiler/testData/compileKotlinAgainstKotlin/ConstructorVararg.A.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("DefaultConstructor.A.kt")
|
||||
public void testDefaultConstructor_A() throws Exception {
|
||||
doTest("compiler/testData/compileKotlinAgainstKotlin/DefaultConstructor.A.kt");
|
||||
|
||||
@@ -269,6 +269,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT
|
||||
doTest("compiler/testData/loadKotlin/constructor/ConstructorCollectionParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorVararg.kt")
|
||||
public void testConstructorVararg() throws Exception {
|
||||
doTest("compiler/testData/loadKotlin/constructor/ConstructorVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorWithTwoDefArgs.kt")
|
||||
public void testConstructorWithTwoDefArgs() throws Exception {
|
||||
doTest("compiler/testData/loadKotlin/constructor/ConstructorWithTwoDefArgs.kt");
|
||||
|
||||
+5
@@ -271,6 +271,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso
|
||||
doTestCheckingPrimaryConstructors("compiler/testData/loadKotlin/constructor/ConstructorCollectionParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorVararg.kt")
|
||||
public void testConstructorVararg() throws Exception {
|
||||
doTestCheckingPrimaryConstructors("compiler/testData/loadKotlin/constructor/ConstructorVararg.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("ConstructorWithTwoDefArgs.kt")
|
||||
public void testConstructorWithTwoDefArgs() throws Exception {
|
||||
doTestCheckingPrimaryConstructors("compiler/testData/loadKotlin/constructor/ConstructorWithTwoDefArgs.kt");
|
||||
|
||||
Reference in New Issue
Block a user