@azure-tools/codegen
Version:
Autorest Code generator common and base classes
126 lines • 4.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.shadowPosition = exports.ShadowedNodePath = exports.enableSourceTracking = exports.getMappings = void 0;
const type_1 = require("./type");
const getMap = "_#get-map#_";
const getPosition = "_#get-position#_";
const getActualValue = "_#get-value#_";
function getMappings(instance) {
return instance[getMap];
}
exports.getMappings = getMappings;
function enableSourceTracking(instance, enforce = true, path = "$", map = {}, cache = new Map()) {
let proxy = cache.get(path);
if (!proxy) {
proxy = new Proxy(instance, {
get: (target, p, receiver) => {
if (p === getMap) {
return map;
}
const value = target[p];
switch ((0, type_1.typeOf)(value)) {
case "undefined":
case "null":
case "function":
case "string":
case "boolean":
case "number":
return value;
case "array":
return enableSourceTracking(value, enforce, `${path}[${String(p)}]`, map, cache);
case "object":
return enableSourceTracking(value, enforce, `${path}.${String(p)}`, map, cache);
}
throw new Error(`Unhandled type withMap for '${(0, type_1.typeOf)(value)}'`);
},
set: (target, p, value, receiver) => {
let memberPath = "";
switch ((0, type_1.typeOf)(target)) {
case "array":
memberPath = `${path}[${String(p)}]`;
break;
case "object":
memberPath = `${path}.${String(p)}`;
break;
default:
throw new Error(`Unhandled 'set' for type withMap on '${(0, type_1.typeOf)(value)}'`);
}
if (value === undefined) {
// remove the existing value
delete target[p];
delete map[memberPath];
return true;
}
if (value === null) {
// remove the existing value
target[p] = null;
delete map[memberPath];
return true;
}
const pos = value[getPosition];
if (pos) {
map[memberPath] = pos;
target[p] = value[getActualValue];
// TODO: we should actually iterate thru whole graph here and set the source locations
// for each item individually.
return true;
}
if (enforce) {
throw new Error(`Must supply source informaton on setting property '${memberPath}' when enforce is true.`);
}
target[p] = value.valueOf();
return true;
},
});
cache.set(path, proxy);
}
return proxy;
}
exports.enableSourceTracking = enableSourceTracking;
exports.ShadowedNodePath = Symbol("ObjectPosition");
function shadowPosition(source, cache = new WeakMap(), path = []) {
const cached = cache.get(source);
if (cached) {
return cached;
}
const proxy = new Proxy(source, {
get(target, p) {
if (p === exports.ShadowedNodePath) {
// they want the source location for this node.
return path;
}
const value = target[p];
const key = getKey(p);
switch ((0, type_1.typeOf)(value)) {
case "undefined":
case "null":
case "function":
case "string":
case "boolean":
case "number":
return value;
case "array":
return shadowPosition(value, cache, [...path, key]);
case "object":
return shadowPosition(value, cache, [...path, key]);
default:
throw new Error(`Unhandled shadow of type '${(0, type_1.typeOf)(value)}' `);
}
},
});
cache.set(source, proxy);
return proxy;
}
exports.shadowPosition = shadowPosition;
function getKey(p) {
switch (typeof p) {
case "symbol":
return p.toString();
case "number":
return p;
case "string": {
return isNaN(p) || isNaN(parseFloat(p)) ? p : parseInt(p, 10);
}
}
}
//# sourceMappingURL=source-track.js.map