void parseCpool()

in flex/src/com/intellij/lang/javascript/flex/importer/Abc.java [388:565]


  void parseCpool() {
    int i, j;
    int n;
    int start = data.getPosition();

    // ints
    n = readU32();
    ints = new Integer[n > 0 ? n : 1];
    ints[0] = 0;
    for (i = 1; i < n; i++) {
      ints[i] = readU32();
    }

    // uints
    n = readU32();
    uints = new Integer[n > 0 ? n : 1];
    uints[0] = 0;
    for (i = 1; i < n; i++) {
      uints[i] = readU32();
    }

    // doubles
    n = readU32();
    doubles = new Double[n > 0 ? n : 1];
    doubles[0] = Double.NaN;
    for (i = 1; i < n; i++) {
      doubles[i] = data.readDouble();
    }

    reportAboutPercentage("Cpool numbers size ", data, start, processor);
    start = data.getPosition();

    // strings
    n = readU32();
    strings = new String[n];
    strings[0] = "";
    for (i = 1; i < n; i++) {
      strings[i] = data.readUTFBytes(readU32());
    }

    reportAboutPercentage("Cpool strings count " + n + " size ", data, start, processor);
    start = data.getPosition();

    // namespaces
    n = readU32();
    namespaces = new String[n];
    namespaces[0] = PUBLIC_NS;
    for (i = 1; i < n; i++) {
      switch (data.readByte()) {
        case CONSTANT_Namespace, CONSTANT_PackageNs, CONSTANT_PackageInternalNs,
          CONSTANT_ProtectedNs, CONSTANT_StaticProtectedNs, CONSTANT_StaticProtectedNs2 -> {
          namespaces[i] = strings[readU32()];
          // todo mark kind of namespace.
        }
        case CONSTANT_PrivateNs -> {
          readU32();
          namespaces[i] = "private";
        }
      }
    }

    reportAboutPercentage("Cpool namespaces count " + n + " size ", data, start, processor);
    start = data.getPosition();

    // namespace sets
    n = readU32();
    nssets = new String[n][];
    for (i = 1; i < n; i++) {
      int count = readU32();
      String[] nsset = nssets[i] = new String[count];
      for (j = 0; j < count; j++) {
        nsset[j] = namespaces[readU32()];
      }
    }

    reportAboutPercentage("Cpool nssets count " + n + " size ", data, start, processor);
    start = data.getPosition();

    // multinames
    n = readU32();
    names = new Multiname[n];
    namespaces[0] = anyNs;
    strings[0] = "*"; // any name

    final class TypeNameInfo {
      int index;
      int base;
      IntList genericIndices;
    }

    final List<TypeNameInfo> typeNameInfos = new ArrayList<>();

    for (i = 1; i < n; i++) {
      switch (data.readByte()) {
        case CONSTANT_Qname, CONSTANT_QnameA -> names[i] = new Multiname(new String[]{namespaces[readU32()]}, strings[readU32()]);
        case CONSTANT_RTQname, CONSTANT_RTQnameA -> names[i] = new Multiname(new String[]{strings[readU32()]}, null);
        case CONSTANT_RTQnameL, CONSTANT_RTQnameLA -> names[i] = null;
        case CONSTANT_NameL, CONSTANT_NameLA -> names[i] = new Multiname(PUBLIC_NS_SET, null);
        case CONSTANT_Multiname, CONSTANT_MultinameA -> {
          String name = strings[readU32()];
          names[i] = new Multiname(nssets[readU32()], name);
        }
        case CONSTANT_MultinameL, CONSTANT_MultinameLA -> names[i] = new Multiname(nssets[readU32()], null);
        case CONSTANT_TypeName -> {
          // TODO:
          int nameId = readU32();
          final TypeNameInfo e = new TypeNameInfo();
          typeNameInfos.add(e);
          e.index = i;
          e.base = nameId;

          int count = readU32();
          if (count > 0) e.genericIndices = new IntArrayList();

          if (count > 0) {
            for (int k = 0; k < count; k++) {
              nameId = readU32();
              e.genericIndices.add(nameId);
            }
          }
        }
        default -> throw new Error("invalid kind " + data.getByte(data.getPosition() - 1));
      }
    }

    boolean hasSomething = false;
    boolean doneSomething = false;

    do {
      NextType:
      for (TypeNameInfo tni : typeNameInfos) {
        if (names[tni.index] != null) continue;
        if (names[tni.base] == null) {
          hasSomething = true;
          continue;
        }

        StringBuilder nsName = new StringBuilder(names[tni.base].toString());

        if (tni.genericIndices != null) {
          nsName.append(".<");
          for (int k = 0; k < tni.genericIndices.size(); k++) {
            if (k != 0) nsName.append(",");

            final Multiname typeArgName = names[tni.genericIndices.getInt(k)];
            if (typeArgName == null) continue NextType;
            String typeArgNameString;

            if (processor instanceof AS3InterfaceDumper) {
              boolean hasNotEmptyNs = typeArgName.hasNotEmptyNs();
              final boolean vector = hasNotEmptyNs && typeArgName.nsset[0].equals("__AS3__.vec");
              final boolean isPrivate = hasNotEmptyNs && typeArgName.nsset[0].equals("private");
              typeArgNameString = vector || isPrivate ? typeArgName.name : typeArgName.toString();
              typeArgNameString = StringUtil.replace(typeArgNameString, "::", ".") + (vector ? " " : "");
            }
            else {
              typeArgNameString = typeArgName.toString();
            }
            nsName.append(typeArgNameString);
          }

          nsName.append(">");
        }

        final int index = nsName.indexOf("::");

        names[tni.index] =
          new Multiname(index != -1 ? new String[]{nsName.substring(0, index)}:PUBLIC_NS_SET, index != -1 ? nsName.substring(index + 2) : nsName.toString());
        doneSomething = true;
      }
    } while (hasSomething && doneSomething);

    reportAboutPercentage("Cpool names count " + n + " size ", data, start, processor);
    start = data.getPosition();

    namespaces[0] = PUBLIC_NS;
    strings[0] = "*";
  }