@eagleoutice/flowr
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
85 lines • 4.41 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveByName = resolveByName;
exports.resolvesToBuiltInConstant = resolvesToBuiltInConstant;
const environment_1 = require("./environment");
const logic_1 = require("../../util/logic");
const identifier_1 = require("./identifier");
const info_1 = require("../info");
const FunctionTargetTypes = identifier_1.ReferenceType.Function | identifier_1.ReferenceType.BuiltInFunction | identifier_1.ReferenceType.Unknown | identifier_1.ReferenceType.Argument | identifier_1.ReferenceType.Parameter;
const VariableTargetTypes = identifier_1.ReferenceType.Variable | identifier_1.ReferenceType.Parameter | identifier_1.ReferenceType.Argument | identifier_1.ReferenceType.Unknown;
const ConstantTargetTypes = identifier_1.ReferenceType.Constant | identifier_1.ReferenceType.BuiltInConstant | identifier_1.ReferenceType.Unknown;
const BuiltInConstantTargetTypes = identifier_1.ReferenceType.BuiltInConstant | identifier_1.ReferenceType.Unknown;
const BuiltInFunctionTargetTypes = identifier_1.ReferenceType.BuiltInFunction | identifier_1.ReferenceType.Unknown;
const TargetTypePredicate = {
[identifier_1.ReferenceType.Unknown]: () => true,
[identifier_1.ReferenceType.Function]: ({ type }) => (0, identifier_1.isReferenceType)(type, FunctionTargetTypes),
[identifier_1.ReferenceType.Variable]: ({ type }) => (0, identifier_1.isReferenceType)(type, VariableTargetTypes),
[identifier_1.ReferenceType.Constant]: ({ type }) => (0, identifier_1.isReferenceType)(type, ConstantTargetTypes),
[identifier_1.ReferenceType.Parameter]: () => true,
[identifier_1.ReferenceType.Argument]: () => true,
[identifier_1.ReferenceType.BuiltInConstant]: ({ type }) => (0, identifier_1.isReferenceType)(type, BuiltInConstantTargetTypes),
[identifier_1.ReferenceType.BuiltInFunction]: ({ type }) => (0, identifier_1.isReferenceType)(type, BuiltInFunctionTargetTypes)
};
/**
* Resolves a given identifier name to a list of its possible definition location using R scoping and resolving rules.
*
* @param name - The name of the identifier to resolve
* @param environment - The current environment used for name resolution
* @param target - The target (meta) type of the identifier to resolve
*
* @returns A list of possible identifier definitions (one if the definition location is exactly and always known), or `undefined`
* if the identifier is undefined in the current scope/with the current environment information.
*/
function resolveByName(name, environment, target = identifier_1.ReferenceType.Unknown) {
let current = environment.current;
let definitions = undefined;
const wantedType = TargetTypePredicate[target];
do {
const definition = current.memory.get(name);
if (definition !== undefined) {
const filtered = target === identifier_1.ReferenceType.Unknown ? definition : definition.filter(wantedType);
if (filtered.length === definition.length && definition.every(d => (0, info_1.happensInEveryBranch)(d.controlDependencies))) {
return definition;
}
else if (filtered.length > 0) {
definitions ??= [];
definitions = definitions.concat(filtered);
}
}
current = current.parent;
} while (current.id !== environment_1.BuiltInEnvironment.id);
const builtIns = current.memory.get(name);
if (definitions) {
return builtIns === undefined ? definitions : definitions.concat(builtIns);
}
else {
return builtIns;
}
}
function resolvesToBuiltInConstant(name, environment, wantedValue) {
if (name === undefined) {
return logic_1.Ternary.Never;
}
const definition = resolveByName(name, environment, identifier_1.ReferenceType.Constant);
if (definition === undefined) {
return logic_1.Ternary.Never;
}
let all = true;
let some = false;
for (const def of definition) {
if (def.type === identifier_1.ReferenceType.BuiltInConstant && def.value === wantedValue) {
some = true;
}
else {
all = false;
}
}
if (all) {
return logic_1.Ternary.Always;
}
else {
return some ? logic_1.Ternary.Maybe : logic_1.Ternary.Never;
}
}
//# sourceMappingURL=resolve-by-name.js.map