Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/plans/generic-constructor-compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,27 @@ Stop after this declared distinct-generic-constructor relation passes the pinned
boundary and controls. Repeated class evaluation/computed keys remain #1906;
arbitrary dynamic superclass support remains #1907. General structural class,
conditional-type or inference conformance is outside this successor.

## Implementation evidence (#1963)

The constructor relation now projects constructor parameters, constructed instance
members and required static members into a single contextual signature relation.
Alpha-renaming and inference therefore use one substitution across all three.
Private/protected declaration origins and ECMAScript private brands are checked
before structural projection, including separate static visibility metadata and
common-base origins. Existing declaration-identity fast paths and cache keys remain.
Class expressions now publish their private field/method metadata as private metadata.

Runtime construction reads generic constructor bindings rather than selecting the
original expression template after reassignment. Literal inferred type arguments
are widened to their corresponding CLR primitive when closing an aliased constructor.

On Windows ARM64/.NET 10.0.12, all three retained positive sources match Node in CLI
interpretation and IL-verified standalone output. Their shared tests also exercise
the interpreter, in-process compiled execution and serialized verification/execution
with 30-second harness deadlines. All four retained negatives remain rejected.
The final focused selection passes 52 tests; the broader generic/compatibility/class
expression/private-field selection passes 936 tests with compiled IL verification.
Release, code-quality gates and the actual analyzer-aware AOT/trim/single-file build
pass; its zero-warning inventory matches the committed baseline. Hosted execution
was not exercised by these new tests.
22 changes: 22 additions & 0 deletions docs/plans/namespace-class-identity.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,25 @@ evidence remains missing; the new controls demonstrate the same diagnostic famil
without claiming to reconstruct the historical source.

The finite successor is [#1968](https://github.com/nickna/SharpTS/issues/1968).

## Implementation verification (#1968)

The checked declaration now supplies the canonical emitted class owner. Namespace
and module scopes are retained through method, constructor and property-dispatch
emission, and checked references resolve that owner. Namespace object and variable
storage is module-local. Interpreter exports accept namespace declarations, and
reopened namespaces retain earlier exported class bindings. Emitted class metadata
keeps the guest simple name independently of the canonical CLR name.

Both sibling fixtures now print `1 2 9`; both module import orders print `1 2`.
These unchanged fixtures pass API execution in both engines and CLI compilation,
IL verification and standalone execution, with empty stderr and a 30-second
per-case deadline. Additional shared controls cover nested/reopened namespaces,
private storage/origins, typed signatures, inheritance, bare self-construction,
module namespace variables and constructor aliases with observable names.

The affected namespace/class-expression/generic/private/module selection passes
711 tests with `SHARPTS_VERIFY_COMPILED=1`, including #1781's original standalone
construction regression. The quality gate passes. Release and actual AOT analyzer
baseline checks pass; the analyzer inventory has zero warnings. Hosted execution is not claimed
for the new fixtures. The historical baseline evidence above remains unchanged.
65 changes: 65 additions & 0 deletions docs/plans/private-in-brand-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,3 +94,68 @@ Stop after the specified grammar, declared-name lookup and brand cases pass.
Private-method values remain #1961; repeated class-evaluation identity and
computed-key behavior remain #1906. General parser compatibility, broader class
features and unrelated conformance changes do not enter this successor.

## Implementation verification (#1962)

The implementation adds the relational AST node, lexical checked-owner lookup,
right-operand traversal and presence queries in both engines. Nested class
expressions retain their enclosing evaluation owner; derived instances use the
declaring template's brand, and generic static probes use the exact guest owner.
Instance fields install in source order after their initializer completes, while
the method brand is available before those initializers run.

Validation on Windows ARM64, 2026-10-06:

| Check | Recorded result |
| --- | --- |
| Release build of `SharpTS.Tests` | Succeeded, zero errors; existing NU1902 package advisory |
| `PrivateInTests`, `PrivateInParserTests`, `AstDispatchTests` | 95 passed, zero failed |
| Private/generic/class-expression/arrow/repeated-class selection | 2,043 passed, zero failed, after the #1965 capture follow-up |
| Runtime reference fixtures | All 14 matched Node v25.5.0 stdout, exit 0 and empty stderr |
| Code-quality gate | Passed: 27 duplicate groups, zero errors |
| Actual AOT/trim/single-file analyzer restore and rebuild | Passed: unchanged zero-warning baseline |
| Pinned TypeScript checker smoke gate | Passed: all 32 corpus cases, clean TypeScript 6.0.3 checkout |

The shared runtime tests execute both engines, serialize and verify emitted IL,
and execute the resulting assembly. Thirteen fixtures also execute without a
deployed `SharpTS.dll`; the proxy fixture uses the deployed runtime. Module-owner
controls run in both engines and verify the compiled multi-file assembly. The
default execution deadline is 30 seconds. Runtime reference sources were emitted
with TypeScript 7.0.2 (`--target ES2022 --skipLibCheck --noImplicitAny false`);
the final flag permits the timing fixtures' unannotated private fields without
changing their runtime source. Node's native type stripper was not used as the
reference parser for the generator fixtures.

Two added static-write controls reject assignment before a private field's
initializer has completed, leave its brand absent, and evaluate the RHS once.
They also cover an abrupt RHS and successful assignment after installation for
a generic named owner and repeated class expressions. The preserved pre-fix
compiler (`28DF7ED461F26E6AEE0B34B29FA287925CC2C4D1FC9DB30298A13D5768E621E3`)
failed these semantic controls in both engines even though its emitted IL
verified. The candidate matches Node; the two reference emissions additionally
set `--useUnknownInCatchVariables false` for the caught-error message assertion.

The pinned Test262 comparison selected all 19 `class-fields-private-in` files at
revision `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33`. In each engine the unchanged,
preserved `c782c870` binary reported 11 parse errors and eight deferred negative
cases; the candidate reported eight passes, three parse errors and the same
eight deferred negatives. All worker processes exited 0 with empty stderr and
no runtime failures or timeouts. Two remaining errors require private accessor
declaration parsing; the third uses `function await()` as an ordinary identifier.
The deferred negative cases are not credited as validated semantics; local
parser/checker negative tests provide the separate negative coverage.

Evidence is retained under `artifacts/issue1962-lexical-*`,
`artifacts/issue1962-static-write/` (focused TRX, reference and pre-fix outputs),
`artifacts/issue1965-shadow-capture/broader-tests.log`,
`artifacts/validation/code-quality-final.log` and `artifacts/validation/issue1962/`.
The latter includes exact commands, binary hashes and every Test262 classification.
The final candidate rerun preserves the same eight passes, three parse errors and
eight deferred negatives in each engine. A separate 28-process CLI matrix checks
the three retained positives against Node, interpretation, verified standalone
emission, and hosted initialization with default declarations and `--noLib`.
Hosted execution uses the public factory and `InitializeAsync`, with a 30-second
process deadline; it is separate from ordinary entry-point execution. These
checks do not claim native AOT publication. The consolidated PR records the
full-suite results separately. The checker gate uses the clean pinned TypeScript
6.0.3 corpus and its committed diagnostics without live `tsc` or npm.
48 changes: 48 additions & 0 deletions docs/plans/private-method-values.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,53 @@
# Private-method values: bounded implementation design (#1901)

## Implementation evidence (#1961)

Private method extraction now returns a canonical, unbound callable after checking
the receiver against the lexical declaration's brand. Ordinary declarations cache
their callable in a non-generic adapter; generic instance access uses the existing
private-instance bridge. Class expressions cache private callables and static
private state on each evaluated class definition. Repeated expression evaluations
therefore retain different brands, values, and captured environments.

The adapter executes the source body with an explicit guest receiver. Public
property reads, writes, calls, and returned closures use that receiver. Private
access continues to use the lexical owner's storage, including after suspension.
Name, arity, defaults/rest, strict receiver semantics, and non-constructibility use
the emitted function contracts. `PrivateClassElementRegistry` checks adapter,
cache, constructor, and initializer ownership and requires their emitted bodies
before completion. No runtime type generation or SharpTS deployment dependency
is introduced.

`PrivateMethodValueTests` executes eleven sources in interpretation, in-process
compilation, verified saved IL, and standalone deployment. The sources cover
generic identity, extraction evaluation once, borrowed receivers, public writes
and calls, private brands, static state, all four method kinds, returned closures,
defaults/rest, and a timer suspension. Separate tests cover same-named module
declarations and checker rejection of outside access, assignment, and undeclared
private names. Node v25.5.0 matches all eleven expected outputs; TypeScript 7.0.2
accepts the two retained positive fixtures and rejects the outside-access control.

A targeted Test262 comparison against unchanged `c782c870`, at the pinned corpus
revision `d5e73fc8d2c663554fb72e2380a8c2bc1a318a33`, improves
`private-method-get-and-call.js` from RuntimeError to Pass in both engines, with
no regressions in the eight selected files. Three metadata files retain their
parser errors (method-trailing semicolons), and three compiled inherited/inner
arrow controls retain their runtime errors. These outcomes are not counted as
passing conformance checks or silently removed from the comparison.

Final verification passes 22 focused tests and 779 affected regressions with
strict compiled IL verification enabled. The retained positive CLI fixtures also
pass saved-assembly IL verification and exact-output standalone execution without
SharpTS.dll. The Release solution build and all code-quality gates pass; the
analyzer-aware restore/rebuild reports zero AOT/trim/single-file warnings and
matches the checked baseline. The bounded regression selection excludes the
pre-existing lock-decorator IL failure reproduced at `69f2b081`; the separate
async-arrow/inheritance IL failures recorded for #1965 remain unchanged.

The remaining runtime-valued local declaration work is tracked separately by
#1967; this evidence does not claim that repeatedly executed local declarations
already receive the class-expression evaluation identity.

## Evidence and disposition

The notes linked by #1901 and #1854 report preserved generic and non-generic
Expand Down
91 changes: 91 additions & 0 deletions docs/plans/repeated-class-evaluation.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,94 @@ new syntax and unrelated conformance failures remain their existing tasks. The
inline prototype-call IL failure is a separate verification defect,
[#1966](https://github.com/nickna/SharpTS/issues/1966); its failure
is retained rather than used to claim this representation work is repaired.

## Implementation evidence for #1964

Each class-expression evaluation now returns a fresh emitted `$ClassDefinition`
with its own prototype, constructor back-reference, name and arity. A generated
factory passes the selected definition into the shared template's constructor
before instance field initialization. Generic arguments are erased at that
factory boundary, so instances of one guest definition share its prototype.
Runtime construction, Reflect construction, `typeof`, and `instanceof` recognize
these definition values. The interpreter uses definition identity for class
brands and evaluates instance initializers with their owning environment and
receiver. Named expressions retain their local body binding.

`RepeatedClassDefinitionTests` covers repeated evaluations in functions, loops,
closures, modules, async and generator suspension, plus generic arguments,
initializers, prototype mutation, default arguments and bound construction. The
ten source controls run in both engines and as serialized, IL-verified programs.
The module control runs in both engines. A reused runtime emitter test separately
verifies fresh metadata ownership and saved IL in ordinary and hosted emission;
this is emission evidence, not a hosted class-factory execution claim.

On Windows ARM64/.NET 10.0.12 and Node v25.5.0, the unchanged
`constructors-only.ts` now prints `false` in verified CLI standalone output.
`prototype-separate-values.ts` prints `false`, `false`, `true true`, and
`true false`, matching Node. Both standalone runs complete within 30 seconds
with empty stderr and without SharpTS.dll in the output directory. The inline
`identity.ts` source remains the separate #1966 verifier control.

The affected class-expression/owner/local-class, constructor, generic, computed
member, namespace and prototype suite passes all 1,181 tests with compiled IL
verification enabled. The full Release solution build and code-quality gates
pass (28 duplicate groups, zero errors). The actual AOT/trim/single-file analyzer
passes the unchanged zero-warning baseline. Definition-owned computed keys,
capture snapshots and static initialization continue in #1965.

## Implementation evidence for #1966

The unchanged inline `identity.ts` reproduced the reported `BackwardBranch`
error at offset 709 after #1964. The reflection constructor's argument-padding
loop jumped forward over its body and then backward into it while the enclosing
prototype query retained values on the evaluation stack. Moving the loop check
to the top makes its stack height determinable in one forward scan.

The original source now passes CLI IL verification and prints `false` / `false`
in standalone output, matching Node, within 30 seconds with empty stderr.
`InlineConstructorPrototypeTests` verifies all three source controls as saved
assemblies and executes them in both engines and without SharpTS.dll. Additional
controls retain left-to-right, exactly-once callee/argument evaluation, omitted
parameter defaults, and prototype identity for an aliased CLR constructor.
All 279 affected constructor, class-expression owner, generic-constructor and
prototype tests pass with compiled verification enabled; the Release core/test
build passes. The original reference expectation and verifier remain intact.

## Implementation evidence for #1965

Each class-expression definition now owns its ordered computed keys, captured
bindings, member descriptors, static fields and initialization. Keys are evaluated
once, before static fields/blocks, and retained across suspension; instances read
their lexical definition's keys rather than mutable template static fields.
String and Symbol methods/accessors register in source order on the fresh
prototype or constructor. Static methods retain the selected definition separately
from the caller's `this`. Captured bindings retain their original display-class or
cell storage, so later writes and closures returned by methods remain live.
Async/generator method state machines retain the instance or static definition,
and suspended closure emitters share the same environment population path.
Instance method values use pre-emitted adapters that retain the lexical definition
separately from their explicit guest receiver. Borrowing a method across class
evaluations therefore retains its original captures while observing the caller's
public fields, including after suspension.

`RepeatedClassStateTests` exercises 18 source controls in interpretation,
in-process compilation, serialized IL verification/execution and standalone
deployment, plus two module execution modes with serialized module verification.
The source controls include retained constructors after a second evaluation,
string/Symbol fields and members, accessors, static captures and borrowed
receivers, initialization order, abrupt keys, interleaved awaits, inherited keys,
awaited keys/heritage, live captured writes and closures returned after suspension.
All 18 match Node v25.5.0. The unchanged `computed-keys.ts` passes verified CLI
standalone execution within 30 seconds, with empty stderr and no SharpTS.dll,
printing `false 2` / `5 5 undefined undefined 5`. The unchanged one-definition
generic computed-key expectation remains in the affected regression selection.

The full Release solution build passes. Quality gates report 27 duplicate groups
and zero errors; the obsolete suspended-closure duplicate exception was removed
after sharing emission. The actual AOT/trim/single-file analyzer matches the
unchanged zero-warning baseline. The affected verification selection has 1,596
passing tests. A separately recorded async-lock verifier failure also reproduces
on unchanged `69f2b081`; three other failures in the wider async selection likewise
reproduce there. These baseline failures are not counted as passes. Hosted
execution is not part of this evidence. Runtime-valued ordinary-user-class
heritage remains the separate #1967 task.
Loading
Loading