diff --git a/src/Xamarin.Android.Tools.Bytecode/AttributeInfo.cs b/src/Xamarin.Android.Tools.Bytecode/AttributeInfo.cs index c58918a18..62ae790e9 100644 --- a/src/Xamarin.Android.Tools.Bytecode/AttributeInfo.cs +++ b/src/Xamarin.Android.Tools.Bytecode/AttributeInfo.cs @@ -429,7 +429,7 @@ public string Descriptor { public override string ToString () { - return string.Format ("LocalVariableTableEntry(Name='{0}', Descriptor='{1}')", Name, Descriptor); + return $"LocalVariableTableEntry(Name='{Name}', Descriptor='{Descriptor}', StartPC={StartPC}, Index={Index})"; } } diff --git a/src/Xamarin.Android.Tools.Bytecode/ClassFile.cs b/src/Xamarin.Android.Tools.Bytecode/ClassFile.cs index 2ab54dd28..9763c7743 100644 --- a/src/Xamarin.Android.Tools.Bytecode/ClassFile.cs +++ b/src/Xamarin.Android.Tools.Bytecode/ClassFile.cs @@ -98,6 +98,8 @@ public string PackageName { } } + public string FullJniName => "L" + ThisClass.Name.Value + ";"; + public string SourceFileName { get { var sourceFile = Attributes.Get (); diff --git a/src/Xamarin.Android.Tools.Bytecode/Methods.cs b/src/Xamarin.Android.Tools.Bytecode/Methods.cs index 3add9fcdd..c73335607 100644 --- a/src/Xamarin.Android.Tools.Bytecode/Methods.cs +++ b/src/Xamarin.Android.Tools.Bytecode/Methods.cs @@ -90,17 +90,21 @@ public ParameterInfo[] GetParameters () if (locals != null) { var names = locals.LocalVariables.Where (p => p.StartPC == 0).ToList (); int start = 0; - if ((AccessFlags & MethodAccessFlags.Static) == 0) + if (names.Count != parameters.Length && + !AccessFlags.HasFlag (MethodAccessFlags.Static) && + names.Count > start && + names [start].Descriptor == DeclaringType.FullJniName) { start++; // skip `this` parameter + } if (!DeclaringType.IsStatic && names.Count > start && (parameters.Length == 0 || parameters [0].Type.BinaryName != names [start].Descriptor)) { start++; // JDK 8? } - if (((AccessFlags & MethodAccessFlags.Synthetic) != MethodAccessFlags.Synthetic) && + if (!AccessFlags.HasFlag (MethodAccessFlags.Synthetic) && ((names.Count - start) != parameters.Length) && !enumCtor) { - Log.Warning (1,"class-parse: warning: method {0}.{1}{2}: " + + Log.Debug ("class-parse: method {0}.{1}{2}: " + "Local variables array has {3} entries ('{4}'); descriptor has {5} entries!", DeclaringType.ThisClass.Name.Value, Name, Descriptor, names.Count - start, @@ -111,7 +115,7 @@ public ParameterInfo[] GetParameters () for (int i = 0; i < max; ++i) { parameters [i].Name = names [start+i].Name; if (parameters [i].Type.BinaryName != names [start + i].Descriptor) { - Log.Warning (1, "class-parse: warning: method {0}.{1}{2}: " + + Log.Debug ("class-parse: method {0}.{1}{2}: " + "Local variable type descriptor mismatch! Got '{3}'; expected '{4}'.", DeclaringType.ThisClass.Name.Value, Name, Descriptor, parameters [i].Type.BinaryName, @@ -122,7 +126,7 @@ public ParameterInfo[] GetParameters () var sig = GetSignature (); if (sig != null) { if ((sig.Parameters.Count != parameters.Length) && !enumCtor) { - Log.Warning (1,"class-parse: warning: method {0}.{1}{2}: " + + Log.Debug ("class-parse: method {0}.{1}{2}: " + "Signature ('{3}') has {4} entries; Descriptor '{5}' has {6} entries!", DeclaringType.ThisClass.Name.Value, Name, Descriptor, Attributes.Get(), diff --git a/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs b/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs index a5d5b35e8..ccbacb489 100644 --- a/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs +++ b/src/Xamarin.Android.Tools.Bytecode/XmlClassDeclarationBuilder.cs @@ -39,7 +39,7 @@ public XElement ToXElement () GetExtendsGenericAware (), new XAttribute ("final", (classFile.AccessFlags & ClassAccessFlags.Final) != 0), new XAttribute ("name", GetThisClassName ()), - new XAttribute ("jni-signature", "L" + classFile.ThisClass.Name.Value + ";"), + new XAttribute ("jni-signature", classFile.FullJniName), GetSourceFile (), new XAttribute ("static", classFile.IsStatic), new XAttribute ("visibility", GetVisibility (classFile.Visibility)), diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/JvmOverloadsConstructorTests.cs b/tests/Xamarin.Android.Tools.Bytecode-Tests/JvmOverloadsConstructorTests.cs new file mode 100644 index 000000000..f9fd5cec7 --- /dev/null +++ b/tests/Xamarin.Android.Tools.Bytecode-Tests/JvmOverloadsConstructorTests.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +using Xamarin.Android.Tools.Bytecode; + +using NUnit.Framework; + +using Assembly = System.Reflection.Assembly; + +namespace Xamarin.Android.Tools.BytecodeTests { + + [TestFixture] + public class JvmOverloadsConstructorTests : ClassFileFixture { + + const string ClassFile = "JvmOverloadsConstructor.class"; + const string XmlFile = "JvmOverloadsConstructor.xml"; + + [Test] + public void ClassFile_WithJavaType_class () + { + var c = LoadClassFile (ClassFile); + new ExpectedTypeDeclaration { + MajorVersion = 0x32, + MinorVersion = 0, + ConstantPoolCount = 59, + AccessFlags = ClassAccessFlags.Public | ClassAccessFlags.Final | ClassAccessFlags.Super, + FullName = "JvmOverloadsConstructor", + Superclass = new TypeInfo ("java/lang/Object", "Ljava/lang/Object;"), + Methods = { + new ExpectedMethodDeclaration { + Name = "", + AccessFlags = MethodAccessFlags.Public, + ReturnDescriptor = "V", + Parameters = { + new ParameterInfo ("something", "LJvmOverloadsConstructor;", "LJvmOverloadsConstructor;"), + new ParameterInfo ("id", "I", "I"), + new ParameterInfo ("imageId", "I", "I"), + new ParameterInfo ("title", "Ljava/lang/String;", "Ljava/lang/String;"), + new ParameterInfo ("useDivider", "Z", "Z"), + }, + }, + new ExpectedMethodDeclaration { + Name = "", + AccessFlags = MethodAccessFlags.Public | MethodAccessFlags.Synthetic, + ReturnDescriptor = "V", + Parameters = { + new ParameterInfo ("p0", "LJvmOverloadsConstructor;", "LJvmOverloadsConstructor;"), + new ParameterInfo ("p1", "I", "I"), + new ParameterInfo ("p2", "I", "I"), + new ParameterInfo ("p3", "Ljava/lang/String;", "Ljava/lang/String;"), + new ParameterInfo ("p4", "Z", "Z"), + new ParameterInfo ("p5", "I", "I"), + new ParameterInfo ("p6", "Lkotlin/jvm/internal/DefaultConstructorMarker;", "Lkotlin/jvm/internal/DefaultConstructorMarker;"), + }, + }, + new ExpectedMethodDeclaration { + Name = "", + AccessFlags = MethodAccessFlags.Public, + ReturnDescriptor = "V", + Parameters = { + new ParameterInfo ("something", "LJvmOverloadsConstructor;", "LJvmOverloadsConstructor;"), + new ParameterInfo ("id", "I", "I"), + new ParameterInfo ("imageId", "I", "I"), + new ParameterInfo ("title", "Ljava/lang/String;", "Ljava/lang/String;"), + }, + }, + new ExpectedMethodDeclaration { + Name = "", + AccessFlags = MethodAccessFlags.Public, + ReturnDescriptor = "V", + Parameters = { + new ParameterInfo ("something", "LJvmOverloadsConstructor;", "LJvmOverloadsConstructor;"), + new ParameterInfo ("id", "I", "I"), + new ParameterInfo ("title", "Ljava/lang/String;", "Ljava/lang/String;"), + }, + }, + new ExpectedMethodDeclaration { + Name = "", + AccessFlags = MethodAccessFlags.Public, + ReturnDescriptor = "V", + Parameters = { + new ParameterInfo ("something", "LJvmOverloadsConstructor;", "LJvmOverloadsConstructor;"), + new ParameterInfo ("title", "Ljava/lang/String;", "Ljava/lang/String;"), + }, + }, + }, + }.Assert (c); + } + + [Test] + public void XmlDeclaration_WithJavaType_class () + { + AssertXmlDeclaration (ClassFile, XmlFile); + } + } +} + diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/Resources/JvmOverloadsConstructor.xml b/tests/Xamarin.Android.Tools.Bytecode-Tests/Resources/JvmOverloadsConstructor.xml new file mode 100644 index 000000000..3cf7ae7e2 --- /dev/null +++ b/tests/Xamarin.Android.Tools.Bytecode-Tests/Resources/JvmOverloadsConstructor.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/JvmOverloadsConstructor.class b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/JvmOverloadsConstructor.class new file mode 100644 index 000000000..6a23a3a7d Binary files /dev/null and b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/JvmOverloadsConstructor.class differ diff --git a/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/JvmOverloadsConstructor.kt b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/JvmOverloadsConstructor.kt new file mode 100644 index 000000000..3e5c00f13 --- /dev/null +++ b/tests/Xamarin.Android.Tools.Bytecode-Tests/kotlin/JvmOverloadsConstructor.kt @@ -0,0 +1,11 @@ +class JvmOverloadsConstructor { + @JvmOverloads + constructor( + something : JvmOverloadsConstructor, + id: Int = 1, + imageId: Int = 2, + title: String, + useDivider: Boolean = false + ) { + } +}