Skip to content

[patch] Call super() first in a JavaScript derived class's constructor - #156

Merged
matt-edmondson merged 2 commits into
mainfrom
fix/103-javascript-super-call
Oct 5, 2026
Merged

matt-edmondson merged 2 commits into
mainfrom
fix/103-javascript-super-call

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Fixes #103

Problem

JavaScriptGenerator wrote class Circle extends Shape but never wrote a super(...) call in the constructor. Every new Circle() therefore threw ReferenceError: Must call super constructor in derived class before accessing 'this'.... C++ and C# call the base's default constructor implicitly, so the same AST worked in those targets.

Change

  • GenerateMethod now takes the enclosing class's BaseType. A constructor in a derived class opens with super();, before any this.x = ... initialiser assignment.
  • An initialiser named after the base type is the C++ : Base(args) idiom. It is now emitted as super(value);, not as this.Shape = value;. This was the issue's second acceptance bullet.
  • A class with no base type is unchanged and gets no super call.

Tests

New tests in JavaScriptGeneratorTests:

  • A text test checks that super(); comes before this.radius = radius;.
  • A text test checks that a base-named initialiser becomes super(radius);, with no this.Shape.
  • A text test checks that a non-derived class gets no super.
  • A Node.js toolchain test runs the issue's repro and expects the output 2 shape. It is inconclusive when node is not on the path.

With the generator change reverted, the three derived-class tests fail. The full suite passes: 1058/1058.

🤖 Generated with Claude Code

https://claude.ai/code/session_01N47Hdpq8iSMutiKdDS81pa


Generated by Claude Code

The JavaScript generator wrote `class Circle extends Shape` but never wrote a
`super(...)` call in the constructor, so every `new Circle()` threw
ReferenceError before it could assign to `this`. C++ and C# call the base's
default constructor implicitly, so the same AST worked in those targets.

A constructor in a class with a BaseType now opens with `super();`. An
initialiser named after the base (the C++ `: Base(args)` idiom) supplies the
argument as `super(value);` rather than being assigned to `this.Base`.

Fixes #103

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N47Hdpq8iSMutiKdDS81pa
The super() call pushed GenerateMethod's cognitive complexity to 16, over
SonarCloud's limit of 15 (S3776). The initialiser loop, including skipping
the initialiser already passed to super, now lives in
WriteInitialiserAssignments. Output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N47Hdpq8iSMutiKdDS81pa
@sonarqubecloud

sonarqubecloud Bot commented Oct 5, 2026

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit 2c677bb into main Oct 5, 2026
14 checks passed
@matt-edmondson
matt-edmondson deleted the fix/103-javascript-super-call branch October 6, 2026 00:04
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.

JavaScript: constructor of a class with a BaseType never calls super(), so every new Derived() throws ReferenceError

1 participant