Skip to content

Commit f5ee3a6

Browse files
author
nickna
committed
feat(ILEmitter): refactor super constructor calls into EmitSuperConstructorCall method
1 parent f095563 commit f5ee3a6

1 file changed

Lines changed: 47 additions & 72 deletions

File tree

Compilation/ILEmitter.Calls.cs

Lines changed: 47 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -34,42 +34,7 @@ protected override void EmitCall(Expr.Call c)
3434
: null;
3535
if (parentCtor != null)
3636
{
37-
// Load this
38-
IL.Emit(OpCodes.Ldarg_0);
39-
40-
// Load arguments with proper type conversions
41-
var parentCtorParams = parentCtor.GetParameters();
42-
for (int i = 0; i < c.Arguments.Count; i++)
43-
{
44-
EmitExpression(c.Arguments[i]);
45-
if (i < parentCtorParams.Length)
46-
{
47-
EmitConversionForParameter(c.Arguments[i], parentCtorParams[i].ParameterType);
48-
}
49-
else
50-
{
51-
EmitBoxIfNeeded(c.Arguments[i]);
52-
}
53-
}
54-
55-
// Pad missing optional arguments with appropriate default values
56-
for (int i = c.Arguments.Count; i < parentCtorParams.Length; i++)
57-
{
58-
EmitDefaultForType(parentCtorParams[i].ParameterType);
59-
}
60-
61-
// Call parent constructor
62-
// Handle generic superclass with type arguments (e.g., extends Box<string>)
63-
ConstructorInfo ctorToCall = parentCtor;
64-
Type? baseType = _ctx.CurrentClassBuilder?.BaseType;
65-
if (baseType != null && baseType.IsGenericType && baseType.IsConstructedGenericType)
66-
{
67-
// Get the constructor for the closed generic type
68-
ctorToCall = TypeBuilder.GetConstructor(baseType, parentCtor);
69-
}
70-
IL.Emit(OpCodes.Call, ctorToCall);
71-
IL.Emit(OpCodes.Ldnull); // constructor call returns undefined
72-
SetStackUnknown();
37+
EmitSuperConstructorCall(parentCtor, c.Arguments);
7338
return;
7439
}
7540

@@ -98,42 +63,7 @@ protected override void EmitCall(Expr.Call c)
9863

9964
if (parentExprCtor != null)
10065
{
101-
// Load this
102-
IL.Emit(OpCodes.Ldarg_0);
103-
104-
// Load arguments with proper type conversions
105-
var parentExprCtorParams = parentExprCtor.GetParameters();
106-
for (int i = 0; i < c.Arguments.Count; i++)
107-
{
108-
EmitExpression(c.Arguments[i]);
109-
if (i < parentExprCtorParams.Length)
110-
{
111-
EmitConversionForParameter(c.Arguments[i], parentExprCtorParams[i].ParameterType);
112-
}
113-
else
114-
{
115-
EmitBoxIfNeeded(c.Arguments[i]);
116-
}
117-
}
118-
119-
// Pad missing optional arguments with appropriate default values
120-
for (int i = c.Arguments.Count; i < parentExprCtorParams.Length; i++)
121-
{
122-
EmitDefaultForType(parentExprCtorParams[i].ParameterType);
123-
}
124-
125-
// Call parent constructor
126-
// Handle generic superclass with type arguments (e.g., extends Box<string>)
127-
ConstructorInfo exprCtorToCall = parentExprCtor;
128-
Type? exprBaseType = _ctx.CurrentClassBuilder?.BaseType;
129-
if (exprBaseType != null && exprBaseType.IsGenericType && exprBaseType.IsConstructedGenericType)
130-
{
131-
// Get the constructor for the closed generic type
132-
exprCtorToCall = TypeBuilder.GetConstructor(exprBaseType, parentExprCtor);
133-
}
134-
IL.Emit(OpCodes.Call, exprCtorToCall);
135-
IL.Emit(OpCodes.Ldnull); // constructor call returns undefined
136-
SetStackUnknown();
66+
EmitSuperConstructorCall(parentExprCtor, c.Arguments);
13767
return;
13868
}
13969
}
@@ -2426,4 +2356,49 @@ private void EmitPromiseInstanceMethodCall(Expr promise, string methodName, List
24262356

24272357
SetStackUnknown();
24282358
}
2359+
2360+
/// <summary>
2361+
/// Emits a super() constructor call with proper argument handling and generic type support.
2362+
/// </summary>
2363+
/// <param name="parentCtor">The parent class constructor to call.</param>
2364+
/// <param name="arguments">The arguments to pass to the constructor.</param>
2365+
private void EmitSuperConstructorCall(ConstructorBuilder parentCtor, List<Expr> arguments)
2366+
{
2367+
// Load this
2368+
IL.Emit(OpCodes.Ldarg_0);
2369+
2370+
// Load arguments with proper type conversions
2371+
var ctorParams = parentCtor.GetParameters();
2372+
for (int i = 0; i < arguments.Count; i++)
2373+
{
2374+
EmitExpression(arguments[i]);
2375+
if (i < ctorParams.Length)
2376+
{
2377+
EmitConversionForParameter(arguments[i], ctorParams[i].ParameterType);
2378+
}
2379+
else
2380+
{
2381+
EmitBoxIfNeeded(arguments[i]);
2382+
}
2383+
}
2384+
2385+
// Pad missing optional arguments with appropriate default values
2386+
for (int i = arguments.Count; i < ctorParams.Length; i++)
2387+
{
2388+
EmitDefaultForType(ctorParams[i].ParameterType);
2389+
}
2390+
2391+
// Call parent constructor
2392+
// Handle generic superclass with type arguments (e.g., extends Box<string>)
2393+
ConstructorInfo ctorToCall = parentCtor;
2394+
Type? baseType = _ctx.CurrentClassBuilder?.BaseType;
2395+
if (baseType != null && baseType.IsGenericType && baseType.IsConstructedGenericType)
2396+
{
2397+
// Get the constructor for the closed generic type
2398+
ctorToCall = TypeBuilder.GetConstructor(baseType, parentCtor);
2399+
}
2400+
IL.Emit(OpCodes.Call, ctorToCall);
2401+
IL.Emit(OpCodes.Ldnull); // constructor call returns undefined
2402+
SetStackUnknown();
2403+
}
24292404
}

0 commit comments

Comments
 (0)