## Summary
Moves `static/assert.ts` and `static/rison.ts` to `shared/` directory to
make them available to both frontend and backend code without browser
dependencies. Updates all import paths across the codebase (~47 files).
## Motivation
This refactoring eliminates browser dependencies in these utilities,
allowing them to be imported by Node.js contexts (like Cypress test
files) without causing module load failures. This is a prerequisite for
upcoming Cypress test improvements.
## Changes
- Move `static/assert.ts` → `shared/assert.ts`
- Move `static/rison.ts` → `shared/rison.ts`
- Update `biome.json` to allow `hasOwnProperty` in `shared/` directory
- Update all imports across `static/`, `lib/`, and `test/` directories
(47 files changed)
## Benefits
- No functional changes, purely a code reorganization
- Makes these utilities accessible to both frontend and backend without
circular dependencies
- Enables future Cypress improvements that require these utilities in
Node.js context
- All tests pass ✓ (699 tests)
## Test Plan
- [x] TypeScript compilation passes
- [x] Linting passes
- [x] All unit tests pass (699 tests)
- [x] Pre-commit hooks pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
## What
Adds support for seeing Yul (Solidity IR) as intermediate output when
compiling Solidity.
This PR also enables that view for the Resolc compiler.
### Main Additions
- [x] Support viewing Yul in a supplementary view
- Solidity compilers can enable this by setting
`this.compiler.supportsYulView = true` in the compiler's constructor
- If custom processing of the Yul output or the Yul output filename is
needed, the compiler can override `processYulOutput()` or
`getYulOutputFilename()`
- [x] Enable the Yul view for Resolc
- [x] Implement a Yul backend option for filtering out debug info from
the output
### Notes
Source mappings are currently not handled for Yul -> Solidity.
## Overall Usage
### Steps
* Choose Solidity as the language
* Choose a Resolc compiler
* View intermediate results:
* Yul
* (Hide/show debug info by toggling "Hide Debug Info" in the Yul view
filters)
## Screenshots
<img width="1502" height="903" alt="ce-yul-view"
src="https://github.com/user-attachments/assets/ccc897e2-cd8d-4c33-962c-522d60b63134"
/>
<img width="1405" height="474" alt="Clojure in Compiler Explorer 2"
src="https://github.com/user-attachments/assets/76dfed9b-d0eb-4764-b371-9c6023088a50"
/>
With Macro Expansion:
<img width="1642" height="594" alt="image"
src="https://github.com/user-attachments/assets/8b511af9-3617-426e-868d-5a99e5db5756"
/>
TODO
- [x] Language configuration
- [x] Compile via wrapper
- Inject namespace if necessary to simplify minimal code sample
- Parse Unix style command line parameters into compiler bindings
- Place file in path according to namespace
- [x] Install some versions of Clojure [PR
here](https://github.com/compiler-explorer/infra/pull/1849)
- [x] Macroexpansion view (modeled on Rust macro expansion view)
- [x] Filter out command line options that would break wrapper operation
- [x] ~~Parse `--help` output to a list of options~~ Reverted because
not applicable.
- [x] Short form compiler options
- [x] Support Clojure compiler settings via env var, like
`JAVA_OPTS=-Dclojure.compiler.direct-linking=true
-Dclojure.compiler.elide-meta=[:doc,:file]`
NOT DOING
- [x] ~~Support loading dependencies~~ Non-trivial enhancement. Not
necessary for initial release.
---------
Co-authored-by: Matt Godbolt <matt@godbolt.org>
Add Claude Explain feature for AI-powered code explanations
This PR introduces Claude Explain, a new feature that provides AI-powered explanations of compiler output directly within Compiler Explorer.
Key features:
Claude Explain functionality:
- New explain view pane
- Explains compiler output with full context of source code and compilation output
- Configurable audience level and explanation type
- Response caching to improve performance and reduce API calls
- Usage statistics display showing requests used and token counts
User experience:
- Consent flow on first use explaining data handling and privacy
- AI disclaimer banner warning about potential LLM inaccuracies
- Respects "no-ai" directive in source code for users who don't want AI processing
Privacy and security:
- Data sent to Anthropic's Claude API as documented in privacy policy
- No data used for model training
- Clear consent required before first use
- Support for opting out via "no-ai" directive
The feature is marked as beta and can be enabled via configuration.
Co-authored-by: Claude <noreply@anthropic.com>
- latest biome, and fix its configuration
- fixes "static" content to be globally configured too (instead of
per-line)
- fixes issues:
- imports fixed up
- `Date.now()` vs `+new Date()`
- some unused things `_` prefixed
After discussion with the team, turned off the unused parameter warning.
## Summary
This PR significantly improves type safety for GoldenLayout
configurations, continuing work from issue #4490 "The War of The Types".
This is an **incremental improvement** that establishes a solid
foundation for future work.
## ✅ What We've Accomplished
### Core Type Infrastructure
- **Created comprehensive type system** in
`static/components.interfaces.ts`
- **Added `ComponentConfig<K>`** with proper generic constraints for
type-safe component configurations
- **Added `GoldenLayoutConfig`** to replace unsafe `any[]` content with
strongly-typed `ItemConfig[]`
- **Created `ComponentStateMap`** mapping component names to their
expected state types
- **Added proper TypeScript component name constants** with `as const`
for literal type inference
### Component Configuration Type Safety
- **All component factory functions** now return strongly-typed
configurations
- **Clean type syntax**: `ComponentConfig<'compiler'>` using the
exported constants
- **Eliminated unsafe casts** in component creation and drag source
setup
- **Fixed hub method signatures** that incorrectly expected
`ContentItem` instead of `ItemConfig`
### Bug Fixes and Code Quality
- **Fixed Jeremy's TODO**: Improved `fixBugsInConfig` function typing
- **Discovered and fixed hub type bug**:
`addAtRoot`/`addInEditorStackIfPossible` now accept correct types
- **Removed legacy conversion functions** that were no longer needed
- **Replaced verbose TODO comments** with GitHub issue references for
better organization
### Documentation and Planning
- **Created GitHub issues**
[#7807](https://github.com/compiler-explorer/compiler-explorer/issues/7807)
and
[#7808](https://github.com/compiler-explorer/compiler-explorer/issues/7808)
for remaining work
- **Documented type safety approach** with clear explanations of design
decisions
- **Added comprehensive implementation notes** for future contributors
## 🚧 What's Next (GitHub Issues)
- **Issue #7807**: [Type-safe
serialization/deserialization](https://github.com/compiler-explorer/compiler-explorer/issues/7807)
- localStorage persistence and URL sharing
- SerializedLayoutState implementation
- Version migration support
- **Issue #7808**: [Configuration validation and remaining type
gaps](https://github.com/compiler-explorer/compiler-explorer/issues/7808)
- Enable `fromGoldenLayoutConfig` validation
- Fix upstream GoldenLayout TypeScript definitions
- State type normalization (addresses #4490)
## 📊 Impact
### Type Safety Improvements
- **No more `any` casts** in component configuration creation
- **Compile-time validation** of component names and state types
- **Better IDE support** with autocomplete and type checking
- **Runtime safety** through proper TypeScript interfaces
### Code Quality
- **~100 lines of verbose TODO comments** replaced with concise GitHub
issue references
- **Technical debt reduction** through elimination of unsafe casting
patterns
- **Improved maintainability** with centralized type definitions
- **Better error messages** when component configurations are incorrect
### Files Modified
- `static/components.interfaces.ts` - Core type definitions
- `static/components.ts` - Component factory functions and utilities
- `static/main.ts` - Layout initialization and configuration handling
- `static/hub.ts` - Fixed method signatures
- `static/panes/*.ts` - Updated component creation patterns
## ✅ Testing & Validation
- **All existing tests pass** - no runtime regressions
- **TypeScript compilation succeeds** with strict type checking
- **Linting passes** with no new warnings
- **Pre-commit hooks validated** all changes
- **Manual testing confirmed** layout functionality works correctly
## 🎯 Ready to Merge
This PR represents a **significant incremental improvement** that:
- ✅ **Provides immediate value** through better type safety
- ✅ **Maintains full backward compatibility**
- ✅ **Establishes solid foundation** for future improvements
- ✅ **Centralizes remaining work** in well-documented GitHub issues
- ✅ **Ready for production use** with no runtime changes
The remaining work is clearly tracked in the linked GitHub issues and
can be tackled incrementally in future PRs.
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Removes `rootDirs` so all imports will be relative in the frontend
- Updates (and unifies) imports to be `../types/...` etc instead of
relying on "types" being in the rootDir for the frontend.
- Fixes one type that was being picked up from `lib` in the frontend.
- Adds a precommit hook to check in future
Paves the way to writing _unit_ tests for the frontend for the subset of
the frontend code we can import from `node` (which might be a lot of
it!)
Fixes#7792
Bootstrap styles `a:has([href])` as a link so the attribute had been
used in the past for things that aren't actually links, yet we want the
style for. It's better to just use `.link-primary` so it doesn't affect
the contents as discovered in #7792
This PR completes the migration from Bootstrap 4 to Bootstrap 5.3.5
following the plan outlined in
[docs/Bootstrap5Migration.md](https://github.com/compiler-explorer/compiler-explorer/blob/mg/bootstrap5/docs/Bootstrap5Migration.md).
## Migration Process
We followed a phased approach as documented in the migration plan:
1. **Phase 1: Dependency Updates and Basic Setup**
- Updated Bootstrap from 4.6.2 to 5.3.5
- Added @popperjs/core dependency (replacing Popper.js)
- Updated Tom Select theme from bootstrap4 to bootstrap5
2. **Phase 2: Global CSS Class Migration**
- Updated directional utility classes (ml/mr → ms/me)
- Updated floating utility classes (float-left/right → float-start/end)
- Updated text alignment classes (text-left/right → text-start/end)
3. **Phase 3: HTML Attribute Updates**
- Updated data attributes to use Bootstrap 5 prefixes (data-bs-toggle,
data-bs-target, etc.)
- Fixed tab navigation issues
4. **Phase 4: JavaScript API Compatibility Layer**
- Created bootstrap-utils.ts compatibility layer
- Updated component initialization for modals, dropdowns, popovers, etc.
5. **Phase 5: Component Migration**
- Updated and tested specific components (modals, dropdowns, toasts,
etc.)
- Fixed styling issues in cards and button groups
6. **Phase 6: Form System Updates**
- Updated form control classes to Bootstrap 5 standards
- Updated checkbox/radio markup patterns
- Simplified input groups
7. **Phase 7: Navbar Structure Updates**
- Updated navbar structure with container-fluid
- Fixed responsive behavior
8. **Phase 8: SCSS Variables and Theming**
- Added custom CSS fixes for navbar alignment
- Verified theme compatibility
9. **Phase 9: Accessibility Improvements**
- Updated sr-only to visually-hidden
- Added proper ARIA attributes
- Enhanced screen reader support
## Key Changes
- No more jQuery dependency in Bootstrap 5
- New prefix for data attributes (data-bs-*)
- Improved accessibility with ARIA attributes
- Updated positioning classes (start/end instead of left/right)
- Simplified input group structure
## Test Plan
1. **Navigation Testing**
- Verify all dropdown menus open and close properly
- Test mobile menu responsiveness
- Check tab navigation in settings dialog
2. **Component Testing**
- Verify all modals open and close correctly (settings, share,
load/save)
- Test tooltips and popovers
- Check form controls in different dialogs
3. **Layout Testing**
- Test responsiveness on different screen sizes
- Verify proper alignment of elements
- Check dark mode compatibility
4. **Specific Features to Test**
- Compiler selection and options
- Share dialog functionality
- Settings dialog
- Tree view (IDE mode)
- Font selection dropdown
5. **Browser Testing**
- Test in Chrome, Firefox, Safari
- Test in mobile browsers
## Note on Further Improvements
After this migration is stable, we could consider Phase 12: removing
jQuery dependency entirely, as Bootstrap 5 no longer requires it. This
would be a separate effort.
---------
Co-authored-by: Claude <noreply@anthropic.com>
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>
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
- Uses strings across the board in the UI part (no functional change
here from before; all state is the same as it was before).
- Sends _arrays_ in the POST, using the same `splitArguments` code as
the backend.
- Backend _still supports_ strings (though doesn't advertise), also
using same `splitArguments`.
- Moves `splitArguments` into common utils, and rephrases to avoid
unnecessary use of underscore and ES2021+ code.
Tested locally:
- with both old and new client code (ran new backend and old webcode to
show sending strings still works)
- with creating and removing tool windows (checked with `ldd` locally)
- with various strings on the client `moo foo "this is bad" #moo` and
even "error" things like `this is "badger` (with a missing close quote).
All works as you'd expect
Happy to break the "move the splitArguments" code into a separate PR if
that'd be easier to review separately.
Fixes#7195
This patch adds two options to the clangir pane that affects the clangir
compilation pipeline:
* Flat CIR enables the emission of flat clangir CFG;
* -fclangir-mem2reg enables the mem2reg pass on the flat clangir CFG.
This does fix#7019, but unfortunately in IR lines like -
```
%2 = mul nsw i32 %0, %0
```
Monaco assigns both the `mul` and `nsw` tokens with type
'operators.llvm-ir' (handled as asm keyword by this PR) and requests the
backend for their docs. Only `mul` is an actual documented keyword -
`nsw` is just a modifier and the request fails with errors like `GET
http://localhost:10240/api/asm/llvm/nsw 404 (Not Found)` thrown at
[getAssemblyDocumentation](63dd5e35a5/static/api/api.ts (L50-L51)).
This draft PR is meant for discussion. Would it be enough eg to wrap the
request in `getAssemblyDocumentation` in a try-catch? Maybe the right
thing to do would be to intervene in the monarch parsing for llvm-ir?
Other ideas that I'm missing?
---------
Co-authored-by: Mats Jun <mats@jun.codes>
This includes among others:
- Proper tsification of various tools code,
- Elimination of the `CompilationInfo2` type,
- Use of `CompilationInfo` instead of `Record<any, any>` in some places
- These lines in CompilationResult:
```
// Temp hack until we get all code to agree on type of asm
asm?: ResultLine[] | string;
```
The next task would be to get all code to agree on the type of
CompilationResult.asm, thereby enabling fixing of most the remaining
TSification.
When a new pane (such as the LLVM IR view) is opened using a button in
the “Add new...” or “Add tool...” menu, the button is disabled. This can
be confusing when the pane is not visible (e. g. when it is in a tab in
the background), because it can also be interpreted as “this is not
supported“.
This PR adds an `[already open]` to the button when it is disabled.
_No functional changes intended_
The existing type functions a little like this:
"Take the intersection of all common properties of all values in
HTMLElementTagNameMap"
This very much just happens to be the same as HTMLElement, since that's
the declared base for all of the types in HTMLElementTagNameMap. This
small patch simplifies this type (and makes it significantly easier to
read the code)
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
Currently the clangir compiler is implemented by a special clang variant
whose compilation options list gets appended with `-Xclang -fclangir
-Xclang -emit-cir`. This introduces a problem: we no longer gets access
to its LLVM IR output and assembly output because `-emit-cir` is an
exclusive option.
This patch resolves this problem by introducing a new ClangIR pane,
similar to the LLVM IR pane or Rust MIR pane. A new output kind named
`ClangIR` is added to the "Add new..." drop down menu and it toggles the
ClangIR pane. This patch then removes `-Xclang -emit-cir` from the
options list of the clangir compiler. The clangir compiler will then
output assembly code just like other clang compilers. The removed
options will be added back when compiled from the ClangIR pane.
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
Make MonacoPane calls `createDecorationsCollection` in a single place
instead of forcing many subclasses to remember to call
`initDecorations`. Some subclasses never use DecorationsCollection and
call init for no reason now, but it still seems healthier - this avoids
the possibility of a MonacoPane subclass trying to use an uninitialized
decoration collection.
Also remove the depracated `deltaDecorations` from stack-usage-view.
Demangled Rust identifiers under the `legacy` name mangling scheme rely
on a hash to disambiguate items with the same name, such as different
monomorphisations of the same function or different closures’
`call_once` methods.
In the `v0` mangling scheme, this is no longer a problem. However,
configuring the demangler to show hashes in `legacy` names will include
crate-id hashes in `v0` names, which are [mostly
unneeded](https://rust-lang.github.io/rfcs/2603-rust-symbol-name-mangling-v0.html#appendix-a---suggested-demangling).
This PR introduces a new checkbox *Options...* → *Verbose demangling*
that lets the user select if they want to include disambiguating hashes
in demangled identifiers.
This checkbox is only shown for compilers that support verbose
demangling, and deactivated when the *Demangle identifiers* checkbox is
unchecked.
Resolves#1754.
Resolves#6255.
Compilers like to encode short-ish strings into immediate arguments to
various assembly instructions. This makes it hard to read the assembly.
To improve readability, show a string representation of a number’s bytes
when they’re valid UTF-8.
This now also shows a string representation for *unprintable* ASCII
characters, such as `10` being shown as `"\n"` or `1` as `"\u0001"`.
Resolves#6220.
## Examples
([link](https://godbolt.org/z/7hzn6b8YG))
* 8583909746840200552: `8'583'909'746'840'200'552 =
0x7720'2C6F'6C6C'6568 = 6.5188685003648344e+265 = "hello, w"`
* 1684828783: `1'684'828'783 = 0x646C'726F = 1.74467096e+22f = "orld"`
* -6934491452449512253: `-6'934'491'452'449'512'253 =
0x9FC3'BCC3'B6C3'A4C3 = -1.1500622354593239e-155 = "äöüß"`
* 1633837924: `1'633'837'924 = 0x6162'6364 = 2.61007876e+20f = "dcba"`
* 97: `97 = 0x61 = 1.35925951e-43f = "a"`
* 10: `10 = 0xA = 1.40129846e-44f = "\n"`
* 92: `92 = 0x5C = 1.28919459e-43f = "\\"`
## Open questions
* The code assumes little-endian encoding, so the string representation
is reversed compared to the numeric representation (see `integer`
example). Should this be configurable or should the bytes not be
reversed?
* Negative numbers are masked to 64-bit unsigned ints (same as in the
hex representation), so if the number is shorter than 8 bytes, it has
some leading `ff` bytes and is not valid UTF-8 (see
`small_negative_number` in the example link). Is this an acceptable
limitation?
* I'd like to add some tests for `getNumericToolTip`, but I’m not really
familiar with TypeScript. I tried to importing
`static/panes/compiler.ts` in a test file, but
([after](https://github.com/vitest-dev/vitest/discussions/1806#discussioncomment-3570047)
some [struggling](https://vitest.dev/config/#environment)) it seems that
that file needs a [specific DOM
element](3c26c64ca3/static/options.ts (L27))
that is not present during testing. The simplest solution I could come
up with is moving `getNumericToolTip` into another file (such as
`static/utils.ts`). Is that okay or is is it possible test
`static/panes/compiler.ts` some other way?
---------
Co-authored-by: Patrick Quist <partouf@gmail.com>
And change 'toggle' to 'hide' to better express the intention.
Fixes#6225.
<!-- THIS COMMENT IS INVISIBLE IN THE FINAL PR, BUT FEEL FREE TO REMOVE
IT
Thanks for taking the time to improve CE. We really appreciate it.
Before opening the PR, please make sure that the tests & linter pass
their checks,
by running `make check`.
In the best case scenario, you are also adding tests to back up your
changes,
but don't sweat it if you don't. We can discuss them at a later date.
Feel free to append your name to the CONTRIBUTORS.md file
Thanks again, we really appreciate this!
-->
Long numbers are sometimes hard to read in the numeric tooltip. To
improve readability, this PR adds language-specific digit separators to
the numeric tooltip.
Decimal numbers are grouped into chunks of three digits while
hexadecimal numbers are grouped into chunks of length four.
The digit separator is language-specific and chosen so that the number
is a valid token in the source language.
[Examples](https://godbolt.org/z/s86cMbjeK):
* for C++, hovering the number `8583909746840200552` shows this tooltip:
`8'583'909'746'840'200'552 = 0x7720'2C6F'6C6C'6568 =
6.5188685003648344e+265`
* for Python, hovering the number `-12345678` shows this tooltip:
`-123_456_789 = 0xFFFF_FFFF_F8A4_32EB = -2.66427945e+34f`
For languages that don’t have a `digitSeparator` set, the tooltip is not
changed.
Replace the deprecated `monaco.editor.ICodeEditor.deltaDecorations` with `monaco.editor.IEditorDecorationsCollection`
Seems that today the official way of colouring monaco editors is having
them `createDecorationsCollection`, keep the resulting
decorations-collection and call `set` on it with new decorations
whenever needed.
There are many possible design choices on where to put it, I opted to
put `editorDecorations` in `MonacoPane`, and have
`MonacoPane.createEditor` initialize it only in panes where decorations
are actually used.
Also some signatures changed which had a broad (but non-interesting)
impact.