fixtureApiVersionsXml function
Builds a complete synthetic api-versions.xml for classes: every public
class and member is listed at since="1", except fixtureNonSdkClasses;
classes present in the hand-written fixtures/java/basic/api-versions.xml
are taken verbatim from it (so availability tests control them exactly).
Implementation
String fixtureApiVersionsXml(DirectoryClassSource classes) {
final overridesText = File(
p.join(findRepoRoot(), 'fixtures', 'java', 'basic', 'api-versions.xml'),
).readAsStringSync();
final overrides = ApiVersionsIndex.parse(overridesText);
final body = StringBuffer();
final start = overridesText.indexOf('<class ');
final end = overridesText.lastIndexOf('</api>');
body.writeln(overridesText.substring(start, end).trimRight());
for (final name in classes.classNames) {
if (overrides.classes.containsKey(name) ||
fixtureNonSdkClasses.contains(name)) {
continue;
}
final cf = ClassFile.parse(classes.read(name)!);
final internal = name.replaceAll('.', '/');
body.writeln('\t<class name="$internal" since="1">');
if (cf.superName != null) {
body.writeln('\t\t<extends name="${cf.superName}"/>');
}
for (final i in cf.interfaces) {
body.writeln('\t\t<implements name="$i"/>');
}
for (final m in cf.methods) {
if (m.has(AccessFlags.public | AccessFlags.protected) &&
!m.has(AccessFlags.synthetic)) {
body.writeln(
'\t\t<method name="${m.name.replaceAll('<', '<')}${m.descriptor}"/>',
);
}
}
for (final f in cf.fields) {
if (f.has(AccessFlags.public | AccessFlags.protected)) {
body.writeln('\t\t<field name="${f.name}"/>');
}
}
body.writeln('\t</class>');
}
return '<?xml version="1.0" encoding="utf-8"?>\n<api version="3">\n$body</api>\n';
}