# All files / src/core types.js

100% Statements 26/26
100% Branches 4/4
100% Functions 6/6
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
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74

    23x
    23x
    23x

    81x

    81x
    81x
    81x
    81x
    81x

    81x

    122x
    122x

    3x

    119x

    26x
    26x
    26x

    26x

    1x
    1x

    32x

    26x

    26x
    26x

    81x

     /**
     * Types plugin. Parses all types before the rest of the program
     *
     * (Does not handle Generic Types)
     *
     * @flow
     */
    import Syntax from 'walt-syntax';
    import { mapNode } from 'walt-parser-tools/map-node';
    import walkNode from 'walt-parser-tools/walk-node';
    import type { SemanticPlugin } from '../flow/types';

    export default function typePlugin(): SemanticPlugin {
      return {
        semantics() {
          return {
            [Syntax.Typedef]: _ => ([node]) => node,
            [Syntax.Program]: next => args => {
              const [ast, context] = args;
              const { types } = context;
              // Types have to be pre-parsed before the rest of the program
              const astWithTypes = mapNode({
                [Syntax.Export]: (node, transform) => {
                  const [maybeType] = node.params;
                  if (
                    maybeType != null &&
                    [Syntax.Typedef, Syntax.Struct].includes(maybeType.Type)
                  ) {
                    return transform({
                      ...maybeType,
                      meta: {
                        ...maybeType.meta,
                        EXPORTED: true,
                      },
                    });
                  }
                  return node;
                },
                [Syntax.Typedef]: (node, _) => {
                  let argumentsCount = 0;
                  const [fnArgs] = node.params;
                  const defaultArgs = [];

                  walkNode({
                    Assignment(assignment) {
                      const defaultValue = assignment.params[1];
                      defaultArgs.push(defaultValue);
                    },
                    Type() {
                      argumentsCount += 1;
                    },
                  })(fnArgs);
                  const parsed = {
                    ...node,
                    meta: {
                      ...node.meta,
                      FUNCTION_METADATA: {
                        argumentsCount,
                      },
                      DEFAULT_ARGUMENTS: defaultArgs,
                    },
                  };
                  types[node.value] = parsed;
                  return parsed;
                },
              })(ast);

              return next([astWithTypes, context]);
            },
          };
        },
      };
    }