# All files / src/core array.js

100% Statements 23/23
100% Branches 8/8
100% Functions 7/7
100% Lines 21/21

    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

    23x
    23x
    23x

    81x

    162x
    193x

    193x
    9x

    184x

    81x

    81x
    639x
    639x

    639x
    61x

    578x

    81x
    29x

    58x

    29x

    29x

     /**
     * Array Plugin
     *
     * @flow
     */
    import Syntax from 'walt-syntax';
    import { find } from 'walt-parser-tools/scope';
    import { TYPE_ARRAY } from '../semantics/metadata';
    import type { SemanticPlugin } from '../flow/types';

    export default function arrayPlugin(): SemanticPlugin {
      return {
        semantics() {
          const declaration = next => args => {
            const [node, context] = args;

            // For every declaration of array types we will strip the declaration type
            // to a core type (i32) and attach the original type reference as metadata
            if (node.type && node.type.endsWith('[]')) {
              return next([
                {
                  ...node,
                  type: 'i32',
                  meta: { ...node.meta, [TYPE_ARRAY]: node.type.slice(0, -2) },
                },
                context,
              ]);
            }

            return next(args);
          };

          return {
            [Syntax.Declaration]: declaration,
            [Syntax.ImmutableDeclaration]: declaration,
            [Syntax.Identifier]: next => args => {
              const [node, context] = args;
              const ref = find(context.scopes, node.value);
              // Before moving on to the core parser all identifiers need to have
              // concrete basic types
              if (ref && ref.meta[TYPE_ARRAY]) {
                return next([
                  {
                    ...node,
                    type: ref.type,
                    meta: { ...node.meta, ...ref.meta },
                  },
                  context,
                ]);
              }

              return next(args);
            },
            [Syntax.ArraySubscript]: _ignore => (args, transform) => {
              const [node, context] = args;

              // To find out the type of this subscript we first must process it's
              // parameters <identifier, field>
              const params = node.params.map(p => transform([p, context]));

              const [identifier] = params;

              return {
                ...node,
                params,
                type: identifier.meta[TYPE_ARRAY],
              };
            },
          };
        },
      };
    }