Skip to content
This repository was archived by the owner on Jul 6, 2026. It is now read-only.

Commit 03cb8e2

Browse files
committed
[Java.Interop.Tools.JavaSource] Support html tags with attributes (#1286)
Context: dotnet/android#9647dotnet/android#9647 attempted to import API docs for API 35, and produced the following warning: The following issues were found, review the build log for more details: > ## Unable to translate remarks for android/app/admin/DevicePolicyManager: > JavadocImport-Error (31:39): Syntax error, expected: </p>, </P>, #PCDATA, <tt>, <TT>, <i>, <I>, <a attr=, <code>, {@code, {@docroot}, {@inheritdoc}, {@link, {@linkplain, {@literal, {@see, {@value}, {@value, IgnorableDeclaration, {@PARAM, UnknownHtmlElementStart, <p>, <P>, <pre , @author, @apiSince, @deprecated, @deprecatedSince, @exception, @inheritdoc, @hide, @PARAM, @return, @see, @Serialdata, @serialField, @SInCE, @throws, @[unknown], @Version <li>A <i id="deviceowner">Device Owner</i>, which only ever exists on the ^ Parsing logic fails here because the `<i>` tag has an `id` attribute _and_ is present in an open `<p>` tag. Turns Out™ that HTML allows attributes on nearly *everything*; e.g. from [§3.2.3 Global attributes][0]: > The following attributes are common to and may be specified on all > [HTML elements](https://dev.w3.org/html5/spec-LC/infrastructure.html#html-elements) > (even those not defined in this specification): > * … > * `id` Given this, it doesn't make sense for `CreateStartElement()` to not allow any attributes. Update `CreateStartElement()` so that *all* elements *ignore* any specified attributes (by default), which allows `<i id="deviceowner">Device Owner</i>` to work. The regex used has also been improved to include word boundaries around the tag name to make sure that it does not match unexpected elements. [0]: https://dev.w3.org/html5/spec-LC/elements.html#global-attributes
1 parent 2a1e180 commit 03cb8e2

2 files changed

Lines changed: 9 additions & 18 deletions

File tree

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

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
6666
varfontstyle_i=CreateHtmlToCrefElement(grammar,"i","i",InlineDeclarations,optionalEnd:true);
6767

6868
varpreText=newPreBlockDeclarationBodyTerminal();
69-
PreBlockDeclaration.Rule=CreateStartElementIgnoreAttribute("pre")+preText+CreateEndElement("pre",grammar,optional:true);
69+
PreBlockDeclaration.Rule=CreateStartElement("pre")+preText+CreateEndElement("pre",grammar,optional:true);
7070
PreBlockDeclaration.AstConfig.NodeCreator=(context,parseNode)=>{
7171
if(!grammar.ShouldImport(ImportJavadoc.Remarks)){
7272
parseNode.AstNode="";
@@ -82,7 +82,7 @@ internal void CreateRules (SourceJavadocToXmldocGrammar grammar)
8282
FontStyleDeclaration.Rule=fontstyle_tt|fontstyle_i;
8383

8484
PBlockDeclaration.Rule=
85-
CreateStartElement("p",grammar)+InlineDeclarations+CreateEndElement("p",grammar,optional:true)
85+
CreateStartElement("p")+InlineDeclarations+CreateEndElement("p",grammar,optional:true)
8686
;
8787
PBlockDeclaration.AstConfig.NodeCreator=(context,parseNode)=>{
8888
varremarks=FinishParse(context,parseNode).Remarks;
@@ -260,7 +260,7 @@ static string GetChildNodesAsString (ParseTreeNode parseNode)
260260

261261
staticNonTerminalCreateHtmlToCrefElement(Grammargrammar,stringhtmlElement,stringcrefElement,BnfTermbody,booloptionalEnd=false)
262262
{
263-
varstart=CreateStartElement(htmlElement,grammar);
263+
varstart=CreateStartElement(htmlElement);
264264
varend=CreateEndElement(htmlElement,grammar,optionalEnd);
265265
varnonTerminal=newNonTerminal("<"+htmlElement+">",ConcatChildNodes){
266266
Rule=start+body+end,
@@ -275,28 +275,15 @@ static NonTerminal CreateHtmlToCrefElement (Grammar grammar, string htmlElement,
275275
returnnonTerminal;
276276
}
277277

278-
staticNonTerminalCreateStartElement(stringstartElement,Grammargrammar)
278+
staticRegexBasedTerminalCreateStartElement(stringstartElement,stringattribute="")
279279
{
280-
varstart=newNonTerminal("<"+startElement+">",nodeCreator:(context,parseNode)=>parseNode.AstNode=""){
281-
Rule=grammar.ToTerm("<"+startElement+">")|"<"+startElement.ToUpperInvariant()+">",
282-
};
283-
returnstart;
284-
}
285-
286-
staticRegexBasedTerminalCreateStartElementIgnoreAttribute(stringstartElement,stringattribute)
287-
{
288-
returnnewRegexBasedTerminal($"<{startElement}{attribute}",$@"(?i)<{startElement}\s*{attribute}[^>]*>"){
280+
returnnewRegexBasedTerminal($"<{startElement}{attribute}>",$@"(?i)<\b{startElement}\b\s*{attribute}[^>]*>"){
289281
AstConfig=newAstNodeConfig{
290282
NodeCreator=(context,parseNode)=>parseNode.AstNode="",
291283
},
292284
};
293285
}
294286

295-
staticRegexBasedTerminalCreateStartElementIgnoreAttribute(stringstartElement)
296-
{
297-
returnCreateStartElementIgnoreAttribute(startElement,"");
298-
}
299-
300287
staticNonTerminalCreateEndElement(stringendElement,Grammargrammar,booloptional=false)
301288
{
302289
varend=newNonTerminal(endElement,nodeCreator:(context,parseNode)=>parseNode.AstNode=""){

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ public void PBlockDeclaration ()
3434
r=p.Parse("<p>r= <em>unknown</em> text");
3535
Assert.IsFalse(r.HasErrors(),DumpMessages(r,p));
3636
Assert.AreEqual("<para>r= &lt;em&gt;unknown&lt;/em&gt; text</para>",r.Root.AstNode.ToString());
37+
38+
r=p.Parse("<p>For <li>A <i id=\"deviceowner\">Device Owner</i>");
39+
Assert.IsFalse(r.HasErrors(),DumpMessages(r,p));
40+
Assert.AreEqual("<para>For &lt;li&gt;A <i>Device Owner</i></para>",r.Root.AstNode.ToString());
3741
}
3842

3943
[Test]

0 commit comments

Comments
 (0)