You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -23,12 +23,13 @@ Capture DSL method calls as `DslDefinition` during indexing, then process them a
23
23
24
24
### Phase 1: Indexing
25
25
26
-
The `Graph` maintains an allowlist of DSL target method names:
26
+
The `Graph` maintains a registry of DSL processors. During indexing, the method `is_dsl_target()` checks if a method name matches any registered processor:
**Two definition types are created during indexing:**
@@ -83,24 +84,37 @@ Standard resolution runs, which resolves `receiver_name` to a fully qualified na
83
84
84
85
### Phase 3: DSL Processing
85
86
86
-
A new method `process_dsl_definitions()` is called after `resolve_all()`. It processes all `ConstantToDslDefinition`s:
87
+
A new method `process_dsl_definitions()` is called after `resolve_all()`. It iterates over all `DslDefinition`s (not just those with constant assignments):
87
88
88
-
1. Look up the referenced `DslDefinition`
89
-
2. Get the resolved receiver via `graph.names().get(&receiver_name)`
90
-
3. Dispatch to handler based on resolved receiver + method name:
89
+
1. Get the `DslDefinition`
90
+
2. Resolve the receiver to a `DeclarationId` (if any)
91
+
3. Look up any associated `ConstantToDslDefinition` (optional)
92
+
4. Find a matching processor from the registry and dispatch
-**Handler matches (e.g., `::Class.new`)**: Transform `ConstantToDslDefinition` into `DynamicClassDefinition` with the constant name. Creates `ClassDeclaration`.
101
-
-**No handler matches (e.g., `SomeClass.new`)**: Transform `ConstantToDslDefinition` into regular `ConstantDefinition`. We don't know what `SomeClass.new` returns.
113
+
-**Create appropriate definitions** (e.g., `DynamicClassDefinition` for `Class.new`)
-**Reassign owned members** to the new definition by updating their `lexical_nesting_id`
102
116
103
-
Each handler also decides what to do with owned members (reassign to the new definition, discard, etc.). When members are reassigned, their `lexical_nesting_id`is NOT updated - it preserves the lexical structure as written in source code.
117
+
Each handler decides what to do with owned members (reassign to the new definition, discard, etc.). When members are reassigned, their `lexical_nesting_id`IS updated to point to the new `DynamicClassDefinition` or `DynamicModuleDefinition`. This ensures that `resolve_lexical_owner` can find the correct declaration during Phase 4 resolution.
Arguments are captured in a structured format to save downstream consumers from parsing:
135
+
Arguments are captured as raw source text strings. This keeps indexing simple - resolution handlers interpret the strings as needed:
122
136
123
137
```rust
124
-
enumDslArgument {
125
-
Symbol(StringId),
126
-
String(StringId),
127
-
Boolean(bool),
128
-
Integer(i64),
129
-
Constant(NameId),
130
-
Block { offset:Offset }, // Location for AST revisit if needed
138
+
/// Represents a single argument in a DSL call.
139
+
/// Values are captured as raw source text strings.
140
+
pubenumDslArgument {
141
+
/// A positional argument (e.g., `Parent` in `Class.new(Parent)`)
142
+
Positional(String),
143
+
/// A keyword argument (e.g., `class_name: "User"`)
144
+
KeywordArg { key:String, value:String },
145
+
/// A splat argument (e.g., `*args`)
146
+
Splat(String),
147
+
/// A double splat argument (e.g., `**kwargs`)
148
+
DoubleSplat(String),
149
+
/// A block argument (e.g., `&block`)
150
+
BlockArg(String),
131
151
}
132
152
133
153
structDslArgumentList {
134
-
positional:Vec<DslArgument>,
135
-
keyword:HashMap<StringId, DslArgument>,
136
-
block:Option<Offset>,
154
+
arguments:Vec<DslArgument>,
155
+
block_offset:Option<Offset>, // Location of do...end block
137
156
}
138
157
```
139
158
159
+
Example: `Foo.new("123", bar: true, *args, **kwargs, &block)` becomes:
160
+
161
+
-`Positional("\"123\"")`
162
+
-`KeywordArg { key: "bar", value: "true" }`
163
+
-`Splat("args")`
164
+
-`DoubleSplat("kwargs")`
165
+
-`BlockArg("block")`
166
+
140
167
### Block Ownership
141
168
142
169
All DSL calls automatically own their block contents. This simplifies indexing logic - the handler decides what to do with owned definitions during processing:
Verify `Bar` is correctly handled as a nested constant (`Foo::Bar` with `inner` method). And `Foo` has `name`and `name=` methods.
495
+
Verify `Bar` is correctly handled as a nested constant (`Foo::Bar` with `inner` method). And `Foo` has `name`method from attr_accessor. Note: attr_accessor only creates getter declarations in this codebase.
0 commit comments