Ejemplo n.º 1
0
  @Override
  public void visitTopLevel(JCCompilationUnit tree) {
    JavaFileObject prev = log.useSource(tree.sourcefile);
    boolean addEnv = false;
    boolean isPkgInfo =
        tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
    if (tree.pid != null) {
      tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
      if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
        if (isPkgInfo) {
          addEnv = true;
        } else {
          log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
        }
      }
    } else {
      tree.packge = syms.unnamedPackage;
    }
    tree.packge.complete(); // Find all classes in package.
    Env<AttrContext> topEnv = topLevelEnv(tree);

    // Save environment of package-info.java file.
    if (isPkgInfo) {
      Env<AttrContext> env0 = typeEnvs.get(tree.packge);
      if (env0 == null) {
        typeEnvs.put(tree.packge, topEnv);
      } else {
        JCCompilationUnit tree0 = env0.toplevel;
        if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
          log.warning(
              tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
          if (addEnv
              || (tree0.packageAnnotations.isEmpty()
                  && tree.docComments != null
                  && tree.docComments.get(tree) != null)) {
            typeEnvs.put(tree.packge, topEnv);
          }
        }
      }

      for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;

      Name name = names.package_info;
      ClassSymbol c = reader.enterClass(name, tree.packge);
      c.flatname = names.fromString(tree.packge + "." + name);
      c.sourcefile = tree.sourcefile;
      c.completer = null;
      c.members_field = new Scope(c);
      tree.packge.package_info = c;
    }
    classEnter(tree.defs, topEnv);
    if (addEnv) {
      todo.append(topEnv);
    }
    log.useSource(prev);
    result = null;
  }
 public static Class<?> malform(Class<?> type) throws Exception {
   ClassReader classReader = new ClassReader(type.getName());
   ClassWriter classWriter = new ClassWriter(classReader, 0);
   classReader.accept(new SignatureMalformer(classWriter), 0);
   ClassLoader classLoader =
       new ByteArrayClassLoader(
           null,
           Collections.singletonMap(type.getName(), classWriter.toByteArray()),
           null,
           ByteArrayClassLoader.PersistenceHandler.MANIFEST,
           PackageDefinitionStrategy.NoOp.INSTANCE);
   return classLoader.loadClass(type.getName());
 }
  protected byte[] transformClass(byte[] bytes, String clssname) {
    InputStream is = getClass().getResourceAsStream("/" + clssname.replace('.', '/') + ".class");

    ClassReader orig = null;
    try {
      ClassReader crRepl = new ClassReader(is);
      ClassNode cnRepl = new ClassNode(Opcodes.ASM4);
      crRepl.accept(cnRepl, ClassReader.SKIP_FRAMES);

      ClassReader crOrig = new ClassReader(bytes);
      ClassNode cnOrig = new ClassNode(Opcodes.ASM4);
      crOrig.accept(cnOrig, ClassReader.SKIP_FRAMES);

      for (Object ofnRepl : cnRepl.fields) {
        FieldNode fnRepl = (FieldNode) ofnRepl;

        if (hasReplaceAnnotation(fnRepl.visibleAnnotations)) {
          FieldNode fnOrig = findField(cnOrig.fields, fnRepl);
          if (fnOrig != null) {
            cnOrig.fields.remove(fnOrig);
            cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl));
          }
        } else if (hasAddAnnotation(fnRepl.visibleAnnotations)) {
          cnOrig.fields.add(cnOrig.fields.size(), scrubField(cnOrig, cnRepl, fnRepl));
        }
      }

      for (Object omnRepl : cnRepl.methods) {
        MethodNode mnRepl = (MethodNode) omnRepl;

        if (hasReplaceAnnotation(mnRepl.visibleAnnotations)) {
          MethodNode mnOrig = findMethod(cnOrig.methods, mnRepl);
          if (mnOrig != null) {
            cnOrig.methods.remove(mnOrig);
            cnOrig.methods.add(cnOrig.methods.size(), scrubMethod(cnOrig, cnRepl, mnRepl));
          }
        } else if (hasAddAnnotation(mnRepl.visibleAnnotations)) {
          cnOrig.methods.add(cnOrig.methods.size() + 1, scrubMethod(cnOrig, cnRepl, mnRepl));
        }
      }

      ClassWriter cwNew = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
      cnOrig.accept(cwNew);
      return cwNew.toByteArray();
    } catch (IOException e) {
      e.printStackTrace(); // To change body of catch statement use File | Settings | File
      // Templates.
    }

    return bytes;
  }
  public Pair<ClassRepr, Set<UsageRepr.Usage>> analyze(final int fileName, final ClassReader cr) {
    final ClassCrawler visitor = new ClassCrawler(fileName);

    cr.accept(visitor, 0);

    return visitor.getResult();
  }
Ejemplo n.º 5
0
 private List<Instruction> transformInvoke(InvokeInstruction insn) {
   if (insn.getType() != InvocationType.VIRTUAL) {
     return null;
   }
   MethodReference method = insn.getMethod();
   if (method.getClassName().equals(ResourceArray.class.getName())
       || method.getClassName().equals(ResourceMap.class.getName())) {
     if (method.getName().equals("keys")) {
       return transformKeys(insn);
     }
     InvokeInstruction accessInsn = new InvokeInstruction();
     accessInsn.setType(InvocationType.SPECIAL);
     ValueType[] types = new ValueType[method.getDescriptor().parameterCount() + 2];
     types[0] = ValueType.object("java.lang.Object");
     System.arraycopy(
         method.getDescriptor().getSignature(),
         0,
         types,
         1,
         method.getDescriptor().parameterCount() + 1);
     accessInsn.setMethod(
         new MethodReference(ResourceAccessor.class.getName(), method.getName(), types));
     accessInsn.getArguments().add(insn.getInstance());
     accessInsn.getArguments().addAll(insn.getArguments());
     accessInsn.setReceiver(insn.getReceiver());
     return Arrays.asList(accessInsn);
   }
   ClassReader iface = innerSource.get(method.getClassName());
   if (iface == null
       || !innerSource.isSuperType(Resource.class.getName(), iface.getName()).orElse(false)) {
     return null;
   }
   if (method.getName().startsWith("get")) {
     if (method.getName().length() > 3) {
       return transformGetterInvocation(insn, getPropertyName(method.getName().substring(3)));
     }
   } else if (method.getName().startsWith("is")) {
     if (method.getName().length() > 2) {
       return transformGetterInvocation(insn, getPropertyName(method.getName().substring(2)));
     }
   } else if (method.getName().startsWith("set")) {
     if (method.getName().length() > 3) {
       return transformSetterInvocation(insn, getPropertyName(method.getName().substring(3)));
     }
   }
   return null;
 }
Ejemplo n.º 6
0
    /** Enter a set of generated class files. */
    private List<ClassSymbol> enterClassFiles(Map<String, JavaFileObject> classFiles) {
      ClassReader reader = ClassReader.instance(context);
      Names names = Names.instance(context);
      List<ClassSymbol> list = List.nil();

      for (Map.Entry<String, JavaFileObject> entry : classFiles.entrySet()) {
        Name name = names.fromString(entry.getKey());
        JavaFileObject file = entry.getValue();
        if (file.getKind() != JavaFileObject.Kind.CLASS) throw new AssertionError(file);
        ClassSymbol cs;
        if (isPkgInfo(file, JavaFileObject.Kind.CLASS)) {
          Name packageName = Convert.packagePart(name);
          PackageSymbol p = reader.enterPackage(packageName);
          if (p.package_info == null)
            p.package_info = reader.enterClass(Convert.shortName(name), p);
          cs = p.package_info;
          if (cs.classfile == null) cs.classfile = file;
        } else cs = reader.enterClass(name, file);
        list = list.prepend(cs);
      }
      return list.reverse();
    }
Ejemplo n.º 7
0
  public void visitTopLevel(JCCompilationUnit tree) {
    JavaFileObject prev = log.useSource(tree.sourcefile);
    boolean addEnv = false;
    boolean isPkgInfo =
        tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
    if (tree.pid != null) {
      tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
      if (tree.packageAnnotations.nonEmpty()) {
        if (isPkgInfo) {
          addEnv = true;
        } else {
          log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
        }
      }
    } else {
      tree.packge = syms.unnamedPackage;
    }
    tree.packge.complete(); // Find all classes in package.
    Env<AttrContext> env = topLevelEnv(tree);

    // Save environment of package-info.java file.
    if (isPkgInfo) {
      Env<AttrContext> env0 = typeEnvs.get(tree.packge);
      if (env0 == null) {
        typeEnvs.put(tree.packge, env);
      } else {
        JCCompilationUnit tree0 = env0.toplevel;
        if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
          log.warning(
              tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
          if (addEnv
              || (tree0.packageAnnotations.isEmpty()
                  && tree.docComments != null
                  && tree.docComments.get(tree) != null)) {
            typeEnvs.put(tree.packge, env);
          }
        }
      }
    }
    classEnter(tree.defs, env);
    if (addEnv) {
      todo.append(env);
    }
    log.useSource(prev);
    result = null;
  }
Ejemplo n.º 8
0
  protected Enter(Context context) {
    context.put(enterKey, this);

    log = Log.instance(context);
    reader = ClassReader.instance(context);
    make = TreeMaker.instance(context);
    syms = Symtab.instance(context);
    chk = Check.instance(context);
    memberEnter = MemberEnter.instance(context);
    types = Types.instance(context);
    annotate = Annotate.instance(context);
    lint = Lint.instance(context);

    predefClassDef =
        make.ClassDef(make.Modifiers(PUBLIC), syms.predefClass.name, null, null, null, null);
    predefClassDef.sym = syms.predefClass;
    todo = Todo.instance(context);
    fileManager = context.get(JavaFileManager.class);
  }
Ejemplo n.º 9
0
  /**
   * Construct a proxy generator. This generator is used when we need to create a proxy object for a
   * class or an interface given a map of closures.
   *
   * @param closureMap the delegates implementations
   * @param superClass corresponding to the superclass class visitor
   * @param interfaces extra interfaces the proxy should implement
   * @param proxyLoader the class loader which should be used to load the generated proxy
   * @param delegateClass if not null, generate a delegate field with the corresponding class
   * @param emptyBody if set to true, the unimplemented abstract methods will receive an empty body
   *     instead of throwing an {@link UnsupportedOperationException}.
   */
  public ProxyGeneratorAdapter(
      final Map<Object, Object> closureMap,
      final Class superClass,
      final Class[] interfaces,
      final ClassLoader proxyLoader,
      final boolean emptyBody,
      final Class delegateClass) {
    super(new ClassWriter(0));
    this.visitedMethods = new LinkedHashSet<Object>();
    this.delegatedClosures =
        closureMap.isEmpty() ? EMPTY_DELEGATECLOSURE_MAP : new HashMap<String, Boolean>();
    boolean wildcard = false;
    for (Map.Entry<Object, Object> entry : closureMap.entrySet()) {
      String name = entry.getKey().toString();
      if ("*".equals(name)) {
        wildcard = true;
      }
      this.delegatedClosures.put(name, Boolean.FALSE);
    }
    this.hasWildcard = wildcard;

    // if we have to delegate to another object, generate the appropriate delegate field
    // and collect the name of the methods for which delegation is active
    this.generateDelegateField = delegateClass != null;
    this.objectDelegateMethods =
        generateDelegateField
            ? createDelegateMethodList(delegateClass, interfaces)
            : EMPTY_STRING_SET;
    this.delegateClass = delegateClass;

    // a proxy is supposed to be a concrete class, so it cannot extend an interface.
    // If the provided superclass is an interface, then we replace the superclass with Object
    // and add this interface to the list of implemented interfaces
    boolean isSuperClassAnInterface = superClass.isInterface();
    this.superClass = isSuperClassAnInterface ? Object.class : superClass;

    // create the base list of classes which have possible methods to be overloaded
    this.classList = new LinkedList<Class>();
    this.classList.add(superClass);
    if (generateDelegateField) {
      classList.add(delegateClass);
    }
    if (interfaces != null) {
      Collections.addAll(this.classList, interfaces);
    }
    this.proxyName = proxyName();
    this.loader = proxyLoader != null ? new InnerLoader(proxyLoader) : findClassLoader(superClass);
    this.emptyBody = emptyBody;

    // generate bytecode
    ClassWriter writer = (ClassWriter) cv;
    ClassReader cr = createClassVisitor(Object.class);
    cr.accept(this, 0);
    byte[] b = writer.toByteArray();
    //        CheckClassAdapter.verify(new ClassReader(b), true, new PrintWriter(System.err));
    cachedClass = loader.defineClass(proxyName.replace('/', '.'), b);
    // cache no-arg constructor
    Class[] args =
        generateDelegateField ? new Class[] {Map.class, delegateClass} : new Class[] {Map.class};
    Constructor constructor;
    try {
      constructor = cachedClass.getConstructor(args);
    } catch (NoSuchMethodException e) {
      constructor = null;
    }
    cachedNoArgConstructor = constructor;
  }
Ejemplo n.º 10
0
  public void visitClassDef(JCClassDecl tree) {
    Symbol owner = env.info.scope.owner;
    Scope enclScope = enterScope(env);
    ClassSymbol c;
    if (owner.kind == PCK) {
      // We are seeing a toplevel class.
      PackageSymbol packge = (PackageSymbol) owner;
      for (Symbol q = packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
      c = reader.enterClass(tree.name, packge);
      packge.members().enterIfAbsent(c);
      if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
        log.error(tree.pos(), "class.public.should.be.in.file", tree.name);
      }
    } else {
      if (!tree.name.isEmpty() && !chk.checkUniqueClassName(tree.pos(), tree.name, enclScope)) {
        result = null;
        return;
      }
      if (owner.kind == TYP) {
        // We are seeing a member class.
        c = reader.enterClass(tree.name, (TypeSymbol) owner);
        if ((owner.flags_field & INTERFACE) != 0) {
          tree.mods.flags |= PUBLIC | STATIC;
        }
      } else {
        // We are seeing a local class.
        c = reader.defineClass(tree.name, owner);
        c.flatname = chk.localClassName(c);
        if (!c.name.isEmpty()) chk.checkTransparentClass(tree.pos(), c, env.info.scope);
      }
    }
    tree.sym = c;

    // Enter class into `compiled' table and enclosing scope.
    if (chk.compiled.get(c.flatname) != null) {
      duplicateClass(tree.pos(), c);
      result = types.createErrorType(tree.name, (TypeSymbol) owner, Type.noType);
      tree.sym = (ClassSymbol) result.tsym;
      return;
    }
    chk.compiled.put(c.flatname, c);
    enclScope.enter(c);

    // Set up an environment for class block and store in `typeEnvs'
    // table, to be retrieved later in memberEnter and attribution.
    Env<AttrContext> localEnv = classEnv(tree, env);
    typeEnvs.put(c, localEnv);

    // Fill out class fields.
    c.completer = memberEnter;
    c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
    c.sourcefile = env.toplevel.sourcefile;
    c.members_field = new Scope(c);

    ClassType ct = (ClassType) c.type;
    if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
      // We are seeing a local or inner class.
      // Set outer_field of this class to closest enclosing class
      // which contains this class in a non-static context
      // (its "enclosing instance class"), provided such a class exists.
      Symbol owner1 = owner;
      while ((owner1.kind & (VAR | MTH)) != 0 && (owner1.flags_field & STATIC) == 0) {
        owner1 = owner1.owner;
      }
      if (owner1.kind == TYP) {
        ct.setEnclosingType(owner1.type);
      }
    }

    // Enter type parameters.
    ct.typarams_field = classEnter(tree.typarams, localEnv);

    // Add non-local class to uncompleted, to make sure it will be
    // completed later.
    if (!c.isLocal() && uncompleted != null) uncompleted.append(c);
    //      System.err.println("entering " + c.fullname + " in " + c.owner);//DEBUG

    // Recursively enter all member classes.
    classEnter(tree.defs, localEnv);

    result = c.type;
  }
Ejemplo n.º 11
0
  @NotNull
  public InlineResult doTransform(
      @NotNull AnonymousObjectGeneration anonymousObjectGen,
      @NotNull FieldRemapper parentRemapper) {
    final List<InnerClassNode> innerClassNodes = new ArrayList<InnerClassNode>();
    ClassBuilder classBuilder = createClassBuilder();
    final List<MethodNode> methodsToTransform = new ArrayList<MethodNode>();

    reader.accept(
        new ClassVisitor(InlineCodegenUtil.API, classBuilder.getVisitor()) {
          @Override
          public void visit(
              int version,
              int access,
              @NotNull String name,
              String signature,
              String superName,
              String[] interfaces) {
            InlineCodegenUtil.assertVersionNotGreaterThanJava6(version, name);
            super.visit(version, access, name, signature, superName, interfaces);
          }

          @Override
          public void visitInnerClass(
              @NotNull String name, String outerName, String innerName, int access) {
            innerClassNodes.add(new InnerClassNode(name, outerName, innerName, access));
          }

          @Override
          public MethodVisitor visitMethod(
              int access,
              @NotNull String name,
              @NotNull String desc,
              String signature,
              String[] exceptions) {
            MethodNode node = new MethodNode(access, name, desc, signature, exceptions);
            if (name.equals("<init>")) {
              if (constructor != null)
                throw new RuntimeException(
                    "Lambda, SAM or anonymous object should have only one constructor");

              constructor = node;
            } else {
              methodsToTransform.add(node);
            }
            return node;
          }

          @Override
          public FieldVisitor visitField(
              int access,
              @NotNull String name,
              @NotNull String desc,
              String signature,
              Object value) {
            addUniqueField(name);
            if (InlineCodegenUtil.isCapturedFieldName(name)) {
              return null;
            } else {
              return super.visitField(access, name, desc, signature, value);
            }
          }

          @Override
          public void visitSource(String source, String debug) {
            sourceInfo = source;
            debugInfo = debug;
          }

          @Override
          public void visitEnd() {}
        },
        ClassReader.SKIP_FRAMES);

    if (!inliningContext.isInliningLambda) {
      if (debugInfo != null && !debugInfo.isEmpty()) {
        sourceMapper = SourceMapper.Companion.createFromSmap(SMAPParser.parse(debugInfo));
      } else {
        // seems we can't do any clever mapping cause we don't know any about original class name
        sourceMapper = IdenticalSourceMapper.INSTANCE;
      }
      if (sourceInfo != null && !InlineCodegenUtil.GENERATE_SMAP) {
        classBuilder.visitSource(sourceInfo, debugInfo);
      }
    } else {
      if (sourceInfo != null) {
        classBuilder.visitSource(sourceInfo, debugInfo);
      }
      sourceMapper = IdenticalSourceMapper.INSTANCE;
    }

    ParametersBuilder allCapturedParamBuilder = ParametersBuilder.newBuilder();
    ParametersBuilder constructorParamBuilder = ParametersBuilder.newBuilder();
    List<CapturedParamInfo> additionalFakeParams =
        extractParametersMappingAndPatchConstructor(
            constructor,
            allCapturedParamBuilder,
            constructorParamBuilder,
            anonymousObjectGen,
            parentRemapper);
    List<MethodVisitor> deferringMethods = new ArrayList<MethodVisitor>();

    for (MethodNode next : methodsToTransform) {
      MethodVisitor deferringVisitor = newMethod(classBuilder, next);
      InlineResult funResult =
          inlineMethodAndUpdateGlobalResult(
              anonymousObjectGen,
              parentRemapper,
              deferringVisitor,
              next,
              allCapturedParamBuilder,
              false);

      Type returnType = Type.getReturnType(next.desc);
      if (!AsmUtil.isPrimitive(returnType)) {
        String oldFunReturnType = returnType.getInternalName();
        String newFunReturnType = funResult.getChangedTypes().get(oldFunReturnType);
        if (newFunReturnType != null) {
          inliningContext.typeRemapper.addAdditionalMappings(oldFunReturnType, newFunReturnType);
        }
      }
      deferringMethods.add(deferringVisitor);
    }

    for (MethodVisitor method : deferringMethods) {
      method.visitEnd();
    }

    generateConstructorAndFields(
        classBuilder,
        allCapturedParamBuilder,
        constructorParamBuilder,
        anonymousObjectGen,
        parentRemapper,
        additionalFakeParams);

    SourceMapper.Companion.flushToClassBuilder(sourceMapper, classBuilder);

    ClassVisitor visitor = classBuilder.getVisitor();
    for (InnerClassNode node : innerClassNodes) {
      visitor.visitInnerClass(node.name, node.outerName, node.innerName, node.access);
    }

    writeOuterInfo(visitor);

    classBuilder.done();

    anonymousObjectGen.setNewLambdaType(newLambdaType);
    return transformationResult;
  }
  /** Index format : @see jd.gui.spi.Indexer */
  @SuppressWarnings("unchecked")
  public void index(API api, Container.Entry entry, Indexes indexes) {
    // Cleaning sets...
    typeDeclarationSet.clear();
    constructorDeclarationSet.clear();
    methodDeclarationSet.clear();
    fieldDeclarationSet.clear();
    typeReferenceSet.clear();
    constructorReferenceSet.clear();
    methodReferenceSet.clear();
    fieldReferenceSet.clear();
    stringSet.clear();
    superTypeNameSet.clear();
    descriptorSet.clear();

    try (InputStream inputStream = entry.getInputStream()) {
      // Index field, method, interfaces & super type
      ClassReader classReader = new ClassReader(inputStream);
      classReader.accept(
          classIndexer, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);

      // Index descriptors
      for (String descriptor : descriptorSet) {
        new SignatureReader(descriptor).accept(signatureIndexer);
      }

      // Index references
      char[] buffer = new char[classReader.getMaxStringLength()];

      for (int i = classReader.getItemCount() - 1; i > 0; i--) {
        int startIndex = classReader.getItem(i);

        if (startIndex != 0) {
          int tag = classReader.readByte(startIndex - 1);

          switch (tag) {
            case 7: // CONSTANT_Class
              String className = classReader.readUTF8(startIndex, buffer);
              if (className.startsWith("[")) {
                new SignatureReader(className).acceptType(signatureIndexer);
              } else {
                typeReferenceSet.add(className);
              }
              break;
            case 8: // CONSTANT_String
              String str = classReader.readUTF8(startIndex, buffer);
              stringSet.add(str);
              break;
            case 9: // CONSTANT_Fieldref
              int nameAndTypeItem = classReader.readUnsignedShort(startIndex + 2);
              int nameAndTypeIndex = classReader.getItem(nameAndTypeItem);
              tag = classReader.readByte(nameAndTypeIndex - 1);
              if (tag == 12) { // CONSTANT_NameAndType
                String fieldName = classReader.readUTF8(nameAndTypeIndex, buffer);
                fieldReferenceSet.add(fieldName);
              }
              break;
            case 10: // CONSTANT_Methodref:
            case 11: // CONSTANT_InterfaceMethodref:
              nameAndTypeItem = classReader.readUnsignedShort(startIndex + 2);
              nameAndTypeIndex = classReader.getItem(nameAndTypeItem);
              tag = classReader.readByte(nameAndTypeIndex - 1);
              if (tag == 12) { // CONSTANT_NameAndType
                String methodName = classReader.readUTF8(nameAndTypeIndex, buffer);
                if ("<init>".equals(methodName)) {
                  int classItem = classReader.readUnsignedShort(startIndex);
                  int classIndex = classReader.getItem(classItem);
                  className = classReader.readUTF8(classIndex, buffer);
                  constructorReferenceSet.add(className);
                } else {
                  methodReferenceSet.add(methodName);
                }
              }
              break;
          }
        }
      }

      String typeName = classIndexer.name;

      // Append sets to indexes
      addToIndex(indexes, "typeDeclarations", typeDeclarationSet, entry);
      addToIndex(indexes, "constructorDeclarations", constructorDeclarationSet, entry);
      addToIndex(indexes, "methodDeclarations", methodDeclarationSet, entry);
      addToIndex(indexes, "fieldDeclarations", fieldDeclarationSet, entry);
      addToIndex(indexes, "typeReferences", typeReferenceSet, entry);
      addToIndex(indexes, "constructorReferences", constructorReferenceSet, entry);
      addToIndex(indexes, "methodReferences", methodReferenceSet, entry);
      addToIndex(indexes, "fieldReferences", fieldReferenceSet, entry);
      addToIndex(indexes, "strings", stringSet, entry);

      // Populate map [super type name : [sub type name]]
      if (superTypeNameSet.size() > 0) {
        Map<String, Collection> index = indexes.getIndex("subTypeNames");

        for (String superTypeName : superTypeNameSet) {
          index.get(superTypeName).add(typeName);
        }
      }

    } catch (Exception ignore) {
    }
  }