Skip to content

Commit 3a9f770

Browse files
authored
[Java.Interop.Tools.JavaSource] Handle common parsing exceptions (#1060)
Fixes the 91 instances of exceptions being thrown when generating API docs for the API-33 version of Mono.Android. The two most common instances were: System.IndexOutOfRangeException: Index was outside the bounds of the array. at Java.Interop.Tools.JavaSource.UnknownHtmlElementStartTerminal.TryMatch (Irony.Parsing.ParsingContext context, Irony.Parsing.ISourceStream source) [0x0003e] in /Users/builder/azdo/_work/4/s/external/Java.Interop/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/SourceJavadocToXmldocGrammar.HtmlBnfTerms.cs:390 System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index at System.Collections.Generic.List`1[T].get_Item (System.Int32 index) [0x00009] in <08f46039e5064c628bf7795f9b970b7b>:0 at Java.Interop.Tools.JavaSource.SourceJavadocToXmldocGrammar+BlockTagsBnfTerms+<>c__DisplayClass1_0.<CreateRules>b__8 (Irony.Ast.AstContext context, Irony.Parsing.ParseTreeNode parseNode) [0x00025] in /Users/builder/azdo/_work/4/s/external/Java.Interop/src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/SourceJavadocToXmldocGrammar.BlockTagsBnfTerms.cs:151 35 of the 118 href element parsing errors have also been fixed.
1 parent 984711a commit 3a9f770

File tree

3 files changed

+34
-15
lines changed

3 files changed

+34
-15
lines changed

src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/SourceJavadocToXmldocGrammar.BlockTagsBnfTerms.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,12 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
145145
if (!grammar.ShouldImport (ImportJavadoc.ReturnTag)) {
146146
return;
147147
}
148-
// When encountering multiple @return keys in a line, append subsequent @return key content to the original <returns> element.
149148
var jdi = FinishParse (context, parseNode);
149+
// If we have no return value, continue
150+
if (parseNode.ChildNodes.Count < 2) {
151+
return;
152+
}
153+
// When encountering multiple @return keys in a line, append subsequent @return key content to the original <returns> element.
150154
if (jdi.Returns.Count == 0) {
151155
var r = new XElement ("returns",
152156
AstNodeToXmlContent (parseNode.ChildNodes [1]));

src/Java.Interop.Tools.JavaSource/Java.Interop.Tools.JavaSource/SourceJavadocToXmldocGrammar.HtmlBnfTerms.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Collections.Generic;
33
using System.IO;
44
using System.Linq;
5+
using System.Net;
6+
using System.Xml;
57
using System.Xml.Linq;
68

79
using Irony.Ast;
@@ -111,20 +113,17 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
111113
}
112114
}
113115

114-
XNode astNodeElement = new XText (unparsedAElementValue);
115-
try {
116-
var seeElement = XElement.Parse ($"<see href={unparsedAElementValue}</see>");
117-
var hrefValue = seeElement.Attribute ("href")?.Value ?? string.Empty;
118-
if (!string.IsNullOrEmpty (hrefValue) &&
116+
var seeElement = TryParseHRef (unparsedAElementValue);
117+
if (seeElement == null)
118+
seeElement = TryParseHRef (WebUtility.HtmlDecode (unparsedAElementValue), logError: true);
119+
120+
var hrefValue = seeElement?.Attribute ("href")?.Value ?? string.Empty;
121+
if (!string.IsNullOrEmpty (hrefValue) &&
119122
(hrefValue.StartsWith ("http", StringComparison.OrdinalIgnoreCase) || hrefValue.StartsWith ("www", StringComparison.OrdinalIgnoreCase))) {
120-
parseNode.AstNode = seeElement;
121-
} else {
122-
// TODO: Need to convert relative paths or code references to appropriate CREF value.
123-
parseNode.AstNode = astNodeElement;
124-
}
125-
} catch (Exception) {
126-
Console.Error.WriteLine ($"# Unable to parse HTML element: <see href={unparsedAElementValue}</see>");
127-
parseNode.AstNode = astNodeElement;
123+
parseNode.AstNode = seeElement;
124+
} else {
125+
// TODO: Need to convert relative paths or code references to appropriate CREF value.
126+
parseNode.AstNode = new XText (unparsedAElementValue);
128127
}
129128
};
130129

@@ -185,6 +184,17 @@ static IEnumerable<XElement> GetParagraphs (ParseTreeNodeList children)
185184
}
186185
}
187186

187+
static XElement? TryParseHRef (string unparsedAElementValue, bool logError = false)
188+
{
189+
try {
190+
return XElement.Parse ($"<see href={unparsedAElementValue}</see>");
191+
} catch (Exception x) {
192+
if (logError)
193+
Console.Error.WriteLine ($"## Unable to parse HTML element: <see href={unparsedAElementValue}</see>\n{x.GetType ()}: {x.Message}");
194+
return null;
195+
}
196+
}
197+
188198
public readonly NonTerminal AllHtmlTerms = new NonTerminal (nameof (AllHtmlTerms), ConcatChildNodes);
189199

190200
public readonly NonTerminal TopLevelInlineDeclaration = new NonTerminal (nameof (TopLevelInlineDeclaration), ConcatChildNodes);
@@ -387,7 +397,7 @@ public override void Init (GrammarData grammarData)
387397
source.PreviewPosition += 1;
388398
int start = source.Location.Position;
389399
int stop = start;
390-
while (source.Text [stop] != '>' && stop < source.Text.Length)
400+
while (stop < source.Text.Length && source.Text [stop] != '>' )
391401
stop++;
392402
if (addingRemarks) {
393403
Console.Error.WriteLine ($"# Unsupported HTML element: {source.Text.Substring (start, stop - start)}");

tests/Java.Interop.Tools.JavaSource-Tests/SourceJavadocToXmldocGrammar.HtmlBnfTermsTests.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ public void HyperLinkDeclaration ()
6262
Assert.AreEqual ("<see href=\"https://developer.android.com/guide/topics/manifest/application-element.html\">application</see>",
6363
r.Root.AstNode.ToString ());
6464

65+
r = p.Parse ("<a href=\"http://www.ietf.org/rfc/rfc2396.txt\">RFC&nbsp;2396: Uniform Resource Identifiers (URI): Generic Syntax</a>");
66+
Assert.IsFalse (r.HasErrors (), DumpMessages (r, p));
67+
Assert.AreEqual ("<see href=\"http://www.ietf.org/rfc/rfc2396.txt\">RFC 2396: Uniform Resource Identifiers (URI): Generic Syntax</see>",
68+
r.Root.AstNode.ToString ());
69+
6570
r = p.Parse ("<a href=\"AutofillService.html#FieldClassification\">field classification</a>");
6671
Assert.IsFalse (r.HasErrors (), DumpMessages (r, p));
6772
Assert.AreEqual ("\"AutofillService.html#FieldClassification\"&gt;field classification",

0 commit comments

Comments
 (0)