All files / src/abap/nodes _abstract_node.ts

100% Statements 53/53
94.73% Branches 18/19
100% Functions 6/6
100% Lines 53/53

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 541x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1967483x 1967483x 1x 1x 1x 1x 1x 1x 252043x 105046x 252043x 85172x 146997x 61825x 61825x 252043x 1x 1x 1773819x 1108854x 1773819x 664965x 664965x 664965x 1773819x 1x 1x 11461764x 11461764x 11461764x 1x 1x 43681x 43681x 43681x 1x 1x 336953x 336953x 336953x 1x 1x  
import {INode} from "./_inode";
import {AbstractToken} from "../1_lexer/tokens/abstract_token";
 
// shared constant, so nodes without children don't waste memory on empty arrays
const EMPTY: readonly INode[] = Object.freeze([]);
 
export abstract class AbstractNode<T extends INode> implements INode {
  // a single child is stored directly, most nodes have exactly one child and an array costs ~56 bytes
  private children: T | T[];
 
  public constructor() {
    this.children = EMPTY as T[];
  }
 
  public abstract get(): any;
  public abstract getFirstToken(): AbstractToken;
  public abstract getLastToken(): AbstractToken;
 
  public addChild(n: T) {
    if (this.children === EMPTY) {
      this.children = n;
    } else if (Array.isArray(this.children)) {
      this.children.push(n);
    } else {
      this.children = [this.children, n];
    }
  }
 
  public setChildren(children: T[]) {
    if (children.length === 1) {
      this.children = children[0];
    } else {
      // copy, input arrays are built via push() and carry over-allocated backing stores
      this.children = children.length === 0 ? EMPTY as T[] : children.slice();
    }
  }
 
  public getChildren(): readonly T[] {
    const children = this.children;
    return Array.isArray(children) ? children : [children];
  }
 
  public getFirstChild(): T | undefined {
    const children = this.children;
    return Array.isArray(children) ? children[0] : children;
  }
 
  public getLastChild(): T | undefined {
    const children = this.children;
    return Array.isArray(children) ? children[children.length - 1] : children;
  }
 
}