From 82a4c94ec475102859feffa2c6c47efcd1b4d131 Mon Sep 17 00:00:00 2001 From: Jonathan Pobst Date: Fri, 19 Jul 2019 10:30:46 -0500 Subject: [PATCH] [generator] Strip arity from Cecil imported types. --- .../generator/Extensions/ManagedExtensions.cs | 20 +++++++++ .../CecilApiImporter.cs | 8 ++-- .../Unit-Tests/ManagedExtensionsTests.cs | 31 +++++++++++++ .../Tests/Unit-Tests/ManagedTests.cs | 44 +++++++++++++++++++ tools/generator/Tests/generator-Tests.csproj | 1 + 5 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 tools/generator/Tests/Unit-Tests/ManagedExtensionsTests.cs diff --git a/tools/generator/Extensions/ManagedExtensions.cs b/tools/generator/Extensions/ManagedExtensions.cs index 1bddc6ddd..8b345a2e5 100644 --- a/tools/generator/Extensions/ManagedExtensions.cs +++ b/tools/generator/Extensions/ManagedExtensions.cs @@ -45,6 +45,26 @@ public static IEnumerable GetParameters (this MethodDefinition m, Cus yield return CecilApiImporter.CreateParameter (p, type, rawtype); } } + + public static string StripArity (this string type) + { + if (string.IsNullOrWhiteSpace (type)) + return type; + + int tick_index; + + // Need to loop for things like List`1> + while ((tick_index = type.IndexOf ('`')) >= 0) { + var less_than_index = type.IndexOf ('<', tick_index); + + if (less_than_index == -1) + return type; + + type = type.Substring (0, tick_index) + type.Substring (less_than_index); + } + + return type; + } } #endif } diff --git a/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs b/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs index 00c1b000e..57df99319 100644 --- a/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs +++ b/tools/generator/Java.Interop.Tools.Generator.Importers/CecilApiImporter.cs @@ -93,7 +93,7 @@ public static Field CreateField (FieldDefinition f) IsStatic = f.IsStatic, JavaName = reg_attr != null ? ((string) reg_attr.ConstructorArguments [0].Value).Replace ('/', '.') : f.Name, Name = f.Name, - TypeName = f.FieldType.FullNameCorrected (), + TypeName = f.FieldType.FullNameCorrected ().StripArity (), Value = f.Constant == null ? null : f.FieldType.FullName == "System.String" ? '"' + f.Constant.ToString () + '"' : f.Constant.ToString (), Visibility = f.IsPublic ? "public" : f.IsFamilyOrAssembly ? "protected internal" : f.IsFamily ? "protected" : f.IsAssembly ? "internal" : "private" }; @@ -181,8 +181,8 @@ public static Method CreateMethod (GenBase declaringType, MethodDefinition m) IsStatic = m.IsStatic, IsVirtual = m.IsVirtual, JavaName = reg_attr != null ? ((string) reg_attr.ConstructorArguments [0].Value) : m.Name, - ManagedReturn = m.ReturnType.FullNameCorrected (), - Return = m.ReturnType.FullNameCorrected (), + ManagedReturn = m.ReturnType.FullNameCorrected ().StripArity (), + Return = m.ReturnType.FullNameCorrected ().StripArity (), Visibility = m.Visibility () }; @@ -211,7 +211,7 @@ public static Parameter CreateParameter (ParameterDefinition p, string jnitype, // FIXME: safe to use CLR type name? assuming yes as we often use it in metadatamap. // FIXME: IsSender? var isEnumType = GetGeneratedEnumAttribute (p.CustomAttributes) != null;; - return new Parameter (SymbolTable.MangleName (p.Name), jnitype ?? p.ParameterType.FullNameCorrected (), null, isEnumType, rawtype); + return new Parameter (SymbolTable.MangleName (p.Name), jnitype ?? p.ParameterType.FullNameCorrected ().StripArity (), null, isEnumType, rawtype); } public static Parameter CreateParameter (string managedType, string javaType) diff --git a/tools/generator/Tests/Unit-Tests/ManagedExtensionsTests.cs b/tools/generator/Tests/Unit-Tests/ManagedExtensionsTests.cs new file mode 100644 index 000000000..562afb84a --- /dev/null +++ b/tools/generator/Tests/Unit-Tests/ManagedExtensionsTests.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MonoDroid.Generation; +using NUnit.Framework; + +namespace generatortests +{ + [TestFixture] + public class ManagedExtensionsTests + { + [Test] + public void StripArity () + { + Assert.AreEqual ("List", "List`1".StripArity ()); + Assert.AreEqual ("List>", "List`10>".StripArity ()); + Assert.AreEqual ("List", "List".StripArity ()); + Assert.AreEqual ("List`1", "List`1".StripArity ()); + Assert.AreEqual ("List", "List`1".StripArity ()); + Assert.AreEqual ("List", "List`1`".StripArity ()); + Assert.AreEqual ("List<", "List`1<".StripArity ()); + Assert.AreEqual ("List<", "List`<".StripArity ()); + Assert.AreEqual ("<", "`1<".StripArity ()); + Assert.AreEqual ("`", "`".StripArity ()); + Assert.AreEqual (string.Empty, string.Empty.StripArity ()); + Assert.IsNull ((null as string).StripArity ()); + } + } +} diff --git a/tools/generator/Tests/Unit-Tests/ManagedTests.cs b/tools/generator/Tests/Unit-Tests/ManagedTests.cs index 7e50073d5..e880fe213 100644 --- a/tools/generator/Tests/Unit-Tests/ManagedTests.cs +++ b/tools/generator/Tests/Unit-Tests/ManagedTests.cs @@ -2,6 +2,7 @@ using Mono.Cecil; using MonoDroid.Generation; using NUnit.Framework; +using System.Collections.Generic; using System.IO; using System.Linq; @@ -42,6 +43,27 @@ public void UnknownTypes (object unknown) { } public interface IService { } } +namespace GenericTestClasses +{ + public class MyCollection : List + { + [Register ("mycollection", "()V", "")] + public MyCollection (List p0, List p1) + { + } + + public List field; + + public Dictionary field2; + + [Register ("dostuff", "()V", "")] + public Dictionary> DoStuff (IEnumerable>>> p) + { + return new Dictionary> (); + } + } +} + namespace generatortests { [TestFixture] @@ -206,5 +228,27 @@ public void Interface () Assert.AreEqual ("com.mypackage.service", @interface.JavaName); Assert.AreEqual ("Lcom/mypackage/service;", @interface.JniName); } + + [Test] + public void StripArity () + { + var @class = CecilApiImporter.CreateClass (module.GetType ("GenericTestClasses.MyCollection`1"), options); + + // Class (Leave Arity on types) + Assert.AreEqual ("GenericTestClasses.MyCollection`1", @class.FullName); + + // Constructor + Assert.AreEqual ("System.Collections.Generic.List", @class.Ctors [0].Parameters [0].RawNativeType); + Assert.AreEqual ("System.Collections.Generic.List", @class.Ctors [0].Parameters [1].RawNativeType); + + // Field + Assert.AreEqual ("System.Collections.Generic.List", @class.Fields [0].TypeName); + Assert.AreEqual ("System.Collections.Generic.Dictionary", @class.Fields [1].TypeName); + + // Method + Assert.AreEqual ("System.Collections.Generic.IEnumerable>>>", @class.Methods [0].Parameters [0].RawNativeType); + Assert.AreEqual ("System.Collections.Generic.Dictionary>", @class.Methods [0].ReturnType); + Assert.AreEqual ("System.Collections.Generic.Dictionary>", @class.Methods [0].ManagedReturn); + } } } diff --git a/tools/generator/Tests/generator-Tests.csproj b/tools/generator/Tests/generator-Tests.csproj index 6ec10faa6..6bc9b3336 100644 --- a/tools/generator/Tests/generator-Tests.csproj +++ b/tools/generator/Tests/generator-Tests.csproj @@ -74,6 +74,7 @@ +