@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
105 lines • 4.64 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.tryNormalizeAccess = tryNormalizeAccess;
const normalize_argument_1 = require("./functions/normalize-argument");
const parser_1 = require("../../json/parser");
const arrays_1 = require("../../../../../../util/arrays");
const assert_1 = require("../../../../../../util/assert");
const normalize_meta_1 = require("../normalize-meta");
const type_1 = require("../../../model/type");
const normalize_single_node_1 = require("./structure/normalize-single-node");
const r_function_call_1 = require("../../../model/nodes/r-function-call");
const normalize_expressions_1 = require("./structure/normalize-expressions");
function normalizeAbstractArgument(x, data, operator) {
if (x.length === 0) {
return r_function_call_1.EmptyArgument;
}
else if (x.length !== 1 || x[0].name === type_1.RawRType.Expression) {
const gotAccess = (0, normalize_argument_1.tryToNormalizeArgument)(data, x);
(0, assert_1.guard)(gotAccess !== undefined, () => `expected one access result in access as argument, yet received ${JSON.stringify(gotAccess)} for ${JSON.stringify([operator, x])}`);
return gotAccess;
}
else {
const node = (0, normalize_single_node_1.normalizeSingleNode)(data, x[0]);
(0, assert_1.guard)(node.type !== type_1.RType.ExpressionList, () => `expected expression list to be parsed as argument, yet received ${JSON.stringify(node)} for ${JSON.stringify(x)}`);
return {
type: type_1.RType.Argument,
location: node.location,
lexeme: node.lexeme,
name: undefined,
value: node,
info: {
fullRange: node.location,
fullLexeme: node.lexeme,
additionalTokens: []
}
};
}
}
/**
* Tries to normalize the given data as access (e.g., indexing).
*
* @param data - The data used by the parser (see {@link NormalizerData})
* @param mappedWithName - The JSON object to extract the meta-information from
*
* @returns The parsed {@link RAccess} or `undefined` if the given construct is not accessing a value
*/
function tryNormalizeAccess(data, mappedWithName) {
if (mappedWithName.length < 3) {
parser_1.parseLog.trace('expected at least three elements are required to parse an access');
return undefined;
}
const accessOp = mappedWithName[1];
let operator;
let closingLength = 0;
switch (accessOp.name) {
case type_1.RawRType.BracketLeft:
operator = '[';
closingLength = 1;
break;
case type_1.RawRType.Dollar:
operator = '$';
break;
case type_1.RawRType.At:
operator = '@';
break;
case type_1.RawRType.DoubleBracketLeft:
operator = '[[';
closingLength = 2;
break;
default:
parser_1.parseLog.trace(`expected second element to be an access operator, yet received ${accessOp.name}`);
return undefined;
}
const accessed = mappedWithName[0];
if (accessed.name !== type_1.RawRType.Expression && accessed.name !== type_1.RawRType.ExprOfAssignOrHelp && accessed.name !== type_1.RawRType.LegacyEqualAssign) {
parser_1.parseLog.trace(`expected accessed element to be wrapped an expression, yet received ${accessed.name}`);
return undefined;
}
const parsedAccessed = (0, normalize_expressions_1.normalizeExpressions)(data, [accessed]);
if (parsedAccessed.length !== 1) {
parser_1.parseLog.trace(`expected accessed element to be wrapped an expression, yet received ${accessed.name}`);
return undefined;
}
const remaining = mappedWithName.slice(2, mappedWithName.length - closingLength);
parser_1.parseLog.trace(`${remaining.length} remaining arguments for access`);
const splitAccessOnComma = (0, arrays_1.splitArrayOn)(remaining, x => x.name === type_1.RawRType.Comma);
const parsedAccess = splitAccessOnComma.map(x => {
return normalizeAbstractArgument(x, data, operator);
});
const { content, location } = (0, normalize_meta_1.retrieveMetaStructure)(accessOp.content);
return {
type: type_1.RType.Access,
location,
lexeme: content,
accessed: parsedAccessed[0],
operator,
access: parsedAccess,
info: {
fullRange: data.currentRange,
additionalTokens: [],
fullLexeme: data.currentLexeme
}
};
}
//# sourceMappingURL=normalize-access.js.map