diff --git a/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs b/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs index 84a67af3f..9d4db08f4 100644 --- a/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs +++ b/src/Xamarin.Android.Tools.Bytecode/ClassPath.cs @@ -13,6 +13,7 @@ namespace Xamarin.Android.Tools.Bytecode { public enum JavaDocletType { DroidDoc, + DroidDoc2, Java6, Java7, Java8, @@ -225,7 +226,8 @@ void FixupParametersFromDocs (XElement api) AndroidDocScraper CreateDocScraper (string dir) { switch (DocletType) { - default: return new DroidDocScraper (dir); + 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); diff --git a/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs b/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs index 113d69bfd..be69ce441 100644 --- a/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs +++ b/src/Xamarin.Android.Tools.Bytecode/JavaDocumentScraper.cs @@ -35,20 +35,60 @@ namespace Xamarin.Android.Tools.Bytecode { enum JavaDocKind { DroidDoc, + DroidDoc2, Java6, - Java7 + Java7, + Java8 } class DroidDocScraper : AndroidDocScraper { const String pattern_head_droiddoc = ".*.*") + { + } + + string prev_path; + string [] prev_contents; + + protected override IEnumerable GetContentLines (string path) + { + if (prev_path == path) + return prev_contents; + else { + prev_path = path; + string all = File.ReadAllText (path).Replace ('\r', ' ').Replace ('\n', ' '); + int start = all.IndexOf ("", StringComparison.Ordinal); + all = start < 0 ? all : all.Substring (start); + int end = all.IndexOf ("", StringComparison.Ordinal); + all = end < 0 ? all : all.Substring (0, end); + // ... is the basic structure so is used as the end of member, but we also use

here. + // Sometimes another can appear after "" (for the end of context member) and that messes regex match. + // So, with any

, we interrupt consecutive matches. + prev_contents = all.Split (new string [] { "

", "" }, StringSplitOptions.RemoveEmptyEntries); + return prev_contents; + } + } + + protected override bool ShouldResetMatchBuffer (string text) + { + return true; + } + } + class JavaDocScraper : AndroidDocScraper { const String pattern_head_javadoc = " GetContentLines (string path) { - string pkgName = packageDir.Replace ('/', '.'); - string className = Path.GetFileNameWithoutExtension (file).Replace ('$', '.'); - - string html = File.ReadAllText (file); + return File.ReadAllText (path).Split ('\n'); + } + + protected virtual bool ShouldResetMatchBuffer (string text) + { + // sometimes we get incomplete tag, so cache it until it gets complete or matched. + // I *know* this is a hack. + return reset_pattern_head == null || text.EndsWith (">", StringComparison.Ordinal) || !continuous_param_lines && !text.StartsWith (reset_pattern_head, StringComparison.Ordinal); } - public String[] GetParameterNames (string package, string type, string method, string[] ptypes, bool isVarArgs) + public virtual String[] GetParameterNames (string package, string type, string method, string[] ptypes, bool isVarArgs) { - String path = package.Replace ('.', '/') + '/' + type.Replace ('$', '.') + ".html"; + string path = package.Replace ('.', '/') + '/' + type.Replace ('$', '.') + ".html"; string file = Path.Combine (root, path); if (!File.Exists (file)) { Log.Warning (1,"Warning: no document found : " + file); @@ -153,44 +199,39 @@ public String[] GetParameterNames (string package, string type, string method, s buffer.Append (param_sep); buffer.Append (ptypes [i].Replace ('$', '.')); } + buffer.Replace ("[", "\\[").Replace ("]", "\\]"); buffer.Append (close_method); - buffer.Append ("\".*\\((.*)\\)"); - buffer.Replace ("[", "\\[").Replace ("]", "\\]").Replace ("?", "\\?"); + buffer.Append ("\".*\\(([^(]*)\\)"); + buffer.Append (post_close_method_parens); + buffer.Replace ("?", "\\?"); Regex pattern = new Regex (buffer.ToString (), RegexOptions.Multiline); try { - var reader = File.OpenText (file); - try { - String text = ""; - String prev = null; - while ((text = reader.ReadLine ()) != null) { - if (prev != null) - prev = text = prev + text; - var matcher = pattern.Match (text); - if (matcher.Success) { - var plist = matcher.Groups [1]; - String[] parms = plist.Value.Split (new string [] {", "}, StringSplitOptions.RemoveEmptyEntries); - if (parms.Length != ptypes.Length) { - Log.Warning (1, "failed matching {0} (expected {1} params, got {2} params)", buffer, ptypes.Length, parms.Length); - return null; - } - String[] result = new String [ptypes.Length]; - for (int i = 0; i < ptypes.Length; i++) { - String[] toks = parms [i].Split (parameter_pair_splitter); - result [i] = toks [toks.Length - 1]; - } - reader.Close (); - return result; + String text = ""; + String prev = null; + foreach (var _text in GetContentLines (file)) { + text = _text.TrimEnd ('\r'); + if (prev != null) + prev = text = prev + text; + var matcher = pattern.Match (text); + if (matcher.Success) { + var plist = matcher.Groups [1]; + String[] parms = plist.Value.Split (new string [] {", "}, StringSplitOptions.RemoveEmptyEntries); + if (parms.Length != ptypes.Length) { + Log.Warning (1, "failed matching {0} (expected {1} params, got {2} params)", buffer, ptypes.Length, parms.Length); + return null; + } + String[] result = new String [ptypes.Length]; + for (int i = 0; i < ptypes.Length; i++) { + String[] toks = parms [i].Split (parameter_pair_splitter); + result [i] = toks [toks.Length - 1]; } - // sometimes we get incomplete tag, so cache it until it gets complete or matched. - // I *know* this is a hack. - if (reset_pattern_head == null || text.EndsWith (">", StringComparison.Ordinal) || !continuous_param_lines && !text.StartsWith (reset_pattern_head, StringComparison.Ordinal)) - prev = null; - else - prev = text; + return result; } - } finally { - reader.Close (); + if (ShouldResetMatchBuffer (text)) + prev = null; + else + prev = text; } } catch (Exception e) { Log.Error ("ERROR in {0}.{1}: {2}", type, method, e); diff --git a/tools/class-parse/Program.cs b/tools/class-parse/Program.cs index 4cafcfccb..8b85470a4 100644 --- a/tools/class-parse/Program.cs +++ b/tools/class-parse/Program.cs @@ -90,6 +90,7 @@ public static void Main (string[] args) static Dictionary JavaDocletTypeMapping = new Dictionary { { "droiddoc", JavaDocletType.DroidDoc }, + { "droiddoc2", JavaDocletType.DroidDoc2 }, { "java6", JavaDocletType.Java6 }, { "java7", JavaDocletType.Java7 }, { "java8", JavaDocletType.Java8 },