Repository navigation
fix: skip members whose names aren't identifiers instead of throwing - #79
Open
willeastcott wants to merge 1 commit into
Open
willeastcott wants to merge 1 commit into
willeastcott wants to merge 1 commit into
Conversation
getType() returns null for a class member whose name isn't an identifier:
a private field (#secret), a computed (['computed']), quoted ('quoted') or
numeric (42) name. Two callers used the result without checking:
- getNodeAsAttribute() destructured it, so an @Attribute tag on such a
member, or such a member in an @interface type, threw "Cannot destructure
property 'type' of 'getType(...)' as it is null".
- getAttributes() read type.name, so any script class with such a member
threw "Cannot read properties of null (reading 'name')".
The editor's code editor runs getAttributes() in its esm-script worker for
attribute autofill, so a script with a private field crashed the worker on
every parse. Both now skip the member, as it can't be an attribute anyway.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
getType()returnsnullfor a class member whose name isn't an identifier: a private field (#secret), or a computed (['computed']), quoted ('quoted') or numeric (42) name. Two callers used the result without checking it:getAttributes()readtype.namefor every non-static property of an ESM script, so any script class with such a member threwTypeError: Cannot read properties of null (reading 'name').AttributeParser.getNodeAsAttribute()destructured the result, so an@attributetag on such a member, or such a member inside an@interfacetype, threwTypeError: Cannot destructure property 'type' of 'getType(...)' as it is null.getAttributes()callsparseAttributes()first, so a script with an@interfaceattribute or a tagged private field hits this one first.Both threw out of the parser, so the whole file returned no attributes and no diagnostics. The PlayCanvas Editor's code editor runs
getAttributes()in a web worker for attribute autofill, so a script with a plain private field crashed that worker on every parse, and these crashes show up in the editor's error reports.Changes
getAttributes()skips a member whengetType()returnsnull.getNodeAsAttribute()returns early in the same case. Both of its callers already treat an empty result as "not an attribute".member-names.valid.jsregression coverage: one script with a private field, a private field tagged@attribute, computed, quoted and numeric names, an@interfaceattribute whose type has a private field, and two valid attributes. It checks thatparseAttributes()andgetAttributes()both succeed with no errors, that only the identifier-named attributes come back, and that the interface's schema leaves out its private field.Members with these names can't be attributes, so they're skipped silently, which matches how other non-attribute members are treated. An
@attributetag on a private field is ignored rather than reported. That could become an error in a follow-up if it's worth flagging.Testing
npm test: the 5 new tests pass. Before the fix, bothbeforehooks threw the destructuring error; with only thegetNodeAsAttribute()change, thegetAttributes()test threw thetype.nameerror, so both guards are needed. All other tests are unchanged. On my Windows checkoutmisc.valid.js"a" fails the same way with and without this change, becausecore.autocrlfadds a trailing\rto its multi-line description.npm run lintandtsc -p tsconfig.build.json --noEmitare clean.Manual smoke test
#secret = 1;alongside/** @attribute */ speed = 1;, then parse and open attribute autofill in the code editor.speedis still offered and nothing throws./** @attribute @type {number} */ #secret = 1;.#secretisn't listed as an attribute.🤖 Generated with Claude Code