code-quality batch (T-112)
test / unit + widget + golden + a11y (push) Failing after 31s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m7s
test / unit + widget + golden + a11y (push) Failing after 31s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m7s
Seven small consultant findings, one commit:
1. TreeSitterLib stores last dlopen error + path in static fields
instead of swallowing them. Callers that observe a null instance
can now read the diagnostic.
2. Drop the Cmsghdr alias in libc.dart — back-compat shim with no
callers; CLAUDE.md forbids those in a solo repo.
3. Drop EditorController._events field + the unused_field
suppression. The constructor still subscribes via `events.on<...>`
for _eventSub; the field itself was speculative retention.
4. Replace inline hex / errno literals in native_pty.dart with
PosixErrno.{eintr,ebadf,epipe} and new libc.{pollin, pollAnyErr,
sighup, sigkill, sigwinch}. PosixErrno gains eintr.
5. ExtensionManager records activate/deactivate exceptions in a
`_failed` map exposed as `failedExtensions` + `didFail(id)`.
Listeners are notified on entry/exit; cleared on a clean
activate. UI surfaces the degraded state instead of pretending
everything is fine.
6. file_tree_view imports FileEntry via the clide.dart barrel
instead of `package:clide/src/files/listing.dart` directly — the
leak the consultant flagged (barrel already re-exports it).
7. test_app branch in main.dart wrapped in `if (kDebugMode)` so
release tree-shaker elides the test harness from shipping
binaries. Source import stays; tree-shake handles the rest.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -243,6 +243,15 @@ class TreeSitterLib {
|
||||
@visibleForTesting
|
||||
static TreeSitterLib fromDynamicLibrary(DynamicLibrary lib) => TreeSitterLib._(lib);
|
||||
|
||||
/// Most recent error raised while trying to dlopen the tree-sitter
|
||||
/// library, paired with the path that was attempted. Cleared on a
|
||||
/// successful open. Null means "no attempt failed yet."
|
||||
///
|
||||
/// Callers that observe a null `instance` after `init()` should read
|
||||
/// this for the diagnostic instead of guessing.
|
||||
static Object? lastOpenError;
|
||||
static String? lastOpenErrorPath;
|
||||
|
||||
static DynamicLibrary? _openLibrary() {
|
||||
final libName = Platform.isLinux
|
||||
? 'libtree-sitter.so'
|
||||
@@ -251,12 +260,22 @@ class TreeSitterLib {
|
||||
: Platform.isWindows
|
||||
? 'tree-sitter.dll'
|
||||
: null;
|
||||
if (libName == null) return null;
|
||||
if (libName == null) {
|
||||
lastOpenError = 'unsupported platform ${Platform.operatingSystem}';
|
||||
lastOpenErrorPath = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Try standard dlopen path first (works when lib is in bundle/lib/).
|
||||
try {
|
||||
return DynamicLibrary.open(libName);
|
||||
} catch (_) {}
|
||||
final lib = DynamicLibrary.open(libName);
|
||||
lastOpenError = null;
|
||||
lastOpenErrorPath = null;
|
||||
return lib;
|
||||
} catch (e) {
|
||||
lastOpenError = e;
|
||||
lastOpenErrorPath = libName;
|
||||
}
|
||||
|
||||
// Try next to executable.
|
||||
final exe = File(Platform.resolvedExecutable).parent.path;
|
||||
@@ -264,8 +283,14 @@ class TreeSitterLib {
|
||||
final path = '$dir/$libName';
|
||||
if (File(path).existsSync()) {
|
||||
try {
|
||||
return DynamicLibrary.open(path);
|
||||
} catch (_) {}
|
||||
final lib = DynamicLibrary.open(path);
|
||||
lastOpenError = null;
|
||||
lastOpenErrorPath = null;
|
||||
return lib;
|
||||
} catch (e) {
|
||||
lastOpenError = e;
|
||||
lastOpenErrorPath = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user