Skip to content

Commit

Permalink
WIP 1
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Sep 9, 2023
1 parent eee1bdd commit e526ecf
Show file tree
Hide file tree
Showing 17 changed files with 2,311 additions and 656 deletions.
1 change: 1 addition & 0 deletions lib/init/globals.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ function processOne(val, type, parent, key, noPreload, globals) {
* @returns {undefined}
*/
function catalogValue(val, props, nextLevelQueue, nextPriorityQueue, globals) {
if (val === undefined) return;
if (isPrimitive(val)) return;
if (globals.has(val)) return;
if (val instanceof Module) return; // To prevent `Module._cache` being cataloged
Expand Down
128 changes: 88 additions & 40 deletions lib/serialize/arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,110 @@
'use strict';

// Modules
const t = require('@babel/types');
const t = require('@babel/types'),
{isNumber} = require('is-it-type');

// Imports
const {createDependency} = require('./records.js'),
{recordIsCircular} = require('./utils.js');
const {getClassProtoSetters} = require('./utils.js');

// Constants
const MODIFIER_NAMES = ['writable', 'enumerable', 'configurable'];

// Exports

const arrayProtoSetters = getClassProtoSetters(Array);

module.exports = {
serializeArray(arr, record) {
const varName = record.varNode.name,
elementNodes = [],
defaultProps = [];
let numTrailingCircularOrValueless = 0,
numTrailingEmpty = 0;
for (let index = 0; index < arr.length; index++) {
let valNode;
const descriptor = Object.getOwnPropertyDescriptor(arr, index);
if (!descriptor) {
valNode = null;
numTrailingEmpty++;
/**
* Trace Array.
* Array length is recorded as `record.extra.length`.
* @param {Array} arr - Array
* @param {Object} record - Record
* @returns {Function} - Serializer function
*/
traceArray(arr, record) {
this.traceProperties(arr, record, Array.prototype, undefined, arrayShouldSkipKey);
record.extra = {length: arr.length};
return this.serializeArray;
},

/**
* Serialize Array.
* @param {Object} record - Record
* @param {Object} record.extra - Extra props object
* @param {number} record.extra.length - Array length
* @returns {Object} - AST node
*/
serializeArray(record) {
const elementNodes = [],
extraProps = [];
let index = 0,
numTrailingEmpty = 0,
numTrailingCircularOrValueless = 0;
for (let prop of record.props) {
// Skip properties which aren't array elements
const {key} = prop;
if (!isNumber(key)) {
extraProps.push(prop);
continue;
}

// Create gaps for empty keys
if (index !== key) {
do {
elementNodes.push(null);
numTrailingEmpty++;
index++;
} while (index !== key);
numTrailingCircularOrValueless = 0;
} else if (!('value' in descriptor)) {
valNode = null;
numTrailingCircularOrValueless++;
} else {
const val = descriptor.value,
valRecord = this.serializeValue(val, `${varName}_${index}`, `[${index}]`);
valNode = valRecord.varNode;
if (recordIsCircular(valRecord)) {
// Circular reference - leave it to `wrapWithProperties()` to assign value
valNode = null;
numTrailingCircularOrValueless++;
} else {
createDependency(record, valRecord, elementNodes, index);
numTrailingCircularOrValueless = 0;
numTrailingEmpty = 0;
defaultProps.push({
name: `${index}`, value: val, writable: true, enumerable: true, configurable: true
});
}

const {valRecord} = prop;
let elementNode;
if (valRecord && !valRecord.isCircular) {
// Non-circular value
elementNode = this.serializeValue(valRecord);
numTrailingEmpty = 0;
numTrailingCircularOrValueless = 0;

// If requires descriptor to be modified, add to `extraProps`
// for `wrapWithProperties()` to add descriptor
if (MODIFIER_NAMES.some(modifierName => prop[modifierName] === false)) {
prop = {...prop, valRecord: undefined, isExisting: true};
for (const modifierName of MODIFIER_NAMES) {
if (prop[modifierName]) prop[modifierName] = undefined;
}
extraProps.push({...prop, valRecord: undefined, isExisting: true});
}
} else {
// Circular value or getter/setter - pass to `wrapWithProperties()` to deal with
elementNode = null;
numTrailingCircularOrValueless++;
extraProps.push(prop);
}

elementNodes.push(valNode);
elementNodes.push(elementNode);
index++;
}

// If last entries were circular references or descriptors without values and will be set later
// by assignment, placeholders entries can be removed without disrupting entry order.
// Any empty elements that proceeded them can be removed too.
if (numTrailingCircularOrValueless > 0) {
const {length} = record.extra;
if (index !== length) {
// Add empty elements to fill up to length
do {
elementNodes.push(null);
index++;
} while (index !== length);
} else if (numTrailingCircularOrValueless > 0) {
// Last entries were circular references or descriptors without values and will be set later.
// Empty trailing entries can be removed without disrupting entry order.
elementNodes.length -= numTrailingCircularOrValueless + numTrailingEmpty;
}

// Create array node and wrap in extra properties (including circular assignments)
// Create array
const node = t.arrayExpression(elementNodes);
return this.wrapWithProperties(arr, record, node, Array.prototype, defaultProps, arrayShouldSkipKey);

// Wrap with extra props
return this.wrapWithProperties(node, record, arrayProtoSetters, extraProps);
}
};

Expand Down
7 changes: 7 additions & 0 deletions lib/serialize/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const {activateTracker, getTrackerResult, trackerError} = require('../shared/tra
createDependency, createAssignment
} = require('./records.js'),
{recordIsCircular, setAddFrom, deleteFirst} = require('./utils.js'),
{FUNCTION_TYPE} = require('./types.js'),
assertBug = require('../shared/assertBug.js');

// Exports
Expand All @@ -52,6 +53,12 @@ const commentTypePropsMap = {
};

module.exports = {
traceFunction(val, record) {
// TODO
record.type = FUNCTION_TYPE;
throw new Error('Functions not supported');
},

serializeFunction(fn, record) {
// Rename var if function has name
const {varNode} = record,
Expand Down
Loading

0 comments on commit e526ecf

Please sign in to comment.