generateGenericInterceptor function
Emits the full D4.registerBridged{,Static}MethodInterceptor(...) call for
config, including the re-dispatch switch (typeName) over its type-arg
allow-list.
Returns the empty string when GenericInterceptorConfig.typeArgVariants is empty (nothing to re-dispatch). The output is a single statement (trailing newline included) suitable for emission inside the generated interceptor registration function.
Implementation
String generateGenericInterceptor(GenericInterceptorConfig config) {
if (config.typeArgVariants.isEmpty) return '';
final className = config.className;
final methodName = config.methodName;
final ctxIndex = config.contextArgIndex;
final ctxType = config.contextArgType;
// Static re-dispatch targets the class itself; instance re-dispatch targets
// the validated receiver.
final receiver = config.isStatic ? className : 't';
final registerFn = config.isStatic
? 'registerBridgedStaticMethodInterceptor'
: 'registerBridgedMethodInterceptor';
final lambdaParams = config.isStatic
? '(visitor, positional, named, typeArgs)'
: '(visitor, target, positional, named, typeArgs)';
final b = StringBuffer();
b.writeln(' // Re-dispatch $className.$methodName<T> over the declared');
b.writeln(" // type-arg allow-list so the type-erased bridge boundary doesn't");
b.writeln(' // collapse <T> to <dynamic>. Generated by the d4rtgen generic-');
b.writeln(' // interceptor generator.');
b.writeln(" D4.$registerFn('$className', '$methodName',");
b.writeln(' $lambdaParams {');
if (!config.isStatic) {
b.writeln(' final t = target is $className ? target : null;');
b.writeln(' if (t == null) return null;');
}
b.writeln(' if (positional.length <= $ctxIndex) return null;');
b.writeln(' final ctx = positional[$ctxIndex];');
b.writeln(' if (ctx is! $ctxType) return null;');
b.writeln(' final typeName = (typeArgs != null && typeArgs.isNotEmpty)');
b.writeln(' ? typeArgs[0].name');
b.writeln(' : null;');
b.writeln(' final byType = switch (typeName) {');
for (final t in config.typeArgVariants) {
b.writeln(" '$t' => $receiver.$methodName<$t>(ctx),");
}
b.writeln(' _ => null,');
b.writeln(' };');
final fallback = config.fallbackExpr;
if (fallback != null) {
b.writeln(' if (byType != null) return byType;');
b.writeln(' return $fallback;');
} else {
b.writeln(' return byType;');
}
b.writeln(' });');
return b.toString();
}