Repository navigation
Run Flutter widget code on Codename One - #5883
shai-almog wants to merge 525 commits into
Conversation
Flutter vs Codename OneSame application, built both ways: Flutter's AOT compile of the gallery, and the identical Dart source transpiled to Java on Codename One. Lower is better for every metric, so a ratio above 1.00x means Codename One is ahead by that factor. android9 interleaved rounds; host load 0.45, 1.71, 1.5
Compute -- the VM workloads (
Gate: within tolerance against
ios9 interleaved rounds; host load 42.79, 42.91, 29.18
Compute -- the VM workloads ( Not measured: iOS compute is not measured: a device build needs signed hardware, and on the simulator Flutter runs its JIT debug engine rather than AOT code. The macOS row runs the same ParparVM and Dart AOT compilers on the same Apple silicon. Gate: within tolerance against
javascript9 interleaved rounds; host load 2.49, 1.3, 0.54
Compute -- the VM workloads (
Gate: within tolerance against
linux9 interleaved rounds; host load 0.24, 2.86, 2.36
Compute -- the VM workloads (
Gate: within tolerance against
macos9 interleaved rounds; host load 8.24, 21.08, 20.38
Compute -- the VM workloads (
Gate: within tolerance against
windows9 interleaved rounds
Compute -- the VM workloads (
Gate: within tolerance against
Codename One wins 26 of 26 measured metrics across 6 platform(s). |
|
Compared 12 screenshots: 12 matched. |
Native fidelity (Android, Material 3)54 pairs compared -- median 95.6%, worst 91.3% ( Distribution --
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Side-by-side comparisons (worst first)
|
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
Cloudflare Preview
|
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: AMD64 Family 25 Model 1 Stepping 1, AuthenticAMD (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 170 screenshots: 170 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
|
|
Compared 185 screenshots: 185 matched. ParparVM vs HotSpot (JDK 25): Linux x64Runner CPU: AMD EPYC 9V74 80-Core Processor (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 185 screenshots: 185 matched. ParparVM vs HotSpot (JDK 25): Linux arm64Runner CPU: Neoverse-N2 (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows arm64Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Developer Guide build artifacts are available for download from this workflow run: Developer Guide quality checks:
|
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
|
Compared 206 screenshots: 206 matched. |
Native fidelity (ios-27-metal)68 pairs compared -- median 94.6%, worst 74.5% ( Distribution --
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Side-by-side comparisons (worst first)
|
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2af86e5ba
ℹ️ 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".
Native fidelity (iOS Modern, Metal)68 pairs compared -- median 95.0%, worst 83.5% ( Distribution --
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Side-by-side comparisons (worst first)
|
|
Compared 163 screenshots: 163 matched. |
|
Compared 236 screenshots: 236 matched. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9bd3a88194
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 311de5406f
ℹ️ 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".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9808bc8c30
ℹ️ 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".
|
Compared 179 screenshots: 179 matched. Benchmark Results
Detailed Performance Metrics
ParparVM vs HotSpot (JDK 25): macOS arm64Runner CPU: Apple M1 (Virtual) (baseline 1 improvement past the baseline, which fails until rebaselined:
Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
A change that moves performance ON PURPOSE records the new baseline in Result: improved past the baseline: rebaseline required |
run-gc-verify.sh's nograce self-test caught nothing (0 of 5) on 5efe54b and on HEAD. Not because #5940 made grace unnecessary -- concurrent cycles still keep every fresh object by grace -- but because DeadFieldElimination (#5903) deletes instance fields nothing reads, and GraceAudit's Node fields were write-only: the translated Node had no fields, the fresh node held nothing, and skipping the grace pass lost nothing. Swept every driver and fixture with javap for write-only fields and fixed the gate ones: - GraceAudit: Node and Filler fields read. nograce caught 5/5 (macOS and Linux arm64), clean run 239 passes; refs checked 13k -> 219k. - SbEscape: Holder.ref was write-only, so the stack builder was never published and self-test6 reported "NOTHING noticed" on every tree. Now caught (5 reports), control clean. - GcVerifyApp (the GcHeapIntegrity gate): Node had no fields, so its first hazard was gone; the gate and its nograce half only worked through the array/map hazards. Fields read; clean and nograce-caught at 1 and 4 markers on Linux arm64, RESULT matches the JVM. - LegacyGrace, BulkCopyBarrier, GcUncooperativeThreadApp: reference fields that had been reduced to leaves. halfblock (self-test4) is probabilistic per run and cannot be made deterministic from the driver: System.gc() is a request, the driver also runs in run-gauntlet.sh against a JVM (no verifier-only native), and a hybrid minor never traces the old held map. Measured 7/20 per run at the old 4MB trigger, 18/20 at 1MB macOS, 20/20 Linux arm64. It now runs at 1MB with up to 10 attempts, stopping at the first catch and reporting which attempt it was, and 10 controls that must all be clean. Rationale is in the script. run-gc-verify.sh: GC-VERIFY GREEN twice on macOS (it was FAILED before: self-test, self-test4, self-test6). GcHeapIntegrity and GcUncooperativeThread integration tests pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ared Root-caused the observation from the halfblock work: 64 WeakReferences to unreachable int[8] referents, stack scrubbed, none cleared after many forced collections. Not a reference-processing bug and not a stray root. The referents sit on the thread's current allocation page for that size class. No sweep touches an owned page (BIBOP-INVARIANTS R5), so they stay mark -1, and cn1GcSweepReclaimsObj -- which must answer exactly what the sweep frees -- keeps them in a concurrent cycle. Measured (Linux arm64, 1 and 4 markers): 0/64 cleared after 20 concurrent cycles; 64/64 once the thread filled and retired the page; 64/64 under CN1_GC_HYBRID_FORCE=1, whose stop-the-world cycles retire held threads' pages. Identical on master 6478b2f and before #5940 (6516c1c^). The JVM clears all 64. Not avoidable in a concurrent cycle (the owner bumps the page while it runs, and the barriers' fresh filter relies on grace there) and bounded to one page per size class per thread. No gate depends on it: RefPolicy's payloads are legacy-heap, GcMarkCompletenessTest checks codegen only, and the JS weak-ref tests run on the JavaScript port. Recorded in a comment at cn1GcSweepReclaimsObj and in vm/CLAUDE.md so a future test retires the page before asserting a clear. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…AM rows - Developer guide and the initializr skill reference now say Dart support is experimental: some widget callbacks and parameters are accepted and ignored. - READINESS.md gap list re-checked against source: three of four text-field gaps and the vertical drag callbacks are resolved; Image.scaled is back on the point sampler since 3eb1c18. - flutter-bench code size: javascript +15,693 bytes, android +25,396 bytes, from frozen const collections, locale/Directionality and typed fields for untyped collection literals (1f97b4f, 358604f). - macos-arm64 objectAllocation RAM ratio 0.708 -> 0.958: master measures the same (6478b2f, its build-macos is red with this verdict); inherited, not caused here. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Conflicts: - perf-baseline.yml: both sides diff against the merge's first parent; kept ours, which also runs the flutter-bench check. - archetype common/pom.xml: kept both generate-sources executions, transcode-flutter and master's compile-android-res. - SimpleDateFormatTest: master's header and month-name test plus our time-zone tests (content auto-merged; add/add header only). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
#5961 rebaselined the same row to 0.814 from eight runs (tolerance 0.3), which covers this branch's 0.958; two overlays moving one row fail the gate. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
+148,467 code bytes (+1.16%) arrived with master's JavaScript text selection and startup fix, classic Android apps and backend security; measured on run 37824086148. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c5c1affc36
ℹ️ 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".
…mangles '-' - Navigator: pushReplacementNamed on the implicit base makes the replacement the new non-poppable base; every route-taking path accepts the common Route type (CupertinoPageRoute, PageRouteBuilder), not only MaterialPageRoute. - dart-transpiler: lib/main.dart wins among several libraries with main(); ambiguity without it is a diagnostic naming the candidates. - Lazy statics follow Dart: a non-late static read during its own initialization throws; a late one re-runs the initializer, and late final throws if bound meanwhile. The parser dropped `late` on top-level variables. - SimpleDateFormat.equals compares zone ID, raw offset and DST use. - ReachabilityCull.mangle folds '-' like every other mangler; master's HyphenatedNamesIntegrationTest hit the CN1_CULL_TRAP stub. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0b14bca2eb
ℹ️ 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".
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… and themes
- ReachabilityCull: a method whose every Class.forName takes a string literal
allocates only the named classes present in the app; an absent name (Kotlin's
kotlin.jvm.internal.Reflection probing kotlin-reflect) allocates nothing, as
forName throws ClassNotFoundException. It used to widen to every no-arg class,
which defeated the cull for any app bundling the Kotlin stdlib and raised the
translator's peak RSS ~130 MB on the hello suite once master added Kotlin tests.
- DateTime validates Dart's +/-8.64e15 ms range before converting to micros.
- DString case conversion applies Unicode's unconditional full mappings
(sharp s -> SS) and Final_Sigma, per code point, locale independent.
- DartUri component decoding is strict UTF-8 and throws FormatException.
- RegExp documents why unicode: true is accepted though inert.
- NativeThemes keeps a theme opened by its bare openLayered("/Name").
- InternalPickerWidget: DurationSpinner3D's value is a Long of milliseconds.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e8d2fa7df3
ℹ️ 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".
…ration, Indic conjuncts - DateTime.add/subtract and the field constructors' microsecond argument validate the result against Dart's range, detecting long overflow from the signs. - Dart == on a nullable numeric or bool operand goes through DartRuntime.eq instead of Java's ==, which unboxed null (NPE) and compared boxes by reference. - AnimationController.duration is nullable with no default, as in Flutter: forward/reverse/repeat and a duration-less animateTo throw FlutterError; fling keeps a fallback since Flutter's spring needs none. - Characters implements UAX #29 GB9c, so consonant + virama + consonant is one grapheme cluster (maxLength no longer splits a conjunct). - Pushback in code: NaN set elements (DartSet) and lazy sync* (DartIterable); the sync* limitation is now listed in READINESS.md and the conversion skill. - flutter-bench: JavaScript sizes get a 0.5% tolerance, as Android code has. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
cn1GcTryResumeActive raised threadActive with a relaxed store, issued a standalone seq_cst fence and re-read threadBlockedByGC relaxed. The fence is MFENCE on x86-64 (several times a locked instruction on AMD Zen) and a full DMB on arm64, on a path the allocation pacing parks and allocation-path safepoints pass constantly. Since the handshake landed (27ef65f) the self-hosted translator measured 0.63x of JDK 25 on a Linux x64 EPYC 7763 perf-gate runner where master measured 0.47-0.50x, memory unchanged. A seq_cst store and a seq_cst load give the same store-load ordering against the collector's seq_cst fence (one total order covers both): XCHG plus a plain load on x86-64, STLR plus LDAR on arm64. GcHeapIntegrityIntegrationTest's resume-window fault gate still passes (the handshake catches the block, the old protocol is still caught). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8c2e73d8d0
ℹ️ 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".
| long wall = (daysFromCivil(y, m, 1) + day - 1) * DAY_MS | ||
| + hour * 3600000L + minute * 60000L + second * 1000L + millisecond; |
There was a problem hiding this comment.
Guard field-based DateTime construction against overflow
When any date component is very large, this unchecked arithmetic can wrap into an apparently valid epoch before millisToMicros performs its range check. For example, DateTime.utc(9223372036854775807, 1, 1, 0, 0, 0, 0, 0) currently becomes a date around year -2 instead of rejecting the out-of-range input, silently corrupting externally supplied dates. Normalize and combine the components with checked arithmetic, then reject results outside the supported DateTime range.
Useful? React with 👍 / 👎.
| if (w.getMaxLength() != null && w.getMaxLength().longValue() >= 0) { | ||
| // The native cap counts UTF-16 units, and maxLength counts characters: a | ||
| // single emoji can be eleven units. It is therefore only a generous upper | ||
| // bound; userEdited enforces the real limit on character boundaries. | ||
| tf.setMaxSize((int) Math.min(Integer.MAX_VALUE, w.getMaxLength().longValue() * 16)); |
There was a problem hiding this comment.
Remove the native cap from unlimited text fields
When maxLength is null or negative, this branch leaves the Codename One editor's default maxSize of 124 in place, so a fresh Flutter TextField that is supposed to accept unlimited input stops accepting characters after 124 UTF-16 units. The same omission leaves the previous native cap installed when a rebuilt field changes from a finite limit to unlimited; explicitly restore an unlimited native maximum in the else case.
Useful? React with 👍 / 👎.
| @Override | ||
| protected void updateComponent(Component c) { | ||
| if (field != null) { | ||
| apply(field); | ||
| } |
There was a problem hiding this comment.
Rebuild text-field decoration children on updates
When a rebuild changes prefixIcon or suffixIcon, this update path only reapplies properties to the existing editor, while the icon labels and surrounding row were created once by decorated() and are never synchronized. A password field that swaps visibility and visibility_off after toggling obscurity therefore keeps displaying the original glyph, and adding or removing an icon has no effect; rebuild or update the decoration child structure when these widgets change.
Useful? React with 👍 / 👎.
| for (OverlayEntry e : newEntries) { | ||
| insert(e, below, above); | ||
| } |
There was a problem hiding this comment.
Preserve entry order when inserting above an overlay anchor
When insertAll is called with an above anchor, every iteration recomputes the same anchorIndex + 1, so later entries are inserted in front of earlier ones. For example, inserting [a, b] above an existing entry produces anchor, b, a, reversing both paint and hit-test order from the caller's list; advance a shared insertion index or iterate in reverse for this case.
Useful? React with 👍 / 👎.
The Linux hello perf gate showed the self-hosted translator's peak RSS ~60MB above master on ParparVM (arm64 hello RAM 1.01x vs 0.87x). Measured on JDK 25 with Epsilon GC over the recorded hello translation, the branch allocated ~3.84GB against master's ~3.68GB, and all of the difference was the reachability cull: with -Dcn1.reachabilityCull=false it matched master. Live heap was flat (~410MB) in every arm, so it was churn, which ParparVM's concurrent collector turns into peak RSS. The largest allocation site was MethodDependencyGraph.getCallers copying the caller set into a fresh ArrayList on every lookup; the dead-method passes look up every surviving method's callers each iteration, and the cull adds a follow-up pass. Both callers only read it. As an unmodifiable view, the same translation allocates ~3.26GB (below master), live heap unchanged, identical output (2315 .c files). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Adds MethodChannel/EventChannel so a transpiled Flutter app's platform code ports to plain Java by changing imports, matching Android's io.flutter.plugin.common shape: - com.codename1.flutter.platform (new): MethodChannel with nested MethodCallHandler/Result, EventChannel with nested StreamHandler/EventSink, MethodCall, PlatformException, MissingPluginException. Mirrors the real Android API; the constructor drops BinaryMessenger since there is no transport to abstract in-process. - com.codename1.flutter.services (new): the Dart-side MethodChannel/ EventChannel the package:flutter/services.dart stub binds to. setMethodCallHandler is concretely typed Funcs.Func1<MethodCall, Object> rather than Object: the transpiler emits every Dart closure literal as a bare, untyped Java lambda with no wrapping (confirmed empirically -- Future.then/catchError/whenComplete are the only names the emitter special-cases), so the real parameter must be a genuine functional interface or the generated call fails to compile. - FlutterChannelRegistry: the in-process, by-name directory both packages share, so either side may register first. - dart.async.Stream/StreamSubscription/StreamController (dart-runtime): a minimal broadcast-only Stream, needed because EventChannel. receiveBroadcastStream() returns one. listen()'s onData is concretely Funcs.VoidFunc1<T> for the same bare-lambda reason as setMethodCallHandler. - Stub files (flutter-runtime META-INF/dart, loaded from the classpath like every runtime stub): flutter_services.dart and dart_async_stream.dart. - Test harness: BehaviorTest/TestSupport now support a *.stub.dart file (loaded into the StubRegistry instead of parsed as a program source) paired with a *.java file, so a fixture can declare and compile its own hand-written Java class for Dart to call into -- used by the new flutter_services_channels behavior fixture, which proves package:flutter/services.dart compiles unchanged and runs both directions (Dart invoking Java, Java invoking Dart, errors, MissingPluginException, async replies, and an event stream with cancel -> onCancel) against a real Java handler. - Developer guide snippets (compiled, not illustrative): Java MethodCallHandler/invokeMethod/StreamHandler examples and a LibGreetingLib stand-in for a transpiled top-level function, plus the matching Dart-side services.dart usage. Not implemented: Stream's single-subscription buffering, sync:true's exact semantics distinction, fromIterable/periodic/asyncMap/transform/ distinct/take/skip/timeout/expand, and StreamSubscription.pause(resumeSignal) -- all documented on dart.async.Stream's class comment. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The sibling of cn1:import-android-project. Pointed at a Flutter project (-Dcn1.flutter.import=<dir>), it: - copies lib/** into common/src/main/flutter, keeping a .flutter-import-files hash record so a re-import keeps local edits and prunes what upstream deleted; - copies every asset and font pubspec.yaml declares, including directory keys and assets that live in pub packages, located through .dart_tool/package_config.json or pubspec.lock plus the pub cache -- what benchcn1's stage-assets.sh did by hand; - reports each pub dependency as covered (the runtime implements its API, or it is an asset-only package whose files were copied) or not; - writes the entry class that runs the Dart main(), saving the project's own as .pre-flutter-import, and carries the pubspec name/version into the settings; - wires common/pom.xml: uncomments the archetype's codenameone-flutter-runtime dependency (or inserts it) and adds the transcode-flutter execution to a pom generated before it was bound, naming the XML to paste when it cannot. Against the Flutter Gallery: 161 Dart files and 193 assets, three asset packages resolved from the pub cache, collection, flutter_staggered_grid_view and nested reported as not covered. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A Java handler answering result.success(87) handed Dart an Integer -- what ported Kotlin Int code produces -- where transpiled Dart expects a Long, and a java.util.List where it calls DartList methods; on iOS the cast is unchecked, so that is a native crash. Flutter's codec does this conversion on a real platform channel. FlutterChannelRegistry.toDart now maps Integer/Short/Byte to Long, Float to Double and Java lists and maps to DartList/DartMap (recursively) for every value Java hands to Dart: invokeMethod arguments, results, events and error details. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…<->Dart calls The chapter now leads with what a team moving from Flutter gets: four charts (installed size, executable code, cold start, memory at rest) from the flutter-bench run on every platform, where Codename One is ahead on every measured metric, followed by why the comparison is tilted toward Flutter (it runs Flutter's own showcase through a runtime that reimplements Flutter's widget model) and which platforms are not measured in full and why. - Side-by-side gallery screenshots (Flutter left, Codename One right) for five demos, replacing the single text-field shot. - "Importing a Flutter application": cn1:import-flutter-project replaces the manual dependency/copy steps. - "Migrating an entire application" / "Migrating a single form" replace the two "use case" sections; the latter explains how a Dart widget class is constructed from Java. - "Calling between Java and Dart": MethodChannel both ways and EventChannel with the Java platform API that mirrors io.flutter.plugin.common, the value mapping, calling Dart top-level functions directly, and shared notifiers. - scripts/flutter-bench/render_doc_charts.py renders the charts from the benchmark's result files through benchlib.verdict, so they show the published report's own statistics. - The porting skill teaches the import goal and channels. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…cator color gaps Fixes three rendering gaps found by diffing the transpiled Flutter Gallery against Flutter's own rendering: - CupertinoButton never resolved CupertinoTheme.of(context).primaryColor / primaryContrastingColor (packages/flutter/lib/src/cupertino/button.dart), so it rendered as a plain Material TextButton/ElevatedButton -- purple text and a grey pill with a drop shadow instead of iOS blue with no shadow. It now builds an explicit ButtonStyle (color, elevation 0, BorderRadius.circular(8) for .filled) and ButtonRenderElement honours that style's foreground/background/elevation instead of always falling back to the Material ColorScheme. - TextField ignored enabled:false entirely. Per Material 2's InputDecorator._getActiveColor, a disabled field now recolours its label/hint, input text and underline to ThemeData.disabledColor (black38 default) and washes a filled field's fill lighter. - TabBar's indicatorColor/indicatorWeight/indicatorSize setters were no-ops and unselectedLabelColor fell back to labelColor, so no indicator ever painted and every tab label was the same colour. TabBar now stacks each tab over a 2dp indicator strip (ThemeData.indicatorColor, default white) painted only for the selected tab, and defaults unselectedLabelColor to labelColor.withAlpha(0xB2) when the bar states a labelColor but no unselectedLabelColor of its own, matching _TabBarState's real resolution. Added CupertinoButtonThemeTest, TextFieldDisabledStyleTest and TabBarIndicatorTest; updated TabBarLabelTest for the new per-tab Column (label + indicator strip) wrapper. All 552 flutter-runtime tests pass. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ixes, add the gallery home Captured in the phone skin from one simulator run against the fixed runtime. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>




















































































































































































































































































































































































Compiles Dart widget source to Java at build time and runs it on Codename One's own renderer. There is no Dart VM in the result, no embedded engine and no platform view — a Dart screen becomes ordinary Codename One components, so it inherits the theme, the event thread, the accessibility tree and the native build.
Two entry points, which are the two things a user actually wants to do:
FlutterUI.wrap(widget)returns aContainerthat goes anywhere an ordinary component does, for putting one Dart screen inside an existing app. It deliberately does not install the Material base theme, so it will not restyle the screen around it.FlutterUI.runApp(widget)mounts the tree as the whole UI, and does install it.The build wiring is the archetype's own: the
transcode-fluttergoal is already bound and is a silent no-op untilsrc/main/flutterexists. No Dart SDK is involved — the transpiler is Java and the Dart is input, never executed.Benchmark
scripts/flutter-benchbuilds one application two ways — the Flutter toolchain's release build, and the identical Dart source transpiled by Codename One — and publishes size, start-up and idle memory per platform to the PR and to port status.Neither application is vendored.
prepare.shtakes the gallery from the Flutter SDK CI clones and copies the same 159 files into both trees, so the comparison cannot drift: there is no second copy for an edit to land on. An earlier round of this work compared two different galleries and every number it produced was meaningless. The Codename One side is generated from the shipping archetype with the runtime dependency enabled — the two steps the guide tells a user to take — so a change that breaks the documented wiring breaks the benchmark too.Three measurement decisions, each because the obvious alternative flattered us:
FIRSTCONTENTis a UI-thread callback that runs before that frame is rasterised, while ourFIRSTFRAMEfires once the form is on screen. Comparing them charges one runtime for rasterising its first screen and not the other — which is what the harness this replaces did. Flutter's figure is reported as a range and the ratio uses the end least favourable to us.Runneris a thin launcher and the Dart image sits inFrameworks/App.framework. Sizing the executable compared our whole runtime against their stub.And two refusals rather than a substituted number:
Nothing contacts the build server: the
*-sourceandlocal-*targets build on the runner. Only our own numbers are gated, so a Flutter SDK upgrade that grows their build cannot turn ours red.Fidelity work in this PR
RoundBorderdraws itself when there is no shadow and nouiidmode, instead of going through a component-sized offscreen image. The cache hides the cost for a static shape; for one that animates its size it does not — a circle growing to 1618×1618 threw away a 10MB surface per frame.Component.paintInternalImplclips every component to its own rectangle, soFractionalTranslationdrew most of itself into the discarded region — the feature-discovery circle rendered as a quadrant with two straight edges meeting at its centre.FittedBoxwas a pass-through. Flutter lays its child out unbounded and scales the result, which is why text inside one shrinks instead of wrapping.Cardrebuilt its border every time, andRoundRectBordercaches its shadow against the border instance, so every rebuild re-rendered it with a gaussian blur. With the cache off it also translates the liveGraphicsby the shadow offset and never undoes it, so cards drifted 9px down and 4px across, accumulating down the page.Verification
/demo/card14.98% → 2.30%,/demo/grid-lists26.30% → 0.32%prepare.shverified end to end; the generated project builds 563 Java files from 159 Dart files, which also exercises the documented user pathNot yet proven
No benchmark platform adapter has been exercised end to end —
run_bench.py --listreports that rather than implying otherwise, and the first CI run is the thing to review. The native compile steps (xcodebuild, gradle, clang-cl, GTK3) have not run on a runner.This is also the first mention of the feature in
docs/, which has carried none until now.