diff --git a/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs b/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs index 9d4db08f4..aee01e485 100644 --- a/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs +++ b/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs @@ -17,6 +17,7 @@ public enum JavaDocletType { Java6, Java7, Java8, + _ApiXml } public class ClassPath { @@ -217,20 +218,21 @@ void FixupParametersFromDocs (XElement api) if (DocumentationPaths == null) return; foreach (var path in DocumentationPaths) { - if (!Directory.Exists (path)) + if (!Directory.Exists (path) && !File.Exists (path)) continue; FixupParametersFromDocs (api, path); } } - AndroidDocScraper CreateDocScraper (string dir) + IAndroidDocScraper CreateDocScraper (string src) { switch (DocletType) { - default: return new DroidDoc2Scraper (dir); - case JavaDocletType.DroidDoc: return new DroidDocScraper (dir); - case JavaDocletType.Java6: return new JavaDocScraper (dir); - case JavaDocletType.Java7: return new Java7DocScraper (dir); - case JavaDocletType.Java8: return new Java8DocScraper (dir); + default: return new DroidDoc2Scraper (src); + case JavaDocletType.DroidDoc: return new DroidDocScraper (src); + case JavaDocletType.Java6: return new JavaDocScraper (src); + case JavaDocletType.Java7: return new Java7DocScraper (src); + case JavaDocletType.Java8: return new Java8DocScraper (src); + case JavaDocletType._ApiXml: return new ApiXmlDocScraper (src); } } diff --git a/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs b/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs index be69ce441..1438841f6 100644 --- a/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs +++ b/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs @@ -125,7 +125,7 @@ public Java8DocScraper (string dir) } } - public abstract class AndroidDocScraper + public abstract class AndroidDocScraper : IAndroidDocScraper { readonly String pattern_head; readonly String reset_pattern_head; @@ -269,6 +269,54 @@ public static void LoadXml (String filename) } catch (Exception ex) { Log.Error ("Annotations parser error: " + ex); } - } + } + } + + public interface IAndroidDocScraper + { + String[] GetParameterNames (string package, string type, string method, string[] ptypes, bool isVarArgs); + } + + public class ApiXmlDocScraper : IAndroidDocScraper + { + public ApiXmlDocScraper (string apiXmlFile) + { + xdoc = XDocument.Load (apiXmlFile); + } + + XDocument xdoc; + + public string[] GetParameterNames (string package, string type, string method, string[] ptypes, bool isVarArgs) + { + var methodOrCtor = method == "constructor" ? + "constructor[" : $"method[@name='{method}'"; + + var pcount = ptypes.Length; + + var xpath = new StringBuilder (); + + xpath.Append ($"/api/package[@name='{package}']/*[self::class or self::interface]/"); + + if (method == "constructor") + xpath.Append ("constructor["); + else + xpath.Append ($"method[@name='{method}'"); + + xpath.Append ($" and count(parameter)={pcount}"); + + if (pcount > 0) { + xpath.Append (" and "); + xpath.Append (string.Join (" and ", ptypes.Select ((pt, pindex) => $"parameter[{pindex + 1}][@type='{pt}']"))); + } + + xpath.Append ("]"); + + var methodElem = xdoc.XPathSelectElement (xpath.ToString ()); + + if (methodElem != null) + return methodElem.Elements ("parameter").Select (pe => pe.Attribute ("name")?.Value).ToArray (); + + return new string[0]; + } } } diff --git a/src/Xamarin.Android.Tools.Bytecode/Tests/ClassFileFixture.cs b/src/Xamarin.Android.Tools.Bytecode/Tests/ClassFileFixture.cs index 3fa30b30c..e305de8f2 100644 --- a/src/Xamarin.Android.Tools.Bytecode/Tests/ClassFileFixture.cs +++ b/src/Xamarin.Android.Tools.Bytecode/Tests/ClassFileFixture.cs @@ -25,7 +25,7 @@ protected static string LoadString (string resource) return r.ReadToEnd (); } - protected static void AssertXmlDeclaration (string classResource, string xmlResource, string documentationPath = null) + protected static void AssertXmlDeclaration (string classResource, string xmlResource, string documentationPath = null, JavaDocletType? javaDocletType = null) { var classPathBuilder = new ClassPath () { ApiSource = "class-parse", @@ -33,10 +33,14 @@ protected static void AssertXmlDeclaration (string classResource, string xmlReso documentationPath, }, }; + if (javaDocletType.HasValue) + classPathBuilder.DocletType = javaDocletType.Value; classPathBuilder.Add (LoadClassFile (classResource)); var actual = new StringWriter (); classPathBuilder.ApiSource = "class-parse"; + if (javaDocletType.HasValue) + classPathBuilder.DocletType = javaDocletType.Value; classPathBuilder.SaveXmlDescription (actual); var expected = LoadString (xmlResource); diff --git a/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupApiXmlDocs.xml b/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupApiXmlDocs.xml new file mode 100644 index 000000000..81696912a --- /dev/null +++ b/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupApiXmlDocs.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupTests.cs b/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupTests.cs index 410a1990e..e7b4035e3 100644 --- a/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupTests.cs +++ b/src/Xamarin.Android.Tools.Bytecode/Tests/ParameterFixupTests.cs @@ -29,6 +29,31 @@ public void XmlDeclaration_FixedUpFromDocumentation() } } + [Test] + public void XmlDeclaration_FixedUpFromApiXmlDocumentation() + { + string tempFile = null; + + try + { + tempFile = Path.GetTempFileName(); + File.WriteAllText(tempFile, LoadString("ParameterFixupApiXmlDocs.xml")); + + AssertXmlDeclaration("Collection.class", "ParameterFixupFromDocs.xml", tempFile, Bytecode.JavaDocletType._ApiXml); + } + catch (Exception ex) + { + try + { + if (File.Exists(tempFile)) + File.Delete(tempFile); + } + catch { } + + Assert.Fail("An unexpected exception was thrown : {0}", ex); + } + } + [Test] public void XmlDeclaration_DoesNotThrowAnExceptionIfDocumentationNotFound () { diff --git a/src/Xamarin.Android.Tools.Bytecode/Tests/Xamarin.Android.Tools.Bytecode-Tests.csproj b/src/Xamarin.Android.Tools.Bytecode/Tests/Xamarin.Android.Tools.Bytecode-Tests.csproj index e710d0487..efa111cc3 100644 --- a/src/Xamarin.Android.Tools.Bytecode/Tests/Xamarin.Android.Tools.Bytecode-Tests.csproj +++ b/src/Xamarin.Android.Tools.Bytecode/Tests/Xamarin.Android.Tools.Bytecode-Tests.csproj @@ -151,6 +151,9 @@ Collection.class + + ParameterFixupApiXmlDocs.xml + diff --git a/tools/class-parse/Program.cs b/tools/class-parse/Program.cs index 8b85470a4..a426ca699 100644 --- a/tools/class-parse/Program.cs +++ b/tools/class-parse/Program.cs @@ -94,6 +94,7 @@ public static void Main (string[] args) { "java6", JavaDocletType.Java6 }, { "java7", JavaDocletType.Java7 }, { "java8", JavaDocletType.Java8 }, + { "apixml", JavaDocletType.ApiXml }, }; static JavaDocletType GetJavaDocletType (string value)