# All files / src/semantics map-struct.js

100% Statements 25/25
100% Branches 5/5
100% Functions 3/3
100% Lines 25/25

    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
    54
    55
    56
    57
    58
    59
    60
    61
    23x
    23x
    23x
    23x

    23x

    23x

    8x
    8x
    8x
    8x

    25x
    25x
    25x

    25x
    25x
    25x

    2x
    2x

    23x

    8x

    23x
    8x

    8x

    8x
    8x

     // @flow
    import curry from "curry";
    import invariant from "invariant";
    import Syntax from "../Syntax";
    import walkNode from "../utils/walk-node";
    import type { NodeType } from "../flow/types";
    import { OBJECT_SIZE, OBJECT_KEY_TYPES, TYPE_OBJECT } from "./metadata";

    export const getByteOffsetsAndSize = (
      objectLiteralNode: NodeType
    ): [{ [string]: number }, number, { [string]: string }] => {
      const offsetsByKey = {};
      const keyTypeMap = {};
      let size = 0;
      walkNode({
        [Syntax.Pair]: keyTypePair => {
          const { value: key } = keyTypePair.params[0];
          const { value: typeString } = keyTypePair.params[1];
          invariant(
            offsetsByKey[key] == null,
            `Duplicate key ${key} not allowed in object type`
          );

          keyTypeMap[key] = typeString;
          offsetsByKey[key] = size;
          switch (typeString) {
            case "i64":
            case "f64":
              size += 8;
              break;
            case "i32":
            case "f32":
            default:
              size += 4;
          }
        },
      })(objectLiteralNode);

      return [offsetsByKey, size, keyTypeMap];
    };

    const mapStruct = curry(({ userTypes }, node, _ignore) => {
      const [offsetsByKey, totalSize, keyTypeMap] = getByteOffsetsAndSize(
        node.params[0]
      );

      const struct = {
        ...node,
        meta: {
          [TYPE_OBJECT]: offsetsByKey,
          [OBJECT_SIZE]: totalSize,
          [OBJECT_KEY_TYPES]: keyTypeMap,
        },
      };

      userTypes[struct.value] = struct;
      return struct;
    });

    export default mapStruct;