Skip to content

Commit a0728ed

Browse files
authored
[Java.Interop.Tools.JavaSource] Fix remaining parsing errors (#1036)
All 431 instances of `JavadocImport-Error` that would occur when generating API docs for `Mono.Android.dll` have been fixed. Problematic scenarios that have been fixed include: * `@hide` and `@inheritDoc` tags with trailing content * `<tt>` or `<i>` elements with no closing tag * `<pre>` elements with an attribute and/or no closing elements * `<a name="">` or `<a id="">` elements inside of an unclosed `<p>` element * `<a href="">` elements with mixed casing or spacing * `{@link foo` tags without a closing bracket * Any extra occurrences of `@`, `{`, or `}`
1 parent 9e858bb commit a0728ed

File tree

7 files changed

+677
-12
lines changed

7 files changed

+677
-12
lines changed

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

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,16 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
102102
};
103103

104104
// Ignore @hide tags
105-
HideDeclaration.Rule = "@hide";
105+
HideDeclaration.Rule = "@hide"
106+
| "@hide" + BlockValues
107+
;
106108
HideDeclaration.AstConfig.NodeCreator = (context, parseNode) => {
107109
FinishParse (context, parseNode);
108110
};
109111

110-
InheritDocDeclaration.Rule = "@inheritDoc";
112+
InheritDocDeclaration.Rule = "@inheritDoc"
113+
| "@inheritDoc" + BlockValues
114+
;
111115
InheritDocDeclaration.AstConfig.NodeCreator = (context, parseNode) => {
112116
if (!grammar.ShouldImport (ImportJavadoc.InheritDocTag)) {
113117
return;

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

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
2323
AllHtmlTerms.Rule = TopLevelInlineDeclaration
2424
| PBlockDeclaration
2525
| PreBlockDeclaration
26+
| IgnorableElementDeclaration
2627
;
2728

2829
var inlineDeclaration = new NonTerminal ("<html inline decl>", ConcatChildNodes) {
@@ -59,11 +60,11 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
5960
parseNode.AstNode = "";
6061
};
6162

62-
var fontstyle_tt = CreateHtmlToCrefElement (grammar, "tt", "c", InlineDeclarations);
63-
var fontstyle_i = CreateHtmlToCrefElement (grammar, "i", "i", InlineDeclarations);
63+
var fontstyle_tt = CreateHtmlToCrefElement (grammar, "tt", "c", InlineDeclarations, optionalEnd: true);
64+
var fontstyle_i = CreateHtmlToCrefElement (grammar, "i", "i", InlineDeclarations, optionalEnd: true);
6465

6566
var preText = new PreBlockDeclarationBodyTerminal ();
66-
PreBlockDeclaration.Rule = CreateStartElement ("pre", grammar) + preText + CreateEndElement ("pre", grammar);
67+
PreBlockDeclaration.Rule = CreateStartElementIgnoreAttribute ("pre") + preText + CreateEndElement ("pre", grammar, optional: true);
6768
PreBlockDeclaration.AstConfig.NodeCreator = (context, parseNode) => {
6869
if (!grammar.ShouldImport (ImportJavadoc.Remarks)) {
6970
parseNode.AstNode = "";
@@ -125,6 +126,16 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
125126
parseNode.AstNode = astNodeElement;
126127
}
127128
};
129+
130+
// Start to trim out unusable HTML elements/tags, but not any inner values
131+
IgnorableElementDeclaration.Rule =
132+
CreateStartElementIgnoreAttribute ("a", "name") + InlineDeclarations + CreateEndElement ("a", grammar, optional: true)
133+
| CreateStartElementIgnoreAttribute ("a", "id") + InlineDeclarations + CreateEndElement ("a", grammar, optional: true)
134+
;
135+
IgnorableElementDeclaration.AstConfig.NodeCreator = (context, parseNode) => {
136+
var aElementValue = new XText (parseNode.ChildNodes [1].AstNode.ToString ());
137+
parseNode.AstNode = aElementValue;
138+
};
128139
}
129140

130141
static IEnumerable<XElement> GetParagraphs (ParseTreeNodeList children)
@@ -193,8 +204,9 @@ static IEnumerable<XElement> GetParagraphs (ParseTreeNodeList children)
193204
public readonly NonTerminal PBlockDeclaration = new NonTerminal (nameof (PBlockDeclaration), ConcatChildNodes);
194205
public readonly NonTerminal PreBlockDeclaration = new NonTerminal (nameof (PreBlockDeclaration), ConcatChildNodes);
195206
public readonly NonTerminal InlineHyperLinkDeclaration = new NonTerminal (nameof (InlineHyperLinkDeclaration), ConcatChildNodes);
207+
public readonly NonTerminal IgnorableElementDeclaration = new NonTerminal (nameof (IgnorableElementDeclaration), ConcatChildNodes);
196208

197-
public readonly Terminal InlineHyperLinkOpenTerm = new RegexBasedTerminal ("<a href=", @"<a\s*href=") {
209+
public readonly Terminal InlineHyperLinkOpenTerm = new RegexBasedTerminal ("<a href=", @"(?i)<a\s*href\s*=") {
198210
AstConfig = new AstNodeConfig {
199211
NodeCreator = (context, parseNode) => parseNode.AstNode = "",
200212
},
@@ -231,6 +243,20 @@ static NonTerminal CreateStartElement (string startElement, Grammar grammar)
231243
return start;
232244
}
233245

246+
static RegexBasedTerminal CreateStartElementIgnoreAttribute (string startElement, string attribute)
247+
{
248+
return new RegexBasedTerminal ($"<{startElement} {attribute}", $@"(?i)<{startElement}\s*{attribute}[^>]*>") {
249+
AstConfig = new AstNodeConfig {
250+
NodeCreator = (context, parseNode) => parseNode.AstNode = "",
251+
},
252+
};
253+
}
254+
255+
static RegexBasedTerminal CreateStartElementIgnoreAttribute (string startElement)
256+
{
257+
return CreateStartElementIgnoreAttribute (startElement, "");
258+
}
259+
234260
static NonTerminal CreateEndElement (string endElement, Grammar grammar, bool optional = false)
235261
{
236262
var end = new NonTerminal (endElement, nodeCreator: (context, parseNode) => parseNode.AstNode = "") {

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

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Data;
34
using System.IO;
45
using System.Linq;
56
using System.Xml.Linq;
@@ -28,6 +29,7 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
2829
| LiteralDeclaration
2930
| SeeDeclaration
3031
| ValueDeclaration
32+
| IgnorableDeclaration
3133
;
3234

3335
CodeDeclaration.Rule = grammar.ToTerm ("{@code") + InlineValue + "}";
@@ -54,12 +56,20 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
5456
parseNode.AstNode = new XText ("To be added");
5557
};
5658

57-
LinkDeclaration.Rule = grammar.ToTerm ("{@link") + InlineValue + "}";
59+
LinkDeclaration.Rule = grammar.ToTerm ("{@link") + InlineValue + new NonTerminal ("Optional }", nodeCreator: (context, parseNode) => parseNode.AstNode = "") {
60+
Rule = grammar.ToTerm ("}") | grammar.Empty,
61+
};
5862
LinkDeclaration.AstConfig.NodeCreator = (context, parseNode) => {
5963
// TODO: *everything*; {@link target label}, but target can contain spaces!
6064
// Also need to convert to appropriate CREF value, use code text for now.
65+
// Also some {@link tags are missing a closing bracket, use plain text rather than throwing for now.
6166
var target = parseNode.ChildNodes [1].AstNode;
62-
parseNode.AstNode = new XElement ("c", target);
67+
var optionalBracketMatch = parseNode.ChildNodes [2];
68+
if (optionalBracketMatch.ChildNodes.Count > 0 && optionalBracketMatch.ChildNodes [0].Term.Name == "}") {
69+
parseNode.AstNode = new XElement ("c", target);
70+
} else {
71+
parseNode.AstNode = new XText (target.ToString ());
72+
}
6373
};
6474

6575
LinkplainDeclaration.Rule = grammar.ToTerm ("{@linkplain") + InlineValue + "}";
@@ -97,6 +107,15 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
97107
parseNode.AstNode = new XText ("To be added");
98108
}
99109
};
110+
111+
// Inline content may contain reserved characters with no tags or special parsing rules, do not throw when encountering them
112+
IgnorableDeclaration.Rule = grammar.ToTerm ("@ ")
113+
| grammar.ToTerm ("{")
114+
| grammar.ToTerm ("}")
115+
;
116+
IgnorableDeclaration.AstConfig.NodeCreator = (context, parseNode) => {
117+
parseNode.AstNode = new XText (parseNode.ChildNodes [0].Term.Name.Trim ());
118+
};
100119
}
101120

102121
public readonly NonTerminal AllInlineTerms = new NonTerminal (nameof (AllInlineTerms), ConcatChildNodes);
@@ -129,6 +148,9 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
129148

130149
// https://docs.oracle.com/javase/7/docs/technotes/tools/windows/javadoc.html#value
131150
public readonly NonTerminal ValueDeclaration = new NonTerminal (nameof (ValueDeclaration));
151+
152+
public readonly NonTerminal IgnorableDeclaration = new NonTerminal (nameof (IgnorableDeclaration));
153+
132154
}
133155
}
134156
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ public void InheritDocDeclaration ()
6565
Assert.IsFalse (r.HasErrors (), "@inheritDoc: " + DumpMessages (r, p));
6666
// TODO: Enable after adding support for @inheritDoc
6767
Assert.IsNull (r.Root.AstNode, "@inheritDoc should be ignored, but node was not null.");
68+
69+
r = p.Parse ("@inheritDoc With extra");
70+
Assert.IsFalse (r.HasErrors (), "@inheritDoc with trailing content " + DumpMessages (r, p));
71+
// TODO: Enable after adding support for @inheritDoc
72+
Assert.IsNull (r.Root.AstNode, "@inheritDoc with trailing content should be ignored, but node was not null.");
6873
}
6974

7075
[Test]
@@ -75,6 +80,9 @@ public void HideDeclaration ()
7580
var r = p.Parse ("@hide");
7681
Assert.IsFalse (r.HasErrors (), "@hide: " + DumpMessages (r, p));
7782
Assert.IsNull (r.Root.AstNode, "@hide should be ignored, but node was not null.");
83+
r = p.Parse ("@hide Method is broken");
84+
Assert.IsFalse (r.HasErrors (), "@hide with trailing content: " + DumpMessages (r, p));
85+
Assert.IsNull (r.Root.AstNode, "@hide with trailing content should be ignored, but node was not null.");
7886
}
7987

8088
[Test]

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public void PreBlockDeclaration ()
4646
Assert.AreEqual ("<code lang=\"text/java\">this @contains &lt;arbitrary/&gt; text.</code>",
4747
r.Root.AstNode.ToString ());
4848

49+
r = p.Parse ("<pre class=\"prettyprint\">ColorSpace cs = ColorSpace.get(ColorSpace.Named.DCI_P3);");
50+
Assert.IsFalse (r.HasErrors (), DumpMessages (r, p));
51+
Assert.AreEqual ($"<code lang=\"text/java\">ColorSpace cs = ColorSpace.get(ColorSpace.Named.DCI_P3);</code>",
52+
r.Root.AstNode.ToString ());
4953
}
5054

5155
[Test]

0 commit comments

Comments
 (0)