Small no-op refactoring around NormalizeIntersectionTypes.
@@ -27,35 +27,56 @@ import java.util.stream.Stream;
public final class NormalizeIntersectionTypes extends NormalizationPass {
@Override
public void applyTo(CompilationUnit compilationUnit) {
- final Map<TypeDescriptor, TypeDescriptor> intersectionTypesByReplacements =
- Maps.newLinkedHashMap();
- class NormalizeIntersectionTypeNaming extends AbstractRewriter {
+ Map<TypeDescriptor, TypeDescriptor> normalizedTypesByIntersectionType = Maps.newLinkedHashMap();
+ compilationUnit.accept(
+ new AbstractRewriter() {
@Override
public Node rewriteTypeDescriptor(final TypeDescriptor typeDescriptor) {
- if (typeDescriptor.isIntersection()) {
- if (intersectionTypesByReplacements.containsKey(typeDescriptor)) {
- return intersectionTypesByReplacements.get(typeDescriptor);
+ if (!typeDescriptor.isIntersection()) {
+ return typeDescriptor;
+ }
+
+ TypeDescriptor normalizedType = normalizedTypesByIntersectionType.get(typeDescriptor);
+ if (normalizedType == null) {
+ TypeDescriptor enclosingTypeDescriptor = getCurrentType().getDescriptor();
+ normalizedType =
+ createIntersectionType(
+ typeDescriptor,
+ enclosingTypeDescriptor,
+ normalizedTypesByIntersectionType.size());
+ normalizedTypesByIntersectionType.put(typeDescriptor, normalizedType);
+ }
+
+ return normalizedType;
+ }
+ });
+
+ // Synthesize classes for intersection types.
+ for (TypeDescriptor typeDescriptor : normalizedTypesByIntersectionType.values()) {
+ Type syntheticType = new Type(Kind.CLASS, Visibility.PACKAGE_PRIVATE, typeDescriptor);
+ syntheticType.setAbstract(true);
+ compilationUnit.addType(syntheticType);
+ }
}
- final TypeDescriptor enclosingClassTypeDescriptor = getCurrentType().getDescriptor();
+
+ private TypeDescriptor createIntersectionType(
+ TypeDescriptor typeDescriptor, TypeDescriptor enclosingClassTypeDescriptor, int uniqueId) {
// Here we synthesize a class name of the form:
// 00<binaryClassname of first intersected type>
// The extra 0 removes the possibility of a name conflict with a lambda type with a
// potentially equal method name. TODO: Centralize the anonymous class counter.
- final String simpleName =
- "0"
- + intersectionTypesByReplacements.size()
- + typeDescriptor.getIntersectedTypeDescriptors().get(0).getBinaryClassName();
+ String simpleName =
+ "0" + uniqueId + typeDescriptor.getIntersectedTypeDescriptors().get(0).getBinaryClassName();
List<String> classComponents =
Lists.newArrayList(enclosingClassTypeDescriptor.getClassComponents());
classComponents.add(simpleName);
- final List<String> packageComponents =
+ List<String> packageComponents =
Lists.newArrayList(enclosingClassTypeDescriptor.getPackageComponents());
String packageName = Joiner.on(".").join(packageComponents);
- TypeDescriptor fixedType =
- TypeDescriptor.Builder.from(typeDescriptor)
+ return TypeDescriptor.Builder.from(typeDescriptor)
.setBinaryName(enclosingClassTypeDescriptor.getBinaryName() + "$" + simpleName)
.setEnclosingTypeDescriptorFactory(
new DescriptorFactory<TypeDescriptor>() {
@@ -84,19 +105,5 @@ public final class NormalizeIntersectionTypes extends NormalizationPass {
}
})
.build();
- intersectionTypesByReplacements.put(typeDescriptor, fixedType);
- return fixedType;
- }
- return typeDescriptor;
- }
- }
-
- compilationUnit.accept(new NormalizeIntersectionTypeNaming());
- // Synthesize classes for intersection types.
- for (TypeDescriptor typeDescriptor : intersectionTypesByReplacements.values()) {
- Type syntheticType = new Type(Kind.CLASS, Visibility.PACKAGE_PRIVATE, typeDescriptor);
- syntheticType.setAbstract(true);
- compilationUnit.addType(syntheticType);
- }
}
}
