in resources/src/main/java/org/robolectric/res/ResourceRemapper.java [54:127]
private void remapRClass(boolean isPrimary, Class<?> rClass) {
// Collect all the local attribute id -> name mappings. These are used when processing the stylables to look up
// the reassigned values.
Map<Integer, String> localAttributeIds = new HashMap<>();
for (Class<?> aClass : rClass.getClasses()) {
if (aClass.getSimpleName().equals("attr")) {
for (Field field : aClass.getFields()) {
try {
localAttributeIds.put(field.getInt(null), field.getName());
} catch (IllegalAccessException e) {
throw new RuntimeException("Could not read attr value for " + field.getName(), e);
}
}
}
}
for (Class<?> innerClass : rClass.getClasses()) {
String resourceType = innerClass.getSimpleName();
if (!resourceType.startsWith("styleable")) {
for (Field field : innerClass.getFields()) {
try {
if (!isPrimary && Modifier.isFinal(field.getModifiers())) {
throw new IllegalArgumentException(rClass + " contains final fields, these will be inlined by the compiler and cannot be remapped.");
}
String resourceName = resourceType + "/" + field.getName();
Integer value = resIds.get(resourceName);
if (value != null) {
field.setAccessible(true);
field.setInt(null, value);
resourceIdGenerator.record(field.getInt(null), resourceType, field.getName());
} else if (resIds.containsValue(field.getInt(null))) {
int remappedValue = resourceIdGenerator.generate(resourceType, field.getName());
field.setInt(null, remappedValue);
resIds.put(resourceName, remappedValue);
} else {
if (isPrimary) {
resourceIdGenerator.record(field.getInt(null), resourceType, field.getName());
resIds.put(resourceName, field.getInt(null));
} else {
int remappedValue = resourceIdGenerator.generate(resourceType, field.getName());
field.setInt(null, remappedValue);
resIds.put(resourceName, remappedValue);
}
}
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}
}
// Reassign the ids in the style arrays accordingly.
for (Class<?> innerClass : rClass.getClasses()) {
String resourceType = innerClass.getSimpleName();
if (resourceType.startsWith("styleable")) {
for (Field field : innerClass.getFields()) {
if (field.getType().equals(int[].class)) {
try {
int[] styleableArray = (int[]) (field.get(null));
for (int k = 0; k < styleableArray.length; k++) {
Integer value = resIds.get("attr/" + localAttributeIds.get(styleableArray[k]));
if (value != null) {
styleableArray[k] = value;
}
}
} catch (IllegalAccessException e) {
throw new IllegalStateException(e);
}
}
}
}
}
}