Compare commits
2 commits
7b5290e9d9
...
b1bafb418e
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b1bafb418e | ||
![]() |
05ffbba5ba |
1 changed files with 61 additions and 23 deletions
|
@ -1,7 +1,57 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import '../metadata.dart';
|
import '../metadata.dart';
|
||||||
import 'reflector.dart';
|
import 'reflector.dart';
|
||||||
import '../mirrors/special_types.dart';
|
import '../mirrors.dart';
|
||||||
|
import '../mirrors/mirror_system_impl.dart';
|
||||||
|
import '../exceptions.dart';
|
||||||
|
|
||||||
|
/// A wrapper for constructor factory functions that provides scanner-style toString()
|
||||||
|
class _FactoryWrapper {
|
||||||
|
final Type type;
|
||||||
|
final String constructorName;
|
||||||
|
final MirrorSystemImpl mirrorSystem;
|
||||||
|
final ClassMirror classMirror;
|
||||||
|
|
||||||
|
_FactoryWrapper(this.type, this.constructorName)
|
||||||
|
: mirrorSystem = MirrorSystemImpl.current(),
|
||||||
|
classMirror = MirrorSystemImpl.current().reflectClass(type);
|
||||||
|
|
||||||
|
dynamic noSuchMethod(Invocation invocation) {
|
||||||
|
if (invocation.isMethod && invocation.memberName == #call) {
|
||||||
|
List<dynamic> positionalArgs;
|
||||||
|
Map<Symbol, dynamic> namedArgs;
|
||||||
|
|
||||||
|
// Handle scanner-style call: (List args, [Map namedArgs])
|
||||||
|
if (invocation.positionalArguments.length <= 2 &&
|
||||||
|
invocation.positionalArguments.first is List) {
|
||||||
|
positionalArgs = invocation.positionalArguments[0] as List;
|
||||||
|
namedArgs = invocation.positionalArguments.length > 1
|
||||||
|
? invocation.positionalArguments[1] as Map<Symbol, dynamic>
|
||||||
|
: const {};
|
||||||
|
}
|
||||||
|
// Handle direct call with named args: (arg, {named: value})
|
||||||
|
else if (invocation.namedArguments.isNotEmpty) {
|
||||||
|
positionalArgs = invocation.positionalArguments;
|
||||||
|
namedArgs = invocation.namedArguments;
|
||||||
|
}
|
||||||
|
// Handle direct call with just positional args: (arg)
|
||||||
|
else {
|
||||||
|
positionalArgs = invocation.positionalArguments;
|
||||||
|
namedArgs = const {};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create instance using the mirror system
|
||||||
|
return classMirror
|
||||||
|
.newInstance(Symbol(constructorName), positionalArgs, namedArgs)
|
||||||
|
.reflectee;
|
||||||
|
}
|
||||||
|
return super.noSuchMethod(invocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() =>
|
||||||
|
'Closure: (List<dynamic>, [Map<Symbol, dynamic>?]) => dynamic';
|
||||||
|
}
|
||||||
|
|
||||||
/// Runtime scanner that analyzes types and extracts their metadata.
|
/// Runtime scanner that analyzes types and extracts their metadata.
|
||||||
class Scanner {
|
class Scanner {
|
||||||
|
@ -10,12 +60,12 @@ class Scanner {
|
||||||
|
|
||||||
/// Scans a type and extracts its metadata.
|
/// Scans a type and extracts its metadata.
|
||||||
static void scanType(Type type) {
|
static void scanType(Type type) {
|
||||||
// Get type name and analyze it
|
// First register the type with Reflector
|
||||||
final typeName = type.toString();
|
Reflector.register(type);
|
||||||
final typeInfo = TypeAnalyzer.analyze(type);
|
|
||||||
|
|
||||||
// Register type for reflection
|
// Get mirror system and analyze type
|
||||||
Reflector.registerType(type);
|
final mirrorSystem = MirrorSystemImpl.current();
|
||||||
|
final typeInfo = TypeAnalyzer.analyze(type);
|
||||||
|
|
||||||
// Register properties
|
// Register properties
|
||||||
for (var property in typeInfo.properties) {
|
for (var property in typeInfo.properties) {
|
||||||
|
@ -76,23 +126,11 @@ class Scanner {
|
||||||
/// Creates a constructor factory function for a given type and constructor.
|
/// Creates a constructor factory function for a given type and constructor.
|
||||||
static Function? _createConstructorFactory(
|
static Function? _createConstructorFactory(
|
||||||
Type type, ConstructorInfo constructor) {
|
Type type, ConstructorInfo constructor) {
|
||||||
final typeObj = type as dynamic;
|
final wrapper = _FactoryWrapper(type, constructor.name);
|
||||||
|
return (List<dynamic> args, [Map<Symbol, dynamic>? namedArgs]) {
|
||||||
// Create a factory function that takes a list of positional args and optional named args
|
return wrapper.noSuchMethod(
|
||||||
return (List positionalArgs, [Map<Symbol, dynamic>? namedArgs]) {
|
Invocation.method(#call, args, namedArgs ?? {}),
|
||||||
try {
|
);
|
||||||
if (constructor.name.isEmpty) {
|
|
||||||
// For default constructor
|
|
||||||
return Function.apply(typeObj, positionalArgs, namedArgs);
|
|
||||||
} else {
|
|
||||||
// For named constructor
|
|
||||||
final namedConstructor = typeObj[constructor.name];
|
|
||||||
return Function.apply(namedConstructor, positionalArgs, namedArgs);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
print('Warning: Failed to create instance: $e');
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue