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

95.65% Statements 22/23
83.33% Branches 5/6
100% Functions 3/3
95.65% Lines 22/23

    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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    23x
    23x
    23x
    23x

    23x
    24x

    2x

    2x

    2x

    2x

    44x
    44x

    44x

    32x
    32x
    32x

    32x
    32x

    12x
    2x

    2x

    12x

     // @flow
    import curry from "curry";
    import Syntax from "../Syntax";
    import mapNode from "../utils/map-node";
    import {
      FUNCTION_INDEX,
      TYPE_INDEX,
      TYPE_CONST,
      GLOBAL_INDEX,
    } from "./metadata";

    export const mapImport = curry((options, node, _) => {
      return mapNode({
        [Syntax.BinaryExpression]: (as, transform) => {
          const [maybePair, asIdentifier] = as.params;
          // if the original import is not typed this isn't a valid import and is ignored
          Iif (maybePair.Type !== Syntax.Pair) {
            // No transform happens here (the transform is what creates the global fn to reference)
            return as;
          }
          // Continue transforming the import as before, the AS metadata will notify
          // the generator to ask for the original import.
          const [original, typeNode] = maybePair.params;

          return transform({
            ...maybePair,
            params: [
              {
                ...asIdentifier,
                meta: {
                  ...original.meta,
                  // <new-value> AS <original-value>
                  AS: original.value,
                },
              },
              typeNode,
            ],
          });
        },
        [Syntax.Pair]: (pairNode, __) => {
          const { types, functions, globals } = options;
          const [identifierNode, typeNode] = pairNode.params;

          if (types[typeNode.value] != null) {
            // crate a new type

            const functionIndex = Object.keys(functions).length;
            const typeIndex = Object.keys(types).indexOf(typeNode.value);
            const functionNode = {
              ...identifierNode,
              id: identifierNode.value,
              type: types[typeNode.value].type,
              meta: {
                ...identifierNode.meta,
                [FUNCTION_INDEX]: functionIndex,
                [TYPE_INDEX]: typeIndex,
                FUNCTION_METADATA: types[typeNode.value].meta.FUNCTION_METADATA,
                DEFAULT_ARGUMENTS: types[typeNode.value].meta.DEFAULT_ARGUMENTS,
              },
            };
            functions[identifierNode.value] = functionNode;
            return {
              ...pairNode,
              params: [functionNode, types[typeNode.value]],
            };
          }

          if (!["Table", "Memory"].includes(typeNode.type)) {
            const index = Object.keys(globals).length;

            globals[identifierNode.value] = {
              ...identifierNode,
              meta: { [GLOBAL_INDEX]: index, [TYPE_CONST]: true },
              type: typeNode.type,
            };
          }

          return pairNode;
        },
      })(node);
    });