Ensured labels are not mistaken for comments by skipping comment
filtering when the line matches a label definition
Added a regression test verifying that labels starting with “@” remain
visible even when comment filtering is enabled
Fixes#7889
Tested with
npm run lint
npm run ts-check
npm run test-min
npm run check-frontend-imports
make check
## Summary
This PR improves the pre-commit hook performance by:
- Using `vitest related` to run only tests affected by changed files
- Adding ability to skip expensive tests (filter tests) during
pre-commit
- Providing a consistent mechanism for skipping expensive tests
## Changes
- Modified `lint-staged.config.mjs` to run `vitest related` with
`SKIP_EXPENSIVE_TESTS=true`
- Updated `test/filter-tests.ts` to use idiomatic `describe.skipIf()`
for conditional test execution
- Changed `test-min` script to use `SKIP_EXPENSIVE_TESTS` environment
variable instead of `--exclude`
- Updated `CLAUDE.md` with documentation about the new test workflow
## Impact
- Pre-commit hooks are now much faster as they:
- Only run tests related to changed files
- Skip 688 expensive filter tests
- Use the same skipping mechanism as `npm run test-min`
## Testing
- ✅ Verified `vitest related` correctly identifies and runs related
tests
- ✅ Confirmed filter tests are skipped when `SKIP_EXPENSIVE_TESTS=true`
- ✅ Tested that full test suite still runs all tests when env var is not
set
- ✅ Pre-commit hooks work correctly with the new setup
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Fixes EBADF error in HeaptrackWrapper by removing redundant file
descriptor close operation
- The net.Socket takes ownership of the FD and closes it during cleanup,
making manual close unnecessary and dangerous
## Root Cause Analysis
The issue occurred in `lib/runtime-tools/heaptrack-wrapper.ts:133` where
the code attempted to manually close a file descriptor that was already
owned by a `net.Socket`. When creating a socket with `new
net.Socket({fd: fd})`, the socket takes ownership of the file descriptor
and closes it during cleanup operations like `resetAndDestroy()`.
Attempting to close the FD again results in:
1. EBADF errors when the FD hasn't been recycled
2. Potentially closing a different resource if the FD has been recycled
by the OS
## Solution
Removed the manual `oldfs.close(fd)` call since the socket handles FD
cleanup automatically. This prevents both the EBADF error and the more
dangerous scenario of closing recycled file descriptors.
## Verification
Created tests to verify that `net.Socket` takes ownership of file
descriptors:
```javascript
// Test confirms that after socket.destroy(), the FD is no longer valid
const fd = fs.openSync(pipePath, O_RDWR | O_NONBLOCK);
const socket = new net.Socket({ fd: fd, readable: true, writable: true });
socket.destroy();
// fs.fstatSync(fd) throws EBADF - confirming FD was closed by socket
```
## Test Plan
- [x] TypeScript compilation passes
- [x] Minimal test suite passes
- [x] Pre-commit hooks pass
- [x] Created unit test to verify net.Socket FD ownership behavior
Fixes COMPILER-EXPLORER-EA7
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
This adds some unit tests for the front end.
- configures "frontend tests" as a unit tests in `static/tests`,
removing the old cypress-requiring "unit" tests
- hack enough of a DOM to get things working
- port motd and id tests
- *adds* a golden layout checks (see #7807)
- Updates READMEs etc
---------
Co-authored-by: Claude <noreply@anthropic.com>
Fix#7809 and then some:
Stop processing opt-remarks if none were requested,
Make gcc dump remarks to file,
separate opt-file handling to ClangCompiler and GccCompiler,
make DefaultCompiler inherit GccCompiler,
move some tests around.
Resolves#7780.
Basically a follow-up to #7652; the output format of `rustc --help` was
changed to include angle brackets `<` and `>`. This PR updates the
regexes used to parse the help output and adds some tests.
## Summary
- Extracted source line handling logic into a dedicated
`SourceLineHandler` class that consolidates .loc, .stabs, and .6502
directive parsing
- Extracted label processing logic into a `LabelProcessor` class with
methods for finding used labels and filtering
- Created a `ParsingState` class to manage parsing loop state variables
in a centralized way
- Fully integrated all components into the main `AsmParser` class,
replacing the original complex parsing loop
## Changes Made
- **SourceLineHandler**: Unifies `.loc`, `.d2line`, `.cv_loc`, `.dbg`,
`.stabn`, and 6502 debug directive parsing
- **LabelProcessor**: Handles complex label detection, filtering, and
cleanup logic with MIPS/non-MIPS support
- **ParsingState**: Encapsulates state management during parsing
(inNvccCode, inCustomAssembly, etc.)
- **Integration**: All components work together through well-defined
interfaces
## Verification
- ✅ All 1082+ tests pass, including new subclass compatibility tests
from PR #7779
- ✅ All 670+ filter tests pass, confirming exact behavior preservation
- ✅ Added comprehensive unit tests for all new components (32 tests
total)
- ✅ TypeScript compilation and linting pass
- ✅ No performance regression in core functionality
## Bug Fix Discovered
The refactoring inadvertently **fixes issue #7781** - EWAVR label
detection bug:
- **Before**: EWAVR couldn't find labels in usage contexts like `ldi
r16, HIGH(_data)` due to `labelFindFor()` returning definition regex
- **After**: Now correctly uses `identifierFindRe` to find labels in
usage contexts
- Updated tests to reflect the corrected behavior
## Benefits
- Reduced complexity in the main `processAsm` method (from 180+ lines to
more manageable chunks)
- Extracted highly testable, focused components with single
responsibilities
- Eliminated code duplication between source handling methods
- Centralized state management reduces scattered variable handling
- Maintained full backward compatibility and exact behavior
- Fixed EWAVR label detection bug as a side effect
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
These tests document the expected functional behavior of AsmParser
subclasses before refactoring work begins, focusing on public API
behavior rather than implementation details.
## Changes
**Test Coverage Added:**
- **VcAsmParser**: Tests VC assembly format with PROC/ENDP structure,
directive handling, comment filtering
- **AsmEWAVRParser**: Tests EWAVR assembly format with label structure,
RSEG/PUBLIC/EXTERN directives
- **SPIRVAsmParser**: Tests SPIR-V assembly with OpFunction/OpLabel
structure, custom %label syntax detection
- **Integration tests**: Cross-parser compatibility and real test case
handling
**Key Insights Documented:**
- VcAsmParser & AsmEWAVRParser have completely custom `processAsm()`
implementations that don't use base class methods
- SPIRVAsmParser uses base class `processAsm()` but overrides
`getUsedLabelsInLine()` for custom label detection
- Different return formats: VC/EWAVR return `{asm: [...]}`, SPIRV
returns full `ParsedAsmResult` with `labelDefinitions`
## Test Plan
```bash
npm run test -- --run vc-asm-parser-tests.ts ewavr-asm-parser-tests.ts spirv-asm-parser-tests.ts asm-parser-subclass-integration-tests.ts
```
These tests establish the baseline behavior that must be preserved
during the upcoming AsmParser refactoring work to ensure subclass
compatibility.
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Fixes COMPILER-EXPLORER-E53: SyntaxError: Unexpected end of JSON input
- Adds robust error handling for malformed client state URLs
- Prevents Sentry notifications for user-caused errors
## Root Cause
The `extractJsonFromBufferAndInflateIfRequired` function and
`unstoredStateHandler` were not properly handling:
- Invalid base64 data in URLs
- Corrupted or malformed JSON after base64 decoding
- Empty JSON strings
This caused uncaught `SyntaxError` exceptions that were being sent to
Sentry as internal server errors.
## Changes
- Added proper error handling for base64 decoding failures
- Added validation for empty JSON strings before parsing
- Changed logging from `warn` to `debug` since this represents user
error
- Removed Sentry capture for malformed URLs to reduce noise
- Return 400 Bad Request instead of 500 Internal Server Error
## Test Plan
- [x] TypeScript compilation passes
- [x] All existing tests pass
- [x] Manual testing with malformed URLs returns 400 instead of 500
- [x] No Sentry errors generated for user-caused malformed URLs
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
This PR updates test files to use the new Vitest timeout syntax,
resolving deprecation warnings.
## Changes
- Updated `test/packager-tests.ts` to pass timeout as a number instead
of `{timeout: 5000}`
- Updated `test/filter-tests.ts` to pass timeout as a number instead of
`{timeout: 10000}`
## Details
Vitest now expects timeouts to be passed directly as a number as the
third parameter to `it()`, rather than as an object. This change updates
all occurrences to use the new syntax.
## Test plan
- [x] All existing tests continue to pass
- [x] No deprecation warnings are shown when running tests
- [x] Linter and type checks pass
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Add DynamoDB support to Google URL shortener to check in preference to goo.gl itself (which will be going away)
- Update ShortLinkResolver to accept AWS properties and use DynamoDB table `goo-gl-links`
- First check DynamoDB for fragment lookup before falling back to Google URL shortener (for now)
- Refactor resolve method to use async/await instead of raw promises for better readability
- Add awsProps to ServerDependencies and pass through component hierarchy
- Configure googleLinksDynamoTable property in AWS config files (defaults to empty)
## Implementation Details
- When `googleLinksDynamoTable` property is configured, `ShortLinkResolver` creates a DynamoDB client
- DynamoDB table uses `fragment` as the key and stores `expanded_url`
- Maintains backwards compatibility by falling back to Google URL (for now) shortener if DynamoDB is not configured or lookup fails
- Google URL shortener fallback will be removed in August 2025 when the service shuts down
## Test plan
- [x] All existing tests pass
- [x] TypeScript compilation succeeds
- [x] Linting passes
- [x] Updated tests to accommodate new awsProps parameter
- [x] Verify fallback to Google URL shortener when DynamoDB not
configured
- [x] Manual testing
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
Fix production CDN loading issues where URLs like
`https://static.ce-cdn.net//vendor.v57...css` (double slash) were being
generated when the `staticUrl` config has a trailing slash.
## Root Cause
PR #7681 refactored static asset handling and replaced
`urljoin(staticRoot, path)` with `${staticRoot}/${path}` string
interpolation, losing URL normalization that `urljoin` provides.
## Changes
- Replace string interpolation with `urljoin()` in
`createDefaultPugRequireHandler()`
- Add comprehensive tests covering all trailing slash scenarios
- Maintain full backward compatibility with existing configurations
## Test plan
- [x] All existing tests pass
- [x] Added 4 new test cases for static URL handling with various slash
scenarios
- [x] Verified TypeScript compilation and linting
- [x] Tested production CDN scenario where
`staticUrl=https://static.ce-cdn.net/`
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
This PR significantly improves maintainability by breaking up the 880+ line monolithic app.ts file into smaller, focused modules with proper testing. The code is now organized into dedicated modules under the lib/app/ directory, making the codebase more maintainable and testable.
## Key changes
- Extract functionality into modules under lib/app/ directory:
- Command-line handling (cli.ts)
- Configuration loading (config.ts)
- Web server setup and middleware (server.ts)
- Core application initialization (main.ts)
- URL handlers, routing, rendering, and controllers
- Add comprehensive unit tests for all new modules
- Make compilationQueue non-optional in the compilation environment
- Improve separation of concerns with dedicated interfaces
- Ensure backward compatibility with existing functionality
- Maintain cross-platform compatibility (Windows/Linux)
## Benefits
- Improved code organization and modularity
- Enhanced testability with proper unit tests
- Better separation of concerns
- Reduced complexity in individual files
- Easier maintenance and future development
This refactoring is a significant step toward a more maintainable codebase while preserving all existing functionality.
* For `nightly` Rust (and 1.88+), the output format of `--help` was
changed in https://github.com/rust-lang/rust/pull/140152.
This PR changes the parser to parse the new format, so that edition
overrides are selectable for `nightly` Rust. Note the `<>`:
```
--edition <2015|2018|2021|2024|future>
Specify which edition of the compiler to use when
compiling code. The default is 2015 and the latest
stable edition is 2024.
```
* Rust <= 1.34 (and >= 1.31) support the 2018 edition, but the help
message only includes `--edition` in verbose mode.
This PR removes the top-level global variable for the base directory and replaces it with a module-level variable managed through a setter function. Key changes include removing the global declaration in lib/global.ts, introducing a local ce_base_directory variable and setBaseDirectory function in lib/assert.ts, and updating app.ts to use the new setter.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Main changes:
- type checker cares about the return value (`void`) of handlers, so no
more `return res.send("...")` as that returns `express` type.
- regexes on slugs no longer supported, but we weren't really using them
in any meaningful way. The two places that had to be updated:
- `/clientstate/:clientstate64` - now uses a regex directly and tests added (thanks @partouf for spotting #4844)
- `/bits/:bits.html` - was some `\w+` but I believe that's unnecessary
for the same reasons
- actually call the Sentry handler. I don't know if this actually worked
before but the API checks suggest not.
Resolves#7521.
With this PR, `@...` suffixes are included in the clickable area for
go-to label.
This also affects PowerPC, where `@...` suffixes are a bit more common
(`@ha` and `@l` will also be marked as clickable).
---------
Co-authored-by: Matt Godbolt <matt@godbolt.org>
- vitest and all test types etc (test pass). Needed a few minor changes
to match new behaviour of `expect().toMatchSnapshot` (trailing
whitespace is now important)
- `which` - read the changes and spot-checked it. They dropped <v18
- `webpack-cli` - changes don't affect our usage. Checked with a local
`webpack` build and a "prod" run (`make` no dev)
- `enhanced-ms` - checked and updated to use new functionality
- `typescript` - all tests pass, no warnings.
Tested the site locally too.
- Add initial support for Numba compilation: asm, demangling, execution
Numba wraps Python functions in `Dispatcher` objects. Each dispatcher
contains zero or more compiled argument-type-indexed overloads of its
function. We import the user's code as a module, and emit the code from
all overloads of all dispatchers that the module publicly exposes.
Name mangling is odd in Numba. It uses a similar mangling syntax to C++,
but also encodes non-symbol (`r"[^a-z0-9_]"`) characters as `_%02x`.
This encoding yields valid identifier names, so it is not strictly
invertible. Here, I have hard-coded some replacements to decode some
common cases at the cost of possible clashes with ugly user-defined
names.
Screenshot captured via `make dev EXTRA_ARGS="--debug --language numba"`

## To do
- [x] Answer questions of #5591.
- [x] Acquire a python environment.
- [ ] Automatically run the python test?
Locally, I have installed a virtual environment with python 3.12.3 with
```shell
path/to/python -m venv venv_numba
path/to/venv_numba/bin/python -m pip install numba==0.61.0 scipy>=0.16
```
and configured its use with
```properties
# compiler-explorer/etc/config/numba.local.properties
compilers=&numba
defaultCompiler=numba_0_61_0
group.numba.compilers=numba_0_61_0
group.numba.baseName=Numba
compiler.numba_0_61_0.exe=/path/to/python3.13
compiler.numba_0_61_0.semver=0.61.0
```
I run this python-side test file with
```python
path/to/venv_numba/bin/python -m unittest etc/scripts/test_numba_wrapper.py
```
---------
Co-authored-by: Mats Jun Larsen <mats@jun.codes>
[ORCA/C](https://github.com/byteworksinc/ORCA-C) is a C compiler that
natively runs on and targets the Apple IIGS. ORCA/C and the programs it
generates can be run on modern Linux systems by using an emulation tool
called [Golden Gate](https://goldengate.gitlab.io).
This adds support for ORCA/C (run via Golden Gate) in Compiler Explorer.
It uses its own assembly format and objdumper (provided by Golden Gate),
so support for those is added. An extra configuration option was also
added to support execution via an emulator, bypassing the usual check
that executables can run natively. Asm docs for the WDC 65C816 processor
were also added.
ORCA/C and Golden Gate are not Free Software, but their rights holders
have given permission for them to be used on Compiler Explorer. Tarballs
for them can be supplied privately. See infra PR:
compiler-explorer/infra#1521
---------
Co-authored-by: Matt Godbolt <matt@godbolt.org>
.. as they're uniform execution options
Note the removal of `(compiler as any).executionType = 'nsjail'` from
tests - seems it didn't do anything.
But better test execution in staging, as I'm having trouble using nsjail
locally.
Rust error message locations (` --> <source>:<line>:<col>`) can have
more than one leading space, e. g. when the source code snippet that is
shown has line numbers greater than ten.
In this example (https://godbolt.org/z/9W8xPv36c), the error message is
not be recognised as an error and there are no red squigglies in the
editor pane.
When passing `-fdiagnostics-urls=always`/`-Z terminal-urls=yes`, the
hyperlink escape sequence was not stripped from the mouse hover widget
in the editor pane.
Link: https://godbolt.org/z/3cP8jj8jc
Hover over the empty braces in the C++ editor or the `i32` in the Rust
editor:
Before:
```
warning: no return statement in function returning non-void []8;;https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Warning-Options.html#index-Wno-return-type-Wreturn-type]8;;]x86-64 gcc 14.2 #1
error[]8;;https://doc.rust-lang.org/error_codes/E0308.htmlE0308]8;;]: mismatched typesrustc nightly #2
```
Now:
```
warning: no return statement in function returning non-void [-Wreturn-type]x86-64 gcc 14.2 #1
error[E0308]: mismatched typesrustc nightly #2
```
In optimized build, odin inlines the world and even ends up inlining the
user visible `main` function into the entry point main. The result is
empty asm output which is confusing. Thus, @require main so that the
compiler doesn't inline user visible main function
#7210