R7b batch 4 #4 — the FINAL R7b language (docs/design/dart-kernel-port-checklist.md is the authoritative quirk list). The fourth vendored-grammar-C language, with a twist: production dart resolved its wasm from tree-sitter-wasms, whose dart dependency is an UNPINNED github:UserNobody14/tree-sitter-dart — a routine dependency update would have silently changed dart's grammar. This PR byte-copies the shipping 0.1.13 artifact into src/extraction/wasm/ (VENDORED_WASM_LANGS += dart) and compiles the same-commit (d4d8f3e337d8) parser.c/scanner.c in the kernel — table identity proven by the kernel-grammar-parity row. crates.io tree-sitter-dart is the nielsenko fork (different lineage) — rejected. The center of gravity is THE SIBLING-BODY DOUBLE-WALK, reproduced bug-for-bug: dart attaches every function/method body as a NEXT SIBLING of its signature, and the TS walkers consume each body TWICE — once via resolveBody (attributed to the function/method) and once via the enclosing generic walk (attributed to the file/class). Duplicate local-function nodes with the SAME id under different parents, duplicated calls/instantiates refs, and file/class-attributed fn-ref twins all emit in the exact observed interleave (a dedicated fixture pins the duplicate-id rows; the bloc kind-census spot-check pins the counts). Also preserved (probe-pinned): the extractBareCall selector matrix (the first callTypes=[] language — cascades completely invisible, `?.` encodes like `.`, the `ConfigT.load()` calls+references double emission with no callee-of-call skip, capitalized-chain `Foo.create().run` re-encode, const-object callee names); the constructor hooks (unnamed ctor skipped, named ctors/factories renamed to the CTOR name with the class as returnType, `@override (T) m()` record-misparse rescued by class-name validation); operator methods minting `method "<anonymous>"`; static_final_declaration constants via the visitNode hook while instance fields mint NOTHING; the prefixed-return-type prefix bug (`other.OtherClass f()` → returnType `other`); enum `with` mixins silent vs `implements` working; anonymous extensions named after the ON type; deferred imports invisible; named-argument callbacks NOT fn-ref-captured (the Flutter `onPressed:` idiom — future accuracy PR, TS-side first); `async*`/`sync*` NOT async; value-refs with the LIVE dart sibling-body pull and the `$X`-vs-`${X}` interpolation asymmetry; dartdoc kept in all three comment forms with the annotation-broken chain. Gates: parity sweeps first-run 0-diff on shelf/bloc/flutter — 5,815 clean files byte-parity, deferrals 10/21/1341 ≈ the survey's 10/21/~1340 (both-arm grammar reality: empty object patterns — the sealed-class idiom — and unnamed `library;` dominate; --max-deferral 0.3); full-init dumps byte-identical ×3 (shelf 7,959 / bloc 40,026 / flutter 1,855,319 dump lines); bloc per-kind node census identical across arms (the double-walk duplicate rows survive the store identically); kernel-dart-parity suite (7 fixtures + in-memory CRLF variants + double-walk duplicate-id pin + generated-file skip pin + two defer pins); full suite 2,688 green ×2 with CODEGRAPH_KERNEL_EXPECT=1. DEFAULT_ROUTED += dart (20 langs — R7b COMPLETE). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
232 lines
4.5 KiB
Dart
232 lines
4.5 KiB
Dart
/// File-level doc for torture (glued to import? no — imports precede nothing).
|
|
import 'dart:async';
|
|
import 'package:torture/other.dart' as other show OtherClass;
|
|
export 'src/reexported.dart' hide Hidden;
|
|
part 'torture_part.dart';
|
|
|
|
/// Doc line one.
|
|
/// Doc line two.
|
|
void topLevel(int count, String label) {
|
|
helper(count);
|
|
}
|
|
|
|
/** Block dartdoc kept. */
|
|
int blockDoc() => 1;
|
|
|
|
// Plain comment doc.
|
|
String plainDoc() => 'x';
|
|
|
|
/// Broken by annotation.
|
|
@deprecated
|
|
void annotated() {}
|
|
|
|
@Deprecated('with args')
|
|
@pragma('vm:entry-point')
|
|
void doubleAnno() {}
|
|
|
|
const SHARED_MAX = 10;
|
|
final DERIVED_VAL = SHARED_MAX + 1;
|
|
const lowercase_const = 1;
|
|
final typedTop = compute();
|
|
var topVar = 5;
|
|
int topTyped = 6;
|
|
final multiA = 1, multiB = 2;
|
|
|
|
int get topGetter => 7;
|
|
set topSetter(int v) {}
|
|
|
|
Future<String> asyncFn() async => 'a';
|
|
Stream<int> genStar() async* {
|
|
yield 1;
|
|
}
|
|
Iterable<int> syncStar() sync* {
|
|
yield 2;
|
|
}
|
|
|
|
num numback(num n) => n;
|
|
dynamic dyn(dynamic d) => d;
|
|
Object obj(Object o) => o;
|
|
List<WidgetT> listRet(Map<String, WidgetT> m) => [];
|
|
WidgetT? nullableRet() => null;
|
|
other.OtherClass prefixedRet() => other.OtherClass();
|
|
T generic<T>(T v) => v;
|
|
|
|
external void externalFn();
|
|
|
|
void params({int? named, required WidgetT child, String note = 'x'}) {}
|
|
void optionals([int pos = 0, WidgetT? w]) {}
|
|
void fnTyped(void cb(int x), int Function(String) modern) {}
|
|
|
|
void bodyShapes(List<int> xs, Object o) {
|
|
var local = 1;
|
|
int typed = 2;
|
|
final con = 3;
|
|
int uninit;
|
|
uninit = 4;
|
|
local = uninit;
|
|
helper(local);
|
|
obj.method(local);
|
|
this_like.deep.call3(local);
|
|
ConfigT.load();
|
|
ConfigT.setting;
|
|
w?.render();
|
|
y2..add(1)..add(2);
|
|
final w1 = WidgetT(1);
|
|
final w2 = new WidgetT(2);
|
|
pad(const EdgeInsetsT.all(8.0));
|
|
FactoryT.create().run();
|
|
lower().chain();
|
|
WidgetT.named(3).chainTail();
|
|
xs.map((e) => e * 2).toList();
|
|
xs.forEach((e) => use(e));
|
|
final lam = (int a) {
|
|
helper(a);
|
|
};
|
|
lam(5);
|
|
void localFn(int n) {
|
|
inner(n);
|
|
}
|
|
localFn(6);
|
|
if (o is WidgetT) {
|
|
use(o);
|
|
}
|
|
final cast = o as WidgetT;
|
|
final tl = <WidgetT>[];
|
|
throw StateError('bad');
|
|
}
|
|
|
|
void interpolation(int count) {
|
|
log('count $count and ${SHARED_MAX} via ${refresh()}');
|
|
}
|
|
|
|
void refTaker() {
|
|
register(topLevel);
|
|
obj.cb = topLevel;
|
|
final table = [topLevel, blockDoc];
|
|
final m = {'k': topLevel, 'x': undefinedName};
|
|
reg2(cb: topLevel);
|
|
forward(topLevel: topLevel);
|
|
final alias = topLevel;
|
|
}
|
|
|
|
/// Class doc.
|
|
@immutable
|
|
class WidgetT extends BaseT with MixA, MixB implements DrawT {
|
|
static const int K_MAX = 9;
|
|
static final sharedInst = WidgetT(0);
|
|
static var mutableStatic = 1;
|
|
final int size;
|
|
final untyped = 5;
|
|
int counter = 0;
|
|
late String title;
|
|
WidgetT(this.size);
|
|
WidgetT.named(this.size) {
|
|
init();
|
|
}
|
|
WidgetT.bodilessNamed() : size = seed();
|
|
factory WidgetT.create() => WidgetT(1);
|
|
const factory WidgetT.redir() = WidgetT2;
|
|
@override
|
|
void render(CanvasT c) {
|
|
c.draw();
|
|
}
|
|
static WidgetT make() => WidgetT(3);
|
|
int get area => size * size;
|
|
set area(int v) {
|
|
counter = v;
|
|
}
|
|
bool get privado => _check();
|
|
bool _check() => true;
|
|
Future<void> load() async {
|
|
await fetch();
|
|
}
|
|
WidgetT operator +(WidgetT o) => WidgetT(size + o.size);
|
|
void useLocalNew() {
|
|
final h = new HolderT(2);
|
|
use(h);
|
|
}
|
|
void readsConst() {
|
|
use(K_MAX);
|
|
}
|
|
}
|
|
|
|
class WidgetT2 extends WidgetT {
|
|
WidgetT2() : super(0);
|
|
void _privateMethod() {}
|
|
}
|
|
|
|
class BaseT {}
|
|
|
|
class DrawT {}
|
|
|
|
class OnlyMix with MixA {}
|
|
|
|
abstract class AbstractT {
|
|
void mustImpl(WidgetT w);
|
|
int get abstractGetter;
|
|
}
|
|
|
|
sealed class ShapeT {}
|
|
|
|
class CircleT extends ShapeT {}
|
|
|
|
mixin MixA on BaseT {
|
|
void mixMethod() {
|
|
helper(1);
|
|
}
|
|
}
|
|
|
|
mixin MixB implements DrawT {
|
|
int get mixGetter => 2;
|
|
}
|
|
|
|
extension WidgetTExt on WidgetT {
|
|
void extMethod() {
|
|
render(CanvasT());
|
|
}
|
|
|
|
int get extGetter => 4;
|
|
}
|
|
|
|
extension on String {
|
|
void anonExt() {}
|
|
}
|
|
|
|
enum ColorT { red, green, blue }
|
|
|
|
/// Enum doc.
|
|
enum StatusT with MixB implements DrawT {
|
|
ok(200),
|
|
err(500);
|
|
|
|
final int code;
|
|
const StatusT(this.code);
|
|
bool get good => code < 400;
|
|
static StatusT parse(int c) => ok;
|
|
}
|
|
|
|
typedef IntFn = int Function(int);
|
|
typedef void LegacyCb(int x);
|
|
typedef MapAlias = Map<String, WidgetT>;
|
|
|
|
extension type MetersT(double value) {
|
|
double get km => value / 1000;
|
|
}
|
|
|
|
void patternUser(Object o) {
|
|
final v = ColorT.red;
|
|
switch (o) {
|
|
case ColorT.blue:
|
|
use(v);
|
|
default:
|
|
break;
|
|
}
|
|
final (a, b) = (1, 2);
|
|
use(a);
|
|
}
|
|
|
|
// π unicode: “smart quotes” précède — column check ☕
|
|
void afterUnicode(String seance) {
|
|
emit('café ☕ done');
|
|
}
|