platform/incubation/reflection/lib/src/mirrors/tem2.dart
2024-12-21 09:53:25 -07:00

269 lines
7.3 KiB
Dart

import 'dart:core';
import 'package:platform_contracts/contracts.dart';
import 'package:platform_reflection/mirrors.dart';
/// Implementation of [MirrorSystemContract] that provides reflection on a set of libraries.
class MirrorSystem implements MirrorSystemContract {
final Map<Uri, LibraryMirrorContract> _libraries;
final IsolateMirrorContract _isolate;
final TypeMirrorContract _dynamicType;
final TypeMirrorContract _voidType;
final TypeMirrorContract _neverType;
MirrorSystem({
required Map<Uri, LibraryMirrorContract> libraries,
required IsolateMirrorContract isolate,
}) : _libraries = libraries,
_isolate = isolate,
_dynamicType = TypeMirror.dynamicType(),
_voidType = TypeMirror.voidType(),
_neverType = TypeMirror(
type: Never,
name: 'Never',
owner: null,
metadata: [],
);
/// Creates a mirror system for the current isolate.
factory MirrorSystem.current() {
// Create core library mirror
final coreLibrary = LibraryMirror.withDeclarations(
name: 'dart:core',
uri: _createDartUri('core'),
owner: null,
);
// Create async library mirror
final asyncLibrary = LibraryMirror.withDeclarations(
name: 'dart:async',
uri: _createDartUri('async'),
owner: null,
);
// Create test library mirror
final testLibrary = LibraryMirror.withDeclarations(
name: 'package:test/test.dart',
uri: Uri.parse('package:test/test.dart'),
owner: null,
);
// Add dependencies to core library
final coreDependencies = [
LibraryDependencyMirror(
isImport: true,
isDeferred: false,
sourceLibrary: coreLibrary,
targetLibrary: asyncLibrary,
prefix: null,
combinators: const [],
),
LibraryDependencyMirror(
isImport: false,
isDeferred: false,
sourceLibrary: coreLibrary,
targetLibrary: asyncLibrary,
prefix: null,
combinators: const [],
),
];
// Create root library with dependencies
final rootLibrary = LibraryMirror(
name: 'dart:core',
uri: _createDartUri('core'),
owner: null,
declarations: const {},
libraryDependencies: coreDependencies,
metadata: [],
);
// Create isolate mirror
final isolate = IsolateMirror.current(rootLibrary);
// Create initial libraries map
final libraries = <Uri, LibraryMirrorContract>{
rootLibrary.uri: rootLibrary,
asyncLibrary.uri: asyncLibrary,
testLibrary.uri: testLibrary,
};
return MirrorSystem(
libraries: libraries,
isolate: isolate,
);
}
/// Creates a URI for a dart: library.
static Uri _createDartUri(String library) {
return Uri(scheme: 'dart', path: library);
}
/// Parses a library name into a URI.
static Uri _parseLibraryName(String name) {
if (name.startsWith('"') && name.endsWith('"')) {
name = name.substring(1, name.length - 1);
}
if (name.startsWith('dart:')) {
final library = name.substring(5);
return _createDartUri(library);
}
return Uri.parse(name);
}
@override
Map<Uri, LibraryMirrorContract> get libraries => Map.unmodifiable(_libraries);
@override
LibraryMirrorContract findLibrary(Symbol libraryName) {
final name = libraryName.toString();
// Remove leading 'Symbol(' and trailing ')'
final normalizedName = name.substring(7, name.length - 1);
final uri = _parseLibraryName(normalizedName);
final library = _libraries[uri];
if (library == null) {
throw ArgumentError('Library not found: $normalizedName');
}
return library;
}
@override
ClassMirrorContract reflectClass(Type type) {
// Check if type is reflectable
if (!Reflector.isReflectable(type)) {
throw ArgumentError('Type is not reflectable: $type');
}
// Create temporary class mirror to serve as owner
final tempMirror = ClassMirror(
type: type,
name: type.toString(),
owner: null,
declarations: const {},
instanceMembers: const {},
staticMembers: const {},
metadata: [],
);
// Get metadata from registry
final properties = Reflector.getPropertyMetadata(type) ?? {};
final methods = Reflector.getMethodMetadata(type) ?? {};
//final constructors = Reflector.getConstructorMetadata(type) ?? [];
// Create declarations map
final declarations = <Symbol, DeclarationMirrorContract>{};
final instanceMembers = <Symbol, MethodMirrorContract>{};
final staticMembers = <Symbol, MethodMirrorContract>{};
// Add properties and methods to declarations
properties.forEach((name, prop) {
declarations[Symbol(name)] = VariableMirror(
name: name,
type: TypeMirror(
type: prop.type,
name: prop.type.toString(),
owner: tempMirror,
metadata: [],
),
owner: tempMirror,
isStatic: false,
isFinal: !prop.isWritable,
isConst: false,
metadata: [],
);
});
methods.forEach((name, method) {
final methodMirror = MethodMirror(
name: name,
owner: tempMirror,
returnType: method.returnsVoid
? TypeMirror.voidType(tempMirror)
: TypeMirror.dynamicType(tempMirror),
parameters: method.parameters
.map((param) => ParameterMirror(
name: param.name,
type: TypeMirror(
type: param.type,
name: param.type.toString(),
owner: tempMirror,
metadata: [],
),
owner: tempMirror,
isOptional: !param.isRequired,
isNamed: param.isNamed,
metadata: [],
))
.toList(),
isStatic: method.isStatic,
metadata: [],
);
declarations[Symbol(name)] = methodMirror;
if (method.isStatic) {
staticMembers[Symbol(name)] = methodMirror;
} else {
instanceMembers[Symbol(name)] = methodMirror;
}
});
// Create class mirror
final mirror = ClassMirror(
type: type,
name: type.toString(),
owner: null,
declarations: declarations,
instanceMembers: instanceMembers,
staticMembers: staticMembers,
metadata: [],
);
// Update owners to point to the real class mirror
declarations.forEach((_, decl) {
if (decl is MutableOwnerMirror) {
decl.setOwner(mirror);
}
});
return mirror;
}
@override
TypeMirrorContract reflectType(Type type) {
// Check if type is reflectable
if (!Reflector.isReflectable(type)) {
throw ArgumentError('Type is not reflectable: $type');
}
return TypeMirror(
type: type,
name: type.toString(),
owner: null,
metadata: [],
);
}
@override
IsolateMirrorContract get isolate => _isolate;
@override
TypeMirrorContract get dynamicType => _dynamicType;
@override
TypeMirrorContract get voidType => _voidType;
@override
TypeMirrorContract get neverType => _neverType;
/// Adds a library to the mirror system.
void addLibrary(LibraryMirrorContract library) {
_libraries[library.uri] = library;
}
/// Removes a library from the mirror system.
void removeLibrary(Uri uri) {
_libraries.remove(uri);
}
}