rosetta-converters_dist_src_converter.js

/***************************************************
 * Licensed Materials - Property of HCL
 * (c)Copyright HCL America, Inc. 2023
 ***************************************************/

/**
 * @module rosetta-converter-api
 */

import antlr from 'antlr4';
import NotesFormulaLexer from './lib/NotesFormulaLexer.js';
import NotesFormulaParser from './lib/NotesFormulaParser.js';
import NotesFormulaToJs from './NotesFormulaToJs.js';
import OpenFormulaLexer from './lib/OpenFormulaLexer.js';
import OpenFormulaParser from './lib/OpenFormulaParser.js';
import OpenFormulaToJs from './OpenFormulaToJs.js';
import ErrorListener from './ErrorListener.js';

const NON_FORMULA = /<%=[\S\s]*%>/g; // detect formula type without non formula string
/**
 * Get javascript code converted from formula
 * @param {Object} rosettajs - rosetta API object
 * @param {String} input - formula string
 * @returns {String} - javascript code
 * @throws {Error} - if formula type is not supported
*/
export function getRosettaJSFromFormula(rosettajs, input) {
  if(!(isNotes(input) || isOpenFormula(input))) {
    throw new Error('Unsupported formula type');
  }

  if(!isOpenFormula(input)){
    if(!input.endsWith(';')) {
      input += ';';
    }
  }

  const errorListener = new ErrorListener();
  const chars = new antlr.InputStream(input);
  const lexer = isOpenFormula(input)? new OpenFormulaLexer(chars) : new NotesFormulaLexer(chars);
  lexer.removeErrorListeners();
  lexer.addErrorListener(errorListener);
  const tokens = new antlr.CommonTokenStream(lexer);
  const parser = isOpenFormula(input)? new OpenFormulaParser(tokens) : new NotesFormulaParser(tokens);
  parser.removeErrorListeners();
  parser.addErrorListener(errorListener);

  const tree = parser.formulaInput();
  if(errorListener.getErrors().length > 0) {
    handleError(errorListener.getErrors());
    return;
  }

  const converter = isOpenFormula(input)? new OpenFormulaToJs(rosettajs, input) : new NotesFormulaToJs(rosettajs, input, lexer);
  const converted = converter.visit(tree);
  return converted;
}

export function isNotes(inputs) {
  return /@[a-zA-Z]|@|:=|=|REM|SELECT|DEFAULT|FIELD|ENVIRONMENT/g.test(inputs.replace(NON_FORMULA, '').trim());
}

export function isOpenFormula(inputs) {
  return inputs.replace(NON_FORMULA, '').trim().startsWith('=');
}

export const LANGUAGE = {
  ERROR: -1,
  UNKNOWN: 0,
  NOTES: 1,
  OPEN_FORMULA: 2
};

export function getFormulaLang(inputs) {
  try {
    if (isOpenFormula(inputs)) {
      return LANGUAGE.OPEN_FORMULA;
    } else if (isNotes(inputs)) {
      return LANGUAGE.NOTES;
    } else {
      return LANGUAGE.UNKNOWN;
    }
  } catch (e) {
    return LANGUAGE.ERROR;
  }
}

function handleError(error) {
  if(error !== null) {
    const msg = JSON.stringify(error);
    throw Error(msg);
  }
}