Files
scriptc/tests/fixtures/npm/cases/static-objects/node_modules/static-ns/index.js
T
2026-10-25 17:13:16 -05:00

215 lines
5.3 KiB
JavaScript

// Constructor functions and namespace functions, some provably the same as
// classes and direct functions, others observably different.
var ns = ns || {};
ns.util = ns.util || {};
ns.util.twice = function (x) {
return 2 * x;
};
ns.util.isSelf = function () {
return this === ns.util;
};
// Indistinguishable from a class.
ns.Point = function (x, y) {
this.x = x;
this.y = y;
};
ns.Point.prototype.norm = function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
};
ns.Point.prototype.moved = function (dx) {
return new ns.Point(this.x + ns.util.twice(dx), this.y);
};
// Called without `new` as well.
ns.Box = function (v) {
this.v = v;
};
ns.Box.prototype.get = function () {
return this.v;
};
// Its prototype members are enumerable through instances.
ns.Bag = function () {
this.a = 1;
};
ns.Bag.prototype.m = function () {
return 2;
};
// Its name is read.
ns.Named = function () {
this.n = 0;
};
ns.Named.prototype.n2 = function () {
return this.n + 2;
};
// Read before its store: undefined then, a function after.
var earlyLate = typeof ns.util.late;
ns.util.late = function (x) {
return x + 1;
};
// Constructed before its store, from a function declaration: a TypeError,
// not a reference to an uninitialized class.
function makeEarly() {
try {
return new ns.Early().v;
} catch (e) {
return e.constructor.name;
}
}
var earlyResult = makeEarly();
ns.Early = function () {
this.v = "early";
};
ns.Early.prototype.get = function () {
return this.v;
};
// A receiver with an effect: the effect still happens.
var receiverReads = 0;
function utilWithEffect() {
receiverReads++;
return ns.util;
}
// A prototype method that is itself constructed.
ns.Maker = function () {
this.k = 1;
};
ns.Maker.prototype.make = function () {
this.made = true;
};
// A method called with a primitive receiver: sloppy mode boxes it.
ns.Prim = function () {
this.v = 1;
};
ns.Prim.prototype.kind = function () {
return typeof this;
};
// Frozen instances: a store that sloppy mode ignores throws in strict mode.
ns.Frozen = function () {
this.a = 1;
};
ns.Frozen.prototype.set = function () {
this.a = 2;
return this.a;
};
// A store into an argument, which may be a primitive or frozen: ignored in
// sloppy mode, a TypeError in strict mode.
ns.Writer = function (target) {
target.length = 0;
this.ok = true;
};
ns.Writer.prototype.done = function () {
return this.ok;
};
// A named constructor expression that refers to its own name.
var Self = function () {
this.n = "outer";
};
ns.Self = function Self(n) {
this.n = n;
this.next = n > 0 ? new Self(n - 1) : null;
};
ns.Self.prototype.depth = function () {
return this.next === null ? 0 : 1 + this.next.depth();
};
// Read through names not yet initialized: a TypeError and a ReferenceError,
// not calls to the direct function.
var aliasLater;
var uninitialized = (function () {
var out = [];
try {
out.push(aliasLater.twice(1));
} catch (e) {
out.push(e.constructor.name);
}
try {
out.push(tdzAlias.twice(1));
} catch (e) {
out.push(e.constructor.name);
}
return out.join("|");
})();
aliasLater = ns.util;
let tdzAlias = ns.util;
// A store between the constructor and its method runs a setter, which sees
// the prototype without the method.
var probeLog = [];
var probe = {
set seen(v) {
try {
probeLog.push(new ns.Gadget().spin());
} catch (e) {
probeLog.push(e.constructor.name);
}
},
};
ns.Gadget = function () {
this.s = 1;
};
probe.seen = 1;
ns.Gadget.prototype.spin = function () {
return this.s;
};
// Its prototype is asked whether a method is enumerable.
ns.Listed = function () {
this.l = 1;
};
ns.Listed.prototype.item = function () {
return this.l;
};
// Its prototype is reached through a plain object's field, and that field
// is asked whether a method is enumerable.
ns.Held = function () {
this.h = 2;
};
ns.Held.prototype.hold = function () {
return this.h;
};
var protoHolder = { prototype: ns.Held.prototype };
ns.run = function () {
var out = [];
var p = new ns.Point(3, 4);
out.push(p.norm(), p.moved(1).x, p instanceof ns.Point, Object.keys(p).join("|"));
var holder = {};
ns.Box.call(holder, 7);
out.push(holder.v, new ns.Box(5).get());
var keys = [];
for (var k in new ns.Bag()) keys.push(k);
out.push(keys.join("|"));
out.push(JSON.stringify(ns.Named.name), new ns.Named().n2());
out.push(ns.util.twice(21), ns.util.isSelf());
out.push(earlyLate, ns.util.late(1), earlyResult, new ns.Early().get());
out.push(utilWithEffect().twice(4), receiverReads);
out.push(typeof new (new ns.Maker()).make());
// The call with a primitive receiver keeps the class form out; it does not
// run, so the output does not depend on how this is passed.
if (out.length < 0) out.push(ns.Prim.prototype.kind.call(5));
out.push(new ns.Prim().kind());
var frozen = Object.freeze(new ns.Frozen());
out.push(Object.isFrozen(frozen), new ns.Frozen().set());
out.push(new ns.Writer({ length: 3 }).done());
out.push(new ns.Self(3).depth(), new Self().n);
out.push(uninitialized, aliasLater.twice(2), tdzAlias.twice(3));
out.push(probeLog.join("|"), new ns.Gadget().spin());
out.push(ns.Listed.prototype.propertyIsEnumerable("item"), new ns.Listed().item());
out.push(protoHolder.prototype.propertyIsEnumerable("hold"), new ns.Held().hold());
return out.join(" ");
};
module.exports = { ns };