Skip to content

Confusing error when static private field is accessed before declaration.  #12904

@dragomirtitian

Description

@dragomirtitian

Bug Report

Current behavior
At runtime, when reading or setting a private static field before its declaration we get the following error: TypeError Cannot read property 'get' of undefined and respectively TypeError Cannot read property 'set' of undefined

REPL
Input Code

class AA {
  static #x = new AA();
  static #y = 0;
  constructor() {
    // Either line will trigger the confusing error
    // One for get the other for set 
    console.log(AA.#y);
    //AA.#y = 10
  }
}

Expected behavior
The private static field access should continue to be an error, but the error message should be more explicit about what the cause of the error is. Node, for example, issues this error Cannot read private member #y from an object whose class did not declare it.

Possible Solution
Change _classStaticPrivateFieldSpecGet and _classStaticPrivateFieldSpecGet helpers to check if descriptor is undefined and issue an appropriate error:

function _classStaticPrivateFieldSpecGet(receiver, classConstructor, descriptor) {
    if (receiver !== classConstructor) {
        throw new TypeError("Private static access of wrong provenance");
    }
    if (descriptor === undefined) {
        throw new TypeError("Private static field was accessed before its declaration.");
    }
    if (descriptor.get) {
        return descriptor.get.call(receiver);
    }
    return descriptor.value;
}

function _classStaticPrivateFieldSpecSet(receiver, classConstructor, descriptor, value) {
    if (receiver !== classConstructor) {
        throw new TypeError("Private static access of wrong provenance");
    }
    if (descriptor === undefined) {
        throw new TypeError("Private static field was accessed before its declaration.");
    }
    if (descriptor.set) {
        descriptor.set.call(receiver, value);
    } else {
        if (!descriptor.writable) {
            throw new TypeError("attempted to set read only private field");
        }
        descriptor.value = value;
    }
    return value;
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions