private void remapRClass()

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);
            }
          }
        }
      }
    }
  }