Skip to content

Commit 953fc1b

Browse files
atsushienojonpryor
authored andcommitted
[api-xml-adjuster] Outer<X>.Inner<Y> class name parsing. (#109)
Fixes: https://bugzilla.xamarin.com/show_bug.cgi?id=46344 `Xamarin.Android.Tools.ApiXmlAdjuster.JavaTypeName.Parse()` would throw an `ArgumentOutOfRangeException` when encountering generic nested types on generic types. Given the following valid Java code: // Java class GenericOuter<TOuter> { public class GenericInner<TInner> { } } class Gapp { public static void main (String[] args) { GenericOuter<Integer>.GenericInner<String> v = null; } } Then the following would fail: JavaTypeName.Parse("GenericOuter<Integer>.GenericInner<String>") System.ArgumentOutOfRangeException: Length cannot be less than zero. Parameter name: length ... Fix `JavaTypeName.Parse()` to support parsing nested generic types on generic types.
1 parent 5398f24 commit 953fc1b

File tree

1 file changed

+17
-2
lines changed

1 file changed

+17
-2
lines changed

src/Xamarin.Android.Tools.ApiXmlAdjuster/JavaTypeName.cs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,25 @@ public static JavaTypeName Parse (string dottedFullName)
5555
ret.ArrayPart += dottedFullName.Substring (aidx);
5656
dottedFullName = dottedFullName.Substring (0, aidx);
5757
}
58-
58+
59+
Func<string, int, int> getMatchingGenericCloser = (str, start) => {
60+
int count = 0;
61+
for (int i = start; i < str.Length; i++) {
62+
switch (str [i]) {
63+
case '<':
64+
count++;
65+
break;
66+
case '>':
67+
if (count-- == 0)
68+
return i;
69+
break;
70+
}
71+
}
72+
return -1;
73+
};
5974
int idx = dottedFullName.IndexOf ('<');
6075
if (idx > 0) {
61-
int last = dottedFullName.LastIndexOf ('>');
76+
int last = getMatchingGenericCloser (dottedFullName, idx + 1);
6277
ret.GenericArguments = ParseCommaSeparatedTypeNames (dottedFullName.Substring (idx + 1, last - idx - 1))
6378
.Select (s => JavaTypeName.Parse (s.Trim ()))
6479
.ToArray ();

0 commit comments

Comments
 (0)