Skip to content

Replace the GUI Builder with a Maven-first Codename One app - #5523

Open
shai-almog wants to merge 91 commits into
masterfrom
feat-guibuilder-rewrite
Open

Replace the GUI Builder with a Maven-first Codename One app#5523
shai-almog wants to merge 91 commits into
masterfrom
feat-guibuilder-rewrite

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

The Settings-era GUI Builder is a Swing tool tied to the pre-Maven project
layout. This replaces it with a standalone Codename One desktop app under
scripts/guibuilder, launched by mvn cn1:guibuilder — the same shape as
cn1:settings and the Game Builder: its own Maven build, its own executable
JAR, and its own Maven Central coordinates
(com.codenameone:codenameone-guibuilder).

What it does

The editor edits .gui XML under src/main/guibuilder and round-trips the
generated Java next to it, so the design surface and the source stay in step.
Generated regions of that Java are protected in the embedded code editor rather
than merely regenerated over.

Guided Layout builds on LayeredLayout with builder-owned relationships —
match width/height, reference targets, anchors — stored by component name.
That is why the model enforces unique names and cascades renames, deletes, and
pastes across every relationship pointing at them; a stale name is a broken
layout and a duplicate name is a duplicate Java field.

Placement adapters cover Border, Layered, Box, Flow, Grid, and Table layouts.
The whole surface is also drivable over MCP (-Dguibuilder.mcp.port=…), which
is how the interaction tests replay complete gestures.

Core changes

Kept to the minimum the editor needs:

  • CodeEditor gains protected-region markers and caret positioning.
  • LayeredLayout UNIT_BASELINE now uses a component's reported baseline
    only when the component also describes its baseline resize behavior. The
    default Component#getBaseline returns the bottom content edge rather than a
    text baseline, so without this the documented font-ascent fallback was
    unreachable and containers and text areas aligned on the wrong line.
  • SplitPane and Tabs no longer assume getComponentForm() is
    non-null. Both can be deinitialized by the same gesture that triggers the
    callback, which the builder hits routinely when it rebuilds the inspector.

Tooling

cn1:guibuilder now forwards every guibuilder.* property, passes the desktop
identity and --add-exports arguments the JavaSE runtime needs, and fails with
a clear message when Maven runs on a JDK older than 17 (previously an
UnsupportedClassVersionError buried in guibuilder.log).

scripts/** is excluded from PR CI, so .github/workflows/guibuilder.yml is
added as the only job that compiles the editor against a freshly built core —
the exact way it can otherwise rot silently. The release workflow gains the
matching Central + R2 publish/confirm steps, wired into the completion gate.

Tests

Suite Result
scripts/guibuilder (JDK 21) 66 pass — DesignerInteraction 41, GuiDocument 18, GeneratedSource 4, CodeEditorInteraction 2, ProjectBinding 1
core-unittests CodeEditorTest, LayeredLayoutTest (JDK 8) 41 pass
OpenGuiBuilderMojoTest 5 pass

scripts/guibuilder/STATUS.md carries the full design notes, the known
limitations, and the phased road map.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings August 5, 2026 07:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR replaces the legacy Swing “Settings-era” GUI Builder with a Maven-first, standalone Codename One desktop app under scripts/guibuilder, integrated with the Maven plugin via mvn cn1:guibuilder. It also adds the minimal core framework changes required to support the new editor (protected regions in the code editor, corrected baseline alignment in LayeredLayout, and null-safety fixes).

Changes:

  • Introduces the new standalone GUI Builder app (common + JavaSE modules), demo project assets, and interaction/unit tests.
  • Extends core editor/layout APIs to support protected generated regions and correct baseline alignment behavior.
  • Updates Maven plugin + release/CI workflows to build, test, and publish the new GUI Builder artifact (com.codenameone:codenameone-guibuilder).

Reviewed changes

Copilot reviewed 44 out of 45 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
scripts/guibuilder/tools/guibuilder-mcp-client.mjs Adds a local Node MCP client for driving/inspecting the GUI Builder over MCP.
scripts/guibuilder/pom.xml Adds standalone GUI Builder Maven reactor parent (Java 17) with publishing profile.
scripts/guibuilder/javase/src/test/java/com/codename1/guibuilder/GeneratedSourceTest.java Verifies generated sources compile together (form + model strategies + guided constraints).
scripts/guibuilder/javase/src/test/java/com/codename1/guibuilder/CodeEditorInteractionTest.java Tests protected region behavior and caret positioning in the pure editor.
scripts/guibuilder/javase/src/desktop/java/com/codename1/guibuilder/CodenameOneGUIBuilderStub.java Desktop stub/launcher wiring + self-tests for editor/guided layout/interaction.
scripts/guibuilder/javase/src/desktop/java/com/codename1/guibuilder/CodenameOneGUIBuilderLauncher.java Small main-class wrapper for the executable jar.
scripts/guibuilder/javase/pom.xml Defines the published com.codenameone:codenameone-guibuilder JavaSE module and executable-jar profile.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/TableLayoutForm.gui Demo GUI fixture for TableLayout behaviors.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/NestedLayoutsForm.gui Demo GUI fixture for nested layout hierarchy behaviors.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/LoginForm.gui Demo GUI fixture for a basic form.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/GuidedLayoutForm.gui Demo GUI fixture for Guided Layout constraints and baseline snapping.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/GridLayoutForm.gui Demo GUI fixture for GridLayout reorder/cell behaviors.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/BoxXLayoutForm.gui Demo GUI fixture for horizontal BoxLayout scrolling/reorder.
scripts/guibuilder/demo-project/src/main/guibuilder/com/example/BorderDropForm.gui Demo GUI fixture for BorderLayout drop/constraint behaviors.
scripts/guibuilder/demo-project/src/main/css/theme.css Demo project theme for previewing styling + dark mode.
scripts/guibuilder/common/src/test/java/com/codename1/guibuilder/project/ProjectBindingTest.java Unit test for parsing the modern binding format.
scripts/guibuilder/common/src/test/java/com/codename1/guibuilder/model/GuiDocumentTest.java Unit tests for document editing, undo/redo, naming, relationships, drag/drop logic.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/ui/GuidedLayoutSupport.java Applies name-based Guided Layout constraints into LayeredLayout at preview/runtime.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/ui/DragGuideOverlay.java Overlay painting for drag/drop guides, selection, and simulated layout previews.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/ui/ComponentPreviewFactory.java Renders live preview components from .gui XML with designer interaction hooks.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/project/ProjectIO.java Loads binding + reads/writes GUI/CSS/source content via FileSystemStorage.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/project/ProjectBinding.java Binding model for guibuilder.input key/value format.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/model/GuiDocument.java Core .gui XML document model with transactions, undo/redo, and relationship management.
scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/GuiBuilderMcpController.java MCP tool registration and event/state streaming for automation/interaction tests.
scripts/guibuilder/common/src/main/css/theme.css Editor UI theme (builder chrome styling + dark mode).
scripts/guibuilder/common/pom.xml Common module config incl. cn1 plugin integration and test artifact attachment.
scripts/guibuilder/common/codenameone_settings.properties GUI Builder CN1 settings (Java 17, desktop defaults, theme flags).
scripts/guibuilder/.gitignore Ignores build output + generated binding input file for demo project.
maven/update-version.sh Extends version bump script to include the new GUI Builder reactor.
maven/core-unittests/src/test/java/com/codename1/ui/layouts/LayeredLayoutTest.java Adds regression test for true-baseline alignment with padding/margins.
maven/core-unittests/src/test/java/com/codename1/ui/CodeEditorTest.java Adds regression tests for protected markers and caret movement.
maven/codenameone-maven-plugin/src/test/java/com/codename1/maven/OpenGuiBuilderMojoTest.java Tests binding output, property forwarding, desktop identity args, and project dir detection.
maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenGuiBuilderMojo.java Replaces legacy jar-based GUI Builder launch with Maven-resolved Java 17 editor launch.
CodenameOne/src/com/codename1/ui/Tabs.java Adds null-safety around getComponentForm() during gesture handling.
CodenameOne/src/com/codename1/ui/layouts/LayeredLayout.java Updates baseline unit behavior to use declared baselines only when resize behavior is declared.
CodenameOne/src/com/codename1/ui/editor/PureEditor.java Adds a setCursor command for pure editor caret positioning.
CodenameOne/src/com/codename1/ui/editor/CodeView.java Adds protected region markers that block edits to generated ranges.
CodenameOne/src/com/codename1/ui/editor/CodePureEditor.java Wires setProtectedMarkers command into CodeView protected-region support.
CodenameOne/src/com/codename1/ui/CodeEditor.java Public API for protected region markers and caret positioning.
CodenameOne/src/com/codename1/components/SplitPane.java Adds null-safety around getComponentForm() during init.
.github/workflows/release-on-maven-central.yml Extends release workflow to deploy/confirm/publish GUI Builder alongside other editors.
.github/workflows/guibuilder.yml Adds dedicated CI workflow to build core + compile/test/package the standalone GUI Builder.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CodenameOne/src/com/codename1/ui/editor/CodeView.java
Comment thread scripts/guibuilder/tools/guibuilder-mcp-client.mjs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b3fb02eb7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@shai-almog

shai-almog commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 151 screenshots: 151 matched.

Native Android coverage

  • 📊 Line coverage: 8.10% (7872/97198 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.08% (41673/515700), branch 2.89% (1407/48723), complexity 3.19% (1668/52272), method 4.91% (1357/27642), class 10.00% (368/3680)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 8.10% (7872/97198 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 8.08% (41673/515700), branch 2.89% (1407/48723), complexity 3.19% (1668/52272), method 4.91% (1357/27642), class 10.00% (368/3680)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6367 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.ClassReader – 0.00% (0/1524 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1187 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.MethodWriter – 0.00% (0/922 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/736 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • okio.okio.Buffer – 0.00% (0/687 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/625 lines covered)
      • org.jacoco.agent.rt.internal_0e20598.asm.org.jacoco.agent.rt.internal_0e20598.asm.Frame – 0.00% (0/570 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 161ms / native 245ms = 0.6x speedup
SIMD float-mul (64K x300) java 150ms / native 95ms = 1.5x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 77.000 ms
Base64 CN1 decode 78.000 ms
Base64 native encode 421.000 ms
Base64 encode ratio (CN1/native) 0.183x (81.7% faster)
Base64 native decode 332.000 ms
Base64 decode ratio (CN1/native) 0.235x (76.5% faster)
Image encode benchmark status skipped (SIMD unsupported)

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

@github-actions

github-actions Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 181 screenshots: 181 matched.
✅ JavaScript-port screenshot tests passed.

Copilot AI review requested due to automatic review settings August 5, 2026 08:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 45 out of 46 changed files in this pull request and generated no new comments.

Suppressed comments (4)

CodenameOne/src/com/codename1/ui/editor/CodeView.java:163

  • Edits at the exact end of a protected block (i.e., immediately after the end marker) are currently treated as "inside" the protected region because the caret check uses <= protectedEnd. This prevents inserting text right after the generated block, which should be allowed.
            if ((start == end && start >= protectedStart && start <= protectedEnd)
                    || (start < protectedEnd && end > protectedStart)) {
                return true;

scripts/guibuilder/tools/guibuilder-mcp-client.mjs:23

  • Incoming messages are parsed with JSON.parse(line) without error handling. If the server emits a malformed line (or the stream is corrupted), the client will crash rather than reporting a parse error and continuing.
    scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/project/ProjectIO.java:87
  • fsUrl() currently just prepends file:// without normalizing Windows paths. On Windows this will produce invalid file URLs (e.g. file://C:\Users\...), and consumers that strip file:// can end up with drive-relative paths (the same pitfall covered by scripts/settings ProjectIOTest). This can break project file reads/writes on Windows.
    public static String fsUrl(String path) {
        if (path == null || path.startsWith("file://") || path.indexOf("://") > 0) return path;
        return "file://" + path;
    }

scripts/guibuilder/tools/guibuilder-mcp-client.mjs:12

  • port is parsed with Number(...) and used directly in net.createConnection(). If the env var/arg is non-numeric, this becomes NaN and the client fails with a low-signal runtime error. Validating the port early provides a clearer failure mode.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f0099dabf7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/guibuilder/javase/pom.xml Outdated
Copilot AI review requested due to automatic review settings August 5, 2026 09:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a745163cb4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 46 out of 47 changed files in this pull request and generated no new comments.

Suppressed comments (4)

CodenameOne/src/com/codename1/ui/editor/CodeView.java:163

  • The protected-region check treats the end marker as inclusive for insertions (start <= protectedEnd), which blocks edits immediately after the closing marker (i.e., at the first character following the protected block). This makes it hard to place user code right after a generated section.
            if ((start == end && start >= protectedStart && start <= protectedEnd)
                    || (start < protectedEnd && end > protectedStart)) {
                return true;

scripts/guibuilder/tools/guibuilder-mcp-client.mjs:26

  • JSON.parse(line) in the socket data handler is unguarded. Any malformed/partial line from the server will throw and crash the client process, leaving pending requests unresolved.
    scripts/guibuilder/tools/guibuilder-mcp-client.mjs:43
  • request() resolves even when the JSON-RPC response contains an error object, so callers proceed as if initialization/tool calls succeeded. This should reject the promise on JSON-RPC errors.
    maven/codenameone-maven-plugin/src/main/java/com/codename1/maven/OpenGuiBuilderMojo.java:68
  • The binding file name includes a random UUID, so every mvn cn1:guibuilder run leaves another stale guibuilder-*.input in ~/.codenameoneGUIBuilder. Over time this can accumulate unnecessarily.
        File runtimeDir = new File(System.getProperty("user.home"), ".codenameoneGUIBuilder");
        runtimeDir.mkdirs();
        File input = new File(runtimeDir, "guibuilder-" + UUID.randomUUID() + ".input");
        writeBinding(input, projectDir, guiDir, sourceDir, cssFile);

@shai-almog

shai-almog commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 148 screenshots: 148 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 262 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 74ms / native 3ms = 24.6x speedup
SIMD float-mul (64K x300) java 78ms / native 2ms = 39.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 158.000 ms
Base64 CN1 decode 96.000 ms
Base64 native encode 898.000 ms
Base64 encode ratio (CN1/native) 0.176x (82.4% faster)
Base64 native decode 426.000 ms
Base64 decode ratio (CN1/native) 0.225x (77.5% faster)
Base64 SIMD encode 53.000 ms
Base64 encode ratio (SIMD/CN1) 0.335x (66.5% faster)
Base64 SIMD decode 46.000 ms
Base64 decode ratio (SIMD/CN1) 0.479x (52.1% faster)
Base64 encode ratio (SIMD/native) 0.059x (94.1% faster)
Base64 decode ratio (SIMD/native) 0.108x (89.2% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 10.000 ms
Image createMask (SIMD on) 4.000 ms
Image createMask ratio (SIMD on/off) 0.400x (60.0% faster)
Image applyMask (SIMD off) 106.000 ms
Image applyMask (SIMD on) 70.000 ms
Image applyMask ratio (SIMD on/off) 0.660x (34.0% faster)
Image modifyAlpha (SIMD off) 96.000 ms
Image modifyAlpha (SIMD on) 78.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.813x (18.8% faster)
Image modifyAlpha removeColor (SIMD off) 71.000 ms
Image modifyAlpha removeColor (SIMD on) 57.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.803x (19.7% faster)

@shai-almog

shai-almog commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 143 screenshots: 143 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 530 seconds

Build and Run Timing

Metric Duration
Simulator Boot 75000 ms
Simulator Boot (Run) 1000 ms
App Install 21000 ms
App Launch 35000 ms
Test Execution 609000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 432ms / native 8ms = 54.0x speedup
SIMD float-mul (64K x300) java 312ms / native 8ms = 39.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 158.000 ms
Base64 CN1 decode 146.000 ms
Base64 native encode 520.000 ms
Base64 encode ratio (CN1/native) 0.304x (69.6% faster)
Base64 native decode 802.000 ms
Base64 decode ratio (CN1/native) 0.182x (81.8% faster)
Base64 SIMD encode 94.000 ms
Base64 encode ratio (SIMD/CN1) 0.595x (40.5% faster)
Base64 SIMD decode 80.000 ms
Base64 decode ratio (SIMD/CN1) 0.548x (45.2% faster)
Base64 encode ratio (SIMD/native) 0.181x (81.9% faster)
Base64 decode ratio (SIMD/native) 0.100x (90.0% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 54.000 ms
Image createMask (SIMD on) 16.000 ms
Image createMask ratio (SIMD on/off) 0.296x (70.4% faster)
Image applyMask (SIMD off) 264.000 ms
Image applyMask (SIMD on) 302.000 ms
Image applyMask ratio (SIMD on/off) 1.144x (14.4% slower)
Image modifyAlpha (SIMD off) 164.000 ms
Image modifyAlpha (SIMD on) 205.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.250x (25.0% slower)
Image modifyAlpha removeColor (SIMD off) 136.000 ms
Image modifyAlpha removeColor (SIMD on) 164.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 1.206x (20.6% slower)

Copilot AI review requested due to automatic review settings August 5, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Suppressed comments (4)

CodenameOne/src/com/codename1/ui/editor/CodeView.java:163

  • Protected-region edit detection treats an insertion exactly at the end marker boundary as protected ("<= protectedEnd"), which prevents typing immediately after a generated block. This makes it impossible to add code right after the protected end marker without first moving further away.
            if ((start == end && start >= protectedStart && start <= protectedEnd)
                    || (start < protectedEnd && end > protectedStart)) {
                return true;

CodenameOne/src/com/codename1/ui/layouts/LayeredLayout.java:3688

  • UNIT_BASELINE absolute pixel calculation mixes the reference component's current size with the target component's preferred size when calling getBaseline(). This can yield incorrect baseline offsets for components that are resized by constraints. Use the component's current size when available, with a preferred-size fallback.
                            int componentBaseline = declaredBaseline(cmp, cmp.getPreferredW(), cmp.getPreferredH());

scripts/guibuilder/tools/guibuilder-mcp-client.mjs:22

  • The TCP client assumes every non-empty line is valid JSON and calls JSON.parse() without a try/catch. Any non-JSON line (e.g., server logging, partial/corrupt output) will throw and crash the client, leaving pending requests unresolved. Handle parse errors explicitly and continue reading.
    CodenameOne/src/com/codename1/ui/layouts/LayeredLayout.java:3142
  • UNIT_BASELINE alignment uses the reference component's current size (ref.getWidth()/getHeight()) but computes the moved component's baseline using its preferred size. If the component is laid out at a non-preferred size, this can misalign baselines. Use the component's current size when available (with a preferred-size fallback if size is still 0 at this point).

This issue also appears on line 3688 of the same file.

                            int componentBaseline = declaredBaseline(cmp, cmp.getPreferredW(), cmp.getPreferredH());

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 83742fbb96

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copilot AI review requested due to automatic review settings August 5, 2026 14:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 52 out of 53 changed files in this pull request and generated no new comments.

Suppressed comments (1)

scripts/guibuilder/common/src/main/java/com/codename1/guibuilder/project/ProjectIO.java:88

  • fsUrl() doesn’t normalize Windows paths (backslashes) or handle drive-letter file URLs. This differs from the existing Settings/Game Builder ProjectIO.fsUrl() implementations and will break binding/file reads and directory creation on Windows (e.g. file://C:\... and ensureParent() relying on /).
    public static String fsUrl(String path) {
        if (path == null || path.startsWith("file://") || path.indexOf("://") > 0) return path;
        return "file://" + path;
    }

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a48a0129f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@shai-almog

shai-almog commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 217 screenshots: 217 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 144 screenshots: 144 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

Copilot AI review requested due to automatic review settings August 5, 2026 14:42

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6daf8abcb0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Type parameters sit before extends, so the superclass check passed while the
generated class is not generic: carried members mentioning T were left in a
class that has no T and the companion stopped compiling. Refused, like an
unsupported superclass, rather than half-migrated.

Copy on the root followed by Paste inserted a cloned Form beneath itself. The
canvas substitutes a content pane container for that nested element while the
generated source emits new Form(...), so the preview and the saved application
stopped describing the same tree -- and the palette cannot add a screen as a
child either. Paste rejects the root-only types; ordinary components are
unaffected, which the test pins alongside.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 84de20afce

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

getPluginContext() is indexed by the current project, and isCN1ProjectDir()
accepts both the aggregator and the app module, so running cn1:guibuilder from
a generated multi-module root gave each execution its own empty map and started
a second editor on the same files -- two processes writing the same .gui.

The guard lives in the session's context for the top level project instead: one
map per invocation, shared by every project in the reactor, and still not a
JVM-wide flag, which was the previous bug where a long lived Maven never
launched again.

The session lookup is its own method so the composition can be tested without
constructing a MavenSession, which this module has no mocking dependency for:
two executions resolving to one map and writing through it, and the fallback to
the per-project context when there is no session. The choice of the top level
project as the key is a line of code rather than something those tests prove.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 25dec5cc01

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Descendants are named in appendGeneratedChildren() and the root was named
nowhere, so the saved screen returned null from getName() and editing the root's
name in the inspector had no runtime effect -- every create-gui-form scaffold
carries one.

enabled, visible and rtl on the root belong to the Form, which is what the
generated class calls them on: setVisible(false) hides the whole screen at
runtime while the canvas, applying them to the content pane, left the surface
and its toolbar on show. They go to the Form layer now, at build time and on a
live inspector edit, and the content pane no longer takes them.

Both follow from splitting the canvas into two layers, like the root UIID
before them; this is the same mistake in the two places that were left.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b22d76337a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Both legacy markers are located with markerLine(), the rule the new-format
merger already used: either marker quoted in a string or mentioned in a comment
above the scaffold was found first, and legacyUserMembers() then cut from that
offset through to the real end marker, taking the developer's members with it.

classDeclaration() matched "class " anywhere, so @register(LoginForm.class )
put one in front of the real declaration; the empty class name that came back
meant the scaffolded constructors were never found and stayed beside the
generated one. It requires a standalone keyword now, and the name is read after
whitespace rather than after exactly one space -- legacyClassHeader() made the
same assumption and is fixed with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ffab07287

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

guidedReferences is pipe separated and a rename is written straight into it, so
a name containing a pipe split into several sides on the next rebuild: the
renamed anchor stopped resolving and its dependant jumped. The reserved
characters are stripped before the name is committed -- whitespace too, since
guidedReferencePositions is space separated and had the same exposure.

An abstract legacy class was rebuilt as a concrete public class while its
abstract members were carried across, so the companion did not compile. Refused
with the type-parameter and superclass cases, and the test pins that a concrete
class of the same shape still migrates.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6a0fc87f54

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

lastIndexOf('}') found the closing brace of a helper class declared after the
form, so the carried region ran past the form's own brace and pulled most of
the helper into the regenerated class. It matches the brace that opens the
detected declaration instead, on the comment-masked copy.

The abstract check scanned backwards and stopped at an '@', so the modifiers in
"public abstract @registered class Foo" were never read and the refusal did not
fire. Annotations are blanked first, through the same helper carryClass
Annotations() now uses rather than its own copy of that loop, and "abstract" is
matched as a token rather than a substring.

A throws clause can carry a Java 8 type-use annotation, which skipThrowsClause
rejected outright -- the handler read as missing and Save appended a duplicate
signature.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5697b1cd48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…uctors

Bounding the carried region at the form's own brace stopped a helper class
being pulled inside the regenerated class and then dropped it altogether -- a
top level declaration deleted on the first save, with its callers left without
a definition. It is appended after the regenerated class, where it was. The
test that asserted its absence was asserting the wrong thing and now pins that
it survives outside the class.

"import com.example.Widget; // used by callbacks" did not end with a semicolon,
so the import was dropped while the member needing it was carried. The header
is read comment-masked and the statement cut at its semicolon.

An annotated scaffold constructor is refused rather than silently replaced by
an unannotated delegate, which leaves a class that compiles while DI no longer
sees the constructor. The check had to go on the delegate path as well as the
removal path: the scaffold's own constructors live inside the DON'T EDIT block
and never reach removeConstructors(), so the first version of this fix did
nothing for the case reported.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f55b7ecaf9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Migration puts a top level declaration back after the regenerated class, but
every later save takes the ordinary marker branch and rebuilds from the
template, so the helper survived exactly one save and the next deleted it.
That branch carries the suffix after the file's final generated marker now, the
same way it already carries the imports for the same reason.

The test saves three times and asserts the helper is there each time and
present exactly once, since appending on every save is the obvious way to get
this wrong in the other direction.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0b7e7a9ae4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

shai-almog and others added 2 commits August 10, 2026 14:05
Every super(...) counted as scaffold work although the scaffold never wrote
one, so removing the constructor replaced a developer's super("Runtime title",
new BorderLayout()) with whatever the .gui says. Only the argument-less form,
which the compiler would insert anyway, is treated as scaffolding.

classDeclaration() took the first class in the file, so a legal package-private
helper declared before the form won: its body was read as the form's user
region and the real form ended up appended after a freshly generated class of
the same name. The declaration is located by the companion's expected class
name, with the old behaviour as the fallback.

Which makes a leading helper reachable, so it is preserved too -- dropping it
would be the trailing-helper bug on the other side, and waiting to be told
about it seemed a poor use of the review. Both are appended after the
regenerated class; order among top level declarations does not matter.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…fore

The sweep caught it, but in the same command as the commit, so it went out with
the previous push instead of before it. Running the two separately from now on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: aee8682d10

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Every this(...) was treated as scaffold work, so a constructor customised to
chain through this(createTenantResources()) was removed and the generated one
created the model directly -- the resource selection and any side effects gone,
silently. Only this(), the scaffold's this(Resources.getGlobalResources()) and
its qualified form are accepted; anything else refuses.

This is the same shape as the super(...) case in the previous commit, on the
statement I left behind there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4e46cb6c10

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The data-change listener writes every keystroke, so by the time the editor
closes the value is usually the one the document has. Writing it again
snapshotted an edit containing nothing, and the next Undo restored identical
text and read as broken -- worse when Undo is what closed the editor, since the
asynchronous completion then landed after the revert and put the text back.

The test needed two corrections before it was worth anything. It held an
Element captured before the undo, which is detached once restore() reparses,
so it read the old value whatever happened; and without a canvas the unguarded
path died in the preview lookup, so removing the fix made the test error rather
than fail its assertion. With both fixed it now fails exactly as reported --
one undo lands on "after" -- and passes with the guard.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95f90b30d1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

legacyResourcesConstructor() took the first ')' while removeConstructors()
counts nesting, so an annotation with arguments in the parameter list split the
two: the removal path recognised the constructor and took it away, the delegate
path did not and added nothing, and every caller of new LoginForm(resources)
stopped compiling. Both count nesting now.

An annotation on that parameter is refused for the same reason a declaration
annotation is: the delegate declares a plain parameter and cannot reproduce it.

The two paths disagreeing is the recurring shape here -- one of them was fixed
to count nesting and the other was left -- so they share the comment saying so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 205986a973

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Prefix matching accepted initGuiBuilderComponentsExtra() as the scaffold's own
call, so removing the constructor took the developer's helper and its side
effects with it. The name before the parenthesis has to be the initializer.

Choosing an occupied BorderLayout region stored the request and let
effectiveBorderConstraint() quietly relocate the child instead, so the picker
read Center while the canvas and the generated source both kept it in North.
The occupant is swapped into the region being vacated, which is what a drop
into an occupied region already does, and the two now agree.

Move earlier/later indexed raw XML children, so a <command> interleaved with
the components was what the selection swapped across: the operation reported
success and dirtied the history while the generated order did not change, and
it took several clicks before anything moved. It counts component siblings.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ab36cce029

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

The guibuilder job hit the one hour limit because of two tests I added. Both
focused a real text component, and focusing one starts native editing on the
simulator, which blocks the EDT that callSeriallyAndWait needs -- so they hung
rather than failed, which is why I never got a result out of them locally
either. They are replaced by the branch that can be driven here: with nothing
editable focused the key belongs to the designer, and with no editor open the
Save shortcut belongs to the form. The focused-surface half is not covered, and
the tests say so rather than pretending otherwise. LiveCssTest is 8 tests in
132 seconds again.

Class annotations are reapplied on every save, not only during migration --
same shape as the imports and the trailing declarations before them, and the
third thing that ordinary branch has had to be taught to carry.

The accessors Object already declares are reserved, so a bindable component
named "Class" no longer generates a getClass() that cannot override the final
one and will not compile.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d12bcaff86

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +6610 to +6612
: "right".equals(value) ? Component.RIGHT : Component.TOP);
} else if ("layeredInsets".equals(attribute) && component.getParent() != null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject qualified custom superclasses with matching simple names

When a legacy companion explicitly extends a project class whose simple name matches the expected CN1 type, such as extends com.acme.Form, this comparison accepts it because simpleTypeName(base) is just Form. The regenerated declaration instead resolves Form from com.codename1.ui.*, silently discarding the custom superclass and potentially removing inherited behavior or APIs used by preserved members. Compare the qualified type when one is supplied, or refuse migration unless the superclass is the actual Codename One class.

Useful? React with 👍 / 👎.

Comment on lines +6461 to +6464
((Tabs) component).setTabPlacement("bottom".equals(value) ? Component.BOTTOM : "left".equals(value) ? Component.LEFT
: "right".equals(value) ? Component.RIGHT : Component.TOP);
} else if ("layeredInsets".equals(attribute) && component.getParent() != null

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject customized initializer arguments during migration

Fresh evidence beyond the resolved initializer-name prefix case is a scaffold constructor containing initGuiBuilderComponents(registerAndGetResources()): this check accepts every argument list as generated work, so migration removes the constructor without evaluating the developer's resource-selection helper or its side effects. Accept only known scaffold argument forms, or refuse migration when the initializer argument is a custom expression.

Useful? React with 👍 / 👎.

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.

2 participants