with one click
eiffel-generify
// Convert concrete-typed Eiffel classes to use generic parameters with proper constraints following ISE EiffelBase patterns. Use with /eiffel.generify command.
// Convert concrete-typed Eiffel classes to use generic parameters with proper constraints following ISE EiffelBase patterns. Use with /eiffel.generify command.
| name | eiffel-generify |
| description | Convert concrete-typed Eiffel classes to use generic parameters with proper constraints following ISE EiffelBase patterns. Use with /eiffel.generify command. |
| allowed-tools | Read, Grep, Glob, Edit, Write, Bash, Task |
Purpose: Convert concrete-typed classes to use generic parameters with proper constraints following ISE EiffelBase patterns. Constraints are design decisions, not afterthoughts.
/eiffel.generify <library-path>
Example:
/eiffel.generify d:\prod\simple_sorter
If no path provided, ask user: "Which library? Provide the full path (e.g., d:\prod\simple_sorter)"
<library-path>/
āāā .eiffel-workflow/
ā āāā evidence/
ā āāā design-scan.md ā INPUT (optional, from /eiffel.design-scan)
ā āāā generification.txt ā OUTPUT (evidence)
āāā src/
ā āāā *.e ā MODIFIED (class headers, feature signatures)
āāā test/
ā āāā *.e ā MODIFIED (update type instantiations)
āāā <library>.ecf ā MAY UPDATE (if dependencies change)
[G -> COMPARABLE] means "this class needs ordering". An unconstrained [G] means "this class truly works with ANY type."detachable separate when types cross processor boundaries.| Operation Used on G | Required Constraint | ISE Example |
|---|---|---|
< > <= >= | G -> COMPARABLE | SORTED_LIST [G -> COMPARABLE] |
hash_code | G -> HASHABLE | HASH_TABLE [G, K -> HASHABLE] |
= /= ~ (object equality) | (none needed ā available on ANY) | ARRAYED_LIST [G] |
+ - * / (arithmetic) | G -> NUMERIC | MATRIX [G -> NUMERIC] |
| binary ops returning same type | like Current pattern | NUMERIC descendants |
| SCOOP safety | G -> detachable separate ANY | MML_MAP [K -> detachable separate ANY, V -> detachable separate ANY] |
| creation | G -> CREATABLE create make end | FACTORY [G -> CREATABLE create make end] |
| domain-specific | G -> SPECIFIC_CLASS | SIMPLE_FACTORY [G -> SIMPLE_CREATABLE] |
If design-scan.md exists: Read <library-path>/.eiffel-workflow/evidence/design-scan.md and present generics findings to user. Ask which finding to implement.
If no scan exists: Ask user:
Which class should be parameterized?
Which concrete type(s) should become generic parameter(s)?
Read the target class. For every feature that uses the concrete type, record:
Build a complete map:
Type: STRING (candidate for G)
Features using STRING:
- put (a_key: STRING; a_value: INTEGER) [parameter]
- item (a_key: STRING): INTEGER [parameter]
- has_key (a_key: STRING): BOOLEAN [parameter]
- keys: ARRAYED_LIST [STRING] [return type]
- internal_table: HASH_TABLE [INTEGER, STRING] [attribute]
Operations on STRING:
- is_equal (via `~` in has_key) ā no constraint needed
- hash_code (via HASH_TABLE key) ā G -> HASHABLE
- out (in debug output) ā no constraint needed (from ANY)
Constraint determination: G -> HASHABLE
For each parameter, specify:
| Parameter | Replaces | Constraint | Justification |
|---|---|---|---|
K | STRING (key type) | K -> HASHABLE | Used as HASH_TABLE key, needs hash_code |
V | INTEGER (value type) | (none) | Only stored and retrieved, no operations |
Naming conventions:
G ā single general parameterK ā key typeV ā value typeG -> COMPARABLE ā when ordering is neededG -> HASHABLE ā when hashing is neededSCOOP check:
<concurrency support="scoop"/>, consider whether parameters need detachable separatedetachable separate constraintslike Current check:
like Current instead of a generic parameterplus (other: like Current): like Current for arithmetic typesCreation constraint check:
G -> SOME_CLASS create make endShow the user:
Proposed class header:
class MY_CLASS [K -> HASHABLE, V]
Feature signature changes (before ā after):
put (a_key: STRING; a_value: INTEGER) ā put (a_key: K; a_value: V)
item (a_key: STRING): INTEGER ā item (a_key: K): V
keys: ARRAYED_LIST [STRING] ā keys: ARRAYED_LIST [K]
Attribute type changes:
internal_table: HASH_TABLE [INTEGER, STRING] ā HASH_TABLE [V, K]
Client code impact (files in src/ AND test/ that instantiate the class):
test/test_my_class.e: line 15: create l_obj.make ā l_obj: MY_CLASS [STRING, INTEGER]; create l_obj.make
src/other_class.e: line 42: my_ref: MY_CLASS ā my_ref: MY_CLASS [STRING, INTEGER]
Constraint justification ā for each constraint, which operations require it
BLOCK until user approves. Ask: "Proceed with this generification? (yes/no/modify)"
Oracle Gate: Before writing any Eiffel code, check the oracle:
echo "$CODE" | /d/prod/simple_oracle/oracle-cli.exe check-code --stdin --library <library-name>
If oracle flags (exit 1): regenerate code addressing the flagged pattern. Repeat until exit 0.
Implementation steps:
src/ AND test/:
# Find all references to the class name
grep -rn "MY_CLASS" <library-path>/src/ <library-path>/test/
Update every instantiation to provide type parameters:
-- Before:
l_obj: MY_CLASS
-- After:
l_obj: MY_CLASS [STRING, INTEGER]
-- Before:
inherit MY_CLASS
-- After:
inherit MY_CLASS [STRING, INTEGER] -- or propagate generic parameter
CRITICAL: Do not forget test files. Grep for the class name across the ENTIRE library.
CRITICAL: cd to the library directory before compiling.
cd <library-path> && /d/prod/ec.sh -batch -config <library>.ecf -target <library>_tests -c_compile
MUST see "System Recompiled."
Common generification compilation errors and fixes:
| Error | Meaning | Fix |
|---|---|---|
| VTCG | Client code violates constraint | Client must provide type that conforms to constraint |
| VTCT | Generic parameter name conflicts with class name | Rename parameter (G, K, V, etc.) |
| VUAR | Operation on generic requires constraint | Add appropriate constraint to parameter |
| VEEN | Missing type parameter in client code | Add [TYPE] to all class references |
| VDRD | Redefined feature signature doesn't match | Update descendants to use generic parameter |
| VTUG | Wrong number of generic parameters | Ensure all references have correct parameter count |
Strategy for resolving errors:
ZERO WARNINGS POLICY: Fix all warnings immediately.
If compilation fails:
oracle-cli.exe record-failure compile <library> error.txtRun existing tests:
cd <library-path> && ./EIFGENs/<library>_tests/W_code/<library>.exe
ALL existing tests must pass. Generification must preserve behavior.
Save evidence to <library-path>/.eiffel-workflow/evidence/generification.txt:
# Generification Evidence
# Library: <library-path>
# Date: [timestamp]
## Target Class
Name: MY_CLASS ā MY_CLASS [K -> HASHABLE, V]
File: src/my_class.e
## Generic Parameters Added
1. K -> HASHABLE
Replaces: STRING
Justification: Used as HASH_TABLE key, requires hash_code
Operations requiring constraint: hash_code (via HASH_TABLE), is_equal
2. V (unconstrained)
Replaces: INTEGER
Justification: Only stored and retrieved, no operations performed
SCOOP note: No cross-processor usage detected
## Feature Signature Changes
- put (a_key: STRING; a_value: INTEGER) ā put (a_key: K; a_value: V)
- item (a_key: STRING): INTEGER ā item (a_key: K): V
- has_key (a_key: STRING): BOOLEAN ā has_key (a_key: K): BOOLEAN
- keys: ARRAYED_LIST [STRING] ā keys: ARRAYED_LIST [K]
## Attribute Changes
- internal_table: HASH_TABLE [INTEGER, STRING] ā HASH_TABLE [V, K]
## Client Code Updated
- test/test_my_class.e: 3 references updated to MY_CLASS [STRING, INTEGER]
- src/other_class.e: 1 reference updated to MY_CLASS [STRING, INTEGER]
## Compilation
Command: /d/prod/ec.sh -batch -config <lib>.ecf -target <lib>_tests -c_compile
Status: PASS
Warnings: NONE
Generification errors resolved: [list or NONE]
## Tests
Command: ./EIFGENs/<lib>_tests/W_code/<lib>.exe
Status: ALL PASS ([n]/[n])
Generification COMPLETE for: <library-path>
Class: MY_CLASS ā MY_CLASS [K -> HASHABLE, V]
- Parameters added: [n] ([list with constraints])
- Features updated: [n]
- Client files updated: [n]
- Compilation: PASS
- Tests: ALL PASS ([n]/[n])
Evidence: <library-path>/.eiffel-workflow/evidence/generification.txt
Do NOT suggest next skills automatically. The generification is done ā let the user decide what's next. Only mention other skills if the user asks.
This skill focuses ONLY on: <library-path>
DO NOT:
DO:
is_equal is used (that's from ANY).<library-path>/.eiffel-workflow/skill-improvements.md ā do NOT modify skills mid-workflow[HINT] Download the complete skill directory including SKILL.md and all related files