function processLeak()

in desktop/plugins/public/leak_canary/processLeakString.tsx [157:254]


function processLeak(output: Leak[], leakInfo: string): Leak[] {
  const lines = leakInfo.split('\n');

  // Elements shows a Object's classname and package, wheras elementsSimple shows
  // just its classname
  const elements = new Map<string, Element>();
  const elementsSimple = new Map<string, Element>();

  let rootElementId = '';

  let i = 0;
  while (i < lines.length && !lines[i].endsWith(LEAK_BEGIN_INDICATOR)) {
    i++;
  }
  i++;

  if (i >= lines.length) {
    return output;
  }

  let elementId = 0;
  let elementIdStr = String(elementId);
  // Last element is leaked object
  let leakedObjName = '';
  while (i < lines.length && lines[i].startsWith('*')) {
    const line = lines[i];

    const prevElementIdStr = String(elementId - 1);
    if (elementId !== 0) {
      // Add element to previous element's children
      safeAddChildElementId(elementIdStr, prevElementIdStr, elements);
      safeAddChildElementId(elementIdStr, prevElementIdStr, elementsSimple);
    } else {
      rootElementId = elementIdStr;
    }
    const element = getElementSimple(line, elementIdStr);
    leakedObjName = element.name;
    elements.set(elementIdStr, element);
    elementsSimple.set(elementIdStr, element);

    i++;
    elementId++;
    elementIdStr = String(elementId);
  }

  while (
    i < lines.length &&
    !lines[i].startsWith(RETAINED_SIZE_INDICATOR) &&
    !lines[i].startsWith(BEGIN_DETAILS_SECTION_INDICATOR)
  ) {
    i++;
  }

  let retainedSize = 'unknown size';

  if (lines[i].startsWith(RETAINED_SIZE_INDICATOR)) {
    const match = lines[i].match(/\* Retaining: (.*)./);
    if (match) {
      retainedSize = match[1];
    }
  }

  while (
    i < lines.length &&
    !lines[i].startsWith(BEGIN_DETAILS_SECTION_INDICATOR)
  ) {
    i++;
  }
  i++;

  // Parse information on each object's fields, package
  const {staticFields, instanceFields, packages} = generateFieldsList(lines, i);

  // While elementsSimple remains as-is, elements has the package of each class
  // inserted, in order to enable 'Show full class path'
  for (const [elementId, pkg] of packages.entries()) {
    const element = elements.get(elementId);
    if (!element) {
      continue;
    }
    // Gets everything before the field name, which is replaced by the package
    const match = element.name.match(/([^\. ]*)(.*)/);
    if (match && match.length === 3) {
      element.name = pkg + match[2];
    }
  }

  output.push({
    title: leakedObjName,
    root: rootElementId,
    elements: toObjectMap(elements),
    elementsSimple: toObjectMap(elementsSimple),
    staticFields: toObjectMap(staticFields, true),
    instanceFields: toObjectMap(instanceFields, true),
    retainedSize: retainedSize,
  });
  return output;
}