All files / src/syntax-sugar sizeof.js

100% Statements 23/23
100% Branches 13/13
100% Functions 3/3
100% Lines 23/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          23x 23x 23x 23x     23x               90x   90x 90x 706x   706x 685x     21x 21x 21x 21x 21x 21x   21x 14x 14x 14x                 7x   7x                        
/**
 * Sizeof helper plugin. Maps size(<THING>) to a static i32 constant
 *
 * @flow
 */
import invariant from 'invariant';
import { find } from 'walt-parser-tools/scope';
import Syntax from 'walt-syntax';
import { OBJECT_SIZE } from '../semantics/metadata';
import type { SemanticPlugin } from '../flow/types';
 
const sizes = {
  i64: 8,
  f64: 8,
  i32: 4,
  f32: 4,
};
 
export default function sizeofPlugin(): SemanticPlugin {
  return {
    semantics() {
      return {
        [Syntax.FunctionCall]: next => args => {
          const [sizeof, context] = args;
 
          if (sizeof.value !== 'sizeof') {
            return next(args);
          }
 
          const { scopes, userTypes, functions } = context;
          const [, target] = sizeof.params;
          const ref = find(scopes, target.value);
          const { type = '' } = ref || {};
          const userType = userTypes[target.value] || userTypes[type];
          const func = functions[target.value];
 
          if (userType != null) {
            const metaSize = userType.meta[OBJECT_SIZE];
            invariant(metaSize, 'Object size information is missing');
            return {
              ...sizeof,
              value: metaSize,
              params: [],
              type: 'i32',
              Type: Syntax.Constant,
            };
          }
 
          const node = ref || func;
 
          return {
            ...sizeof,
            value: sizes[String(node ? node.type : target.value)],
            type: 'i32',
            params: [],
            Type: Syntax.Constant,
          };
        },
      };
    },
  };
}