Skip to content

fix: parser accepts new MemberExpression per ECMA-262 (#78)#97

Merged
nickna merged 1 commit intomainfrom
worktree-issue-78-new-callee
May 1, 2026
Merged

fix: parser accepts new MemberExpression per ECMA-262 (#78)#97
nickna merged 1 commit intomainfrom
worktree-issue-78-new-callee

Conversation

@nickna
Copy link
Copy Markdown
Owner

@nickna nickna commented May 1, 2026

Closes #78.

Summary

  • ParseNewCallee now accepts any PrimaryExpression (literals, function/class expressions, identifiers, parenthesized exprs, this) plus a member-only chain (.name, [index]), and handles nested new. Spread args (new X(...iter)) are parsed via the new ParseNewArgumentList helper.
  • Type checker stops hard-throwing on non-class callees and defers to runtime TypeError (the spec-correct behavior for new <non-constructor>).
  • IL emitter: EmitCalleeExprConstruction was missing a box on the callee, so new true produced invalid IL that crashed the JIT (fatal CLR error 0x80131506). One-line fix.
  • 9 new parser unit tests covering literal/function-expression/index/no-paren/nested/spread shapes.

Test262 deltas

  • Interpreted: +30 new passes, 0 regressions; all 49 ParseError under test/language/expressions/new/ move off-bucket (29 → Pass, 20 → TypeCheckError on unrelated Symbol.iterator limitation).
  • Compiled: same 49 move off-bucket (14 Pass, 14 RuntimeError, 29 TypeCheckError, 2 Fail).

Both baselines regenerated.

Test plan

  • dotnet test SharpTS.Tests/SharpTS.Tests.csproj --filter "FullyQualifiedName~ParserTests" — 569 pass
  • Test262 interpreted baseline regen — 30 new passes, 0 regressions
  • Test262 compiled baseline regen — 49 ParseError → off-bucket, no regressions

Parser previously rejected `new` whose callee wasn't an identifier or
parenthesized expression — including spec-legal forms like `new true`,
`new 1`, `new "abc"`, `new function(){}(...)`, `new ctors[0]()`, and
`new new X()`. This blocked 49 of the 59 tests under
`test/language/expressions/new/` at parse time.

`ParseNewCallee` now consumes any PrimaryExpression and a member-only
chain (`.name`/`[index]`), with explicit recursion for nested `new`.
Argument-list parsing factors out into `ParseNewArgumentList`, picking
up spread support that the spread-err-* test bucket needs.

Type checker no longer hard-throws when the callee static type isn't
a class — for primitives, function expressions, etc. it defers to the
runtime's TypeError-on-non-constructor path (matches the existing
Function/Any branch).

IL emitter: `EmitCalleeExprConstruction` was missing `EmitBoxIfNeeded`
on the callee, so a value-type callee (`new true`) produced invalid IL
that crashed the JIT with a fatal CLR error (0x80131506). Boxing the
callee before storing it to the `object` temp fixes that.

Test262 deltas:
- Interpreted: +30 new passes, 0 regressions; all 49 ParseError under
  `expressions/new/` move off-bucket (29 → Pass, 20 → TypeCheckError).
- Compiled: same 49 move off-bucket (14 Pass, 14 RuntimeError, 29
  TypeCheckError, 2 Fail).

Adds 9 parser unit tests covering the new shapes.
@nickna nickna merged commit fa46056 into main May 1, 2026
1 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parser: accept new MemberExpression without argument list

1 participant