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

Commit 9b89e90

Browse files
authored
[generator] Ignore types without names (#837)
Fixes: #835 Context: https://github.com/firebase/firebase-android-sdk/blob/1fba4a70395c20dcc858b22ee8247acbed7cf8d3/firebase-firestore/src/main/java/com/google/firebase/firestore/model/Document.java Context: https://maven.google.com/web/index.html?q=firestore#com.google.firebase:firebase-firestore:22.1.2 Somehow Google has compiled `firebase-firestore.aar` to contain a `Document$.class` with a "non-sensical" *empty* inner class name: <class abstract="false" deprecated="not deprecated" jni-extends="Ljava/lang/Object;" extends="java.lang.Object" extends-generic-aware="java.lang.Object" final="false" name="Document." jni-signature="Lcom/google/firebase/firestore/model/Document$;" source-file-name="Document.java" static="false" visibility="public" /> The presence of a `//class[@name='Document.']` element causes an `IndexOutOfRangeException` for `generator` when it tries to parse `Document.` into a parent class name and nested class name. System.IndexOutOfRangeException: Index was outside the bounds of the array. at MonoDroid.Generation.XmlApiImporter.CreateGenBaseSupport (System.Xml.Linq.XElement pkg, System.Xml.Linq.XElement elem, System.Boolean isInterface) at MonoDroid.Generation.XmlApiImporter.CreateClass (System.Xml.Linq.XElement pkg, System.Xml.Linq.XElement elem, at MonoDroid.Generation.Parser.ParsePackage (System.Xml.Linq.XElement ns, System.Predicate`1[T] p) at MonoDroid.Generation.Parser.ParsePackage (System.Xml.Linq.XElement ns) at MonoDroid.Generation.Parser.Parse (System.Xml.Linq.XDocument doc, System.Collections.Generic.IEnumerable`1[T] fixups, at MonoDroid.Generation.Parser.Parse (System.String filename, System.Collections.Generic.IEnumerable`1[T] fixups, at Xamarin.Android.Binder.CodeGenerator.Run (Xamarin.Android.Binder.CodeGeneratorOptions options, at Xamarin.Android.Binder.CodeGenerator.Run (Xamarin.Android.Binder.CodeGeneratorOptions options) at Xamarin.Android.Binder.CodeGenerator.Main (System.String[] args) We cannot reproduce *how* to get a `Document$.class` file, so we're currently assuming this is some sort of bytecode manipulation. As such, we are going to have `generator` ignore types with an empty name and types that end in a period, which would indicate a nested type with an empty name.
1 parent 0e01fb5 commit 9b89e90

2 files changed

Lines changed: 55 additions & 6 deletions

File tree

‎tests/generator-Tests/Unit-Tests/XmlApiImporterTests.cs‎

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,5 +266,41 @@ public void IgnoreKotlinInternalMembers ()
266266
Assert.AreEqual(0,klass.Fields.Count);
267267
Assert.AreEqual(0,klass.Methods.Count);
268268
}
269+
270+
[Test]
271+
publicvoidIgnoreTypesWithInvalidNames()
272+
{
273+
varxml=XDocument.Parse(@"
274+
<api>
275+
<package name='com.example.test' jni-name='com/example/test'>
276+
<class name='' visibility='public' />
277+
<class name='Document.' visibility='public' />
278+
<interface name='' visibility='public' />
279+
<interface name='Document.' visibility='public' />
280+
</package>
281+
</api>");
282+
283+
vargens=XmlApiImporter.Parse(xml,opt);
284+
285+
// None of these should be parsed because they have invalid names
286+
Assert.AreEqual(0,gens.Count);
287+
}
288+
289+
[Test]
290+
publicvoidIgnoreUserObfuscatedTypes()
291+
{
292+
varxml=XDocument.Parse(@"
293+
<api>
294+
<package name='com.example.test' jni-name='com/example/test'>
295+
<class name='MyClass' visibility='public' obfuscated='true' />
296+
<interface name='MyInterface' visibility='public' obfuscated='true' />
297+
</package>
298+
</api>");
299+
300+
vargens=XmlApiImporter.Parse(xml,opt);
301+
302+
// None of these should be parsed because the user has said they are obfuscated
303+
Assert.AreEqual(0,gens.Count);
304+
}
269305
}
270306
}

‎tools/generator/Java.Interop.Tools.Generator.Importers/XmlApiImporter.cs‎

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,12 @@ public static List<GenBase> ParsePackage (XElement ns, CodeGenerationOptions opt
6161

6262
switch(elem.Name.LocalName){
6363
case"class":
64-
if(elem.XGetAttribute("obfuscated")=="true")
65-
continue;
66-
gen=CreateClass(ns,elem,options);
64+
if(ShouldBind(elem))
65+
gen=CreateClass(ns,elem,options);
6766
break;
6867
case"interface":
69-
if(elem.XGetAttribute("obfuscated")=="true")
70-
continue;
71-
gen=CreateInterface(ns,elem,options);
68+
if(ShouldBind(elem))
69+
gen=CreateInterface(ns,elem,options);
7270
break;
7371
default:
7472
Report.LogCodedWarning(0,Report.WarningUnexpectedPackageChildNode,elem.Name.ToString());
@@ -522,5 +520,20 @@ static void SetLineInfo (ISourceLineInfo model, XNode node, CodeGenerationOption
522520
model.LinePosition=info.LinePosition;
523521
}
524522
}
523+
524+
staticboolShouldBind(XElementelem)
525+
{
526+
// Don't bind things the user has said are "obfuscated"
527+
if(elem.XGetAttribute("obfuscated")=="true")
528+
returnfalse;
529+
530+
varjava_name=elem.XGetAttribute("name");
531+
532+
// Ignore types that do not have a name (nested classes would end in a period like "Document.")
533+
if(!java_name.HasValue()||java_name.EndsWith(".",StringComparison.Ordinal))
534+
returnfalse;
535+
536+
returntrue;
537+
}
525538
}
526539
}

0 commit comments

Comments
 (0)