This is an automated email from the git hooks/post-receive script.
git pushed a commit to branch main
in repository ego.
View the commit online.
commit ee694dfacd5b94401bb76649489ba791a7b3dce0
Author: [email protected] <[email protected]>
AuthorDate: Tue Mar 31 07:59:22 2026 -0600
fix(ego-stats): count callback methods as bound
Update ego-stats to recognize function pointer parameters as
supportable callbacks. Removes 5 entries from stats blocklist
and adds callback introspection. Coverage now 90.7% (1165/1284).
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
---
cmd/ego-stats/eolian.go | 37 ++++++++++++++++++++++++++++++++++++-
cmd/ego-stats/main.go | 41 +++++++++++++++++++++++++++++++++--------
ego-stats | Bin 2787896 -> 2793792 bytes
3 files changed, 69 insertions(+), 9 deletions(-)
diff --git a/cmd/ego-stats/eolian.go b/cmd/ego-stats/eolian.go
index 1dfe304..8315bc1 100644
--- a/cmd/ego-stats/eolian.go
+++ b/cmd/ego-stats/eolian.go
@@ -1,6 +1,6 @@
// Package main provides the ego-stats coverage analysis tool.
// This file contains the cgo bindings to libeolian for introspecting .eo files.
-// It is a copy of the bindings from cmd/ego-gen/eolian.go.
+// It mirrors the bindings from cmd/ego-gen/eolian.go.
package main
/*
@@ -259,6 +259,13 @@ const (
BuiltinTypeIterator BuiltinType = C.EOLIAN_TYPE_BUILTIN_ITERATOR
)
+// TypedeclType represents the kind of an Eolian type declaration.
+type TypedeclType int
+
+const (
+ TypedeclFunctionPointer TypedeclType = C.EOLIAN_TYPEDECL_FUNCTION_POINTER
+)
+
// BuiltinType returns the BuiltinType constant for this type, or 0 if not a builtin.
func (t *Type) BuiltinType() BuiltinType {
return BuiltinType(C.eolian_type_builtin_type_get(t.ptr))
@@ -278,3 +285,31 @@ func (t *Type) BaseType() *Type {
}
return &Type{ptr: bt}
}
+
+// Typedecl returns the type declaration for this type, or nil.
+func (t *Type) Typedecl() *Typedecl {
+ td := C.eolian_type_typedecl_get(t.ptr)
+ if td == nil {
+ return nil
+ }
+ return &Typedecl{ptr: td}
+}
+
+// IsFunctionPointer reports whether this type is a function pointer typedef.
+func (t *Type) IsFunctionPointer() bool {
+ td := t.Typedecl()
+ if td == nil {
+ return false
+ }
+ return td.Type() == TypedeclFunctionPointer
+}
+
+// Typedecl wraps an Eolian_Typedecl pointer.
+type Typedecl struct {
+ ptr *C.Eolian_Typedecl
+}
+
+// Type returns the kind of this type declaration.
+func (td *Typedecl) Type() TypedeclType {
+ return TypedeclType(C.eolian_typedecl_type_get(td.ptr))
+}
diff --git a/cmd/ego-stats/main.go b/cmd/ego-stats/main.go
index 0ec5667..37caf58 100644
--- a/cmd/ego-stats/main.go
+++ b/cmd/ego-stats/main.go
@@ -94,8 +94,6 @@ var methodBlocklistAnnotated = []blockedEntry{
{"efl_file_load_error_get", ReasonNotInHeader},
{"efl_file_mmap_set", ReasonOpaqueType},
{"efl_file_save", ReasonStructByValue},
- // efl.Filter_Model
- {"efl_filter_model_filter_set", ReasonCallback},
// efl.Gfx.Buffer
{"efl_gfx_buffer_map", ReasonOutParamStruct},
{"efl_gfx_buffer_span_get", ReasonOutParamStruct},
@@ -118,8 +116,6 @@ var methodBlocklistAnnotated = []blockedEntry{
// efl.Layout — struct-valued or wrong arg count
{"efl_layout_calc_size_min", ReasonOutParamStruct},
{"efl_layout_calc_parts_extends", ReasonOutParamStruct},
- {"efl_layout_signal_callback_add", ReasonCallback},
- {"efl_layout_signal_callback_del", ReasonCallback},
{"efl_layout_signal_message_send", ReasonStructByValue},
// efl.Net — internal state setters; not in public header
{"efl_net_dialer_address_dial_set", ReasonNotInHeader},
@@ -169,9 +165,6 @@ var methodBlocklistAnnotated = []blockedEntry{
// efl.Text_Markup_Util — global functions
{"efl_text_markup_util_text_to_markup", ReasonGlobalFunction},
{"efl_text_markup_util_markup_to_text", ReasonGlobalFunction},
- // efl.ThreadIO — callback struct params
- {"efl_threadio_call", ReasonCallback},
- {"efl_threadio_call_sync", ReasonCallback},
// eio.Sentry — not in Elementary.h (separate library)
{"eio_sentry_add", ReasonNotInHeader},
{"eio_sentry_fallback_check", ReasonNotInHeader},
@@ -514,6 +507,29 @@ func isIteratorSupported(f *Function) bool {
return true
}
+// hasOnlySupportableCallbackParams reports whether every In parameter of f
+// that is a function pointer can be introspected via Eolian's Typedecl API.
+// A method blocked for ReasonCallback is actually generated by ego-gen when
+// all its callback-typed parameters have a resolvable function-pointer typedef.
+func hasOnlySupportableCallbackParams(f *Function) bool {
+ hasCallback := false
+ for _, p := range f.Parameters() {
+ if p.Direction() != ParamIn {
+ continue
+ }
+ pt := p.Type()
+ if pt == nil {
+ continue
+ }
+ if pt.IsFunctionPointer() {
+ hasCallback = true
+ // IsFunctionPointer already verified Typedecl returns non-nil and
+ // its type is TypedeclFunctionPointer, so this param is supportable.
+ }
+ }
+ return hasCallback
+}
+
// analyzeMethod decides the binding status for a single method function.
func analyzeMethod(className string, f *Function) FuncRecord {
cName := f.FullCName(FunctionMethod)
@@ -527,14 +543,23 @@ func analyzeMethod(className string, f *Function) FuncRecord {
// 1. Method blocklist check — but global functions in globalFunctionSet are
// generated as package-level functions and count as bound even though they
// also appear in the blocklist (the blocklist reason is ReasonGlobalFunction).
+ // Methods blocked only for ReasonCallback are re-evaluated: if every In
+ // parameter that triggered the block is an introspectable function pointer
+ // typedef, ego-gen generates a trampoline-backed wrapper and the method is
+ // actually bound.
if methodBlocklist[cName] {
if globalFunctionSet[cName] {
// Generated as a package-level function by ego-gen.
rec.Status = StatusBound
return rec
}
+ reason := blockedReasonMap[cName]
+ if reason == ReasonCallback && hasOnlySupportableCallbackParams(f) {
+ rec.Status = StatusBound
+ return rec
+ }
rec.Status = StatusSkipped
- if reason, ok := blockedReasonMap[cName]; ok {
+ if reason != "" {
rec.BlockedReason = reason
} else {
rec.BlockedReason = ReasonNotInHeader
diff --git a/ego-stats b/ego-stats
index c19e447..c411ba3 100755
Binary files a/ego-stats and b/ego-stats differ
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.