Son CV dans un terminal web en Javascript!
https://terminal-cv.gregandev.fr
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
252 lines
6.3 KiB
252 lines
6.3 KiB
2 years ago
|
"use strict";
|
||
|
|
||
|
Object.defineProperty(exports, "__esModule", {
|
||
|
value: true
|
||
|
});
|
||
|
exports.scopeVisitor = exports.Scope = void 0;
|
||
|
|
||
|
function t() {
|
||
|
const data = _interopRequireWildcard(require("@babel/types"));
|
||
|
|
||
|
t = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _assert() {
|
||
|
const data = _interopRequireDefault(require("assert"));
|
||
|
|
||
|
_assert = function () {
|
||
|
return data;
|
||
|
};
|
||
|
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||
|
|
||
|
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
||
|
|
||
|
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
||
|
|
||
|
class Scope {
|
||
|
names = new Set();
|
||
|
bindings = new Map();
|
||
|
references = new Map();
|
||
|
renames = new Map();
|
||
|
inverseRenames = new Map();
|
||
|
|
||
|
constructor(type, parent) {
|
||
|
this.type = type;
|
||
|
this.parent = parent;
|
||
|
this.program = parent ? parent.program : this;
|
||
|
}
|
||
|
|
||
|
has(name) {
|
||
|
if (this.names.has(name)) {
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
if (this.parent) {
|
||
|
return this.parent.has(name);
|
||
|
}
|
||
|
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
add(name) {
|
||
|
this.names.add(name);
|
||
|
}
|
||
|
|
||
|
generateUid(name = 'temp') {
|
||
|
name = t().toIdentifier(name).replace(/^_+/, '').replace(/[0-9]+$/g, '');
|
||
|
let uid;
|
||
|
let i = 0;
|
||
|
|
||
|
do {
|
||
|
uid = '_' + name + (i > 1 ? i : '');
|
||
|
i++;
|
||
|
} while (this.program.names.has(uid));
|
||
|
|
||
|
this.program.names.add(uid);
|
||
|
return uid;
|
||
|
}
|
||
|
|
||
|
addBinding(name, decl, type) {
|
||
|
if (type === 'var' && this.type !== 'function' && this.type !== 'arrow_function' && this.parent) {
|
||
|
this.parent.addBinding(name, decl, type);
|
||
|
} else {
|
||
|
if (type === 'param') type = 'var';
|
||
|
this.names.add(name);
|
||
|
this.bindings.set(name, decl);
|
||
|
this.program.names.add(name);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
getBinding(name) {
|
||
|
var _this$bindings$get, _this$parent;
|
||
|
|
||
|
return (_this$bindings$get = this.bindings.get(name)) !== null && _this$bindings$get !== void 0 ? _this$bindings$get : (_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.getBinding(name);
|
||
|
}
|
||
|
|
||
|
addReference(identifier) {
|
||
|
let references = this.references.get(identifier.name);
|
||
|
|
||
|
if (!references) {
|
||
|
references = new Set();
|
||
|
this.references.set(identifier.name, references);
|
||
|
}
|
||
|
|
||
|
references.add(identifier);
|
||
|
}
|
||
|
|
||
|
rename(from, to) {
|
||
|
// If already renamed, update the original to the final name.
|
||
|
let renamed = this.inverseRenames.get(from);
|
||
|
|
||
|
if (renamed) {
|
||
|
this.renames.set(renamed, to);
|
||
|
} else {
|
||
|
this.renames.set(from, to);
|
||
|
this.inverseRenames.set(to, from);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
exit() {
|
||
|
// Rename declarations in this scope.
|
||
|
for (let [from, to] of this.renames) {
|
||
|
if (!this.names.has(from) && this.parent) {
|
||
|
this.parent.rename(from, to);
|
||
|
}
|
||
|
|
||
|
let references = this.references.get(from);
|
||
|
|
||
|
if (!references) {
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
for (let id of references) {
|
||
|
id.name = to;
|
||
|
}
|
||
|
} // Propagate unknown references to the parent scope.
|
||
|
|
||
|
|
||
|
let parent = this.parent;
|
||
|
|
||
|
if (parent) {
|
||
|
for (let [name, ids] of this.references) {
|
||
|
if (!this.names.has(name)) {
|
||
|
for (let id of ids) {
|
||
|
parent.addReference(id);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
exports.Scope = Scope;
|
||
|
let scopeVisitor = {
|
||
|
Program(node, state) {
|
||
|
if (!state.scope) {
|
||
|
state.scope = new Scope('program');
|
||
|
}
|
||
|
},
|
||
|
|
||
|
Scopable: {
|
||
|
enter(node, state, ancestors) {
|
||
|
if (!t().isScope(node, ancestors[ancestors.length - 2]) || t().isProgram(node) || t().isFunction(node)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
state.scope = new Scope('block', state.scope);
|
||
|
},
|
||
|
|
||
|
exit(node, state, ancestors) {
|
||
|
if (!t().isScope(node, ancestors[ancestors.length - 2])) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
state.scope.exit();
|
||
|
|
||
|
if (state.scope.parent) {
|
||
|
state.scope = state.scope.parent;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
},
|
||
|
Declaration: {
|
||
|
exit(node, {
|
||
|
scope
|
||
|
}) {
|
||
|
if (t().isFunction(node) || t().isExportDeclaration(node)) {
|
||
|
return;
|
||
|
} // Register declarations with the scope.
|
||
|
|
||
|
|
||
|
if ((0, t().isVariableDeclaration)(node)) {
|
||
|
for (let decl of node.declarations) {
|
||
|
let ids = t().getBindingIdentifiers(decl);
|
||
|
|
||
|
for (let id in ids) {
|
||
|
scope.addBinding(id, decl, node.kind);
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
let type;
|
||
|
|
||
|
if ((0, t().isClassDeclaration)(node)) {
|
||
|
type = 'let';
|
||
|
} else if ((0, t().isImportDeclaration)(node)) {
|
||
|
type = 'const';
|
||
|
} else {
|
||
|
(0, _assert().default)(false);
|
||
|
}
|
||
|
|
||
|
let ids = t().getBindingIdentifiers(node);
|
||
|
|
||
|
for (let id in ids) {
|
||
|
scope.addBinding(id, node, type);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
},
|
||
|
|
||
|
Function(node, state) {
|
||
|
// Add function name to outer scope
|
||
|
let name;
|
||
|
|
||
|
if ((0, t().isFunctionDeclaration)(node) && (0, t().isIdentifier)(node.id)) {
|
||
|
name = node.id.name;
|
||
|
state.scope.addBinding(name, node, 'var');
|
||
|
} // Create new scope
|
||
|
|
||
|
|
||
|
let type = t().isArrowFunctionExpression(node) ? 'arrow_function' : 'function';
|
||
|
state.scope = new Scope(type, state.scope); // Add inner bindings to inner scope
|
||
|
|
||
|
let inner = t().getBindingIdentifiers(node);
|
||
|
|
||
|
for (let id in inner) {
|
||
|
if (id !== name) {
|
||
|
state.scope.addBinding(id, inner[id], 'param');
|
||
|
}
|
||
|
}
|
||
|
},
|
||
|
|
||
|
Identifier(node, state, ancestors) {
|
||
|
let parent = ancestors[ancestors.length - 2];
|
||
|
|
||
|
if (!t().isReferenced(node, parent, ancestors[ancestors.length - 3])) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
state.scope.addReference(node);
|
||
|
}
|
||
|
|
||
|
};
|
||
|
exports.scopeVisitor = scopeVisitor;
|