org.objectweb.asm.tree.InnerClassNode Java Examples

The following examples show how to use org.objectweb.asm.tree.InnerClassNode. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Type.java    From spring-graalvm-native with Apache License 2.0 6 votes vote down vote up
public List<Type> getNestedTypes() {
		if (dimensions > 0)
			return Collections.emptyList();
		List<Type> result = null;
		List<InnerClassNode> innerClasses = node.innerClasses;
		for (InnerClassNode inner : innerClasses) {
			if (inner.outerName == null || !inner.outerName.equals(getName())) {
//				System.out.println("SKIPPING "+inner.name+" because outer is "+inner.outerName+" and we are looking at "+getName());
				continue;
			}
			if (inner.name.equals(getName())) {
				continue;
			}
			Type t = typeSystem.resolve(inner.name); // aaa/bbb/ccc/Ddd$Eee
			if (result == null) {
				result = new ArrayList<>();
			}
			result.add(t);
		}
		return result == null ? Collections.emptyList() : result;
	}
 
Example #2
Source File: Type.java    From spring-graalvm-native with Apache License 2.0 6 votes vote down vote up
private Type[] getMemberTypes() {
	if (dimensions > 0)
		return new Type[0];
	List<Type> result = new ArrayList<>();
	List<InnerClassNode> nestMembers = node.innerClasses;
	if (nestMembers != null) {
		for (InnerClassNode icn : nestMembers) {
			if (icn.name.startsWith(this.getName() + "$")) {
				result.add(typeSystem.resolveSlashed(icn.name));
			}
		}
		System.out.println(this.getName()
				+ " has inners " + nestMembers.stream().map(f -> "oo=" + this.getDescriptor() + "::o=" + f.outerName
				+ "::n=" + f.name + "::in=" + f.innerName).collect(Collectors.joining(","))
				+ "  >> " + result);
	}
	return result.toArray(new Type[0]);
}
 
Example #3
Source File: AsmUtils.java    From Stark with Apache License 2.0 6 votes vote down vote up
@Nullable
static String getOuterClassName(@NonNull ClassNode classNode) {
    if (classNode.outerClass != null) {
        return classNode.outerClass;
    }
    if (classNode.innerClasses != null) {
        @SuppressWarnings("unchecked")
        List<InnerClassNode> innerClassNodes = (List<InnerClassNode>) classNode.innerClasses;
        for (InnerClassNode innerClassNode : innerClassNodes) {
            if (innerClassNode.name.equals(classNode.name)) {
                return innerClassNode.outerName;
            }
        }
    }
    return null;
}
 
Example #4
Source File: Type.java    From spring-boot-graal-feature with Apache License 2.0 6 votes vote down vote up
public List<Type> getNestedTypes() {
		List<Type> result = null;
		List<InnerClassNode> innerClasses = node.innerClasses;
		for (InnerClassNode inner: innerClasses) {	
			if (inner.outerName==null || !inner.outerName.equals(getName())) {
//				System.out.println("SKIPPPING "+inner.name+" because outer is "+inner.outerName+" and we are looking at "+getName());
				continue;
			}
			if (inner.name.equals(getName())) {
				continue;
			}
			Type t = typeSystem.resolve(inner.name); // aaa/bbb/ccc/Ddd$Eee
			if (result == null) {
				result = new ArrayList<>();
			}
			result.add(t);
		}
		return result==null?Collections.emptyList():result;
	}
 
Example #5
Source File: AgentJob.java    From RuntimeTransformer with MIT License 6 votes vote down vote up
private Map<String, ClassNode> readInnerClasses(ClassNode classNode) {
    Map<String, ClassNode> ret = new HashMap<>();
    ((List<InnerClassNode>) classNode.innerClasses).stream()
            .filter(node -> node.name.matches(".*\\$[0-9]+"))
            .filter(node -> node.innerName == null && node.outerName == null)
            .map(node -> {
                ClassNode innerClassNode = new ClassNode(Opcodes.ASM5);

                try (InputStream inputStream = this.transformer.getResourceAsStream(node.name.substring(node.name.lastIndexOf('/') + 1) + ".class")) {
                    ClassReader reader = new ClassReader(inputStream);

                    reader.accept(innerClassNode, 0);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                return innerClassNode;
            }).forEach(node -> ret.put(node.name, node));
    return ret;
}
 
Example #6
Source File: AbstractAsyncMethodTransformer.java    From tascalate-async-await with BSD 2-Clause "Simplified" License 6 votes vote down vote up
public ClassNode transform(Type superClassType) {
    log.info("Transforming blocking method: " + classNode.name + "." + originalAsyncMethod.name
            + originalAsyncMethod.desc);
    //removeAsyncAnnotation(originalAsyncMethod);

    // Create InnerClassNode for anoymous class
    String asyncTaskClassName = createInnerClassName(classNode);
    innerClassesOf(classNode).add(new InnerClassNode(asyncTaskClassName, null, null, (originalAsyncMethod.access & ACC_STATIC)));

    // Create accessor methods
    createAccessMethodsForAsyncMethod();

    // Create ClassNode for anonymous class
    ClassNode asyncTaskClassNode = createAnonymousClass(asyncTaskClassName, superClassType);

    // Replace original method

    List<MethodNode> methods = methodsOf(classNode);
    methods.remove(originalAsyncMethod);
    
    createReplacementAsyncMethod(asyncTaskClassName);
    
    //System.out.println(BytecodeTraceUtil.toString(classNode));
    return asyncTaskClassNode;
}
 
Example #7
Source File: StubJarClassEntry.java    From buck with Apache License 2.0 5 votes vote down vote up
private boolean isEnclosingOrMember(InnerClassNode innerClass) {
  if (className.equals(innerClass.name)) {
    // Self!
    return true;
  }

  if (className.equals(innerClass.outerName)) {
    // Member class
    return true;
  }

  // Enclosing class
  return className.startsWith(innerClass.name + "$");
}
 
Example #8
Source File: StubJarClassEntry.java    From buck with Apache License 2.0 5 votes vote down vote up
@Override
public void visitEnd() {
  innerClasses.sort(
      (o1, o2) -> {
        // Enclosing classes and member classes should come first, with their order preserved
        boolean o1IsEnclosingOrMember = isEnclosingOrMember(o1);
        boolean o2IsEnclosingOrMember = isEnclosingOrMember(o2);
        if (o1IsEnclosingOrMember && o2IsEnclosingOrMember) {
          // Preserve order among these
          return 0;
        } else if (o1IsEnclosingOrMember) {
          return -1;
        } else if (o2IsEnclosingOrMember) {
          return 1;
        }

        // References to other classes get sorted.
        return o1.name.compareTo(o2.name);
      });

  for (InnerClassNode innerClass : innerClasses) {
    innerClass.accept(cv);
  }

  nestMembers.stream().sorted().forEach(nestMember -> cv.visitNestMember(nestMember));

  super.visitEnd();
}
 
Example #9
Source File: StubJarClassEntry.java    From buck with Apache License 2.0 5 votes vote down vote up
@Nullable
private static InnerClassNode getInnerClassMetadata(ClassNode node, String className) {
  for (InnerClassNode innerClass : node.innerClasses) {
    if (innerClass.name.equals(className)) {
      return innerClass;
    }
  }

  return null;
}
 
Example #10
Source File: StubJarClassEntry.java    From buck with Apache License 2.0 5 votes vote down vote up
private static boolean isAnonymousOrLocalClass(ClassNode node) {
  InnerClassNode innerClass = getInnerClassMetadata(node);
  while (innerClass != null) {
    if (innerClass.outerName == null) {
      return true;
    }
    innerClass = getInnerClassMetadata(node, innerClass.outerName);
  }

  return false;
}
 
Example #11
Source File: ClassReferenceTracker.java    From buck with Apache License 2.0 5 votes vote down vote up
@Override
public void visitEnd() {
  // If we reference inner classes, we must also reference their outer class(es).
  Set<String> newSet = new HashSet<>();
  for (String referencedClassName : referencedClassNames) {
    newSet.add(referencedClassName);
    InnerClassNode innerClassNode = innerClasses.get(referencedClassName);
    while (innerClassNode != null) {
      newSet.add(innerClassNode.name);
      innerClassNode = innerClasses.get(innerClassNode.outerName);
    }
  }
  referencedClassNames = newSet;
  super.visitEnd();
}
 
Example #12
Source File: ClassReferenceTracker.java    From buck with Apache License 2.0 5 votes vote down vote up
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
  if (name.equals(className) && outerName != null) {
    // If this class is an inner class, its outer class is considered referenced automatically
    addReferencedClassName(outerName);
  }
  innerClasses.put(name, new InnerClassNode(name, outerName, innerName, access));
  super.visitInnerClass(name, outerName, innerName, access);
}
 
Example #13
Source File: MixinInfo.java    From Mixin with MIT License 5 votes vote down vote up
/**
 * Read inner class definitions for the class and locate any synthetic
 * inner classes so that we can add them to the passthrough set in our
 * parent config.
 */
void readInnerClasses() {
    for (InnerClassNode inner : this.validationClassNode.innerClasses) {
        ClassInfo innerClass = ClassInfo.forName(inner.name);
        if ((inner.outerName != null && inner.outerName.equals(this.classInfo.getName()))
                || inner.name.startsWith(this.validationClassNode.name + "$")) {
            if (innerClass.isProbablyStatic() && innerClass.isSynthetic()) {
                this.syntheticInnerClasses.add(inner.name);
            } else {
                this.innerClasses.add(inner.name);
            }
        }
    }
}
 
Example #14
Source File: BytecodeIntrospection.java    From tascalate-async-await with BSD 2-Clause "Simplified" License 5 votes vote down vote up
private static InnerClassNode getInnerClass(ClassNode classNode, String innerClassName) {
    for (InnerClassNode icn : innerClassesOf(classNode)) {
        if (innerClassName.equals(icn.name)) {
            return icn;
        }
    }
    return null;
}
 
Example #15
Source File: IntegrationTestSupport.java    From turbine with Apache License 2.0 5 votes vote down vote up
/**
 * For each preserved InnerClass attribute, keep any information about transitive enclosing
 * classes of the inner class.
 */
private static void addInnerChain(
    Map<String, InnerClassNode> infos, List<InnerClassNode> used, String i) {
  while (infos.containsKey(i)) {
    InnerClassNode info = infos.get(i);
    used.add(info);
    i = info.outerName;
  }
}
 
Example #16
Source File: IntegrationTestSupport.java    From turbine with Apache License 2.0 5 votes vote down vote up
/** Apply a standard sort order to attributes. */
private static void sortAttributes(ClassNode n) {

  n.innerClasses.sort(
      Comparator.comparing((InnerClassNode x) -> x.name)
          .thenComparing(x -> x.outerName)
          .thenComparing(x -> x.innerName)
          .thenComparing(x -> x.access));

  sortAnnotations(n.visibleAnnotations);
  sortAnnotations(n.invisibleAnnotations);
  sortTypeAnnotations(n.visibleTypeAnnotations);
  sortTypeAnnotations(n.invisibleTypeAnnotations);

  for (MethodNode m : n.methods) {
    sortParameterAnnotations(m.visibleParameterAnnotations);
    sortParameterAnnotations(m.invisibleParameterAnnotations);

    sortAnnotations(m.visibleAnnotations);
    sortAnnotations(m.invisibleAnnotations);
    sortTypeAnnotations(m.visibleTypeAnnotations);
    sortTypeAnnotations(m.invisibleTypeAnnotations);
  }

  for (FieldNode f : n.fields) {
    sortAnnotations(f.visibleAnnotations);
    sortAnnotations(f.invisibleAnnotations);

    sortAnnotations(f.visibleAnnotations);
    sortAnnotations(f.invisibleAnnotations);
    sortTypeAnnotations(f.visibleTypeAnnotations);
    sortTypeAnnotations(f.invisibleTypeAnnotations);
  }
}
 
Example #17
Source File: ClassNodeDecompiler.java    From bytecode-viewer with GNU General Public License v3.0 4 votes vote down vote up
protected static PrefixedStringBuilder decompile(
        PrefixedStringBuilder sb, ArrayList<String> decompiledClasses,
        ClassNode cn) {
    ArrayList<String> unableToDecompile = new ArrayList<>();
    decompiledClasses.add(cn.name);
    sb.append(getAccessString(cn.access));
    sb.append(" ");
    sb.append(cn.name);
    if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
        sb.append(" extends ");
        sb.append(cn.superName);
    }

    int amountOfInterfaces = cn.interfaces.size();
    if (amountOfInterfaces > 0) {
        sb.append(" implements ");
        sb.append(cn.interfaces.get(0));
        for (int i = 1; i < amountOfInterfaces; i++) {
            sb.append(", ");
            sb.append(cn.interfaces.get(i));
        }
    }
    sb.append(" {");
    sb.append(BytecodeViewer.nl);
    sb.append("     ");
    sb.append("<ClassVersion=" + cn.version + ">");
    sb.append(BytecodeViewer.nl);

    if (cn.sourceDebug != null) {
        sb.append("     ");
        sb.append("<SourceDebug=" + cn.sourceDebug + ">");
        sb.append(BytecodeViewer.nl);
    }

    if (cn.sourceFile != null) {
        sb.append("     ");
        sb.append("<SourceFile=" + cn.sourceFile + ">");
        sb.append(BytecodeViewer.nl);
    }

    if (cn.signature != null) {
        sb.append("     ");
        sb.append("<Sig=" + cn.signature + ">");
    }

    for (FieldNode fn : cn.fields) {
        sb.append(BytecodeViewer.nl);
        sb.append("     ");
        FieldNodeDecompiler.decompile(sb, fn);
    }
    if (cn.fields.size() > 0) {
        sb.append(BytecodeViewer.nl);
    }
    for (MethodNode mn : cn.methods) {
        sb.append(BytecodeViewer.nl);
        MethodNodeDecompiler.decompile(sb, mn, cn);
    }

    for (Object o : cn.innerClasses) {
        InnerClassNode innerClassNode = (InnerClassNode) o;
        String innerClassName = innerClassNode.name;
        if ((innerClassName != null)
                && !decompiledClasses.contains(innerClassName)) {
            decompiledClasses.add(innerClassName);
            ClassNode cn1 = BytecodeViewer.getClassNode(innerClassName);
            if (cn1 != null) {
                sb.appendPrefix("     ");
                sb.append(BytecodeViewer.nl + BytecodeViewer.nl);
                sb = decompile(sb, decompiledClasses, cn1);
                sb.trimPrefix(5);
                sb.append(BytecodeViewer.nl);
            } else {
                unableToDecompile.add(innerClassName);
            }
        }
    }

    if (!unableToDecompile.isEmpty()) {
        sb.append("// The following inner classes couldn't be decompiled: ");
        for (String s : unableToDecompile) {
            sb.append(s);
            sb.append(" ");
        }
        sb.append(BytecodeViewer.nl);
    }

    if (cn.attrs != null) {
        sb.append(BytecodeViewer.nl);
        for (Attribute attr : cn.attrs) {
            //TODO: finish attributes
            sb.append(attr.type + ": ");// + attr.content.toString());
        }
    }

    //sb.append(BytecodeViewer.nl);
    sb.append("}");
    // System.out.println("Wrote end for " + cn.name +
    // " with prefix length: " + sb.prefix.length());
    return sb;
}
 
Example #18
Source File: BytecodeIntrospection.java    From tascalate-async-await with BSD 2-Clause "Simplified" License 4 votes vote down vote up
@SuppressWarnings("unchecked")
static List<InnerClassNode> innerClassesOf(ClassNode classNode) {
    return null == classNode.innerClasses ? 
           Collections.<InnerClassNode> emptyList() :
           (List<InnerClassNode>) classNode.innerClasses;
}
 
Example #19
Source File: BytecodeDecompiler.java    From java-disassembler with GNU General Public License v3.0 4 votes vote down vote up
protected PrefixedStringBuilder decompile(PrefixedStringBuilder sb, ArrayList<String> decompiledClasses, FileContainer container, ClassNode cn) {
    ArrayList<String> unableToDecompile = new ArrayList<>();
    decompiledClasses.add(cn.name);
    sb.append(getAccessString(cn.access));
    sb.append(" ");
    sb.append(cn.name);
    if (cn.superName != null && !cn.superName.equals("java/lang/Object")) {
        sb.append(" extends ");
        sb.append(cn.superName);
    }

    int amountOfInterfaces = cn.interfaces.size();
    if (amountOfInterfaces > 0) {
        sb.append(" implements ");
        sb.append(cn.interfaces.get(0));
        if (amountOfInterfaces > 1) {
            // sb.append(",");
        }
        for (int i = 1; i < amountOfInterfaces; i++) {
            sb.append(", ");
            sb.append(cn.interfaces.get(i));
        }
    }
    sb.append(" {");
    sb.append(JDA.nl);

    for (Iterator<FieldNode> it = cn.fields.iterator(); it.hasNext(); ) {
        sb.append("     ");
        getFieldNodeDecompiler(sb, it).decompile();
        sb.append(JDA.nl);
        if (!it.hasNext())
            sb.append(JDA.nl);
    }

    for (Iterator<MethodNode> it = cn.methods.iterator(); it.hasNext(); ) {
        getMethodNodeDecompiler(sb, cn, it).decompile();
        if (it.hasNext())
            sb.append(JDA.nl);
    }

    if (settings.getEntry("decompile-inner-classes").getBool())
        for (InnerClassNode innerClassNode : cn.innerClasses) {
            String innerClassName = innerClassNode.name;
            if ((innerClassName != null) && !decompiledClasses.contains(innerClassName)) {
                decompiledClasses.add(innerClassName);
                ClassNode cn1 = container.loadClassFile(container.findClassfile(innerClassName));
                applyFilters(cn1);
                if (cn1 != null) {
                    sb.appendPrefix("     ");
                    sb.append(JDA.nl + JDA.nl);
                    sb = decompile(sb, decompiledClasses, container, cn1);
                    sb.trimPrefix(5);
                    sb.append(JDA.nl);
                } else {
                    unableToDecompile.add(innerClassName);
                }
            }
        }

    if (!unableToDecompile.isEmpty()) {
        sb.append("// The following inner classes couldn't be decompiled: ");
        for (String s : unableToDecompile) {
            sb.append(s);
            sb.append(" ");
        }
        sb.append(JDA.nl);
    }

    sb.append("}");
    // System.out.println("Wrote end for " + cn.name +
    // " with prefix length: " + sb.prefix.length());
    return sb;
}
 
Example #20
Source File: StubJarClassEntry.java    From buck with Apache License 2.0 4 votes vote down vote up
@Nullable
private static InnerClassNode getInnerClassMetadata(ClassNode node) {
  String name = node.name;
  return getInnerClassMetadata(node, name);
}
 
Example #21
Source File: IntegrationTestSupport.java    From turbine with Apache License 2.0 4 votes vote down vote up
/**
 * Remove InnerClass attributes that are no longer needed after member pruning. This requires
 * visiting all descriptors and signatures in the bytecode to find references to inner classes.
 */
private static void removeUnusedInnerClassAttributes(
    Map<String, InnerClassNode> infos, ClassNode n) {
  Set<String> types = new HashSet<>();
  {
    types.add(n.name);
    collectTypesFromSignature(types, n.signature);
    if (n.superName != null) {
      types.add(n.superName);
    }
    types.addAll(n.interfaces);

    addTypesInAnnotations(types, n.visibleAnnotations);
    addTypesInAnnotations(types, n.invisibleAnnotations);
    addTypesInTypeAnnotations(types, n.visibleTypeAnnotations);
    addTypesInTypeAnnotations(types, n.invisibleTypeAnnotations);
  }
  for (MethodNode m : n.methods) {
    collectTypesFromSignature(types, m.desc);
    collectTypesFromSignature(types, m.signature);
    types.addAll(m.exceptions);

    addTypesInAnnotations(types, m.visibleAnnotations);
    addTypesInAnnotations(types, m.invisibleAnnotations);
    addTypesInTypeAnnotations(types, m.visibleTypeAnnotations);
    addTypesInTypeAnnotations(types, m.invisibleTypeAnnotations);

    addTypesFromParameterAnnotations(types, m.visibleParameterAnnotations);
    addTypesFromParameterAnnotations(types, m.invisibleParameterAnnotations);

    collectTypesFromAnnotationValue(types, m.annotationDefault);
  }
  for (FieldNode f : n.fields) {
    collectTypesFromSignature(types, f.desc);
    collectTypesFromSignature(types, f.signature);

    addTypesInAnnotations(types, f.visibleAnnotations);
    addTypesInAnnotations(types, f.invisibleAnnotations);
    addTypesInTypeAnnotations(types, f.visibleTypeAnnotations);
    addTypesInTypeAnnotations(types, f.invisibleTypeAnnotations);
  }

  List<InnerClassNode> used = new ArrayList<>();
  for (InnerClassNode i : n.innerClasses) {
    if (i.outerName != null && i.outerName.equals(n.name)) {
      // keep InnerClass attributes for any member classes
      used.add(i);
    } else if (types.contains(i.name)) {
      // otherwise, keep InnerClass attributes that were referenced in class or member signatures
      addInnerChain(infos, used, i.name);
    }
  }
  addInnerChain(infos, used, n.name);
  n.innerClasses = used;
}
 
Example #22
Source File: StubJarClassEntry.java    From buck with Apache License 2.0 4 votes vote down vote up
@Override
public void visitInnerClass(String name, String outerName, String innerName, int access) {
  innerClasses.add(new InnerClassNode(name, outerName, innerName, access));
}
 
Example #23
Source File: RejectionClassVisitorTest.java    From AVM with MIT License 4 votes vote down vote up
private void compareClasses(ClassNode inputNode, ClassNode outputNode) {
    // Access is unchanged.
    Assert.assertEquals(inputNode.access, outputNode.access);
    
    // Attributes aren't in either.
    Assert.assertNull(inputNode.attrs);
    Assert.assertNull(outputNode.attrs);
    
    // We expect the same number of fields but we need a deep comparison.
    List<FieldNode> inputFields = inputNode.fields;
    List<FieldNode> outputFields = outputNode.fields;
    Assert.assertEquals(inputFields.size(), outputFields.size());
    
    for (int i = 0; i < inputFields.size(); ++i) {
        compareFields(inputFields.get(i), outputFields.get(i));
    }
    
    // Inner classes are unchanged.
    List<InnerClassNode> inputInnerClasses = inputNode.innerClasses;
    List<InnerClassNode> outputInnerClasses = outputNode.innerClasses;
    Assert.assertEquals(inputInnerClasses.size(), outputInnerClasses.size());
    
    for (int i = 0; i < inputInnerClasses.size(); ++i) {
        // Names received user renaming - but only the classes which are strictly user-defined (not MethodHandles).
        String inputName = inputInnerClasses.get(i).name;
        String expectedName = mapper.mapType(inputName, this.preserveDebuggability);
        Assert.assertEquals(expectedName, outputInnerClasses.get(i).name);
    }
    
    // Interfaces are unchanged.
    List<String> inputInterfaces = inputNode.interfaces;
    List<String> outputInterfaces = outputNode.interfaces;
    Assert.assertEquals(inputInterfaces.size(), outputInterfaces.size());
    
    for (int i = 0; i < inputInterfaces.size(); ++i) {
        Assert.assertEquals(mapper.mapType(inputInterfaces.get(i), this.preserveDebuggability), outputInterfaces.get(i));
    }
    
    // Neither use any invisible annotations.
    Assert.assertNull(inputNode.invisibleAnnotations);
    Assert.assertNull(outputNode.invisibleAnnotations);
    Assert.assertNull(inputNode.invisibleTypeAnnotations);
    Assert.assertNull(outputNode.invisibleTypeAnnotations);
    
    // We expect the same number of methods but we need a deep comparison.
    List<MethodNode> inputMethods = inputNode.methods;
    List<MethodNode> outputMethods = outputNode.methods;
    Assert.assertEquals(inputMethods.size(), outputMethods.size());
    
    for (int i = 0; i < inputMethods.size(); ++i) {
        compareMethods(inputMethods.get(i), outputMethods.get(i));
    }
    
    Assert.assertEquals(inputNode.module, outputNode.module);
    
    // There are now no annotations (some of these had them, before).
    Assert.assertNull(outputNode.visibleAnnotations);
    Assert.assertNull(outputNode.visibleTypeAnnotations);
    
    Assert.assertEquals(PackageConstants.kUserSlashPrefix + inputNode.name, outputNode.name);
    Assert.assertEquals(inputNode.outerClass, outputNode.outerClass);
    Assert.assertEquals(inputNode.outerMethod, outputNode.outerMethod);
    Assert.assertEquals(inputNode.outerMethodDesc, outputNode.outerMethodDesc);
    Assert.assertEquals(inputNode.signature, outputNode.signature);
    Assert.assertEquals(inputNode.sourceDebug, outputNode.sourceDebug);
    
    // We expect the sourceFile to be removed.
    Assert.assertNull(outputNode.sourceFile);
    
    Assert.assertEquals(mapper.mapType(inputNode.superName, this.preserveDebuggability), outputNode.superName);
}