/** * Chooses a name to use for renaming in each equivalence class and maps each type in that class * to it. */ private Map<T, String> buildPropNames(UnionFind<T> types, String name) { Map<T, String> names = Maps.newHashMap(); for (Set<T> set : types.allEquivalenceClasses()) { checkState(!set.isEmpty()); String typeName = null; for (T type : set) { if (typeName == null || type.toString().compareTo(typeName) < 0) { typeName = type.toString(); } } String newName; if ("{...}".equals(typeName)) { newName = name; } else { newName = typeName.replaceAll("[^\\w$]", "_") + "$" + name; } for (T type : set) { names.put(type, newName); } } return names; }
/** Invalidates any types related to invalid types. */ void expandTypesToSkip() { // If we are not going to rename any properties, then we do not need to // update the list of invalid types, as they are all invalid. if (shouldRename()) { int count = 0; while (true) { // It should usually only take one time through this do-while. checkState(++count < 10, "Stuck in loop expanding types to skip."); // Make sure that the representative type for each type to skip is // marked as being skipped. Set<T> rootTypesToSkip = Sets.newHashSet(); for (T subType : typesToSkip) { rootTypesToSkip.add(types.find(subType)); } typesToSkip.addAll(rootTypesToSkip); Set<T> newTypesToSkip = Sets.newHashSet(); Set<T> allTypes = types.elements(); int originalTypesSize = allTypes.size(); for (T subType : allTypes) { if (!typesToSkip.contains(subType) && typesToSkip.contains(types.find(subType))) { newTypesToSkip.add(subType); } } for (T newType : newTypesToSkip) { addTypeToSkip(newType); } // If there were not any new types added, we are done here. if (types.elements().size() == originalTypesSize) { break; } } } }
/** Returns true if any instance of this property should be renamed. */ boolean shouldRename() { return !skipRenaming && types != null && types.allEquivalenceClasses().size() > 1; }