| 
 | 1 | +# CLAUDE.md  | 
 | 2 | + | 
 | 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.  | 
 | 4 | + | 
 | 5 | +## Repository Overview  | 
 | 6 | + | 
 | 7 | +Eclipse Platform UI provides the UI building blocks for Eclipse IDE and Eclipse Rich Client Platform (RCP). This includes JFace, workbench, commands framework, data binding, dialogs, editors, views, perspectives, and more. Built on top of SWT (Eclipse Standard Widget Toolkit).  | 
 | 8 | + | 
 | 9 | +**Key Facts:**  | 
 | 10 | +- **Language:** Java 17  | 
 | 11 | +- **Build System:** Maven 3.9.x with Tycho (OSGi/Eclipse plugin build)  | 
 | 12 | +- **Architecture:** OSGi bundles, E4 application model  | 
 | 13 | +- **Size:** 127 MB, 7,675+ Java files  | 
 | 14 | +- **Structure:** 57 production bundles + 34 test bundles + 25 examples  | 
 | 15 | + | 
 | 16 | +## Project Structure  | 
 | 17 | + | 
 | 18 | +```  | 
 | 19 | +eclipse.platform.ui/  | 
 | 20 | +├── bundles/          # 57 OSGi bundles (production code)  | 
 | 21 | +│   ├── org.eclipse.ui.workbench          # Main workbench implementation  | 
 | 22 | +│   ├── org.eclipse.jface                 # JFace toolkit (viewers, dialogs, etc.)  | 
 | 23 | +│   ├── org.eclipse.jface.databinding     # Data binding framework  | 
 | 24 | +│   ├── org.eclipse.jface.text            # Text editing framework  | 
 | 25 | +│   ├── org.eclipse.core.commands         # Commands framework  | 
 | 26 | +│   ├── org.eclipse.core.databinding*     # Core data binding  | 
 | 27 | +│   ├── org.eclipse.e4.ui.*               # E4 workbench, CSS, DI, model  | 
 | 28 | +│   └── org.eclipse.ui.*                  # UI components (IDE, editors, views, etc.)  | 
 | 29 | +├── tests/            # 34 test bundles (mirror structure of bundles/)  | 
 | 30 | +├── examples/         # 25 example bundles  | 
 | 31 | +├── features/         # Eclipse feature definitions  | 
 | 32 | +├── releng/           # Release engineering artifacts  | 
 | 33 | +├── docs/             # Documentation (JFace, RCP, Commands, etc.)  | 
 | 34 | +└── .github/          # GitHub workflows and CI configuration  | 
 | 35 | +```  | 
 | 36 | + | 
 | 37 | +### Key Architectural Components  | 
 | 38 | + | 
 | 39 | +**E4 Platform (Modern):**  | 
 | 40 | +- `org.eclipse.e4.ui.model.workbench` - E4 application model  | 
 | 41 | +- `org.eclipse.e4.ui.workbench*` - E4 workbench implementation  | 
 | 42 | +- `org.eclipse.e4.ui.di` - Dependency injection  | 
 | 43 | +- `org.eclipse.e4.ui.css.*` - CSS styling engine  | 
 | 44 | +- `org.eclipse.e4.core.commands` - Command framework  | 
 | 45 | + | 
 | 46 | +**JFace Toolkit:**  | 
 | 47 | +- `org.eclipse.jface` - Viewers, dialogs, resources, actions  | 
 | 48 | +- `org.eclipse.jface.databinding` - Data binding for UI  | 
 | 49 | +- `org.eclipse.jface.text` - Text editing infrastructure  | 
 | 50 | + | 
 | 51 | +**Legacy Workbench (3.x compatibility):**  | 
 | 52 | +- `org.eclipse.ui.workbench` - Workbench implementation  | 
 | 53 | +- `org.eclipse.ui.ide` - IDE-specific components  | 
 | 54 | +- `org.eclipse.ui.editors` - Editor framework  | 
 | 55 | + | 
 | 56 | +### OSGi Bundle Structure  | 
 | 57 | + | 
 | 58 | +Each bundle contains:  | 
 | 59 | +- `META-INF/MANIFEST.MF` - Bundle metadata and dependencies  | 
 | 60 | +- `build.properties` - Build configuration (what to include in binary)  | 
 | 61 | +- `plugin.xml` - Extension point declarations and contributions (optional)  | 
 | 62 | +- `src/` or `eclipseui/` - Java source code  | 
 | 63 | +- `.settings/` - Eclipse compiler settings  | 
 | 64 | + | 
 | 65 | +## Build System  | 
 | 66 | + | 
 | 67 | +### Critical Limitation  | 
 | 68 | + | 
 | 69 | +**⚠️ IMPORTANT:** Standalone `mvn clean verify` at repository root **WILL FAIL** with "Non-resolvable parent POM" error. This repository requires a parent POM from `eclipse.platform.releng.aggregator`.  | 
 | 70 | + | 
 | 71 | +### Building Individual Bundles  | 
 | 72 | + | 
 | 73 | +Use the `-Pbuild-individual-bundles` profile:  | 
 | 74 | + | 
 | 75 | +```bash  | 
 | 76 | +# Compile a single bundle  | 
 | 77 | +cd bundles/org.eclipse.jface  | 
 | 78 | +mvn clean compile -Pbuild-individual-bundles  | 
 | 79 | + | 
 | 80 | +# Run tests for a single bundle  | 
 | 81 | +cd tests/org.eclipse.jface.tests  | 
 | 82 | +mvn clean verify -Pbuild-individual-bundles  | 
 | 83 | + | 
 | 84 | +# Run specific test class  | 
 | 85 | +mvn test -Pbuild-individual-bundles -Dtest=ViewerTestClass  | 
 | 86 | +```  | 
 | 87 | + | 
 | 88 | +### Maven Configuration  | 
 | 89 | + | 
 | 90 | +Default config in `.mvn/maven.config`:  | 
 | 91 | +- `-Pbuild-individual-bundles` - Enable individual bundle builds  | 
 | 92 | +- `-Dtycho.target.eager=true` - Eager target resolution  | 
 | 93 | +- `-Dtycho.localArtifacts=ignore` - Ignore local artifacts  | 
 | 94 | + | 
 | 95 | +### Test Properties  | 
 | 96 | + | 
 | 97 | +From `pom.xml`:  | 
 | 98 | +- `tycho.surefire.useUIHarness=true` - Use Eclipse UI test harness  | 
 | 99 | +- `tycho.surefire.useUIThread=true` - Run tests on UI thread  | 
 | 100 | +- `failOnJavadocErrors=true` - Fail build on Javadoc errors  | 
 | 101 | + | 
 | 102 | +## Testing  | 
 | 103 | + | 
 | 104 | +### Running Tests  | 
 | 105 | + | 
 | 106 | +**⚠️ IMPORTANT:** Use `mvn verify` (NOT `mvn test`) for Tycho projects. Due to Maven Tycho lifecycle binding, tests run in the `integration-test` phase, not the `test` phase. Running `mvn test` will NOT execute tests.  | 
 | 107 | + | 
 | 108 | +```bash  | 
 | 109 | +# Run all tests in a specific test bundle  | 
 | 110 | +cd tests/org.eclipse.jface.tests  | 
 | 111 | +mvn clean verify -Pbuild-individual-bundles  | 
 | 112 | + | 
 | 113 | +# Run without clean (faster if no changes to dependencies)  | 
 | 114 | +mvn verify -Pbuild-individual-bundles  | 
 | 115 | + | 
 | 116 | +# Run tests for a specific test bundle from repository root  | 
 | 117 | +mvn clean verify -pl :org.eclipse.jface.tests -Pbuild-individual-bundles  | 
 | 118 | + | 
 | 119 | +# Run specific test class within a bundle  | 
 | 120 | +cd tests/org.eclipse.jface.tests  | 
 | 121 | +mvn clean verify -Pbuild-individual-bundles -Dtest=StructuredViewerTest  | 
 | 122 | + | 
 | 123 | +# Skip tests during compilation  | 
 | 124 | +mvn clean compile -Pbuild-individual-bundles -DskipTests  | 
 | 125 | +```  | 
 | 126 | + | 
 | 127 | +**Finding test bundles:** Test bundles mirror production bundles:  | 
 | 128 | +- Production: `bundles/org.eclipse.jface`  | 
 | 129 | +- Tests: `tests/org.eclipse.jface.tests`  | 
 | 130 | + | 
 | 131 | +### JUnit Version Status (October 2025)  | 
 | 132 | + | 
 | 133 | +**Current Migration State:**  | 
 | 134 | +- **JUnit 5 (Modern):** 7 bundles fully migrated, 5 partially migrated  | 
 | 135 | +- **JUnit 4 (Current):** 11 bundles ready for migration, majority of tests  | 
 | 136 | +- **JUnit 3 (Legacy):** Only in `org.eclipse.ui.tests.harness` as compatibility bridge  | 
 | 137 | + | 
 | 138 | +**When writing new tests:**  | 
 | 139 | +- Prefer JUnit 5 (`org.junit.jupiter.api.*`) for new tests  | 
 | 140 | +- Use `@BeforeEach`/`@AfterEach` instead of `@Before`/`@After`  | 
 | 141 | +- Use `@Disabled` instead of `@Ignore`  | 
 | 142 | +- Use `Assertions.*` instead of `Assert.*`  | 
 | 143 | + | 
 | 144 | +**Common test pattern:**  | 
 | 145 | +```java  | 
 | 146 | +@BeforeEach  | 
 | 147 | +public void setUp() {  | 
 | 148 | +    fDisplay = Display.getDefault();  | 
 | 149 | +    fShell = new Shell(fDisplay);  | 
 | 150 | +}  | 
 | 151 | + | 
 | 152 | +@AfterEach  | 
 | 153 | +public void tearDown() {  | 
 | 154 | +    if (fShell != null) {  | 
 | 155 | +        fShell.dispose();  | 
 | 156 | +    }  | 
 | 157 | +}  | 
 | 158 | + | 
 | 159 | +@Test  | 
 | 160 | +public void testSomething() {  | 
 | 161 | +    // Test implementation  | 
 | 162 | +    Assertions.assertEquals(expected, actual);  | 
 | 163 | +}  | 
 | 164 | +```  | 
 | 165 | + | 
 | 166 | +## Common Development Commands  | 
 | 167 | + | 
 | 168 | +### Compilation  | 
 | 169 | + | 
 | 170 | +```bash  | 
 | 171 | +# Compile single bundle  | 
 | 172 | +mvn clean compile -pl :bundle-artifact-id -Pbuild-individual-bundles -q  | 
 | 173 | + | 
 | 174 | +# Compile and run tests  | 
 | 175 | +mvn clean test -pl :bundle-artifact-id -Pbuild-individual-bundles  | 
 | 176 | +```  | 
 | 177 | + | 
 | 178 | +### Finding Code  | 
 | 179 | + | 
 | 180 | +```bash  | 
 | 181 | +# Find test files for a bundle  | 
 | 182 | +ls tests/org.eclipse.jface.tests/src  | 
 | 183 | + | 
 | 184 | +# Find bundle MANIFEST  | 
 | 185 | +cat bundles/org.eclipse.jface/META-INF/MANIFEST.MF  | 
 | 186 | + | 
 | 187 | +# Search for specific code pattern  | 
 | 188 | +grep -r "pattern" bundles/org.eclipse.jface/src  | 
 | 189 | +```  | 
 | 190 | + | 
 | 191 | +## Critical Development Rules  | 
 | 192 | + | 
 | 193 | +### 1. OSGi Dependencies  | 
 | 194 | + | 
 | 195 | +**Always check `META-INF/MANIFEST.MF` before adding imports.** If a package is not in `Import-Package` or `Require-Bundle`, the import will fail at runtime.  | 
 | 196 | + | 
 | 197 | +```  | 
 | 198 | +Require-Bundle: org.eclipse.core.runtime,  | 
 | 199 | + org.eclipse.swt,  | 
 | 200 | + org.eclipse.jface  | 
 | 201 | +Import-Package: org.osgi.service.event  | 
 | 202 | +```  | 
 | 203 | + | 
 | 204 | +### 2. SWT Resource Disposal  | 
 | 205 | + | 
 | 206 | +**Must dispose SWT resources** (except system colors/fonts):  | 
 | 207 | + | 
 | 208 | +```java  | 
 | 209 | +// CORRECT - dispose in finally  | 
 | 210 | +Shell shell = new Shell();  | 
 | 211 | +try {  | 
 | 212 | +    // use shell  | 
 | 213 | +} finally {  | 
 | 214 | +    shell.dispose();  | 
 | 215 | +}  | 
 | 216 | + | 
 | 217 | +// CORRECT - dispose custom colors/fonts/images  | 
 | 218 | +Color color = new Color(display, 255, 0, 0);  | 
 | 219 | +try {  | 
 | 220 | +    // use color  | 
 | 221 | +} finally {  | 
 | 222 | +    color.dispose();  | 
 | 223 | +}  | 
 | 224 | + | 
 | 225 | +// INCORRECT - system resources don't need disposal  | 
 | 226 | +Color systemColor = display.getSystemColor(SWT.COLOR_RED);  | 
 | 227 | +// No dispose needed  | 
 | 228 | +```  | 
 | 229 | + | 
 | 230 | +### 3. UI Thread Requirements  | 
 | 231 | + | 
 | 232 | +**All SWT/JFace UI code must run on the Display thread:**  | 
 | 233 | + | 
 | 234 | +```java  | 
 | 235 | +// Run asynchronously on UI thread  | 
 | 236 | +Display.getDefault().asyncExec(() -> {  | 
 | 237 | +    label.setText("Updated");  | 
 | 238 | +});  | 
 | 239 | + | 
 | 240 | +// Run synchronously (blocks until complete)  | 
 | 241 | +Display.getDefault().syncExec(() -> {  | 
 | 242 | +    button.setEnabled(false);  | 
 | 243 | +});  | 
 | 244 | + | 
 | 245 | +// Check if on UI thread  | 
 | 246 | +if (Display.getCurrent() != null) {  | 
 | 247 | +    // Already on UI thread  | 
 | 248 | +} else {  | 
 | 249 | +    // Need to use asyncExec/syncExec  | 
 | 250 | +}  | 
 | 251 | +```  | 
 | 252 | + | 
 | 253 | +### 4. API Compatibility  | 
 | 254 | + | 
 | 255 | +**Do not break API compatibility.** The build includes API tools that verify:  | 
 | 256 | +- No removal of public API  | 
 | 257 | +- No changes to method signatures  | 
 | 258 | +- No changes to class hierarchies  | 
 | 259 | + | 
 | 260 | +Breaking changes will fail CI with errors in `**/target/apianalysis/*.xml`.  | 
 | 261 | + | 
 | 262 | +### 5. Update build.properties  | 
 | 263 | + | 
 | 264 | +When adding new files or packages, update `build.properties`:  | 
 | 265 | + | 
 | 266 | +```properties  | 
 | 267 | +# Include in binary build  | 
 | 268 | +bin.includes = plugin.xml,\  | 
 | 269 | +               META-INF/,\  | 
 | 270 | +               .,\  | 
 | 271 | +               icons/  | 
 | 272 | + | 
 | 273 | +# Source folders  | 
 | 274 | +source.. = src/  | 
 | 275 | + | 
 | 276 | +# Output folder  | 
 | 277 | +output.. = bin/  | 
 | 278 | +```  | 
 | 279 | + | 
 | 280 | +## Common Patterns  | 
 | 281 | + | 
 | 282 | +### Data Binding  | 
 | 283 | + | 
 | 284 | +```java  | 
 | 285 | +DataBindingContext ctx = new DataBindingContext();  | 
 | 286 | + | 
 | 287 | +// Bind widget to model  | 
 | 288 | +ctx.bindValue(  | 
 | 289 | +    WidgetProperties.text(SWT.Modify).observe(textWidget),  | 
 | 290 | +    BeanProperties.value("propertyName").observe(model)  | 
 | 291 | +);  | 
 | 292 | + | 
 | 293 | +// Dispose when done  | 
 | 294 | +ctx.dispose();  | 
 | 295 | +```  | 
 | 296 | + | 
 | 297 | +### JFace Viewers  | 
 | 298 | + | 
 | 299 | +```java  | 
 | 300 | +TableViewer viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);  | 
 | 301 | +viewer.setContentProvider(ArrayContentProvider.getInstance());  | 
 | 302 | +viewer.setLabelProvider(new LabelProvider() {  | 
 | 303 | +    @Override  | 
 | 304 | +    public String getText(Object element) {  | 
 | 305 | +        return element.toString();  | 
 | 306 | +    }  | 
 | 307 | +});  | 
 | 308 | +viewer.setInput(myList);  | 
 | 309 | +```  | 
 | 310 | + | 
 | 311 | +### Eclipse Commands  | 
 | 312 | + | 
 | 313 | +Commands are defined in `plugin.xml` and handled via handlers:  | 
 | 314 | + | 
 | 315 | +```java  | 
 | 316 | +@Execute  | 
 | 317 | +public void execute(IEclipseContext context) {  | 
 | 318 | +    // Command implementation  | 
 | 319 | +}  | 
 | 320 | +```  | 
 | 321 | + | 
 | 322 | +## CI/GitHub Workflows  | 
 | 323 | + | 
 | 324 | +**Primary workflow:** `.github/workflows/ci.yml`  | 
 | 325 | +- Triggers on push/PR to master (ignores `docs/` and `*.md`)  | 
 | 326 | +- Uses `eclipse.platform.releng.aggregator` for full build  | 
 | 327 | +- Runs on Java 21 with xvnc for headless UI tests  | 
 | 328 | + | 
 | 329 | +**Validation steps:**  | 
 | 330 | +1. Compiler checks (Eclipse compiler)  | 
 | 331 | +2. API compatibility (API tools)  | 
 | 332 | +3. Javadoc generation  | 
 | 333 | +4. Unit tests (JUnit with UI harness)  | 
 | 334 | +5. Test reports published  | 
 | 335 | + | 
 | 336 | +## Troubleshooting  | 
 | 337 | + | 
 | 338 | +### "Non-resolvable parent POM"  | 
 | 339 | +Expected when running `mvn verify` at root. Use `-Pbuild-individual-bundles` for individual bundles.  | 
 | 340 | + | 
 | 341 | +### "Package does not exist"  | 
 | 342 | +Check `META-INF/MANIFEST.MF` - add missing package to `Import-Package` or bundle to `Require-Bundle`.  | 
 | 343 | + | 
 | 344 | +### "API baseline errors"  | 
 | 345 | +You've broken API compatibility. Revert the breaking change or mark it appropriately.  | 
 | 346 | + | 
 | 347 | +### Test hangs  | 
 | 348 | +UI tests must run on Display thread. Use `Display.asyncExec()` or ensure `useUIHarness=true`.  | 
 | 349 | + | 
 | 350 | +### "Widget is disposed"  | 
 | 351 | +Attempting to access disposed SWT widget. Check disposal order and lifecycle.  | 
 | 352 | + | 
 | 353 | +## Documentation  | 
 | 354 | + | 
 | 355 | +Key docs in `docs/` directory:  | 
 | 356 | +- `JFace.md` - JFace framework overview  | 
 | 357 | +- `JFaceDataBinding.md` - Data binding guide  | 
 | 358 | +- `Eclipse4_RCP_FAQ.md` - E4 RCP frequently asked questions  | 
 | 359 | +- `PlatformCommandFramework.md` - Command framework  | 
 | 360 | +- `CSS.md` - CSS styling for E4  | 
 | 361 | + | 
 | 362 | +External links:  | 
 | 363 | +- [Platform UI Wiki](https://wiki.eclipse.org/Platform_UI)  | 
 | 364 | +- [Contributing Guide](https://github.com/eclipse-platform/.github/blob/main/CONTRIBUTING.md)  | 
 | 365 | +- [Eclipse Platform Project](https://projects.eclipse.org/projects/eclipse.platform)  | 
0 commit comments