#1341·gopherjs

Possible overlooked mistakes in prelude/types.js?

Author: CL-JeremyCreated Sep 2, 2024Updated Nov 17, 2024
LabelsNeedsInvestigation

I was looking into possibilities to refactor prelude and stumbled on #1057. Does the change in this specific file even work like this, since typ is a var in a function and not a global?

https://github.com/gopherjs/gopherjs/blob/1ebb325a772c6ac0d0f866c55a8ef9afe7b71273/compiler/prelude/types.js#L61-L69

Wouldn't it be necessary to change line 64 to return function typ(array) { instead?

Related to the above code: there are also 2 references to the prototype of the class, which is empty unless the methods are defined as methods: https://github.com/gopherjs/gopherjs/blob/1ebb325a772c6ac0d0f866c55a8ef9afe7b71273/compiler/prelude/types.js#L237-L243

With the code kept as-is, the lines 242-243 shouldn't be able to override these methods, as the function assignments as in $arrayPtrCtor() would land in the class constructor and happen only at instantiation.

Here is my suggestion for this specific part. I was trying to give the file some type annotations to increase readability. If this change holds true, there might be other JavaScript snippets that are worth looking at regarding similar issues.

javascript
/**
 * Creates constructor functions for array pointer types. Returns a new function
 * instace each time to make sure each type is independent of the other.
 * 
 * @template T
 * @typedef {{
 *  $get(): T,
 *  $set(v: T): void,
 *  $val: T 
 * }} Typ<T>
 * @typedef {(new <T>(v: T) Typ<T>) & {
 *  prototype: Omit<Typ<T>, "$val">,
 *  wrapped: boolean,
 *  keyFor(v: T): T,
 *  elem?: TypClass<T>,
 *  len?: number,
 *  comparable?: boolean,
 *  ptr?: TypClass<T>,
 *  init?(...args): void,
 *  nil?: Typ<T>
 *  copy?(v1: T, v2: T): void,
 * }} TypClass<T>
 * @type {() => TypClass<T>}
 */
var $arrayPtrCtor = () => {
    return class typ {
        $get() { return this.$val; }
        $set(v) { typ.copy(this, v); }
        constructor(array) { this.$val = array; }
    };
};