List split()

in lib/src/ast.dart [118:184]


  List<SequenceNode> split(p.Context context) {
    var componentsToReturn = <SequenceNode>[];
    List<AstNode>? currentComponent;

    void addNode(AstNode node) {
      (currentComponent ??= []).add(node);
    }

    void finishComponent() {
      if (currentComponent == null) return;
      componentsToReturn
          .add(SequenceNode(currentComponent!, caseSensitive: caseSensitive));
      currentComponent = null;
    }

    for (var node in nodes) {
      if (node is! LiteralNode) {
        addNode(node);
        continue;
      }

      if (!node.text.contains('/')) {
        addNode(node);
        continue;
      }

      var text = node.text;
      if (context.style == p.Style.windows) text = text.replaceAll('/', '\\');
      Iterable<String> components = context.split(text);

      // If the first component is absolute, that means it's a separator (on
      // Windows some non-separator things are also absolute, but it's invalid
      // to have "C:" show up in the middle of a path anyway).
      if (context.isAbsolute(components.first)) {
        // If this is the first component, it's the root.
        if (componentsToReturn.isEmpty && currentComponent == null) {
          var root = components.first;
          if (context.style == p.Style.windows) {
            // Above, we switched to backslashes to make [context.split] handle
            // roots properly. That means that if there is a root, it'll still
            // have backslashes, where forward slashes are required for globs.
            // So we switch it back here.
            root = root.replaceAll('\\', '/');
          }
          addNode(LiteralNode(root, caseSensitive: caseSensitive));
        }
        finishComponent();
        components = components.skip(1);
        if (components.isEmpty) continue;
      }

      // For each component except the last one, add a separate sequence to
      // [sequences] containing only that component.
      for (var component in components.take(components.length - 1)) {
        addNode(LiteralNode(component, caseSensitive: caseSensitive));
        finishComponent();
      }

      // For the final component, only end its sequence (by adding a new empty
      // sequence) if it ends with a separator.
      addNode(LiteralNode(components.last, caseSensitive: caseSensitive));
      if (node.text.endsWith('/')) finishComponent();
    }

    finishComponent();
    return componentsToReturn;
  }