Frame.parseV8 constructor

Frame.parseV8(
  1. String frame
)

Parses a string representation of a Chrome/V8 stack frame.

Implementation

factory Frame.parseV8(String frame) => _catchFormatException(frame, () {
      // Try to match a Wasm frame first: the Wasm frame regex won't match a
      // JS frame but the JS frame regex may match a Wasm frame.
      var match = _v8WasmFrame.firstMatch(frame);
      if (match != null) {
        final member = match.namedGroup('member');
        final uri = _uriOrPathToUri(match.namedGroup('uri')!);
        final functionIndex = match.namedGroup('index')!;
        final functionOffset =
            int.parse(match.namedGroup('offset')!, radix: 16);
        return Frame(uri, 1, functionOffset + 1, member ?? functionIndex);
      }

      match = _v8JsFrame.firstMatch(frame);
      if (match != null) {
        // v8 location strings can be arbitrarily-nested, since it adds a
        // layer of nesting for each eval performed on that line.
        Frame parseJsLocation(String location, String member) {
          var evalMatch = _v8EvalLocation.firstMatch(location);
          while (evalMatch != null) {
            location = evalMatch[1]!;
            evalMatch = _v8EvalLocation.firstMatch(location);
          }

          if (location == 'native') {
            return Frame(Uri.parse('native'), null, null, member);
          }

          var urlMatch = _v8JsUrlLocation.firstMatch(location);
          if (urlMatch == null) return UnparsedFrame(frame);

          final uri = _uriOrPathToUri(urlMatch[1]!);
          final line = int.parse(urlMatch[2]!);
          final columnMatch = urlMatch[3];
          final column = columnMatch != null ? int.parse(columnMatch) : null;
          return Frame(uri, line, column, member);
        }

        // V8 stack frames can be in two forms.
        if (match[2] != null) {
          // The first form looks like " at FUNCTION (LOCATION)". V8 proper
          // lists anonymous functions within eval as "<anonymous>", while
          // IE10 lists them as "Anonymous function".
          return parseJsLocation(
              match[2]!,
              match[1]!
                  .replaceAll('<anonymous>', '<fn>')
                  .replaceAll('Anonymous function', '<fn>')
                  .replaceAll('(anonymous function)', '<fn>'));
        } else {
          // The second form looks like " at LOCATION", and is used for
          // anonymous functions.
          return parseJsLocation(match[3]!, '<fn>');
        }
      }

      return UnparsedFrame(frame);
    });