Module refinery.lib.scripts.js.builtins
The functions the language installs on the prototypes of the values a fold holds, and the
constructors owning those prototypes. PROTOTYPE_METHODS is the one table of them: what a member
read on a string, an array, a number, a boolean or a function is answered by where the value does
not own the key, which keys such a read can never find, and which reads hand out an object the
program may write a built-in through. The analysis that guards a fold and the fold itself both read
it here, so neither states a second answer.
Expand source code Browse git
"""
The functions the language installs on the prototypes of the values a fold holds, and the
constructors owning those prototypes. `PROTOTYPE_METHODS` is the one table of them: what a member
read on a string, an array, a number, a boolean or a function is answered by where the value does
not own the key, which keys such a read can never find, and which reads hand out an object the
program may write a built-in through. The analysis that guards a fold and the fold itself both read
it here, so neither states a second answer.
"""
from __future__ import annotations
from refinery.lib.scripts.js.values import BuiltinFunction
PROTOTYPE_METHODS: dict[str, frozenset[str]] = {
'Object': frozenset({
'__defineGetter__',
'__defineSetter__',
'__lookupGetter__',
'__lookupSetter__',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'toLocaleString',
'toString',
'valueOf',
}),
'Function': frozenset({
'apply',
'bind',
'call',
'toString',
}),
'Array': frozenset({
'at',
'concat',
'copyWithin',
'entries',
'every',
'fill',
'filter',
'find',
'findIndex',
'findLast',
'findLastIndex',
'flat',
'flatMap',
'forEach',
'includes',
'indexOf',
'join',
'keys',
'lastIndexOf',
'map',
'pop',
'push',
'reduce',
'reduceRight',
'reverse',
'shift',
'slice',
'some',
'sort',
'splice',
'toLocaleString',
'toReversed',
'toSorted',
'toSpliced',
'toString',
'unshift',
'values',
'with',
}),
'String': frozenset({
'anchor',
'at',
'big',
'blink',
'bold',
'charAt',
'charCodeAt',
'codePointAt',
'concat',
'endsWith',
'fixed',
'fontcolor',
'fontsize',
'includes',
'indexOf',
'isWellFormed',
'italics',
'lastIndexOf',
'link',
'localeCompare',
'match',
'matchAll',
'normalize',
'padEnd',
'padStart',
'repeat',
'replace',
'replaceAll',
'search',
'slice',
'small',
'split',
'startsWith',
'strike',
'sub',
'substr',
'substring',
'sup',
'toLocaleLowerCase',
'toLocaleUpperCase',
'toLowerCase',
'toString',
'toUpperCase',
'toWellFormed',
'trim',
'trimEnd',
'trimLeft',
'trimRight',
'trimStart',
'valueOf',
}),
'Number': frozenset({
'toExponential',
'toFixed',
'toLocaleString',
'toPrecision',
'toString',
'valueOf',
}),
'Boolean': frozenset({
'toString',
'valueOf',
}),
}
"""
The function-valued own properties of the prototype of each constructor named, `constructor` aside,
enumerated from a real engine rather than from the subset this package can run: `normalize` is a
function whether or not a fold can evaluate it, and a read answering `undefined` for it would
contradict `typeof`. Symbol-keyed members are left out, since no string names them.
"""
ALIASED_METHODS: dict[tuple[str, str], str] = {
('String', 'trimLeft') : 'trimStart',
('String', 'trimRight') : 'trimEnd',
}
"""
The prototype keys that hold the same function as another key of the same prototype, mapped to
that other key: `''.trimLeft === ''.trimStart`, and the function's `name` is `trimStart`.
"""
HTML_METHODS: dict[str, tuple[str, str]] = {
'anchor' : ('a', 'name'),
'big' : ('big', ''),
'blink' : ('blink', ''),
'bold' : ('b', ''),
'fixed' : ('tt', ''),
'fontcolor' : ('font', 'color'),
'fontsize' : ('font', 'size'),
'italics' : ('i', ''),
'link' : ('a', 'href'),
'small' : ('small', ''),
'strike' : ('strike', ''),
'sub' : ('sub', ''),
'sup' : ('sup', ''),
}
"""
The methods of `String.prototype` ECMA-262 B.2.2.2 to B.2.2.14 define, each mapped to the tag it
wraps the string in and to the attribute it writes its argument into, or the empty string where it
writes none.
"""
ITERATOR_METHODS = frozenset({'entries', 'keys', 'values'})
"""
The methods of `Array.prototype` that return an iterator over the array.
"""
PROTOTYPE_CHAIN_PROPERTIES = frozenset({'__proto__', 'constructor'})
"""
The two properties that expose the prototype chain itself. Both exist on every value, so answering
`undefined` for them is wrong, and a read of either hands out an object whose properties are the
built-ins every value of a type inherits.
"""
OBJECT_PROTOTYPE_MEMBERS = PROTOTYPE_METHODS['Object'] | PROTOTYPE_CHAIN_PROPERTIES
"""
The members every plain object inherits from `Object.prototype`. An access of one of these names on
an object that does not own it resolves through the prototype rather than to `undefined`, so a fold
that treats an absent own-property as `undefined` must leave these intact.
"""
BUILTIN_MEMBER_NAMES = frozenset().union(*PROTOTYPE_METHODS.values()) | PROTOTYPE_CHAIN_PROPERTIES
"""
Every key a read off a value of a built-in type may find on its prototype chain. A read of one hands
out a built-in object, whose properties a write through the read replaces for every value.
"""
CONSTRUCTORS: dict[str, BuiltinFunction] = {
owner: BuiltinFunction(owner, is_constructor=True) for owner in (*PROTOTYPE_METHODS, 'RegExp')
}
"""
The constructor owning each prototype of `PROTOTYPE_METHODS`, and `RegExp`, by the global name
holding it. The methods of `RegExp.prototype` are left out of `PROTOTYPE_METHODS`: `exec` and
`test` are names a program reads off many objects no regular expression is, such as the module
`child_process`, and `BUILTIN_MEMBER_NAMES` would count every such read as one off a built-in.
"""
def _prototype_functions() -> dict[tuple[str, str], BuiltinFunction]:
functions: dict[tuple[str, str], BuiltinFunction] = {}
for owner, methods in PROTOTYPE_METHODS.items():
for key in methods:
name = ALIASED_METHODS.get((owner, key), key)
function = functions.get((owner, name))
if function is None:
function = functions[owner, name] = BuiltinFunction(name, is_constructor=False)
functions[owner, key] = function
return functions
PROTOTYPE_FUNCTIONS = _prototype_functions()
"""
The function each prototype of `PROTOTYPE_METHODS` holds under each of its keys, by the name of the
constructor owning the prototype and the key. The keys `ALIASED_METHODS` pairs hold one function.
"""
RECEIVER_WRITING_METHODS = frozenset({
'__defineGetter__',
'__defineSetter__',
'copyWithin',
'fill',
'pop',
'push',
'reverse',
'shift',
'sort',
'splice',
'unshift',
})
"""
The methods in `PROTOTYPE_METHODS` that write a property of the object they are called on: the
accessor installers of `Object.prototype` and the mutators of `Array.prototype`. Called on a
prototype, `[].__proto__.push(5)` stores an element every array then inherits.
"""
Global variables
var PROTOTYPE_METHODS-
The function-valued own properties of the prototype of each constructor named,
constructoraside, enumerated from a real engine rather than from the subset this package can run:normalizeis a function whether or not a fold can evaluate it, and a read answeringundefinedfor it would contradicttypeof. Symbol-keyed members are left out, since no string names them. var ALIASED_METHODS-
The prototype keys that hold the same function as another key of the same prototype, mapped to that other key:
''.trimLeft === ''.trimStart, and the function'snameistrimStart. var HTML_METHODS-
The methods of
String.prototypeECMA-262 B.2.2.2 to B.2.2.14 define, each mapped to the tag it wraps the string in and to the attribute it writes its argument into, or the empty string where it writes none. var ITERATOR_METHODS-
The methods of
Array.prototypethat return an iterator over the array. var PROTOTYPE_CHAIN_PROPERTIES-
The two properties that expose the prototype chain itself. Both exist on every value, so answering
undefinedfor them is wrong, and a read of either hands out an object whose properties are the built-ins every value of a type inherits. var OBJECT_PROTOTYPE_MEMBERS-
The members every plain object inherits from
Object.prototype. An access of one of these names on an object that does not own it resolves through the prototype rather than toundefined, so a fold that treats an absent own-property asundefinedmust leave these intact. var BUILTIN_MEMBER_NAMES-
Every key a read off a value of a built-in type may find on its prototype chain. A read of one hands out a built-in object, whose properties a write through the read replaces for every value.
var CONSTRUCTORS-
The constructor owning each prototype of
PROTOTYPE_METHODS, andRegExp, by the global name holding it. The methods ofRegExp.prototypeare left out ofPROTOTYPE_METHODS:execandtestare names a program reads off many objects no regular expression is, such as the modulechild_process, andBUILTIN_MEMBER_NAMESwould count every such read as one off a built-in. var PROTOTYPE_FUNCTIONS-
The function each prototype of
PROTOTYPE_METHODSholds under each of its keys, by the name of the constructor owning the prototype and the key. The keysALIASED_METHODSpairs hold one function. var RECEIVER_WRITING_METHODS-
The methods in
PROTOTYPE_METHODSthat write a property of the object they are called on: the accessor installers ofObject.prototypeand the mutators ofArray.prototype. Called on a prototype,[].__proto__.push(5)stores an element every array then inherits.