refactor: refactored platform reflection to platform mirrors
This commit is contained in:
parent
3e9de4cbb2
commit
a79809f46b
87 changed files with 1443 additions and 954 deletions
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// A utility class for calling methods with dependency injection.
|
/// A utility class for calling methods with dependency injection.
|
||||||
class BoundMethod {
|
class BoundMethod {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'contextual_binding_builder.dart';
|
import 'contextual_binding_builder.dart';
|
||||||
import 'bound_method.dart';
|
import 'bound_method.dart';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// A builder for defining contextual bindings for the container.
|
/// A builder for defining contextual bindings for the container.
|
||||||
class ContextualBindingBuilder implements ContextualBindingBuilderContract {
|
class ContextualBindingBuilder implements ContextualBindingBuilderContract {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Utility class for container-related operations.
|
/// Utility class for container-related operations.
|
||||||
class Util {
|
class Util {
|
||||||
|
|
|
@ -12,7 +12,7 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
dsr_container: ^0.0.1
|
dsr_container: ^0.0.1
|
||||||
platform_contracts: ^0.1.0
|
platform_contracts: ^0.1.0
|
||||||
platform_reflection: ^0.1.0
|
platform_mirrors: ^0.1.0
|
||||||
# path: ^1.8.0
|
# path: ^1.8.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'collection.dart';
|
import 'collection.dart';
|
||||||
|
|
||||||
/// A proxy class for higher-order collection operations.
|
/// A proxy class for higher-order collection operations.
|
||||||
|
@ -31,7 +31,7 @@ class HigherOrderCollectionProxy<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle object property access
|
// Handle object property access
|
||||||
if (Reflector.isReflectable(item.runtimeType)) {
|
if (ReflectionRegistry.isReflectable(item.runtimeType)) {
|
||||||
try {
|
try {
|
||||||
// Use direct property access
|
// Use direct property access
|
||||||
switch (name) {
|
switch (name) {
|
||||||
|
@ -57,7 +57,7 @@ class HigherOrderCollectionProxy<T> {
|
||||||
if (item == null) return null;
|
if (item == null) return null;
|
||||||
|
|
||||||
// Handle method calls
|
// Handle method calls
|
||||||
if (Reflector.isReflectable(item.runtimeType)) {
|
if (ReflectionRegistry.isReflectable(item.runtimeType)) {
|
||||||
try {
|
try {
|
||||||
// Use direct method invocation
|
// Use direct method invocation
|
||||||
switch (_method) {
|
switch (_method) {
|
||||||
|
@ -107,7 +107,7 @@ class HigherOrderCollectionProxy<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle object property access
|
// Handle object property access
|
||||||
if (Reflector.isReflectable(item.runtimeType)) {
|
if (ReflectionRegistry.isReflectable(item.runtimeType)) {
|
||||||
try {
|
try {
|
||||||
// Use direct property access
|
// Use direct property access
|
||||||
switch (property) {
|
switch (property) {
|
||||||
|
@ -149,7 +149,7 @@ class HigherOrderCollectionProxy<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle object property access
|
// Handle object property access
|
||||||
if (Reflector.isReflectable(item.runtimeType)) {
|
if (ReflectionRegistry.isReflectable(item.runtimeType)) {
|
||||||
try {
|
try {
|
||||||
// Use direct property access
|
// Use direct property access
|
||||||
switch (property) {
|
switch (property) {
|
||||||
|
@ -188,8 +188,9 @@ class HigherOrderCollectionProxy<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle object property access
|
// Handle object property access
|
||||||
if (Reflector.isReflectable(item.runtimeType)) {
|
if (ReflectionRegistry.isReflectable(item.runtimeType)) {
|
||||||
final metadata = Reflector.getPropertyMetadata(item.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getPropertyMetadata(item.runtimeType);
|
||||||
return metadata?.containsKey(property) ?? false;
|
return metadata?.containsKey(property) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ environment:
|
||||||
dependencies:
|
dependencies:
|
||||||
meta: ^1.9.0
|
meta: ^1.9.0
|
||||||
platform_contracts: ^0.1.0
|
platform_contracts: ^0.1.0
|
||||||
platform_reflection: ^0.1.0
|
platform_mirrors: ^0.1.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^2.1.0
|
lints: ^2.1.0
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_collections/src/collection.dart';
|
import 'package:platform_collections/src/collection.dart';
|
||||||
import 'package:platform_collections/src/higher_order_collection_proxy.dart';
|
import 'package:platform_collections/src/higher_order_collection_proxy.dart';
|
||||||
|
@ -24,16 +24,16 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
// Register TestModel for reflection
|
// Register TestModel for reflection
|
||||||
Reflector.registerType(TestModel);
|
ReflectionRegistry.registerType(TestModel);
|
||||||
|
|
||||||
// Register properties
|
// Register properties
|
||||||
Reflector.registerProperty(TestModel, 'name', String,
|
ReflectionRegistry.registerProperty(TestModel, 'name', String,
|
||||||
isReadable: true, isWritable: true);
|
isReadable: true, isWritable: true);
|
||||||
Reflector.registerProperty(TestModel, 'age', int,
|
ReflectionRegistry.registerProperty(TestModel, 'age', int,
|
||||||
isReadable: true, isWritable: true);
|
isReadable: true, isWritable: true);
|
||||||
|
|
||||||
// Register methods with proper return types
|
// Register methods with proper return types
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestModel,
|
TestModel,
|
||||||
'greet',
|
'greet',
|
||||||
[], // no parameters
|
[], // no parameters
|
||||||
|
@ -41,7 +41,7 @@ void main() {
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestModel,
|
TestModel,
|
||||||
'setAge',
|
'setAge',
|
||||||
[int], // takes an int parameter
|
[int], // takes an int parameter
|
||||||
|
@ -60,17 +60,17 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reflection registration is correct', () {
|
test('reflection registration is correct', () {
|
||||||
expect(Reflector.isReflectable(TestModel), isTrue,
|
expect(ReflectionRegistry.isReflectable(TestModel), isTrue,
|
||||||
reason: 'TestModel should be reflectable');
|
reason: 'TestModel should be reflectable');
|
||||||
|
|
||||||
final props = Reflector.getPropertyMetadata(TestModel);
|
final props = ReflectionRegistry.getPropertyMetadata(TestModel);
|
||||||
expect(props, isNotNull, reason: 'Property metadata should exist');
|
expect(props, isNotNull, reason: 'Property metadata should exist');
|
||||||
expect(props!['name'], isNotNull,
|
expect(props!['name'], isNotNull,
|
||||||
reason: 'name property should be registered');
|
reason: 'name property should be registered');
|
||||||
expect(props['age'], isNotNull,
|
expect(props['age'], isNotNull,
|
||||||
reason: 'age property should be registered');
|
reason: 'age property should be registered');
|
||||||
|
|
||||||
final methods = Reflector.getMethodMetadata(TestModel);
|
final methods = ReflectionRegistry.getMethodMetadata(TestModel);
|
||||||
expect(methods, isNotNull, reason: 'Method metadata should exist');
|
expect(methods, isNotNull, reason: 'Method metadata should exist');
|
||||||
expect(methods!['greet'], isNotNull,
|
expect(methods!['greet'], isNotNull,
|
||||||
reason: 'greet method should be registered');
|
reason: 'greet method should be registered');
|
||||||
|
@ -155,7 +155,7 @@ void main() {
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
// Clean up reflection metadata after each test
|
// Clean up reflection metadata after each test
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Interface for objects that can provide methods to be mixed in
|
/// Interface for objects that can provide methods to be mixed in
|
||||||
abstract class MacroProvider {
|
abstract class MacroProvider {
|
||||||
|
|
|
@ -7,7 +7,7 @@ environment:
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
platform_contracts: ^0.1.0
|
platform_contracts: ^0.1.0
|
||||||
platform_reflection: ^0.1.0
|
platform_mirrors: ^0.1.0
|
||||||
meta: ^1.9.0
|
meta: ^1.9.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_macroable/platform_macroable.dart';
|
import 'package:platform_macroable/platform_macroable.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
class TestClass with Macroable {}
|
class TestClass with Macroable {}
|
||||||
|
|
|
@ -48,7 +48,7 @@ final value = mirror.getField(#prop).reflectee;
|
||||||
mirror.invoke(#method, [42]);
|
mirror.invoke(#method, [42]);
|
||||||
|
|
||||||
// Platform Reflection
|
// Platform Reflection
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
final reflector = RuntimeReflector.instance;
|
final reflector = RuntimeReflector.instance;
|
||||||
final instance = reflector.createInstance(MyClass, positionalArgs: []) as MyClass;
|
final instance = reflector.createInstance(MyClass, positionalArgs: []) as MyClass;
|
||||||
|
@ -94,7 +94,7 @@ To migrate from dart:mirrors to Platform Reflection:
|
||||||
import 'dart:mirrors';
|
import 'dart:mirrors';
|
||||||
|
|
||||||
// After
|
// After
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Add registration for each reflectable class:
|
2. Add registration for each reflectable class:
|
|
@ -22,7 +22,7 @@ dependencies:
|
||||||
### 1. Define and Register a Class
|
### 1. Define and Register a Class
|
||||||
|
|
||||||
```dart
|
```dart
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
class User {
|
class User {
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
// Custom annotation to demonstrate metadata
|
// Custom annotation to demonstrate metadata
|
||||||
class Validate {
|
class Validate {
|
||||||
|
@ -73,17 +73,17 @@ class User extends Entity {
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
// Register classes for reflection
|
// Register classes for reflection
|
||||||
Reflector.register(Identifiable);
|
ReflectionRegistry.register(Identifiable);
|
||||||
Reflector.register(Entity);
|
ReflectionRegistry.register(Entity);
|
||||||
Reflector.register(User);
|
ReflectionRegistry.register(User);
|
||||||
Reflector.register(Container);
|
ReflectionRegistry.register(Container);
|
||||||
|
|
||||||
// Register Container<int> specifically for reflection
|
// Register Container<int> specifically for reflection
|
||||||
final container = Container<int>(42);
|
final container = Container<int>(42);
|
||||||
Reflector.register(container.runtimeType);
|
ReflectionRegistry.register(container.runtimeType);
|
||||||
|
|
||||||
// Register property metadata directly
|
// Register property metadata directly
|
||||||
Reflector.registerPropertyMetadata(
|
ReflectionRegistry.registerPropertyMetadata(
|
||||||
User,
|
User,
|
||||||
'name',
|
'name',
|
||||||
PropertyMetadata(
|
PropertyMetadata(
|
||||||
|
@ -95,7 +95,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerPropertyMetadata(
|
ReflectionRegistry.registerPropertyMetadata(
|
||||||
User,
|
User,
|
||||||
'age',
|
'age',
|
||||||
PropertyMetadata(
|
PropertyMetadata(
|
||||||
|
@ -106,7 +106,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerPropertyMetadata(
|
ReflectionRegistry.registerPropertyMetadata(
|
||||||
User,
|
User,
|
||||||
'tags',
|
'tags',
|
||||||
PropertyMetadata(
|
PropertyMetadata(
|
||||||
|
@ -117,7 +117,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerPropertyMetadata(
|
ReflectionRegistry.registerPropertyMetadata(
|
||||||
User,
|
User,
|
||||||
'id',
|
'id',
|
||||||
PropertyMetadata(
|
PropertyMetadata(
|
||||||
|
@ -129,7 +129,7 @@ void main() async {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register User methods
|
// Register User methods
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
User,
|
User,
|
||||||
'greet',
|
'greet',
|
||||||
[String],
|
[String],
|
||||||
|
@ -138,7 +138,7 @@ void main() async {
|
||||||
isRequired: [false],
|
isRequired: [false],
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
User,
|
User,
|
||||||
'addTag',
|
'addTag',
|
||||||
[String],
|
[String],
|
||||||
|
@ -147,7 +147,7 @@ void main() async {
|
||||||
isRequired: [true],
|
isRequired: [true],
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
User,
|
User,
|
||||||
'getName',
|
'getName',
|
||||||
[],
|
[],
|
||||||
|
@ -155,7 +155,7 @@ void main() async {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register constructors with creators
|
// Register constructors with creators
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
User,
|
User,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String, String, int, List],
|
parameterTypes: [String, String, int, List],
|
||||||
|
@ -169,7 +169,7 @@ void main() async {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
User,
|
User,
|
||||||
'guest',
|
'guest',
|
||||||
creator: () => User.guest(),
|
creator: () => User.guest(),
|
|
@ -2,17 +2,37 @@ library mirrors;
|
||||||
|
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
|
|
||||||
import 'src/mirrors/mirror_system.dart';
|
import 'src/core/mirror_system.dart';
|
||||||
import 'src/mirrors/instance_mirror.dart';
|
import 'src/mirrors/instance_mirror.dart';
|
||||||
|
|
||||||
/// Core
|
/// Annotations
|
||||||
export 'src/core/library_scanner.dart';
|
export 'src/annotations/reflectable.dart';
|
||||||
export 'src/core/reflector.dart';
|
|
||||||
export 'src/core/runtime_reflector.dart';
|
|
||||||
export 'src/core/scanner.dart';
|
|
||||||
|
|
||||||
/// MirrorSystem
|
/// Core
|
||||||
export 'src/mirrors/mirror_system.dart';
|
export 'src/core/mirror_system.dart';
|
||||||
|
|
||||||
|
/// Discovery
|
||||||
|
export 'src/discovery/type_analyzer.dart';
|
||||||
|
export 'src/discovery/library_scanner.dart';
|
||||||
|
export 'src/discovery/scanner.dart';
|
||||||
|
|
||||||
|
/// Discovery Models
|
||||||
|
export 'src/discovery/models/models.dart';
|
||||||
|
|
||||||
|
/// Exceptions
|
||||||
|
export 'src/exceptions/invalid_arguments_exception.dart';
|
||||||
|
export 'src/exceptions/member_not_found_exception.dart';
|
||||||
|
export 'src/exceptions/not_reflectable_exception.dart';
|
||||||
|
export 'src/exceptions/reflection_exception.dart';
|
||||||
|
|
||||||
|
/// Metadata
|
||||||
|
export 'src/metadata/constructor_metadata.dart';
|
||||||
|
export 'src/metadata/function_metadata.dart';
|
||||||
|
export 'src/metadata/method_metadata.dart';
|
||||||
|
export 'src/metadata/parameter_metadata.dart';
|
||||||
|
export 'src/metadata/property_metadata.dart';
|
||||||
|
export 'src/metadata/type_metadata.dart';
|
||||||
|
export 'src/metadata/type_parameter_metadata.dart';
|
||||||
|
|
||||||
/// Mirrors
|
/// Mirrors
|
||||||
export 'src/mirrors/base_mirror.dart';
|
export 'src/mirrors/base_mirror.dart';
|
||||||
|
@ -28,15 +48,14 @@ export 'src/mirrors/type_mirror.dart';
|
||||||
export 'src/mirrors/type_variable_mirror.dart';
|
export 'src/mirrors/type_variable_mirror.dart';
|
||||||
export 'src/mirrors/variable_mirror.dart';
|
export 'src/mirrors/variable_mirror.dart';
|
||||||
|
|
||||||
|
/// Reflector
|
||||||
|
export 'src/reflector/runtime_reflector.dart';
|
||||||
|
|
||||||
|
/// Registry
|
||||||
|
export 'src/registry/reflection_registry.dart';
|
||||||
|
|
||||||
/// Types
|
/// Types
|
||||||
export 'src/mirrors/special_types.dart';
|
export 'src/types/special_types.dart';
|
||||||
|
|
||||||
/// Metadata and Annotations
|
|
||||||
export 'src/annotations.dart';
|
|
||||||
export 'src/metadata.dart';
|
|
||||||
|
|
||||||
/// Exceptions
|
|
||||||
export 'src/exceptions.dart';
|
|
||||||
|
|
||||||
/// Reflects an instance.
|
/// Reflects an instance.
|
||||||
InstanceMirrorContract reflect(dynamic reflectee) {
|
InstanceMirrorContract reflect(dynamic reflectee) {
|
7
packages/mirrors/lib/src/annotations/reflectable.dart
Normal file
7
packages/mirrors/lib/src/annotations/reflectable.dart
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/// Marks a class as reflectable, allowing runtime reflection capabilities.
|
||||||
|
class Reflectable {
|
||||||
|
const Reflectable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The annotation used to mark classes as reflectable.
|
||||||
|
const reflectable = Reflectable();
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [MirrorSystemContract] that provides reflection on a set of libraries.
|
/// Implementation of [MirrorSystemContract] that provides reflection on a set of libraries.
|
||||||
class MirrorSystem implements MirrorSystemContract {
|
class MirrorSystem implements MirrorSystemContract {
|
||||||
|
@ -162,7 +162,7 @@ class MirrorSystem implements MirrorSystemContract {
|
||||||
|
|
||||||
ClassMirrorContract _createClassMirror(Type type) {
|
ClassMirrorContract _createClassMirror(Type type) {
|
||||||
// Check if type is reflectable
|
// Check if type is reflectable
|
||||||
if (!Reflector.isReflectable(type)) {
|
if (!ReflectionRegistry.isReflectable(type)) {
|
||||||
throw ArgumentError('Type is not reflectable: $type');
|
throw ArgumentError('Type is not reflectable: $type');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,8 +178,8 @@ class MirrorSystem implements MirrorSystemContract {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get metadata from registry
|
// Get metadata from registry
|
||||||
final properties = Reflector.getPropertyMetadata(type) ?? {};
|
final properties = ReflectionRegistry.getPropertyMetadata(type) ?? {};
|
||||||
final methods = Reflector.getMethodMetadata(type) ?? {};
|
final methods = ReflectionRegistry.getMethodMetadata(type) ?? {};
|
||||||
|
|
||||||
// Create declarations map
|
// Create declarations map
|
||||||
final declarations = <Symbol, DeclarationMirrorContract>{};
|
final declarations = <Symbol, DeclarationMirrorContract>{};
|
||||||
|
@ -261,7 +261,7 @@ class MirrorSystem implements MirrorSystemContract {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
TypeMirrorContract reflectType(Type type) {
|
TypeMirrorContract reflectType(Type type) {
|
||||||
if (!Reflector.isReflectable(type)) {
|
if (!ReflectionRegistry.isReflectable(type)) {
|
||||||
throw ArgumentError('Type is not reflectable: $type');
|
throw ArgumentError('Type is not reflectable: $type');
|
||||||
}
|
}
|
||||||
return _getOrCreateTypeMirror(type);
|
return _getOrCreateTypeMirror(type);
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Runtime scanner that analyzes libraries and extracts their metadata.
|
/// Runtime scanner that analyzes libraries and extracts their metadata.
|
||||||
class LibraryScanner {
|
class LibraryScanner {
|
||||||
|
@ -203,73 +203,3 @@ class LibraryAnalyzer {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about a library.
|
|
||||||
class LibraryInfo {
|
|
||||||
final Uri uri;
|
|
||||||
final List<FunctionInfo> topLevelFunctions;
|
|
||||||
final List<VariableInfo> topLevelVariables;
|
|
||||||
final List<DependencyInfo> dependencies;
|
|
||||||
final List<DependencyInfo> exports;
|
|
||||||
|
|
||||||
LibraryInfo({
|
|
||||||
required this.uri,
|
|
||||||
required this.topLevelFunctions,
|
|
||||||
required this.topLevelVariables,
|
|
||||||
required this.dependencies,
|
|
||||||
required this.exports,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about a top-level function.
|
|
||||||
class FunctionInfo {
|
|
||||||
final String name;
|
|
||||||
final List<Type> parameterTypes;
|
|
||||||
final List<ParameterMetadata> parameters;
|
|
||||||
final bool returnsVoid;
|
|
||||||
final Type returnType;
|
|
||||||
final bool isPrivate;
|
|
||||||
|
|
||||||
FunctionInfo({
|
|
||||||
required this.name,
|
|
||||||
required this.parameterTypes,
|
|
||||||
required this.parameters,
|
|
||||||
required this.returnsVoid,
|
|
||||||
required this.returnType,
|
|
||||||
required this.isPrivate,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about a top-level variable.
|
|
||||||
class VariableInfo {
|
|
||||||
final String name;
|
|
||||||
final Type type;
|
|
||||||
final bool isFinal;
|
|
||||||
final bool isConst;
|
|
||||||
final bool isPrivate;
|
|
||||||
|
|
||||||
VariableInfo({
|
|
||||||
required this.name,
|
|
||||||
required this.type,
|
|
||||||
required this.isFinal,
|
|
||||||
required this.isConst,
|
|
||||||
required this.isPrivate,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about a library dependency.
|
|
||||||
class DependencyInfo {
|
|
||||||
final Uri uri;
|
|
||||||
final String? prefix;
|
|
||||||
final bool isDeferred;
|
|
||||||
final List<String> showCombinators;
|
|
||||||
final List<String> hideCombinators;
|
|
||||||
|
|
||||||
DependencyInfo({
|
|
||||||
required this.uri,
|
|
||||||
required this.prefix,
|
|
||||||
required this.isDeferred,
|
|
||||||
required this.showCombinators,
|
|
||||||
required this.hideCombinators,
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
import '../../metadata/parameter_metadata.dart';
|
||||||
|
|
||||||
|
/// Information about a constructor.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a constructor including:
|
||||||
|
/// - The constructor's name
|
||||||
|
/// - Parameter types and metadata
|
||||||
|
class ConstructorInfo {
|
||||||
|
/// The name of the constructor
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// List of parameter types for this constructor
|
||||||
|
final List<Type> parameterTypes;
|
||||||
|
|
||||||
|
/// List of parameter metadata for this constructor
|
||||||
|
final List<ParameterMetadata> parameters;
|
||||||
|
|
||||||
|
/// Creates a new [ConstructorInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [name]: The constructor's name
|
||||||
|
/// - [parameterTypes]: List of parameter types
|
||||||
|
/// - [parameters]: List of parameter metadata
|
||||||
|
const ConstructorInfo({
|
||||||
|
required this.name,
|
||||||
|
required this.parameterTypes,
|
||||||
|
required this.parameters,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (name.isNotEmpty) {
|
||||||
|
buffer.write('$name(');
|
||||||
|
} else {
|
||||||
|
buffer.write('(');
|
||||||
|
}
|
||||||
|
buffer.write(parameters.join(', '));
|
||||||
|
buffer.write(')');
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is ConstructorInfo &&
|
||||||
|
other.name == name &&
|
||||||
|
_listEquals(other.parameterTypes, parameterTypes) &&
|
||||||
|
_listEquals(other.parameters, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
name,
|
||||||
|
Object.hashAll(parameterTypes),
|
||||||
|
Object.hashAll(parameters),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/// Information about a library dependency.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a dependency including:
|
||||||
|
/// - The dependency's URI
|
||||||
|
/// - Import prefix (if any)
|
||||||
|
/// - Whether it's deferred
|
||||||
|
/// - Show/hide combinators
|
||||||
|
class DependencyInfo {
|
||||||
|
/// The URI of the dependency
|
||||||
|
final Uri uri;
|
||||||
|
|
||||||
|
/// The prefix used for this dependency (e.g., 'as prefix')
|
||||||
|
final String? prefix;
|
||||||
|
|
||||||
|
/// Whether this dependency is deferred
|
||||||
|
final bool isDeferred;
|
||||||
|
|
||||||
|
/// List of identifiers shown from this dependency
|
||||||
|
final List<String> showCombinators;
|
||||||
|
|
||||||
|
/// List of identifiers hidden from this dependency
|
||||||
|
final List<String> hideCombinators;
|
||||||
|
|
||||||
|
/// Creates a new [DependencyInfo] instance.
|
||||||
|
///
|
||||||
|
/// Required parameters:
|
||||||
|
/// - [uri]: The dependency's URI
|
||||||
|
/// - [prefix]: The prefix used for this dependency (can be null)
|
||||||
|
/// - [isDeferred]: Whether the dependency is deferred
|
||||||
|
/// - [showCombinators]: List of shown identifiers
|
||||||
|
/// - [hideCombinators]: List of hidden identifiers
|
||||||
|
const DependencyInfo({
|
||||||
|
required this.uri,
|
||||||
|
required this.prefix,
|
||||||
|
required this.isDeferred,
|
||||||
|
required this.showCombinators,
|
||||||
|
required this.hideCombinators,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (isDeferred) buffer.write('deferred ');
|
||||||
|
buffer.write('$uri');
|
||||||
|
if (prefix != null) buffer.write(' as $prefix');
|
||||||
|
if (showCombinators.isNotEmpty)
|
||||||
|
buffer.write(' show ${showCombinators.join(", ")}');
|
||||||
|
if (hideCombinators.isNotEmpty)
|
||||||
|
buffer.write(' hide ${hideCombinators.join(", ")}');
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is DependencyInfo &&
|
||||||
|
other.uri == uri &&
|
||||||
|
other.prefix == prefix &&
|
||||||
|
other.isDeferred == isDeferred &&
|
||||||
|
_listEquals(other.showCombinators, showCombinators) &&
|
||||||
|
_listEquals(other.hideCombinators, hideCombinators);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
uri,
|
||||||
|
prefix,
|
||||||
|
isDeferred,
|
||||||
|
Object.hashAll(showCombinators),
|
||||||
|
Object.hashAll(hideCombinators),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
82
packages/mirrors/lib/src/discovery/models/function_info.dart
Normal file
82
packages/mirrors/lib/src/discovery/models/function_info.dart
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
import '../../metadata/parameter_metadata.dart';
|
||||||
|
|
||||||
|
/// Information about a top-level function.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a function including:
|
||||||
|
/// - The function's name
|
||||||
|
/// - Parameter types and metadata
|
||||||
|
/// - Return type information
|
||||||
|
/// - Privacy status
|
||||||
|
class FunctionInfo {
|
||||||
|
/// The name of the function
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// List of parameter types for this function
|
||||||
|
final List<Type> parameterTypes;
|
||||||
|
|
||||||
|
/// List of parameter metadata for this function
|
||||||
|
final List<ParameterMetadata> parameters;
|
||||||
|
|
||||||
|
/// Whether this function returns void
|
||||||
|
final bool returnsVoid;
|
||||||
|
|
||||||
|
/// The return type of this function
|
||||||
|
final Type returnType;
|
||||||
|
|
||||||
|
/// Whether this function is private
|
||||||
|
final bool isPrivate;
|
||||||
|
|
||||||
|
/// Creates a new [FunctionInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [name]: The function's name
|
||||||
|
/// - [parameterTypes]: List of parameter types
|
||||||
|
/// - [parameters]: List of parameter metadata
|
||||||
|
/// - [returnsVoid]: Whether the function returns void
|
||||||
|
/// - [returnType]: The function's return type
|
||||||
|
/// - [isPrivate]: Whether the function is private
|
||||||
|
const FunctionInfo({
|
||||||
|
required this.name,
|
||||||
|
required this.parameterTypes,
|
||||||
|
required this.parameters,
|
||||||
|
required this.returnsVoid,
|
||||||
|
required this.returnType,
|
||||||
|
required this.isPrivate,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'FunctionInfo(name: $name, returnType: $returnType)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is FunctionInfo &&
|
||||||
|
other.name == name &&
|
||||||
|
_listEquals(other.parameterTypes, parameterTypes) &&
|
||||||
|
_listEquals(other.parameters, parameters) &&
|
||||||
|
other.returnsVoid == returnsVoid &&
|
||||||
|
other.returnType == returnType &&
|
||||||
|
other.isPrivate == isPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
name,
|
||||||
|
Object.hashAll(parameterTypes),
|
||||||
|
Object.hashAll(parameters),
|
||||||
|
returnsVoid,
|
||||||
|
returnType,
|
||||||
|
isPrivate,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
78
packages/mirrors/lib/src/discovery/models/library_info.dart
Normal file
78
packages/mirrors/lib/src/discovery/models/library_info.dart
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
import 'function_info.dart';
|
||||||
|
import 'variable_info.dart';
|
||||||
|
import 'dependency_info.dart';
|
||||||
|
|
||||||
|
/// Information about a library.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a Dart library including:
|
||||||
|
/// - The library's URI
|
||||||
|
/// - Top-level functions defined in the library
|
||||||
|
/// - Top-level variables defined in the library
|
||||||
|
/// - Dependencies (imports) used by the library
|
||||||
|
/// - Exports exposed by the library
|
||||||
|
class LibraryInfo {
|
||||||
|
/// The URI identifying this library
|
||||||
|
final Uri uri;
|
||||||
|
|
||||||
|
/// List of top-level functions defined in this library
|
||||||
|
final List<FunctionInfo> topLevelFunctions;
|
||||||
|
|
||||||
|
/// List of top-level variables defined in this library
|
||||||
|
final List<VariableInfo> topLevelVariables;
|
||||||
|
|
||||||
|
/// List of dependencies (imports) used by this library
|
||||||
|
final List<DependencyInfo> dependencies;
|
||||||
|
|
||||||
|
/// List of exports exposed by this library
|
||||||
|
final List<DependencyInfo> exports;
|
||||||
|
|
||||||
|
/// Creates a new [LibraryInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [uri]: The URI identifying this library
|
||||||
|
/// - [topLevelFunctions]: List of top-level functions
|
||||||
|
/// - [topLevelVariables]: List of top-level variables
|
||||||
|
/// - [dependencies]: List of dependencies (imports)
|
||||||
|
/// - [exports]: List of exports
|
||||||
|
const LibraryInfo({
|
||||||
|
required this.uri,
|
||||||
|
required this.topLevelFunctions,
|
||||||
|
required this.topLevelVariables,
|
||||||
|
required this.dependencies,
|
||||||
|
required this.exports,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'LibraryInfo(uri: $uri)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is LibraryInfo &&
|
||||||
|
other.uri == uri &&
|
||||||
|
_listEquals(other.topLevelFunctions, topLevelFunctions) &&
|
||||||
|
_listEquals(other.topLevelVariables, topLevelVariables) &&
|
||||||
|
_listEquals(other.dependencies, dependencies) &&
|
||||||
|
_listEquals(other.exports, exports);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
uri,
|
||||||
|
Object.hashAll(topLevelFunctions),
|
||||||
|
Object.hashAll(topLevelVariables),
|
||||||
|
Object.hashAll(dependencies),
|
||||||
|
Object.hashAll(exports),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
89
packages/mirrors/lib/src/discovery/models/method_info.dart
Normal file
89
packages/mirrors/lib/src/discovery/models/method_info.dart
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
import '../../metadata/parameter_metadata.dart';
|
||||||
|
|
||||||
|
/// Information about a method.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a method including:
|
||||||
|
/// - The method's name
|
||||||
|
/// - Parameter types and metadata
|
||||||
|
/// - Return type information
|
||||||
|
/// - Whether it's static
|
||||||
|
class MethodInfo {
|
||||||
|
/// The name of the method
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// List of parameter types for this method
|
||||||
|
final List<Type> parameterTypes;
|
||||||
|
|
||||||
|
/// List of parameter metadata for this method
|
||||||
|
final List<ParameterMetadata> parameters;
|
||||||
|
|
||||||
|
/// Whether this method returns void
|
||||||
|
final bool returnsVoid;
|
||||||
|
|
||||||
|
/// The return type of this method
|
||||||
|
final Type returnType;
|
||||||
|
|
||||||
|
/// Whether this method is static
|
||||||
|
final bool isStatic;
|
||||||
|
|
||||||
|
/// Creates a new [MethodInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [name]: The method's name
|
||||||
|
/// - [parameterTypes]: List of parameter types
|
||||||
|
/// - [parameters]: List of parameter metadata
|
||||||
|
/// - [returnsVoid]: Whether the method returns void
|
||||||
|
/// - [returnType]: The method's return type
|
||||||
|
/// - [isStatic]: Whether the method is static
|
||||||
|
const MethodInfo({
|
||||||
|
required this.name,
|
||||||
|
required this.parameterTypes,
|
||||||
|
required this.parameters,
|
||||||
|
required this.returnsVoid,
|
||||||
|
required this.returnType,
|
||||||
|
required this.isStatic,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (isStatic) buffer.write('static ');
|
||||||
|
buffer.write('$returnType $name(');
|
||||||
|
buffer.write(parameters.join(', '));
|
||||||
|
buffer.write(')');
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is MethodInfo &&
|
||||||
|
other.name == name &&
|
||||||
|
_listEquals(other.parameterTypes, parameterTypes) &&
|
||||||
|
_listEquals(other.parameters, parameters) &&
|
||||||
|
other.returnsVoid == returnsVoid &&
|
||||||
|
other.returnType == returnType &&
|
||||||
|
other.isStatic == isStatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
name,
|
||||||
|
Object.hashAll(parameterTypes),
|
||||||
|
Object.hashAll(parameters),
|
||||||
|
returnsVoid,
|
||||||
|
returnType,
|
||||||
|
isStatic,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
9
packages/mirrors/lib/src/discovery/models/models.dart
Normal file
9
packages/mirrors/lib/src/discovery/models/models.dart
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
export 'constructor_info.dart';
|
||||||
|
export 'dependency_info.dart';
|
||||||
|
export 'function_info.dart';
|
||||||
|
export 'library_info.dart';
|
||||||
|
export 'method_info.dart';
|
||||||
|
export 'parameter_info.dart';
|
||||||
|
export 'property_info.dart';
|
||||||
|
export 'type_info.dart';
|
||||||
|
export 'variable_info.dart';
|
100
packages/mirrors/lib/src/discovery/models/parameter_info.dart
Normal file
100
packages/mirrors/lib/src/discovery/models/parameter_info.dart
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
import 'type_info.dart';
|
||||||
|
|
||||||
|
/// Information about a function parameter.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a parameter including:
|
||||||
|
/// - The parameter's name
|
||||||
|
/// - Type
|
||||||
|
/// - Whether it's required, named, or optional
|
||||||
|
/// - Default value
|
||||||
|
/// - Any annotations applied to the parameter
|
||||||
|
class ParameterInfo {
|
||||||
|
/// The name of the parameter
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the parameter
|
||||||
|
final TypeInfo type;
|
||||||
|
|
||||||
|
/// Whether this parameter is required
|
||||||
|
final bool isRequired;
|
||||||
|
|
||||||
|
/// Whether this parameter is named
|
||||||
|
final bool isNamed;
|
||||||
|
|
||||||
|
/// Whether this parameter is optional
|
||||||
|
final bool isOptional;
|
||||||
|
|
||||||
|
/// The default value for this parameter, if any
|
||||||
|
final Object? defaultValue;
|
||||||
|
|
||||||
|
/// List of annotations applied to this parameter
|
||||||
|
final List<Object> annotations;
|
||||||
|
|
||||||
|
/// Creates a new [ParameterInfo] instance.
|
||||||
|
///
|
||||||
|
/// Required parameters:
|
||||||
|
/// - [name]: The parameter's name
|
||||||
|
/// - [type]: The parameter's type
|
||||||
|
/// - [isRequired]: Whether the parameter is required
|
||||||
|
/// - [isNamed]: Whether the parameter is named
|
||||||
|
/// - [isOptional]: Whether the parameter is optional
|
||||||
|
/// - [annotations]: List of annotations on the parameter
|
||||||
|
///
|
||||||
|
/// Optional parameters:
|
||||||
|
/// - [defaultValue]: The default value for this parameter
|
||||||
|
const ParameterInfo({
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
required this.isRequired,
|
||||||
|
required this.isNamed,
|
||||||
|
required this.isOptional,
|
||||||
|
required this.annotations,
|
||||||
|
this.defaultValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (isNamed) buffer.write(isRequired ? 'required ' : '');
|
||||||
|
buffer.write('$type $name');
|
||||||
|
if (defaultValue != null) {
|
||||||
|
buffer.write(' = $defaultValue');
|
||||||
|
}
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is ParameterInfo &&
|
||||||
|
other.name == name &&
|
||||||
|
other.type == type &&
|
||||||
|
other.isRequired == isRequired &&
|
||||||
|
other.isNamed == isNamed &&
|
||||||
|
other.isOptional == isOptional &&
|
||||||
|
other.defaultValue == defaultValue &&
|
||||||
|
_listEquals(other.annotations, annotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
isRequired,
|
||||||
|
isNamed,
|
||||||
|
isOptional,
|
||||||
|
defaultValue,
|
||||||
|
Object.hashAll(annotations),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
48
packages/mirrors/lib/src/discovery/models/property_info.dart
Normal file
48
packages/mirrors/lib/src/discovery/models/property_info.dart
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
/// Information about a property.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a property including:
|
||||||
|
/// - The property's name
|
||||||
|
/// - Type
|
||||||
|
/// - Whether it's final
|
||||||
|
class PropertyInfo {
|
||||||
|
/// The name of the property
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the property
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Whether this property is final
|
||||||
|
final bool isFinal;
|
||||||
|
|
||||||
|
/// Creates a new [PropertyInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [name]: The property's name
|
||||||
|
/// - [type]: The property's type
|
||||||
|
/// - [isFinal]: Whether the property is final
|
||||||
|
const PropertyInfo({
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
required this.isFinal,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (isFinal) buffer.write('final ');
|
||||||
|
buffer.write('$type $name');
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is PropertyInfo &&
|
||||||
|
other.name == name &&
|
||||||
|
other.type == type &&
|
||||||
|
other.isFinal == isFinal;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(name, type, isFinal);
|
||||||
|
}
|
70
packages/mirrors/lib/src/discovery/models/type_info.dart
Normal file
70
packages/mirrors/lib/src/discovery/models/type_info.dart
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
import 'property_info.dart';
|
||||||
|
import 'method_info.dart';
|
||||||
|
import 'constructor_info.dart';
|
||||||
|
|
||||||
|
/// Information about a type.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a type including:
|
||||||
|
/// - The type itself
|
||||||
|
/// - Properties defined on the type
|
||||||
|
/// - Methods defined on the type
|
||||||
|
/// - Constructors defined on the type
|
||||||
|
class TypeInfo {
|
||||||
|
/// The type being described
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// List of properties defined on this type
|
||||||
|
final List<PropertyInfo> properties;
|
||||||
|
|
||||||
|
/// List of methods defined on this type
|
||||||
|
final List<MethodInfo> methods;
|
||||||
|
|
||||||
|
/// List of constructors defined on this type
|
||||||
|
final List<ConstructorInfo> constructors;
|
||||||
|
|
||||||
|
/// Creates a new [TypeInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [type]: The type being described
|
||||||
|
/// - [properties]: List of properties defined on the type
|
||||||
|
/// - [methods]: List of methods defined on the type
|
||||||
|
/// - [constructors]: List of constructors defined on the type
|
||||||
|
const TypeInfo({
|
||||||
|
required this.type,
|
||||||
|
required this.properties,
|
||||||
|
required this.methods,
|
||||||
|
required this.constructors,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'TypeInfo(type: $type)';
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is TypeInfo &&
|
||||||
|
other.type == type &&
|
||||||
|
_listEquals(other.properties, properties) &&
|
||||||
|
_listEquals(other.methods, methods) &&
|
||||||
|
_listEquals(other.constructors, constructors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
type,
|
||||||
|
Object.hashAll(properties),
|
||||||
|
Object.hashAll(methods),
|
||||||
|
Object.hashAll(constructors),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _listEquals<T>(List<T> a, List<T> b) {
|
||||||
|
if (identical(a, b)) return true;
|
||||||
|
if (a.length != b.length) return false;
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
if (a[i] != b[i]) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
69
packages/mirrors/lib/src/discovery/models/variable_info.dart
Normal file
69
packages/mirrors/lib/src/discovery/models/variable_info.dart
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/// Information about a top-level variable.
|
||||||
|
///
|
||||||
|
/// Contains metadata about a variable including:
|
||||||
|
/// - The variable's name
|
||||||
|
/// - Type
|
||||||
|
/// - Whether it's final, const, or private
|
||||||
|
class VariableInfo {
|
||||||
|
/// The name of the variable
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the variable
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Whether this variable is final
|
||||||
|
final bool isFinal;
|
||||||
|
|
||||||
|
/// Whether this variable is const
|
||||||
|
final bool isConst;
|
||||||
|
|
||||||
|
/// Whether this variable is private
|
||||||
|
final bool isPrivate;
|
||||||
|
|
||||||
|
/// Creates a new [VariableInfo] instance.
|
||||||
|
///
|
||||||
|
/// All parameters are required:
|
||||||
|
/// - [name]: The variable's name
|
||||||
|
/// - [type]: The variable's type
|
||||||
|
/// - [isFinal]: Whether the variable is final
|
||||||
|
/// - [isConst]: Whether the variable is const
|
||||||
|
/// - [isPrivate]: Whether the variable is private
|
||||||
|
const VariableInfo({
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
required this.isFinal,
|
||||||
|
required this.isConst,
|
||||||
|
required this.isPrivate,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
final buffer = StringBuffer();
|
||||||
|
if (isConst) buffer.write('const ');
|
||||||
|
if (isFinal) buffer.write('final ');
|
||||||
|
buffer.write('$type $name');
|
||||||
|
return buffer.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
if (identical(this, other)) return true;
|
||||||
|
return other is VariableInfo &&
|
||||||
|
other.name == name &&
|
||||||
|
other.type == type &&
|
||||||
|
other.isFinal == isFinal &&
|
||||||
|
other.isConst == isConst &&
|
||||||
|
other.isPrivate == isPrivate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode {
|
||||||
|
return Object.hash(
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
isFinal,
|
||||||
|
isConst,
|
||||||
|
isPrivate,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
86
packages/mirrors/lib/src/discovery/scanner.dart
Normal file
86
packages/mirrors/lib/src/discovery/scanner.dart
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
import 'dart:core';
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Runtime scanner that analyzes types and extracts their metadata.
|
||||||
|
class Scanner {
|
||||||
|
// Private constructor to prevent instantiation
|
||||||
|
Scanner._();
|
||||||
|
|
||||||
|
// Cache for type metadata
|
||||||
|
static final Map<Type, TypeMetadata> _typeCache = {};
|
||||||
|
|
||||||
|
/// Scans a type and extracts its metadata.
|
||||||
|
static void scanType(Type type) {
|
||||||
|
if (_typeCache.containsKey(type)) return;
|
||||||
|
|
||||||
|
// First register the type with Reflector
|
||||||
|
ReflectionRegistry.register(type);
|
||||||
|
|
||||||
|
// Get mirror system and analyze type
|
||||||
|
//final mirrorSystem = MirrorSystem.current();
|
||||||
|
final typeInfo = TypeAnalyzer.analyze(type);
|
||||||
|
|
||||||
|
// Convert properties, methods, and constructors to metadata
|
||||||
|
final propertyMetadata = <String, PropertyMetadata>{};
|
||||||
|
final methodMetadata = <String, MethodMetadata>{};
|
||||||
|
final constructorMetadata = <ConstructorMetadata>[];
|
||||||
|
|
||||||
|
// Register properties
|
||||||
|
for (var property in typeInfo.properties) {
|
||||||
|
final propertyMeta = PropertyMetadata(
|
||||||
|
name: property.name,
|
||||||
|
type: property.type,
|
||||||
|
isReadable: true,
|
||||||
|
isWritable: !property.isFinal,
|
||||||
|
);
|
||||||
|
propertyMetadata[property.name] = propertyMeta;
|
||||||
|
ReflectionRegistry.registerPropertyMetadata(
|
||||||
|
type, property.name, propertyMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register methods
|
||||||
|
for (var method in typeInfo.methods) {
|
||||||
|
final methodMeta = MethodMetadata(
|
||||||
|
name: method.name,
|
||||||
|
parameterTypes: method.parameterTypes,
|
||||||
|
parameters: method.parameters,
|
||||||
|
returnsVoid: method.returnsVoid,
|
||||||
|
returnType: method.returnType,
|
||||||
|
isStatic: method.isStatic,
|
||||||
|
);
|
||||||
|
methodMetadata[method.name] = methodMeta;
|
||||||
|
ReflectionRegistry.registerMethodMetadata(type, method.name, methodMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register constructors
|
||||||
|
for (var constructor in typeInfo.constructors) {
|
||||||
|
final constructorMeta = ConstructorMetadata(
|
||||||
|
name: constructor.name,
|
||||||
|
parameterTypes: constructor.parameterTypes,
|
||||||
|
parameters: constructor.parameters,
|
||||||
|
);
|
||||||
|
constructorMetadata.add(constructorMeta);
|
||||||
|
ReflectionRegistry.registerConstructorMetadata(type, constructorMeta);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and cache the metadata
|
||||||
|
final metadata = TypeMetadata(
|
||||||
|
type: type,
|
||||||
|
name: type.toString(),
|
||||||
|
properties: propertyMetadata,
|
||||||
|
methods: methodMetadata,
|
||||||
|
constructors: constructorMetadata,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Cache the metadata
|
||||||
|
_typeCache[type] = metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets metadata for a type, scanning it first if needed.
|
||||||
|
static TypeMetadata getTypeMetadata(Type type) {
|
||||||
|
if (!_typeCache.containsKey(type)) {
|
||||||
|
scanType(type);
|
||||||
|
}
|
||||||
|
return _typeCache[type]!;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,88 +1,4 @@
|
||||||
import 'dart:core';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
|
||||||
|
|
||||||
/// Runtime scanner that analyzes types and extracts their metadata.
|
|
||||||
class Scanner {
|
|
||||||
// Private constructor to prevent instantiation
|
|
||||||
Scanner._();
|
|
||||||
|
|
||||||
// Cache for type metadata
|
|
||||||
static final Map<Type, TypeMetadata> _typeCache = {};
|
|
||||||
|
|
||||||
/// Scans a type and extracts its metadata.
|
|
||||||
static void scanType(Type type) {
|
|
||||||
if (_typeCache.containsKey(type)) return;
|
|
||||||
|
|
||||||
// First register the type with Reflector
|
|
||||||
Reflector.register(type);
|
|
||||||
|
|
||||||
// Get mirror system and analyze type
|
|
||||||
//final mirrorSystem = MirrorSystem.current();
|
|
||||||
final typeInfo = TypeAnalyzer.analyze(type);
|
|
||||||
|
|
||||||
// Convert properties, methods, and constructors to metadata
|
|
||||||
final propertyMetadata = <String, PropertyMetadata>{};
|
|
||||||
final methodMetadata = <String, MethodMetadata>{};
|
|
||||||
final constructorMetadata = <ConstructorMetadata>[];
|
|
||||||
|
|
||||||
// Register properties
|
|
||||||
for (var property in typeInfo.properties) {
|
|
||||||
final propertyMeta = PropertyMetadata(
|
|
||||||
name: property.name,
|
|
||||||
type: property.type,
|
|
||||||
isReadable: true,
|
|
||||||
isWritable: !property.isFinal,
|
|
||||||
);
|
|
||||||
propertyMetadata[property.name] = propertyMeta;
|
|
||||||
Reflector.registerPropertyMetadata(type, property.name, propertyMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register methods
|
|
||||||
for (var method in typeInfo.methods) {
|
|
||||||
final methodMeta = MethodMetadata(
|
|
||||||
name: method.name,
|
|
||||||
parameterTypes: method.parameterTypes,
|
|
||||||
parameters: method.parameters,
|
|
||||||
returnsVoid: method.returnsVoid,
|
|
||||||
returnType: method.returnType,
|
|
||||||
isStatic: method.isStatic,
|
|
||||||
);
|
|
||||||
methodMetadata[method.name] = methodMeta;
|
|
||||||
Reflector.registerMethodMetadata(type, method.name, methodMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register constructors
|
|
||||||
for (var constructor in typeInfo.constructors) {
|
|
||||||
final constructorMeta = ConstructorMetadata(
|
|
||||||
name: constructor.name,
|
|
||||||
parameterTypes: constructor.parameterTypes,
|
|
||||||
parameters: constructor.parameters,
|
|
||||||
);
|
|
||||||
constructorMetadata.add(constructorMeta);
|
|
||||||
Reflector.registerConstructorMetadata(type, constructorMeta);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create and cache the metadata
|
|
||||||
final metadata = TypeMetadata(
|
|
||||||
type: type,
|
|
||||||
name: type.toString(),
|
|
||||||
properties: propertyMetadata,
|
|
||||||
methods: methodMetadata,
|
|
||||||
constructors: constructorMetadata,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Cache the metadata
|
|
||||||
_typeCache[type] = metadata;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets metadata for a type, scanning it first if needed.
|
|
||||||
static TypeMetadata getTypeMetadata(Type type) {
|
|
||||||
if (!_typeCache.containsKey(type)) {
|
|
||||||
scanType(type);
|
|
||||||
}
|
|
||||||
return _typeCache[type]!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Analyzes types at runtime to extract their metadata.
|
/// Analyzes types at runtime to extract their metadata.
|
||||||
class TypeAnalyzer {
|
class TypeAnalyzer {
|
||||||
|
@ -325,63 +241,3 @@ class TypeAnalyzer {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Information about a type.
|
|
||||||
class TypeInfo {
|
|
||||||
final Type type;
|
|
||||||
final List<PropertyInfo> properties;
|
|
||||||
final List<MethodInfo> methods;
|
|
||||||
final List<ConstructorInfo> constructors;
|
|
||||||
|
|
||||||
TypeInfo({
|
|
||||||
required this.type,
|
|
||||||
required this.properties,
|
|
||||||
required this.methods,
|
|
||||||
required this.constructors,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about a property.
|
|
||||||
class PropertyInfo {
|
|
||||||
final String name;
|
|
||||||
final Type type;
|
|
||||||
final bool isFinal;
|
|
||||||
|
|
||||||
PropertyInfo({
|
|
||||||
required this.name,
|
|
||||||
required this.type,
|
|
||||||
required this.isFinal,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about a method.
|
|
||||||
class MethodInfo {
|
|
||||||
final String name;
|
|
||||||
final List<Type> parameterTypes;
|
|
||||||
final List<ParameterMetadata> parameters;
|
|
||||||
final bool returnsVoid;
|
|
||||||
final Type returnType;
|
|
||||||
final bool isStatic;
|
|
||||||
|
|
||||||
MethodInfo({
|
|
||||||
required this.name,
|
|
||||||
required this.parameterTypes,
|
|
||||||
required this.parameters,
|
|
||||||
required this.returnsVoid,
|
|
||||||
required this.returnType,
|
|
||||||
required this.isStatic,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about a constructor.
|
|
||||||
class ConstructorInfo {
|
|
||||||
final String name;
|
|
||||||
final List<Type> parameterTypes;
|
|
||||||
final List<ParameterMetadata> parameters;
|
|
||||||
|
|
||||||
ConstructorInfo({
|
|
||||||
required this.name,
|
|
||||||
required this.parameterTypes,
|
|
||||||
required this.parameters,
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Exception thrown when invalid arguments are provided to a reflective operation.
|
||||||
|
class InvalidArgumentsException extends ReflectionException {
|
||||||
|
/// The name of the member being invoked.
|
||||||
|
final String memberName;
|
||||||
|
|
||||||
|
/// The type the member belongs to.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Creates a new invalid arguments exception.
|
||||||
|
const InvalidArgumentsException(this.memberName, this.type)
|
||||||
|
: super('Invalid arguments for $memberName on type $type');
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Exception thrown when a member is not found during reflection.
|
||||||
|
class MemberNotFoundException extends ReflectionException {
|
||||||
|
/// The name of the member that was not found.
|
||||||
|
final String memberName;
|
||||||
|
|
||||||
|
/// The type the member was looked up on.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Creates a new member not found exception.
|
||||||
|
const MemberNotFoundException(this.memberName, this.type)
|
||||||
|
: super('Member $memberName not found on type $type');
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Exception thrown when attempting to reflect on a non-reflectable type.
|
||||||
|
class NotReflectableException extends ReflectionException {
|
||||||
|
/// The type that was not reflectable.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Creates a new not reflectable exception.
|
||||||
|
const NotReflectableException(this.type)
|
||||||
|
: super('Type $type is not reflectable. '
|
||||||
|
'Make sure it is annotated with @reflectable or registered manually.');
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
/// Base class for all reflection-related exceptions.
|
||||||
|
class ReflectionException implements Exception {
|
||||||
|
/// The error message.
|
||||||
|
final String message;
|
||||||
|
|
||||||
|
/// Creates a new reflection exception.
|
||||||
|
const ReflectionException(this.message);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() => 'ReflectionException: $message';
|
||||||
|
}
|
45
packages/mirrors/lib/src/metadata/constructor_metadata.dart
Normal file
45
packages/mirrors/lib/src/metadata/constructor_metadata.dart
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Represents metadata about a type's constructor.
|
||||||
|
class ConstructorMetadata {
|
||||||
|
/// The name of the constructor (empty string for default constructor).
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The parameter types of the constructor in order.
|
||||||
|
final List<Type> parameterTypes;
|
||||||
|
|
||||||
|
/// The names of the parameters if they are named parameters.
|
||||||
|
final List<String>? parameterNames;
|
||||||
|
|
||||||
|
/// Detailed metadata about each parameter.
|
||||||
|
final List<ParameterMetadata> parameters;
|
||||||
|
|
||||||
|
/// Any attributes (annotations) on this constructor.
|
||||||
|
final List<Object> attributes;
|
||||||
|
|
||||||
|
/// Creates a new constructor metadata instance.
|
||||||
|
const ConstructorMetadata({
|
||||||
|
this.name = '',
|
||||||
|
required this.parameterTypes,
|
||||||
|
required this.parameters,
|
||||||
|
this.parameterNames,
|
||||||
|
this.attributes = const [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Whether this constructor uses named parameters.
|
||||||
|
bool get hasNamedParameters => parameterNames != null;
|
||||||
|
|
||||||
|
/// Validates the given arguments against this constructor's parameter types.
|
||||||
|
bool validateArguments(List<Object?> arguments) {
|
||||||
|
if (arguments.length != parameterTypes.length) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
final arg = arguments[i];
|
||||||
|
if (arg != null && arg.runtimeType != parameterTypes[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
38
packages/mirrors/lib/src/metadata/function_metadata.dart
Normal file
38
packages/mirrors/lib/src/metadata/function_metadata.dart
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Represents metadata about a function.
|
||||||
|
class FunctionMetadata {
|
||||||
|
/// The parameters of the function.
|
||||||
|
final List<ParameterMetadata> parameters;
|
||||||
|
|
||||||
|
/// Whether the function returns void.
|
||||||
|
final bool returnsVoid;
|
||||||
|
|
||||||
|
/// The return type of the function.
|
||||||
|
final Type returnType;
|
||||||
|
|
||||||
|
/// Type parameters for generic functions.
|
||||||
|
final List<TypeParameterMetadata> typeParameters;
|
||||||
|
|
||||||
|
/// Creates a new function metadata instance.
|
||||||
|
const FunctionMetadata({
|
||||||
|
required this.parameters,
|
||||||
|
required this.returnsVoid,
|
||||||
|
required this.returnType,
|
||||||
|
this.typeParameters = const [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Validates the given arguments against this function's parameters.
|
||||||
|
bool validateArguments(List<Object?> arguments) {
|
||||||
|
if (arguments.length != parameters.length) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
final arg = arguments[i];
|
||||||
|
if (arg != null && arg.runtimeType != parameters[i].type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
54
packages/mirrors/lib/src/metadata/method_metadata.dart
Normal file
54
packages/mirrors/lib/src/metadata/method_metadata.dart
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Represents metadata about a type's method.
|
||||||
|
class MethodMetadata {
|
||||||
|
/// The name of the method.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The parameter types of the method in order.
|
||||||
|
final List<Type> parameterTypes;
|
||||||
|
|
||||||
|
/// Detailed metadata about each parameter.
|
||||||
|
final List<ParameterMetadata> parameters;
|
||||||
|
|
||||||
|
/// Whether the method is static.
|
||||||
|
final bool isStatic;
|
||||||
|
|
||||||
|
/// Whether the method returns void.
|
||||||
|
final bool returnsVoid;
|
||||||
|
|
||||||
|
/// The return type of the method.
|
||||||
|
final Type returnType;
|
||||||
|
|
||||||
|
/// Any attributes (annotations) on this method.
|
||||||
|
final List<Object> attributes;
|
||||||
|
|
||||||
|
/// Type parameters for generic methods.
|
||||||
|
final List<TypeParameterMetadata> typeParameters;
|
||||||
|
|
||||||
|
/// Creates a new method metadata instance.
|
||||||
|
const MethodMetadata({
|
||||||
|
required this.name,
|
||||||
|
required this.parameterTypes,
|
||||||
|
required this.parameters,
|
||||||
|
required this.returnsVoid,
|
||||||
|
required this.returnType,
|
||||||
|
this.isStatic = false,
|
||||||
|
this.attributes = const [],
|
||||||
|
this.typeParameters = const [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Validates the given arguments against this method's parameter types.
|
||||||
|
bool validateArguments(List<Object?> arguments) {
|
||||||
|
if (arguments.length != parameterTypes.length) return false;
|
||||||
|
|
||||||
|
for (var i = 0; i < arguments.length; i++) {
|
||||||
|
final arg = arguments[i];
|
||||||
|
if (arg != null && arg.runtimeType != parameterTypes[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
30
packages/mirrors/lib/src/metadata/parameter_metadata.dart
Normal file
30
packages/mirrors/lib/src/metadata/parameter_metadata.dart
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/// Represents metadata about a parameter.
|
||||||
|
class ParameterMetadata {
|
||||||
|
/// The name of the parameter.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the parameter.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Whether this parameter is required.
|
||||||
|
final bool isRequired;
|
||||||
|
|
||||||
|
/// Whether this parameter is named.
|
||||||
|
final bool isNamed;
|
||||||
|
|
||||||
|
/// The default value for this parameter, if any.
|
||||||
|
final Object? defaultValue;
|
||||||
|
|
||||||
|
/// Any attributes (annotations) on this parameter.
|
||||||
|
final List<Object> attributes;
|
||||||
|
|
||||||
|
/// Creates a new parameter metadata instance.
|
||||||
|
const ParameterMetadata({
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
required this.isRequired,
|
||||||
|
this.isNamed = false,
|
||||||
|
this.defaultValue,
|
||||||
|
this.attributes = const [],
|
||||||
|
});
|
||||||
|
}
|
26
packages/mirrors/lib/src/metadata/property_metadata.dart
Normal file
26
packages/mirrors/lib/src/metadata/property_metadata.dart
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/// Represents metadata about a type's property.
|
||||||
|
class PropertyMetadata {
|
||||||
|
/// The name of the property.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the property.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// Whether the property can be read.
|
||||||
|
final bool isReadable;
|
||||||
|
|
||||||
|
/// Whether the property can be written to.
|
||||||
|
final bool isWritable;
|
||||||
|
|
||||||
|
/// Any attributes (annotations) on this property.
|
||||||
|
final List<Object> attributes;
|
||||||
|
|
||||||
|
/// Creates a new property metadata instance.
|
||||||
|
const PropertyMetadata({
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
this.isReadable = true,
|
||||||
|
this.isWritable = true,
|
||||||
|
this.attributes = const [],
|
||||||
|
});
|
||||||
|
}
|
96
packages/mirrors/lib/src/metadata/type_metadata.dart
Normal file
96
packages/mirrors/lib/src/metadata/type_metadata.dart
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
|
/// Represents metadata about a type.
|
||||||
|
class TypeMetadata {
|
||||||
|
/// The actual type this metadata represents.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// The name of the type.
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The properties defined on this type.
|
||||||
|
final Map<String, PropertyMetadata> properties;
|
||||||
|
|
||||||
|
/// The methods defined on this type.
|
||||||
|
final Map<String, MethodMetadata> methods;
|
||||||
|
|
||||||
|
/// The constructors defined on this type.
|
||||||
|
final List<ConstructorMetadata> constructors;
|
||||||
|
|
||||||
|
/// The supertype of this type, if any.
|
||||||
|
final TypeMetadata? supertype;
|
||||||
|
|
||||||
|
/// The interfaces this type implements.
|
||||||
|
final List<TypeMetadata> interfaces;
|
||||||
|
|
||||||
|
/// The mixins this type uses.
|
||||||
|
final List<TypeMetadata> mixins;
|
||||||
|
|
||||||
|
/// Any attributes (annotations) on this type.
|
||||||
|
final List<Object> attributes;
|
||||||
|
|
||||||
|
/// Type parameters for generic types.
|
||||||
|
final List<TypeParameterMetadata> typeParameters;
|
||||||
|
|
||||||
|
/// Type arguments if this is a generic type instantiation.
|
||||||
|
final List<TypeMetadata> typeArguments;
|
||||||
|
|
||||||
|
/// Creates a new type metadata instance.
|
||||||
|
const TypeMetadata({
|
||||||
|
required this.type,
|
||||||
|
required this.name,
|
||||||
|
required this.properties,
|
||||||
|
required this.methods,
|
||||||
|
required this.constructors,
|
||||||
|
this.supertype,
|
||||||
|
this.interfaces = const [],
|
||||||
|
this.mixins = const [],
|
||||||
|
this.attributes = const [],
|
||||||
|
this.typeParameters = const [],
|
||||||
|
this.typeArguments = const [],
|
||||||
|
});
|
||||||
|
|
||||||
|
/// Whether this type is generic (has type parameters).
|
||||||
|
bool get isGeneric => typeParameters.isNotEmpty;
|
||||||
|
|
||||||
|
/// Whether this is a generic type instantiation.
|
||||||
|
bool get isGenericInstantiation => typeArguments.isNotEmpty;
|
||||||
|
|
||||||
|
/// Gets a property by name, throwing if not found.
|
||||||
|
PropertyMetadata getProperty(String name) {
|
||||||
|
final property = properties[name];
|
||||||
|
if (property == null) {
|
||||||
|
throw MemberNotFoundException(name, type);
|
||||||
|
}
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a method by name, throwing if not found.
|
||||||
|
MethodMetadata getMethod(String name) {
|
||||||
|
final method = methods[name];
|
||||||
|
if (method == null) {
|
||||||
|
throw MemberNotFoundException(name, type);
|
||||||
|
}
|
||||||
|
return method;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets the default constructor, throwing if not found.
|
||||||
|
ConstructorMetadata get defaultConstructor {
|
||||||
|
return constructors.firstWhere(
|
||||||
|
(c) => c.name.isEmpty,
|
||||||
|
orElse: () => throw ReflectionException(
|
||||||
|
'No default constructor found for type "$name"',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Gets a named constructor, throwing if not found.
|
||||||
|
ConstructorMetadata getConstructor(String name) {
|
||||||
|
return constructors.firstWhere(
|
||||||
|
(c) => c.name == name,
|
||||||
|
orElse: () => throw ReflectionException(
|
||||||
|
'Constructor "$name" not found for type "$type"',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/// Represents metadata about a type parameter.
|
||||||
|
class TypeParameterMetadata {
|
||||||
|
/// The name of the type parameter (e.g., 'T', 'E').
|
||||||
|
final String name;
|
||||||
|
|
||||||
|
/// The type of the parameter.
|
||||||
|
final Type type;
|
||||||
|
|
||||||
|
/// The upper bound of the type parameter, if any.
|
||||||
|
final Type? bound;
|
||||||
|
|
||||||
|
/// Any attributes (annotations) on this type parameter.
|
||||||
|
final List<Object> attributes;
|
||||||
|
|
||||||
|
/// Creates a new type parameter metadata instance.
|
||||||
|
const TypeParameterMetadata({
|
||||||
|
required this.name,
|
||||||
|
required this.type,
|
||||||
|
this.bound,
|
||||||
|
this.attributes = const [],
|
||||||
|
});
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [ClassMirrorContract].
|
/// Implementation of [ClassMirrorContract].
|
||||||
class ClassMirror extends TypeMirror implements ClassMirrorContract {
|
class ClassMirror extends TypeMirror implements ClassMirrorContract {
|
||||||
|
@ -69,7 +69,7 @@ class ClassMirror extends TypeMirror implements ClassMirrorContract {
|
||||||
]) {
|
]) {
|
||||||
try {
|
try {
|
||||||
// Get constructor metadata
|
// Get constructor metadata
|
||||||
final constructors = Reflector.getConstructorMetadata(type);
|
final constructors = ReflectionRegistry.getConstructorMetadata(type);
|
||||||
if (constructors == null || constructors.isEmpty) {
|
if (constructors == null || constructors.isEmpty) {
|
||||||
throw ReflectionException('No constructors found for type $type');
|
throw ReflectionException('No constructors found for type $type');
|
||||||
}
|
}
|
||||||
|
@ -101,7 +101,8 @@ class ClassMirror extends TypeMirror implements ClassMirrorContract {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get instance creator
|
// Get instance creator
|
||||||
final creator = Reflector.getInstanceCreator(type, constructorStr);
|
final creator =
|
||||||
|
ReflectionRegistry.getInstanceCreator(type, constructorStr);
|
||||||
if (creator == null) {
|
if (creator == null) {
|
||||||
throw ReflectionException(
|
throw ReflectionException(
|
||||||
'No instance creator found for constructor $constructorStr');
|
'No instance creator found for constructor $constructorStr');
|
||||||
|
@ -134,7 +135,7 @@ class ClassMirror extends TypeMirror implements ClassMirrorContract {
|
||||||
[Map<Symbol, dynamic>? namedArguments]) {
|
[Map<Symbol, dynamic>? namedArguments]) {
|
||||||
try {
|
try {
|
||||||
// Get method metadata
|
// Get method metadata
|
||||||
final methods = Reflector.getMethodMetadata(type);
|
final methods = ReflectionRegistry.getMethodMetadata(type);
|
||||||
if (methods == null ||
|
if (methods == null ||
|
||||||
!methods.containsKey(_symbolToString(memberName))) {
|
!methods.containsKey(_symbolToString(memberName))) {
|
||||||
throw ReflectionException('Method $memberName not found');
|
throw ReflectionException('Method $memberName not found');
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [InstanceMirrorContract] that provides reflection on instances.
|
/// Implementation of [InstanceMirrorContract] that provides reflection on instances.
|
||||||
class InstanceMirror implements InstanceMirrorContract {
|
class InstanceMirror implements InstanceMirrorContract {
|
||||||
|
@ -26,7 +26,8 @@ class InstanceMirror implements InstanceMirrorContract {
|
||||||
InstanceMirrorContract invoke(Symbol memberName, List positionalArguments,
|
InstanceMirrorContract invoke(Symbol memberName, List positionalArguments,
|
||||||
[Map<Symbol, dynamic> namedArguments = const {}]) {
|
[Map<Symbol, dynamic> namedArguments = const {}]) {
|
||||||
// Get method metadata
|
// Get method metadata
|
||||||
final methods = Reflector.getMethodMetadata(_reflectee.runtimeType);
|
final methods =
|
||||||
|
ReflectionRegistry.getMethodMetadata(_reflectee.runtimeType);
|
||||||
if (methods == null) {
|
if (methods == null) {
|
||||||
throw ReflectionException(
|
throw ReflectionException(
|
||||||
'No methods found for type ${_reflectee.runtimeType}');
|
'No methods found for type ${_reflectee.runtimeType}');
|
||||||
|
@ -90,7 +91,8 @@ class InstanceMirror implements InstanceMirrorContract {
|
||||||
@override
|
@override
|
||||||
InstanceMirrorContract getField(Symbol fieldName) {
|
InstanceMirrorContract getField(Symbol fieldName) {
|
||||||
// Get property metadata
|
// Get property metadata
|
||||||
final properties = Reflector.getPropertyMetadata(_reflectee.runtimeType);
|
final properties =
|
||||||
|
ReflectionRegistry.getPropertyMetadata(_reflectee.runtimeType);
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
throw ReflectionException(
|
throw ReflectionException(
|
||||||
'No properties found for type ${_reflectee.runtimeType}');
|
'No properties found for type ${_reflectee.runtimeType}');
|
||||||
|
@ -146,7 +148,8 @@ class InstanceMirror implements InstanceMirrorContract {
|
||||||
@override
|
@override
|
||||||
InstanceMirrorContract setField(Symbol fieldName, dynamic value) {
|
InstanceMirrorContract setField(Symbol fieldName, dynamic value) {
|
||||||
// Get property metadata
|
// Get property metadata
|
||||||
final properties = Reflector.getPropertyMetadata(_reflectee.runtimeType);
|
final properties =
|
||||||
|
ReflectionRegistry.getPropertyMetadata(_reflectee.runtimeType);
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
throw ReflectionException(
|
throw ReflectionException(
|
||||||
'No properties found for type ${_reflectee.runtimeType}');
|
'No properties found for type ${_reflectee.runtimeType}');
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [LibraryMirrorContract] that provides reflection on libraries.
|
/// Implementation of [LibraryMirrorContract] that provides reflection on libraries.
|
||||||
class LibraryMirror extends TypedMirror implements LibraryMirrorContract {
|
class LibraryMirror extends TypedMirror implements LibraryMirrorContract {
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [MethodMirrorContract] that provides reflection on methods.
|
/// Implementation of [MethodMirrorContract] that provides reflection on methods.
|
||||||
class MethodMirror extends TypedMirror implements MethodMirrorContract {
|
class MethodMirror extends TypedMirror implements MethodMirrorContract {
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [ParameterMirrorContract] that provides reflection on parameters.
|
/// Implementation of [ParameterMirrorContract] that provides reflection on parameters.
|
||||||
class ParameterMirror extends MutableOwnerMirror
|
class ParameterMirror extends MutableOwnerMirror
|
|
@ -1,7 +1,7 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart'
|
import 'package:platform_contracts/contracts.dart'
|
||||||
hide PropertyMetadata, MethodMetadata, ConstructorMetadata;
|
hide PropertyMetadata, MethodMetadata, ConstructorMetadata;
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [TypeMirrorContract] that provides reflection on types.
|
/// Implementation of [TypeMirrorContract] that provides reflection on types.
|
||||||
class TypeMirror extends TypedMirror implements TypeMirrorContract {
|
class TypeMirror extends TypedMirror implements TypeMirrorContract {
|
||||||
|
@ -32,8 +32,8 @@ class TypeMirror extends TypedMirror implements TypeMirrorContract {
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
) {
|
) {
|
||||||
// Register type with reflector if not already registered
|
// Register type with reflector if not already registered
|
||||||
if (!Reflector.isReflectable(type)) {
|
if (!ReflectionRegistry.isReflectable(type)) {
|
||||||
Reflector.registerType(type);
|
ReflectionRegistry.registerType(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate generic type arguments
|
// Validate generic type arguments
|
||||||
|
@ -164,15 +164,15 @@ class TypeMirror extends TypedMirror implements TypeMirrorContract {
|
||||||
|
|
||||||
/// Gets the properties defined on this type.
|
/// Gets the properties defined on this type.
|
||||||
Map<String, PropertyMetadata> get properties =>
|
Map<String, PropertyMetadata> get properties =>
|
||||||
Reflector.getPropertyMetadata(type) ?? {};
|
ReflectionRegistry.getPropertyMetadata(type) ?? {};
|
||||||
|
|
||||||
/// Gets the methods defined on this type.
|
/// Gets the methods defined on this type.
|
||||||
Map<String, MethodMetadata> get methods =>
|
Map<String, MethodMetadata> get methods =>
|
||||||
Reflector.getMethodMetadata(type) ?? {};
|
ReflectionRegistry.getMethodMetadata(type) ?? {};
|
||||||
|
|
||||||
/// Gets the constructors defined on this type.
|
/// Gets the constructors defined on this type.
|
||||||
List<ConstructorMetadata> get constructors =>
|
List<ConstructorMetadata> get constructors =>
|
||||||
Reflector.getConstructorMetadata(type) ?? [];
|
ReflectionRegistry.getConstructorMetadata(type) ?? [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool isSubtypeOf(TypeMirrorContract other) {
|
bool isSubtypeOf(TypeMirrorContract other) {
|
||||||
|
@ -189,7 +189,7 @@ class TypeMirror extends TypedMirror implements TypeMirrorContract {
|
||||||
if (type == voidType) return other.type == voidType;
|
if (type == voidType) return other.type == voidType;
|
||||||
|
|
||||||
// Get type metadata
|
// Get type metadata
|
||||||
final metadata = Reflector.getTypeMetadata(type);
|
final metadata = ReflectionRegistry.getTypeMetadata(type);
|
||||||
if (metadata == null) return false;
|
if (metadata == null) return false;
|
||||||
|
|
||||||
// Check supertype
|
// Check supertype
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:platform_contracts/contracts.dart'
|
import 'package:platform_contracts/contracts.dart'
|
||||||
hide PropertyMetadata, MethodMetadata, ConstructorMetadata;
|
hide PropertyMetadata, MethodMetadata, ConstructorMetadata;
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [TypeVariableMirrorContract] that provides reflection on type variables.
|
/// Implementation of [TypeVariableMirrorContract] that provides reflection on type variables.
|
||||||
class TypeVariableMirror extends TypedMirror
|
class TypeVariableMirror extends TypedMirror
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:core';
|
import 'dart:core';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Implementation of [VariableMirrorContract] that provides reflection on variables.
|
/// Implementation of [VariableMirrorContract] that provides reflection on variables.
|
||||||
class VariableMirror extends MutableOwnerMirror
|
class VariableMirror extends MutableOwnerMirror
|
|
@ -1,6 +1,6 @@
|
||||||
import 'dart:isolate' as isolate;
|
import 'dart:isolate' as isolate;
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// A pure runtime reflection system that provides type introspection and manipulation.
|
/// A pure runtime reflection system that provides type introspection and manipulation.
|
||||||
class RuntimeReflector {
|
class RuntimeReflector {
|
||||||
|
@ -141,12 +141,12 @@ class RuntimeReflector {
|
||||||
}) {
|
}) {
|
||||||
try {
|
try {
|
||||||
// Check if type is reflectable
|
// Check if type is reflectable
|
||||||
if (!Reflector.isReflectable(type)) {
|
if (!ReflectionRegistry.isReflectable(type)) {
|
||||||
throw NotReflectableException(type);
|
throw NotReflectableException(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get constructor metadata
|
// Get constructor metadata
|
||||||
final constructors = Reflector.getConstructorMetadata(type);
|
final constructors = ReflectionRegistry.getConstructorMetadata(type);
|
||||||
if (constructors == null || constructors.isEmpty) {
|
if (constructors == null || constructors.isEmpty) {
|
||||||
throw ReflectionException('No constructors found for type $type');
|
throw ReflectionException('No constructors found for type $type');
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,8 @@ class RuntimeReflector {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Get constructor factory
|
// Get constructor factory
|
||||||
final factory = Reflector.getInstanceCreator(type, constructor.name);
|
final factory =
|
||||||
|
ReflectionRegistry.getInstanceCreator(type, constructor.name);
|
||||||
if (factory == null) {
|
if (factory == null) {
|
||||||
throw ReflectionException(
|
throw ReflectionException(
|
||||||
'No factory found for constructor ${constructor.name} on type $type');
|
'No factory found for constructor ${constructor.name} on type $type');
|
||||||
|
@ -250,7 +251,7 @@ class RuntimeReflector {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if type is reflectable
|
// Check if type is reflectable
|
||||||
if (!Reflector.isReflectable(type)) {
|
if (!ReflectionRegistry.isReflectable(type)) {
|
||||||
throw NotReflectableException(type);
|
throw NotReflectableException(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,10 +268,10 @@ class RuntimeReflector {
|
||||||
_classMirrorCache[type] = emptyMirror;
|
_classMirrorCache[type] = emptyMirror;
|
||||||
|
|
||||||
// Get metadata from registry
|
// Get metadata from registry
|
||||||
final properties = Reflector.getPropertyMetadata(type) ?? {};
|
final properties = ReflectionRegistry.getPropertyMetadata(type) ?? {};
|
||||||
final methods = Reflector.getMethodMetadata(type) ?? {};
|
final methods = ReflectionRegistry.getMethodMetadata(type) ?? {};
|
||||||
final constructors = Reflector.getConstructorMetadata(type) ?? [];
|
final constructors = ReflectionRegistry.getConstructorMetadata(type) ?? [];
|
||||||
final typeMetadata = Reflector.getTypeMetadata(type);
|
final typeMetadata = ReflectionRegistry.getTypeMetadata(type);
|
||||||
|
|
||||||
// Create declarations map
|
// Create declarations map
|
||||||
final declarations = <Symbol, DeclarationMirrorContract>{};
|
final declarations = <Symbol, DeclarationMirrorContract>{};
|
||||||
|
@ -390,7 +391,7 @@ class RuntimeReflector {
|
||||||
/// Reflects on a type, returning its type mirror.
|
/// Reflects on a type, returning its type mirror.
|
||||||
TypeMirrorContract reflectType(Type type) {
|
TypeMirrorContract reflectType(Type type) {
|
||||||
// Check if type is reflectable
|
// Check if type is reflectable
|
||||||
if (!Reflector.isReflectable(type)) {
|
if (!ReflectionRegistry.isReflectable(type)) {
|
||||||
throw NotReflectableException(type);
|
throw NotReflectableException(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,7 +401,7 @@ class RuntimeReflector {
|
||||||
/// Creates a new instance reflector for the given object.
|
/// Creates a new instance reflector for the given object.
|
||||||
InstanceMirrorContract reflect(Object instance) {
|
InstanceMirrorContract reflect(Object instance) {
|
||||||
// Check if type is reflectable
|
// Check if type is reflectable
|
||||||
if (!Reflector.isReflectable(instance.runtimeType)) {
|
if (!ReflectionRegistry.isReflectable(instance.runtimeType)) {
|
||||||
throw NotReflectableException(instance.runtimeType);
|
throw NotReflectableException(instance.runtimeType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Static registry for reflection metadata.
|
/// Static registry for reflection metadata.
|
||||||
class Reflector {
|
class ReflectionRegistry {
|
||||||
// Private constructor to prevent instantiation
|
// Private constructor to prevent instantiation
|
||||||
Reflector._();
|
ReflectionRegistry._();
|
||||||
|
|
||||||
// Type metadata storage
|
// Type metadata storage
|
||||||
static final Map<Type, Map<String, PropertyMetadata>> _propertyMetadata =
|
static final Map<Type, Map<String, PropertyMetadata>> _propertyMetadata =
|
|
@ -1,4 +1,4 @@
|
||||||
name: platform_reflection
|
name: platform_mirrors
|
||||||
description: A lightweight, cross-platform reflection system for Dart
|
description: A lightweight, cross-platform reflection system for Dart
|
||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
publish_to: none
|
publish_to: none
|
|
@ -1,5 +1,5 @@
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
// Function to run in isolate
|
// Function to run in isolate
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
// Top-level function for testing
|
// Top-level function for testing
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart' hide PropertyMetadata;
|
import 'package:platform_contracts/contracts.dart' hide PropertyMetadata;
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
|
@ -18,8 +18,8 @@ void main() {
|
||||||
mirrorSystem = MirrorSystem.instance;
|
mirrorSystem = MirrorSystem.instance;
|
||||||
|
|
||||||
// Register test class
|
// Register test class
|
||||||
Reflector.registerType(TestClass);
|
ReflectionRegistry.registerType(TestClass);
|
||||||
Reflector.registerPropertyMetadata(
|
ReflectionRegistry.registerPropertyMetadata(
|
||||||
TestClass,
|
TestClass,
|
||||||
'name',
|
'name',
|
||||||
PropertyMetadata(
|
PropertyMetadata(
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
|
@ -27,18 +27,18 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
reflector = RuntimeReflector.instance;
|
reflector = RuntimeReflector.instance;
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Type Reflection', () {
|
group('Type Reflection', () {
|
||||||
test('reflectType returns correct type metadata', () {
|
test('reflectType returns correct type metadata', () {
|
||||||
Reflector.register(Person);
|
ReflectionRegistry.register(Person);
|
||||||
final mirror = reflector.reflectType(Person);
|
final mirror = reflector.reflectType(Person);
|
||||||
expect(mirror.simpleName.toString(), contains('Person'));
|
expect(mirror.simpleName.toString(), contains('Person'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reflect creates instance mirror', () {
|
test('reflect creates instance mirror', () {
|
||||||
Reflector.register(Person);
|
ReflectionRegistry.register(Person);
|
||||||
final person = Person('John', 30);
|
final person = Person('John', 30);
|
||||||
final mirror = reflector.reflect(person);
|
final mirror = reflector.reflect(person);
|
||||||
expect(mirror.reflectee, equals(person));
|
expect(mirror.reflectee, equals(person));
|
||||||
|
@ -57,9 +57,10 @@ void main() {
|
||||||
late InstanceMirrorContract mirror;
|
late InstanceMirrorContract mirror;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
Reflector.register(Person);
|
ReflectionRegistry.register(Person);
|
||||||
Reflector.registerProperty(Person, 'name', String);
|
ReflectionRegistry.registerProperty(Person, 'name', String);
|
||||||
Reflector.registerProperty(Person, 'age', int, isWritable: false);
|
ReflectionRegistry.registerProperty(Person, 'age', int,
|
||||||
|
isWritable: false);
|
||||||
|
|
||||||
person = Person('John', 30);
|
person = Person('John', 30);
|
||||||
mirror = reflector.reflect(person);
|
mirror = reflector.reflect(person);
|
||||||
|
@ -94,8 +95,8 @@ void main() {
|
||||||
late InstanceMirrorContract mirror;
|
late InstanceMirrorContract mirror;
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
Reflector.register(Person);
|
ReflectionRegistry.register(Person);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
Person,
|
Person,
|
||||||
'greet',
|
'greet',
|
||||||
[String],
|
[String],
|
||||||
|
@ -123,15 +124,15 @@ void main() {
|
||||||
|
|
||||||
group('Constructor Invocation', () {
|
group('Constructor Invocation', () {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
Reflector.register(Person);
|
ReflectionRegistry.register(Person);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
Person,
|
Person,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String, int],
|
parameterTypes: [String, int],
|
||||||
parameterNames: ['name', 'age'],
|
parameterNames: ['name', 'age'],
|
||||||
creator: (String name, int age) => Person(name, age),
|
creator: (String name, int age) => Person(name, age),
|
||||||
);
|
);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
Person,
|
Person,
|
||||||
'guest',
|
'guest',
|
||||||
creator: () => Person.guest(),
|
creator: () => Person.guest(),
|
|
@ -1,4 +1,4 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
|
@ -64,21 +64,22 @@ class ChildTestClass extends ParentTestClass {
|
||||||
void main() {
|
void main() {
|
||||||
group('Scanner', () {
|
group('Scanner', () {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('scans properties correctly', () {
|
test('scans properties correctly', () {
|
||||||
// Register base metadata
|
// Register base metadata
|
||||||
Reflector.register(TestClass);
|
ReflectionRegistry.register(TestClass);
|
||||||
Reflector.registerProperty(TestClass, 'name', String);
|
ReflectionRegistry.registerProperty(TestClass, 'name', String);
|
||||||
Reflector.registerProperty(TestClass, 'id', int, isWritable: false);
|
ReflectionRegistry.registerProperty(TestClass, 'id', int,
|
||||||
Reflector.registerProperty(TestClass, 'tags', List<String>);
|
isWritable: false);
|
||||||
Reflector.registerProperty(TestClass, 'version', String,
|
ReflectionRegistry.registerProperty(TestClass, 'tags', List<String>);
|
||||||
|
ReflectionRegistry.registerProperty(TestClass, 'version', String,
|
||||||
isWritable: false);
|
isWritable: false);
|
||||||
|
|
||||||
// Scan type
|
// Scan type
|
||||||
Scanner.scanType(TestClass);
|
Scanner.scanType(TestClass);
|
||||||
final metadata = Reflector.getPropertyMetadata(TestClass);
|
final metadata = ReflectionRegistry.getPropertyMetadata(TestClass);
|
||||||
|
|
||||||
expect(metadata, isNotNull);
|
expect(metadata, isNotNull);
|
||||||
expect(metadata!['name'], isNotNull);
|
expect(metadata!['name'], isNotNull);
|
||||||
|
@ -100,8 +101,8 @@ void main() {
|
||||||
|
|
||||||
test('scans methods correctly', () {
|
test('scans methods correctly', () {
|
||||||
// Register base metadata
|
// Register base metadata
|
||||||
Reflector.register(TestClass);
|
ReflectionRegistry.register(TestClass);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'addTag',
|
'addTag',
|
||||||
[String],
|
[String],
|
||||||
|
@ -109,7 +110,7 @@ void main() {
|
||||||
parameterNames: ['tag'],
|
parameterNames: ['tag'],
|
||||||
isRequired: [true],
|
isRequired: [true],
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'greet',
|
'greet',
|
||||||
[String],
|
[String],
|
||||||
|
@ -117,7 +118,7 @@ void main() {
|
||||||
parameterNames: ['greeting'],
|
parameterNames: ['greeting'],
|
||||||
isRequired: [false],
|
isRequired: [false],
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'create',
|
'create',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -130,7 +131,7 @@ void main() {
|
||||||
|
|
||||||
// Scan type
|
// Scan type
|
||||||
Scanner.scanType(TestClass);
|
Scanner.scanType(TestClass);
|
||||||
final metadata = Reflector.getMethodMetadata(TestClass);
|
final metadata = ReflectionRegistry.getMethodMetadata(TestClass);
|
||||||
|
|
||||||
expect(metadata, isNotNull);
|
expect(metadata, isNotNull);
|
||||||
|
|
||||||
|
@ -171,8 +172,8 @@ void main() {
|
||||||
|
|
||||||
test('scans constructors correctly', () {
|
test('scans constructors correctly', () {
|
||||||
// Register base metadata
|
// Register base metadata
|
||||||
Reflector.register(TestClass);
|
ReflectionRegistry.register(TestClass);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
TestClass,
|
TestClass,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String, int, List<String>],
|
parameterTypes: [String, int, List<String>],
|
||||||
|
@ -180,14 +181,14 @@ void main() {
|
||||||
isRequired: [true, true, false],
|
isRequired: [true, true, false],
|
||||||
isNamed: [false, true, true],
|
isNamed: [false, true, true],
|
||||||
);
|
);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
TestClass,
|
TestClass,
|
||||||
'guest',
|
'guest',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Scan type
|
// Scan type
|
||||||
Scanner.scanType(TestClass);
|
Scanner.scanType(TestClass);
|
||||||
final metadata = Reflector.getConstructorMetadata(TestClass);
|
final metadata = ReflectionRegistry.getConstructorMetadata(TestClass);
|
||||||
|
|
||||||
expect(metadata, isNotNull);
|
expect(metadata, isNotNull);
|
||||||
expect(metadata!.length, equals(2));
|
expect(metadata!.length, equals(2));
|
||||||
|
@ -216,11 +217,12 @@ void main() {
|
||||||
|
|
||||||
test('scanned type works with reflection', () {
|
test('scanned type works with reflection', () {
|
||||||
// Register base metadata
|
// Register base metadata
|
||||||
Reflector.register(TestClass);
|
ReflectionRegistry.register(TestClass);
|
||||||
Reflector.registerProperty(TestClass, 'name', String);
|
ReflectionRegistry.registerProperty(TestClass, 'name', String);
|
||||||
Reflector.registerProperty(TestClass, 'id', int, isWritable: false);
|
ReflectionRegistry.registerProperty(TestClass, 'id', int,
|
||||||
Reflector.registerProperty(TestClass, 'tags', List<String>);
|
isWritable: false);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerProperty(TestClass, 'tags', List<String>);
|
||||||
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'addTag',
|
'addTag',
|
||||||
[String],
|
[String],
|
||||||
|
@ -228,7 +230,7 @@ void main() {
|
||||||
parameterNames: ['tag'],
|
parameterNames: ['tag'],
|
||||||
isRequired: [true],
|
isRequired: [true],
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'greet',
|
'greet',
|
||||||
[String],
|
[String],
|
||||||
|
@ -236,7 +238,7 @@ void main() {
|
||||||
parameterNames: ['greeting'],
|
parameterNames: ['greeting'],
|
||||||
isRequired: [false],
|
isRequired: [false],
|
||||||
);
|
);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
TestClass,
|
TestClass,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String, int, List<String>],
|
parameterTypes: [String, int, List<String>],
|
||||||
|
@ -246,7 +248,7 @@ void main() {
|
||||||
creator: (String name, {required int id, List<String>? tags}) =>
|
creator: (String name, {required int id, List<String>? tags}) =>
|
||||||
TestClass(name, id: id, tags: tags),
|
TestClass(name, id: id, tags: tags),
|
||||||
);
|
);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
TestClass,
|
TestClass,
|
||||||
'guest',
|
'guest',
|
||||||
creator: () => TestClass.guest(),
|
creator: () => TestClass.guest(),
|
||||||
|
@ -299,10 +301,10 @@ void main() {
|
||||||
|
|
||||||
test('handles generic types correctly', () {
|
test('handles generic types correctly', () {
|
||||||
// Register base metadata
|
// Register base metadata
|
||||||
Reflector.register(GenericTestClass);
|
ReflectionRegistry.register(GenericTestClass);
|
||||||
Reflector.registerProperty(GenericTestClass, 'value', dynamic);
|
ReflectionRegistry.registerProperty(GenericTestClass, 'value', dynamic);
|
||||||
Reflector.registerProperty(GenericTestClass, 'items', List);
|
ReflectionRegistry.registerProperty(GenericTestClass, 'items', List);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
GenericTestClass,
|
GenericTestClass,
|
||||||
'addItem',
|
'addItem',
|
||||||
[dynamic],
|
[dynamic],
|
||||||
|
@ -310,7 +312,7 @@ void main() {
|
||||||
parameterNames: ['item'],
|
parameterNames: ['item'],
|
||||||
isRequired: [true],
|
isRequired: [true],
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
GenericTestClass,
|
GenericTestClass,
|
||||||
'getValue',
|
'getValue',
|
||||||
[],
|
[],
|
||||||
|
@ -319,14 +321,14 @@ void main() {
|
||||||
|
|
||||||
// Scan type
|
// Scan type
|
||||||
Scanner.scanType(GenericTestClass);
|
Scanner.scanType(GenericTestClass);
|
||||||
final metadata = Reflector.getPropertyMetadata(GenericTestClass);
|
final metadata = ReflectionRegistry.getPropertyMetadata(GenericTestClass);
|
||||||
|
|
||||||
expect(metadata, isNotNull);
|
expect(metadata, isNotNull);
|
||||||
expect(metadata!['value'], isNotNull);
|
expect(metadata!['value'], isNotNull);
|
||||||
expect(metadata['items'], isNotNull);
|
expect(metadata['items'], isNotNull);
|
||||||
expect(metadata['items']!.type, equals(List));
|
expect(metadata['items']!.type, equals(List));
|
||||||
|
|
||||||
final methodMeta = Reflector.getMethodMetadata(GenericTestClass);
|
final methodMeta = ReflectionRegistry.getMethodMetadata(GenericTestClass);
|
||||||
expect(methodMeta, isNotNull);
|
expect(methodMeta, isNotNull);
|
||||||
expect(methodMeta!['addItem'], isNotNull);
|
expect(methodMeta!['addItem'], isNotNull);
|
||||||
expect(methodMeta['getValue'], isNotNull);
|
expect(methodMeta['getValue'], isNotNull);
|
||||||
|
@ -334,24 +336,24 @@ void main() {
|
||||||
|
|
||||||
test('handles inheritance correctly', () {
|
test('handles inheritance correctly', () {
|
||||||
// Register base metadata
|
// Register base metadata
|
||||||
Reflector.register(ParentTestClass);
|
ReflectionRegistry.register(ParentTestClass);
|
||||||
Reflector.register(ChildTestClass);
|
ReflectionRegistry.register(ChildTestClass);
|
||||||
Reflector.registerProperty(ParentTestClass, 'name', String);
|
ReflectionRegistry.registerProperty(ParentTestClass, 'name', String);
|
||||||
Reflector.registerProperty(ChildTestClass, 'name', String);
|
ReflectionRegistry.registerProperty(ChildTestClass, 'name', String);
|
||||||
Reflector.registerProperty(ChildTestClass, 'age', int);
|
ReflectionRegistry.registerProperty(ChildTestClass, 'age', int);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
ParentTestClass,
|
ParentTestClass,
|
||||||
'getName',
|
'getName',
|
||||||
[],
|
[],
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
ChildTestClass,
|
ChildTestClass,
|
||||||
'getName',
|
'getName',
|
||||||
[],
|
[],
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
ChildTestClass,
|
ChildTestClass,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String, int],
|
parameterTypes: [String, int],
|
||||||
|
@ -365,8 +367,9 @@ void main() {
|
||||||
Scanner.scanType(ParentTestClass);
|
Scanner.scanType(ParentTestClass);
|
||||||
Scanner.scanType(ChildTestClass);
|
Scanner.scanType(ChildTestClass);
|
||||||
|
|
||||||
final parentMeta = Reflector.getPropertyMetadata(ParentTestClass);
|
final parentMeta =
|
||||||
final childMeta = Reflector.getPropertyMetadata(ChildTestClass);
|
ReflectionRegistry.getPropertyMetadata(ParentTestClass);
|
||||||
|
final childMeta = ReflectionRegistry.getPropertyMetadata(ChildTestClass);
|
||||||
|
|
||||||
expect(parentMeta, isNotNull);
|
expect(parentMeta, isNotNull);
|
||||||
expect(parentMeta!['name'], isNotNull);
|
expect(parentMeta!['name'], isNotNull);
|
|
@ -1,127 +0,0 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
|
||||||
|
|
||||||
/// Registry of reflectable types and their metadata.
|
|
||||||
class ReflectionRegistry {
|
|
||||||
/// Map of type to its property metadata
|
|
||||||
static final _properties = <Type, Map<String, PropertyMetadata>>{};
|
|
||||||
|
|
||||||
/// Map of type to its method metadata
|
|
||||||
static final _methods = <Type, Map<String, MethodMetadata>>{};
|
|
||||||
|
|
||||||
/// Map of type to its constructor metadata
|
|
||||||
static final _constructors = <Type, List<ConstructorMetadata>>{};
|
|
||||||
|
|
||||||
/// Map of type to its constructor factories
|
|
||||||
static final _constructorFactories = <Type, Map<String, Function>>{};
|
|
||||||
|
|
||||||
/// Registers a type as reflectable
|
|
||||||
static void registerType(Type type) {
|
|
||||||
_properties[type] = {};
|
|
||||||
_methods[type] = {};
|
|
||||||
_constructors[type] = [];
|
|
||||||
_constructorFactories[type] = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers a property for a type
|
|
||||||
static void registerProperty(
|
|
||||||
Type type,
|
|
||||||
String name,
|
|
||||||
Type propertyType, {
|
|
||||||
bool isReadable = true,
|
|
||||||
bool isWritable = true,
|
|
||||||
}) {
|
|
||||||
_properties[type]![name] = PropertyMetadata(
|
|
||||||
name: name,
|
|
||||||
type: propertyType,
|
|
||||||
isReadable: isReadable,
|
|
||||||
isWritable: isWritable,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers a method for a type
|
|
||||||
static void registerMethod(
|
|
||||||
Type type,
|
|
||||||
String name,
|
|
||||||
List<Type> parameterTypes,
|
|
||||||
bool returnsVoid,
|
|
||||||
Type returnType, {
|
|
||||||
List<String>? parameterNames,
|
|
||||||
List<bool>? isRequired,
|
|
||||||
List<bool>? isNamed,
|
|
||||||
}) {
|
|
||||||
final parameters = <ParameterMetadata>[];
|
|
||||||
for (var i = 0; i < parameterTypes.length; i++) {
|
|
||||||
parameters.add(ParameterMetadata(
|
|
||||||
name: parameterNames?[i] ?? 'param$i',
|
|
||||||
type: parameterTypes[i],
|
|
||||||
isRequired: isRequired?[i] ?? true,
|
|
||||||
isNamed: isNamed?[i] ?? false,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
_methods[type]![name] = MethodMetadata(
|
|
||||||
name: name,
|
|
||||||
parameterTypes: parameterTypes,
|
|
||||||
parameters: parameters,
|
|
||||||
returnsVoid: returnsVoid,
|
|
||||||
returnType: returnType,
|
|
||||||
isStatic: false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers a constructor for a type
|
|
||||||
static void registerConstructor(
|
|
||||||
Type type,
|
|
||||||
String name,
|
|
||||||
Function factory, {
|
|
||||||
List<Type>? parameterTypes,
|
|
||||||
List<String>? parameterNames,
|
|
||||||
List<bool>? isRequired,
|
|
||||||
List<bool>? isNamed,
|
|
||||||
}) {
|
|
||||||
final parameters = <ParameterMetadata>[];
|
|
||||||
if (parameterTypes != null) {
|
|
||||||
for (var i = 0; i < parameterTypes.length; i++) {
|
|
||||||
parameters.add(ParameterMetadata(
|
|
||||||
name: parameterNames?[i] ?? 'param$i',
|
|
||||||
type: parameterTypes[i],
|
|
||||||
isRequired: isRequired?[i] ?? true,
|
|
||||||
isNamed: isNamed?[i] ?? false,
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_constructors[type]!.add(ConstructorMetadata(
|
|
||||||
name: name,
|
|
||||||
parameterTypes: parameterTypes ?? [],
|
|
||||||
parameters: parameters,
|
|
||||||
));
|
|
||||||
_constructorFactories[type]![name] = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets property metadata for a type
|
|
||||||
static Map<String, PropertyMetadata>? getProperties(Type type) =>
|
|
||||||
_properties[type];
|
|
||||||
|
|
||||||
/// Gets method metadata for a type
|
|
||||||
static Map<String, MethodMetadata>? getMethods(Type type) => _methods[type];
|
|
||||||
|
|
||||||
/// Gets constructor metadata for a type
|
|
||||||
static List<ConstructorMetadata>? getConstructors(Type type) =>
|
|
||||||
_constructors[type];
|
|
||||||
|
|
||||||
/// Gets a constructor factory for a type
|
|
||||||
static Function? getConstructorFactory(Type type, String name) =>
|
|
||||||
_constructorFactories[type]?[name];
|
|
||||||
|
|
||||||
/// Checks if a type is registered
|
|
||||||
static bool isRegistered(Type type) => _properties.containsKey(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Marks a class as reflectable, allowing runtime reflection capabilities.
|
|
||||||
class Reflectable {
|
|
||||||
const Reflectable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The annotation used to mark classes as reflectable.
|
|
||||||
const reflectable = Reflectable();
|
|
|
@ -1,48 +0,0 @@
|
||||||
/// Base class for all reflection-related exceptions.
|
|
||||||
class ReflectionException implements Exception {
|
|
||||||
/// The error message.
|
|
||||||
final String message;
|
|
||||||
|
|
||||||
/// Creates a new reflection exception.
|
|
||||||
const ReflectionException(this.message);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String toString() => 'ReflectionException: $message';
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Exception thrown when attempting to reflect on a non-reflectable type.
|
|
||||||
class NotReflectableException extends ReflectionException {
|
|
||||||
/// The type that was not reflectable.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// Creates a new not reflectable exception.
|
|
||||||
const NotReflectableException(this.type)
|
|
||||||
: super('Type $type is not reflectable. '
|
|
||||||
'Make sure it is annotated with @reflectable or registered manually.');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Exception thrown when invalid arguments are provided to a reflective operation.
|
|
||||||
class InvalidArgumentsException extends ReflectionException {
|
|
||||||
/// The name of the member being invoked.
|
|
||||||
final String memberName;
|
|
||||||
|
|
||||||
/// The type the member belongs to.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// Creates a new invalid arguments exception.
|
|
||||||
const InvalidArgumentsException(this.memberName, this.type)
|
|
||||||
: super('Invalid arguments for $memberName on type $type');
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Exception thrown when a member is not found during reflection.
|
|
||||||
class MemberNotFoundException extends ReflectionException {
|
|
||||||
/// The name of the member that was not found.
|
|
||||||
final String memberName;
|
|
||||||
|
|
||||||
/// The type the member was looked up on.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// Creates a new member not found exception.
|
|
||||||
const MemberNotFoundException(this.memberName, this.type)
|
|
||||||
: super('Member $memberName not found on type $type');
|
|
||||||
}
|
|
|
@ -1,311 +0,0 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
|
||||||
|
|
||||||
/// Represents metadata about a type parameter.
|
|
||||||
class TypeParameterMetadata {
|
|
||||||
/// The name of the type parameter (e.g., 'T', 'E').
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The type of the parameter.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// The upper bound of the type parameter, if any.
|
|
||||||
final Type? bound;
|
|
||||||
|
|
||||||
/// Any attributes (annotations) on this type parameter.
|
|
||||||
final List<Object> attributes;
|
|
||||||
|
|
||||||
/// Creates a new type parameter metadata instance.
|
|
||||||
const TypeParameterMetadata({
|
|
||||||
required this.name,
|
|
||||||
required this.type,
|
|
||||||
this.bound,
|
|
||||||
this.attributes = const [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents metadata about a parameter.
|
|
||||||
class ParameterMetadata {
|
|
||||||
/// The name of the parameter.
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The type of the parameter.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// Whether this parameter is required.
|
|
||||||
final bool isRequired;
|
|
||||||
|
|
||||||
/// Whether this parameter is named.
|
|
||||||
final bool isNamed;
|
|
||||||
|
|
||||||
/// The default value for this parameter, if any.
|
|
||||||
final Object? defaultValue;
|
|
||||||
|
|
||||||
/// Any attributes (annotations) on this parameter.
|
|
||||||
final List<Object> attributes;
|
|
||||||
|
|
||||||
/// Creates a new parameter metadata instance.
|
|
||||||
const ParameterMetadata({
|
|
||||||
required this.name,
|
|
||||||
required this.type,
|
|
||||||
required this.isRequired,
|
|
||||||
this.isNamed = false,
|
|
||||||
this.defaultValue,
|
|
||||||
this.attributes = const [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents metadata about a type's property.
|
|
||||||
class PropertyMetadata {
|
|
||||||
/// The name of the property.
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The type of the property.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// Whether the property can be read.
|
|
||||||
final bool isReadable;
|
|
||||||
|
|
||||||
/// Whether the property can be written to.
|
|
||||||
final bool isWritable;
|
|
||||||
|
|
||||||
/// Any attributes (annotations) on this property.
|
|
||||||
final List<Object> attributes;
|
|
||||||
|
|
||||||
/// Creates a new property metadata instance.
|
|
||||||
const PropertyMetadata({
|
|
||||||
required this.name,
|
|
||||||
required this.type,
|
|
||||||
this.isReadable = true,
|
|
||||||
this.isWritable = true,
|
|
||||||
this.attributes = const [],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents metadata about a type's method.
|
|
||||||
class MethodMetadata {
|
|
||||||
/// The name of the method.
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The parameter types of the method in order.
|
|
||||||
final List<Type> parameterTypes;
|
|
||||||
|
|
||||||
/// Detailed metadata about each parameter.
|
|
||||||
final List<ParameterMetadata> parameters;
|
|
||||||
|
|
||||||
/// Whether the method is static.
|
|
||||||
final bool isStatic;
|
|
||||||
|
|
||||||
/// Whether the method returns void.
|
|
||||||
final bool returnsVoid;
|
|
||||||
|
|
||||||
/// The return type of the method.
|
|
||||||
final Type returnType;
|
|
||||||
|
|
||||||
/// Any attributes (annotations) on this method.
|
|
||||||
final List<Object> attributes;
|
|
||||||
|
|
||||||
/// Type parameters for generic methods.
|
|
||||||
final List<TypeParameterMetadata> typeParameters;
|
|
||||||
|
|
||||||
/// Creates a new method metadata instance.
|
|
||||||
const MethodMetadata({
|
|
||||||
required this.name,
|
|
||||||
required this.parameterTypes,
|
|
||||||
required this.parameters,
|
|
||||||
required this.returnsVoid,
|
|
||||||
required this.returnType,
|
|
||||||
this.isStatic = false,
|
|
||||||
this.attributes = const [],
|
|
||||||
this.typeParameters = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Validates the given arguments against this method's parameter types.
|
|
||||||
bool validateArguments(List<Object?> arguments) {
|
|
||||||
if (arguments.length != parameterTypes.length) return false;
|
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
|
||||||
final arg = arguments[i];
|
|
||||||
if (arg != null && arg.runtimeType != parameterTypes[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents metadata about a type's constructor.
|
|
||||||
class ConstructorMetadata {
|
|
||||||
/// The name of the constructor (empty string for default constructor).
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The parameter types of the constructor in order.
|
|
||||||
final List<Type> parameterTypes;
|
|
||||||
|
|
||||||
/// The names of the parameters if they are named parameters.
|
|
||||||
final List<String>? parameterNames;
|
|
||||||
|
|
||||||
/// Detailed metadata about each parameter.
|
|
||||||
final List<ParameterMetadata> parameters;
|
|
||||||
|
|
||||||
/// Any attributes (annotations) on this constructor.
|
|
||||||
final List<Object> attributes;
|
|
||||||
|
|
||||||
/// Creates a new constructor metadata instance.
|
|
||||||
const ConstructorMetadata({
|
|
||||||
this.name = '',
|
|
||||||
required this.parameterTypes,
|
|
||||||
required this.parameters,
|
|
||||||
this.parameterNames,
|
|
||||||
this.attributes = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Whether this constructor uses named parameters.
|
|
||||||
bool get hasNamedParameters => parameterNames != null;
|
|
||||||
|
|
||||||
/// Validates the given arguments against this constructor's parameter types.
|
|
||||||
bool validateArguments(List<Object?> arguments) {
|
|
||||||
if (arguments.length != parameterTypes.length) return false;
|
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
|
||||||
final arg = arguments[i];
|
|
||||||
if (arg != null && arg.runtimeType != parameterTypes[i]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents metadata about a type.
|
|
||||||
class TypeMetadata {
|
|
||||||
/// The actual type this metadata represents.
|
|
||||||
final Type type;
|
|
||||||
|
|
||||||
/// The name of the type.
|
|
||||||
final String name;
|
|
||||||
|
|
||||||
/// The properties defined on this type.
|
|
||||||
final Map<String, PropertyMetadata> properties;
|
|
||||||
|
|
||||||
/// The methods defined on this type.
|
|
||||||
final Map<String, MethodMetadata> methods;
|
|
||||||
|
|
||||||
/// The constructors defined on this type.
|
|
||||||
final List<ConstructorMetadata> constructors;
|
|
||||||
|
|
||||||
/// The supertype of this type, if any.
|
|
||||||
final TypeMetadata? supertype;
|
|
||||||
|
|
||||||
/// The interfaces this type implements.
|
|
||||||
final List<TypeMetadata> interfaces;
|
|
||||||
|
|
||||||
/// The mixins this type uses.
|
|
||||||
final List<TypeMetadata> mixins;
|
|
||||||
|
|
||||||
/// Any attributes (annotations) on this type.
|
|
||||||
final List<Object> attributes;
|
|
||||||
|
|
||||||
/// Type parameters for generic types.
|
|
||||||
final List<TypeParameterMetadata> typeParameters;
|
|
||||||
|
|
||||||
/// Type arguments if this is a generic type instantiation.
|
|
||||||
final List<TypeMetadata> typeArguments;
|
|
||||||
|
|
||||||
/// Creates a new type metadata instance.
|
|
||||||
const TypeMetadata({
|
|
||||||
required this.type,
|
|
||||||
required this.name,
|
|
||||||
required this.properties,
|
|
||||||
required this.methods,
|
|
||||||
required this.constructors,
|
|
||||||
this.supertype,
|
|
||||||
this.interfaces = const [],
|
|
||||||
this.mixins = const [],
|
|
||||||
this.attributes = const [],
|
|
||||||
this.typeParameters = const [],
|
|
||||||
this.typeArguments = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Whether this type is generic (has type parameters).
|
|
||||||
bool get isGeneric => typeParameters.isNotEmpty;
|
|
||||||
|
|
||||||
/// Whether this is a generic type instantiation.
|
|
||||||
bool get isGenericInstantiation => typeArguments.isNotEmpty;
|
|
||||||
|
|
||||||
/// Gets a property by name, throwing if not found.
|
|
||||||
PropertyMetadata getProperty(String name) {
|
|
||||||
final property = properties[name];
|
|
||||||
if (property == null) {
|
|
||||||
throw MemberNotFoundException(name, type);
|
|
||||||
}
|
|
||||||
return property;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a method by name, throwing if not found.
|
|
||||||
MethodMetadata getMethod(String name) {
|
|
||||||
final method = methods[name];
|
|
||||||
if (method == null) {
|
|
||||||
throw MemberNotFoundException(name, type);
|
|
||||||
}
|
|
||||||
return method;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the default constructor, throwing if not found.
|
|
||||||
ConstructorMetadata get defaultConstructor {
|
|
||||||
return constructors.firstWhere(
|
|
||||||
(c) => c.name.isEmpty,
|
|
||||||
orElse: () => throw ReflectionException(
|
|
||||||
'No default constructor found for type "$name"',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a named constructor, throwing if not found.
|
|
||||||
ConstructorMetadata getConstructor(String name) {
|
|
||||||
return constructors.firstWhere(
|
|
||||||
(c) => c.name == name,
|
|
||||||
orElse: () => throw ReflectionException(
|
|
||||||
'Constructor "$name" not found for type "$type"',
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents metadata about a function.
|
|
||||||
class FunctionMetadata {
|
|
||||||
/// The parameters of the function.
|
|
||||||
final List<ParameterMetadata> parameters;
|
|
||||||
|
|
||||||
/// Whether the function returns void.
|
|
||||||
final bool returnsVoid;
|
|
||||||
|
|
||||||
/// The return type of the function.
|
|
||||||
final Type returnType;
|
|
||||||
|
|
||||||
/// Type parameters for generic functions.
|
|
||||||
final List<TypeParameterMetadata> typeParameters;
|
|
||||||
|
|
||||||
/// Creates a new function metadata instance.
|
|
||||||
const FunctionMetadata({
|
|
||||||
required this.parameters,
|
|
||||||
required this.returnsVoid,
|
|
||||||
required this.returnType,
|
|
||||||
this.typeParameters = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
/// Validates the given arguments against this function's parameters.
|
|
||||||
bool validateArguments(List<Object?> arguments) {
|
|
||||||
if (arguments.length != parameters.length) return false;
|
|
||||||
|
|
||||||
for (var i = 0; i < arguments.length; i++) {
|
|
||||||
final arg = arguments[i];
|
|
||||||
if (arg != null && arg.runtimeType != parameters[i].type) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_macroable/platform_macroable.dart';
|
import 'package:platform_macroable/platform_macroable.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Provides higher-order tap functionality with macro support.
|
/// Provides higher-order tap functionality with macro support.
|
||||||
///
|
///
|
||||||
|
@ -33,7 +33,7 @@ class HigherOrderTapProxy<T extends Object> with Macroable {
|
||||||
return super.noSuchMethod(invocation);
|
return super.noSuchMethod(invocation);
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
// If not a macro, forward to target
|
// If not a macro, forward to target
|
||||||
final methods = Reflector.getMethodMetadata(_target.runtimeType);
|
final methods = ReflectionRegistry.getMethodMetadata(_target.runtimeType);
|
||||||
if (methods == null) {
|
if (methods == null) {
|
||||||
throw NoSuchMethodError.withInvocation(_target, invocation);
|
throw NoSuchMethodError.withInvocation(_target, invocation);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'once.dart';
|
import 'once.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// A class that provides functionality to ensure methods are only executed once.
|
/// A class that provides functionality to ensure methods are only executed once.
|
||||||
///
|
///
|
||||||
|
@ -25,9 +25,9 @@ class Onceable {
|
||||||
|
|
||||||
// If not executed yet, register the callback type
|
// If not executed yet, register the callback type
|
||||||
if (!_once[key]!.executed &&
|
if (!_once[key]!.executed &&
|
||||||
!Reflector.isReflectable(callback.runtimeType)) {
|
!ReflectionRegistry.isReflectable(callback.runtimeType)) {
|
||||||
Reflector.register(callback.runtimeType);
|
ReflectionRegistry.register(callback.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
callback.runtimeType,
|
callback.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
const <Type>[],
|
const <Type>[],
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_macroable/platform_macroable.dart';
|
import 'package:platform_macroable/platform_macroable.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Provides Laravel-like Optional type functionality with macro support.
|
/// Provides Laravel-like Optional type functionality with macro support.
|
||||||
///
|
///
|
||||||
|
@ -46,7 +46,8 @@ class Optional<T> with Macroable {
|
||||||
final instance = reflector.reflect(_value!);
|
final instance = reflector.reflect(_value!);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
final type = instance.type;
|
final type = instance.type;
|
||||||
final metadata = Reflector.getPropertyMetadata(type.reflectedType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getPropertyMetadata(type.reflectedType);
|
||||||
|
|
||||||
if (metadata != null && metadata.containsKey(key)) {
|
if (metadata != null && metadata.containsKey(key)) {
|
||||||
// Access property through dynamic dispatch
|
// Access property through dynamic dispatch
|
||||||
|
@ -89,7 +90,8 @@ class Optional<T> with Macroable {
|
||||||
final instance = reflector.reflect(_value!);
|
final instance = reflector.reflect(_value!);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
final type = instance.type;
|
final type = instance.type;
|
||||||
final metadata = Reflector.getPropertyMetadata(type.reflectedType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getPropertyMetadata(type.reflectedType);
|
||||||
return metadata != null && metadata.containsKey(key);
|
return metadata != null && metadata.containsKey(key);
|
||||||
}
|
}
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// Provides reflection utilities for examining types and methods at runtime.
|
/// Provides reflection utilities for examining types and methods at runtime.
|
||||||
class SupportReflector {
|
class SupportReflector {
|
||||||
|
@ -28,12 +28,12 @@ class SupportReflector {
|
||||||
final targetType = target is Type ? target : target.runtimeType;
|
final targetType = target is Type ? target : target.runtimeType;
|
||||||
|
|
||||||
// Check if type is registered for reflection
|
// Check if type is registered for reflection
|
||||||
if (!Reflector.isReflectable(targetType)) {
|
if (!ReflectionRegistry.isReflectable(targetType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for regular method
|
// Check for regular method
|
||||||
final methods = Reflector.getMethodMetadata(targetType);
|
final methods = ReflectionRegistry.getMethodMetadata(targetType);
|
||||||
if (methods != null) {
|
if (methods != null) {
|
||||||
// If the method is private, return false
|
// If the method is private, return false
|
||||||
if (methodName.startsWith('_')) {
|
if (methodName.startsWith('_')) {
|
||||||
|
@ -157,12 +157,12 @@ class SupportReflector {
|
||||||
final reflectedType = type.reflectedType;
|
final reflectedType = type.reflectedType;
|
||||||
|
|
||||||
// Check if it's registered for reflection
|
// Check if it's registered for reflection
|
||||||
if (!Reflector.isReflectable(reflectedType)) {
|
if (!ReflectionRegistry.isReflectable(reflectedType)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the property metadata
|
// Get the property metadata
|
||||||
final properties = Reflector.getPropertyMetadata(reflectedType);
|
final properties = ReflectionRegistry.getPropertyMetadata(reflectedType);
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// A mixin that provides method forwarding functionality.
|
/// A mixin that provides method forwarding functionality.
|
||||||
///
|
///
|
||||||
|
@ -38,7 +38,7 @@ mixin ForwardsCalls {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get method metadata
|
// Get method metadata
|
||||||
final methods = Reflector.getMethodMetadata(object.runtimeType);
|
final methods = ReflectionRegistry.getMethodMetadata(object.runtimeType);
|
||||||
if (methods == null || !methods.containsKey(method)) {
|
if (methods == null || !methods.containsKey(method)) {
|
||||||
throwBadMethodCallException(method);
|
throwBadMethodCallException(method);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
/// A trait that provides functionality to reflect on closures.
|
/// A trait that provides functionality to reflect on closures.
|
||||||
mixin ReflectsClosures {
|
mixin ReflectsClosures {
|
||||||
/// Get the number of parameters that a closure accepts.
|
/// Get the number of parameters that a closure accepts.
|
||||||
int getClosureParameterCount(Function closure) {
|
int getClosureParameterCount(Function closure) {
|
||||||
try {
|
try {
|
||||||
final metadata = Reflector.getMethodMetadata(closure.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getMethodMetadata(closure.runtimeType);
|
||||||
if (metadata == null || !metadata.containsKey('call')) {
|
if (metadata == null || !metadata.containsKey('call')) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +20,8 @@ mixin ReflectsClosures {
|
||||||
/// Get the parameter names of a closure.
|
/// Get the parameter names of a closure.
|
||||||
List<String> getClosureParameterNames(Function closure) {
|
List<String> getClosureParameterNames(Function closure) {
|
||||||
try {
|
try {
|
||||||
final metadata = Reflector.getMethodMetadata(closure.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getMethodMetadata(closure.runtimeType);
|
||||||
if (metadata == null || !metadata.containsKey('call')) {
|
if (metadata == null || !metadata.containsKey('call')) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -33,7 +35,8 @@ mixin ReflectsClosures {
|
||||||
/// Get the parameter types of a closure.
|
/// Get the parameter types of a closure.
|
||||||
List<Type> getClosureParameterTypes(Function closure) {
|
List<Type> getClosureParameterTypes(Function closure) {
|
||||||
try {
|
try {
|
||||||
final metadata = Reflector.getMethodMetadata(closure.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getMethodMetadata(closure.runtimeType);
|
||||||
if (metadata == null || !metadata.containsKey('call')) {
|
if (metadata == null || !metadata.containsKey('call')) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -52,7 +55,8 @@ mixin ReflectsClosures {
|
||||||
/// Determine if a closure returns void.
|
/// Determine if a closure returns void.
|
||||||
bool isClosureVoid(Function closure) {
|
bool isClosureVoid(Function closure) {
|
||||||
try {
|
try {
|
||||||
final metadata = Reflector.getMethodMetadata(closure.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getMethodMetadata(closure.runtimeType);
|
||||||
if (metadata == null || !metadata.containsKey('call')) {
|
if (metadata == null || !metadata.containsKey('call')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +70,8 @@ mixin ReflectsClosures {
|
||||||
/// Determine if a closure is nullable.
|
/// Determine if a closure is nullable.
|
||||||
bool isClosureNullable(Function closure) {
|
bool isClosureNullable(Function closure) {
|
||||||
try {
|
try {
|
||||||
final metadata = Reflector.getMethodMetadata(closure.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getMethodMetadata(closure.runtimeType);
|
||||||
if (metadata == null || !metadata.containsKey('call')) {
|
if (metadata == null || !metadata.containsKey('call')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +94,8 @@ mixin ReflectsClosures {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also check if it's marked as async in the metadata
|
// Also check if it's marked as async in the metadata
|
||||||
final metadata = Reflector.getMethodMetadata(closure.runtimeType);
|
final metadata =
|
||||||
|
ReflectionRegistry.getMethodMetadata(closure.runtimeType);
|
||||||
if (metadata == null || !metadata.containsKey('call')) {
|
if (metadata == null || !metadata.containsKey('call')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ dependencies:
|
||||||
platform_conditionable: ^1.0.0
|
platform_conditionable: ^1.0.0
|
||||||
platform_contracts: ^1.0.0
|
platform_contracts: ^1.0.0
|
||||||
platform_macroable: ^1.0.0
|
platform_macroable: ^1.0.0
|
||||||
platform_reflection: ^1.0.0
|
platform_mirrors: ^1.0.0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:platform_support/platform_support.dart';
|
import 'package:platform_support/platform_support.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -10,7 +10,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('Onceable', () {
|
group('Onceable', () {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_support/platform_support.dart';
|
import 'package:platform_support/platform_support.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
class TargetClass {
|
class TargetClass {
|
||||||
|
@ -32,18 +32,18 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
// Register classes for reflection
|
// Register classes for reflection
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
Reflector.register(TargetClass);
|
ReflectionRegistry.register(TargetClass);
|
||||||
|
|
||||||
// Register methods
|
// Register methods
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TargetClass,
|
TargetClass,
|
||||||
'getValue',
|
'getValue',
|
||||||
[/* no parameters */],
|
[/* no parameters */],
|
||||||
false, // not void
|
false, // not void
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TargetClass,
|
TargetClass,
|
||||||
'setValue',
|
'setValue',
|
||||||
[String],
|
[String],
|
||||||
|
@ -52,14 +52,14 @@ void main() {
|
||||||
isRequired: [true],
|
isRequired: [true],
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TargetClass,
|
TargetClass,
|
||||||
'chainedMethod',
|
'chainedMethod',
|
||||||
[/* no parameters */],
|
[/* no parameters */],
|
||||||
false, // not void
|
false, // not void
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TargetClass,
|
TargetClass,
|
||||||
'throwingMethod',
|
'throwingMethod',
|
||||||
[/* no parameters */],
|
[/* no parameters */],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_support/platform_support.dart';
|
import 'package:platform_support/platform_support.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
class TestObject {
|
class TestObject {
|
||||||
|
@ -13,16 +13,16 @@ void main() {
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
reflector = RuntimeReflector.instance;
|
reflector = RuntimeReflector.instance;
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
|
|
||||||
// Register TestObject for reflection
|
// Register TestObject for reflection
|
||||||
Reflector.register(TestObject);
|
ReflectionRegistry.register(TestObject);
|
||||||
|
|
||||||
// Register property
|
// Register property
|
||||||
Reflector.registerProperty(TestObject, 'item', String);
|
ReflectionRegistry.registerProperty(TestObject, 'item', String);
|
||||||
|
|
||||||
// Register constructors
|
// Register constructors
|
||||||
Reflector.registerConstructor(
|
ReflectionRegistry.registerConstructor(
|
||||||
TestObject,
|
TestObject,
|
||||||
'',
|
'',
|
||||||
parameterTypes: [String],
|
parameterTypes: [String],
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_contracts/contracts.dart';
|
import 'package:platform_contracts/contracts.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:platform_support/platform_support.dart';
|
import 'package:platform_support/platform_support.dart';
|
||||||
|
|
||||||
class TestClass {
|
class TestClass {
|
||||||
|
@ -106,8 +106,8 @@ void main() {
|
||||||
testClassMirror.declarations[Symbol('noSuchMethod')] = noSuchMethodMirror;
|
testClassMirror.declarations[Symbol('noSuchMethod')] = noSuchMethodMirror;
|
||||||
|
|
||||||
// Register test classes
|
// Register test classes
|
||||||
Reflector.register(TestClass);
|
ReflectionRegistry.register(TestClass);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'publicMethod',
|
'publicMethod',
|
||||||
[TestClass],
|
[TestClass],
|
||||||
|
@ -117,7 +117,7 @@ void main() {
|
||||||
isNamed: [false],
|
isNamed: [false],
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'_privateMethod',
|
'_privateMethod',
|
||||||
[TestClass],
|
[TestClass],
|
||||||
|
@ -127,7 +127,7 @@ void main() {
|
||||||
isNamed: [false],
|
isNamed: [false],
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
);
|
);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TestClass,
|
TestClass,
|
||||||
'noSuchMethod',
|
'noSuchMethod',
|
||||||
[Invocation],
|
[Invocation],
|
||||||
|
@ -139,20 +139,20 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register enums
|
// Register enums
|
||||||
Reflector.register(SimpleEnum);
|
ReflectionRegistry.register(SimpleEnum);
|
||||||
Reflector.registerProperty(
|
ReflectionRegistry.registerProperty(
|
||||||
SimpleEnum,
|
SimpleEnum,
|
||||||
'values',
|
'values',
|
||||||
List<SimpleEnum>,
|
List<SimpleEnum>,
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.register(BackedEnum);
|
ReflectionRegistry.register(BackedEnum);
|
||||||
Reflector.registerProperty(
|
ReflectionRegistry.registerProperty(
|
||||||
BackedEnum,
|
BackedEnum,
|
||||||
'values',
|
'values',
|
||||||
List<BackedEnum>,
|
List<BackedEnum>,
|
||||||
);
|
);
|
||||||
Reflector.registerProperty(
|
ReflectionRegistry.registerProperty(
|
||||||
BackedEnum,
|
BackedEnum,
|
||||||
'name',
|
'name',
|
||||||
String,
|
String,
|
||||||
|
@ -162,7 +162,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('SupportReflector', () {
|
group('SupportReflector', () {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_support/platform_support.dart';
|
import 'package:platform_support/platform_support.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
|
|
||||||
@reflectable
|
@reflectable
|
||||||
class TappableTest with Tappable {
|
class TappableTest with Tappable {
|
||||||
|
@ -34,11 +34,11 @@ void main() {
|
||||||
instance = TappableTest();
|
instance = TappableTest();
|
||||||
|
|
||||||
// Register class and methods for reflection
|
// Register class and methods for reflection
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
Reflector.register(TappableTest);
|
ReflectionRegistry.register(TappableTest);
|
||||||
|
|
||||||
// Register setValue method
|
// Register setValue method
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TappableTest,
|
TappableTest,
|
||||||
'setValue',
|
'setValue',
|
||||||
[String],
|
[String],
|
||||||
|
@ -48,7 +48,7 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register getValue method
|
// Register getValue method
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TappableTest,
|
TappableTest,
|
||||||
'getValue',
|
'getValue',
|
||||||
[],
|
[],
|
||||||
|
@ -56,7 +56,7 @@ void main() {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Register tap method
|
// Register tap method
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
TappableTest,
|
TappableTest,
|
||||||
'tap',
|
'tap',
|
||||||
[Function],
|
[Function],
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'package:platform_reflection/mirrors.dart';
|
import 'package:platform_mirrors/mirrors.dart';
|
||||||
import 'package:platform_support/src/traits/reflects_closures.dart';
|
import 'package:platform_support/src/traits/reflects_closures.dart';
|
||||||
|
|
||||||
class TestClass with ReflectsClosures {}
|
class TestClass with ReflectsClosures {}
|
||||||
|
@ -16,13 +16,13 @@ void main() {
|
||||||
testClass = TestClass();
|
testClass = TestClass();
|
||||||
|
|
||||||
// Register function types
|
// Register function types
|
||||||
Reflector.register(StringIntFunction);
|
ReflectionRegistry.register(StringIntFunction);
|
||||||
Reflector.register(VoidFunction);
|
ReflectionRegistry.register(VoidFunction);
|
||||||
Reflector.register(AsyncVoidFunction);
|
ReflectionRegistry.register(AsyncVoidFunction);
|
||||||
Reflector.register(IntFunction);
|
ReflectionRegistry.register(IntFunction);
|
||||||
|
|
||||||
// Register method metadata for each function type
|
// Register method metadata for each function type
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
StringIntFunction,
|
StringIntFunction,
|
||||||
'call',
|
'call',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -32,21 +32,21 @@ void main() {
|
||||||
isNamed: [false, false],
|
isNamed: [false, false],
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
VoidFunction,
|
VoidFunction,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
AsyncVoidFunction,
|
AsyncVoidFunction,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
IntFunction,
|
IntFunction,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -55,14 +55,14 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
Reflector.reset();
|
ReflectionRegistry.reset();
|
||||||
});
|
});
|
||||||
|
|
||||||
group('ReflectsClosures', () {
|
group('ReflectsClosures', () {
|
||||||
test('getClosureParameterCount returns correct count', () {
|
test('getClosureParameterCount returns correct count', () {
|
||||||
final closure = (String name, int age) {};
|
final closure = (String name, int age) {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -76,8 +76,8 @@ void main() {
|
||||||
|
|
||||||
test('getClosureParameterCount returns 0 for no parameters', () {
|
test('getClosureParameterCount returns 0 for no parameters', () {
|
||||||
final closure = () {};
|
final closure = () {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -88,8 +88,8 @@ void main() {
|
||||||
|
|
||||||
test('getClosureParameterNames returns correct names', () {
|
test('getClosureParameterNames returns correct names', () {
|
||||||
final closure = (String name, int age) {};
|
final closure = (String name, int age) {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -104,8 +104,8 @@ void main() {
|
||||||
|
|
||||||
test('getClosureParameterNames returns empty list for no parameters', () {
|
test('getClosureParameterNames returns empty list for no parameters', () {
|
||||||
final closure = () {};
|
final closure = () {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -116,8 +116,8 @@ void main() {
|
||||||
|
|
||||||
test('getClosureParameterTypes returns correct types', () {
|
test('getClosureParameterTypes returns correct types', () {
|
||||||
final closure = (String name, int age) {};
|
final closure = (String name, int age) {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -132,8 +132,8 @@ void main() {
|
||||||
|
|
||||||
test('getClosureParameterTypes returns empty list for no parameters', () {
|
test('getClosureParameterTypes returns empty list for no parameters', () {
|
||||||
final closure = () {};
|
final closure = () {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -144,8 +144,8 @@ void main() {
|
||||||
|
|
||||||
test('closureHasParameter returns true for existing parameter', () {
|
test('closureHasParameter returns true for existing parameter', () {
|
||||||
final closure = (String name, int age) {};
|
final closure = (String name, int age) {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -160,8 +160,8 @@ void main() {
|
||||||
|
|
||||||
test('closureHasParameter returns false for non-existent parameter', () {
|
test('closureHasParameter returns false for non-existent parameter', () {
|
||||||
final closure = (String name, int age) {};
|
final closure = (String name, int age) {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[String, int],
|
[String, int],
|
||||||
|
@ -175,8 +175,8 @@ void main() {
|
||||||
|
|
||||||
test('isClosureVoid returns true for void closure', () {
|
test('isClosureVoid returns true for void closure', () {
|
||||||
final closure = () {};
|
final closure = () {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -187,8 +187,8 @@ void main() {
|
||||||
|
|
||||||
test('isClosureVoid returns false for non-void closure', () {
|
test('isClosureVoid returns false for non-void closure', () {
|
||||||
final closure = () => 42;
|
final closure = () => 42;
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -199,8 +199,8 @@ void main() {
|
||||||
|
|
||||||
test('isClosureNullable returns true for nullable closure', () {
|
test('isClosureNullable returns true for nullable closure', () {
|
||||||
final closure = () => null;
|
final closure = () => null;
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -211,8 +211,8 @@ void main() {
|
||||||
|
|
||||||
test('isClosureNullable returns false for non-nullable closure', () {
|
test('isClosureNullable returns false for non-nullable closure', () {
|
||||||
final closure = () {};
|
final closure = () {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -223,8 +223,8 @@ void main() {
|
||||||
|
|
||||||
test('isClosureAsync returns true for async closure', () {
|
test('isClosureAsync returns true for async closure', () {
|
||||||
final closure = () async {};
|
final closure = () async {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
@ -235,8 +235,8 @@ void main() {
|
||||||
|
|
||||||
test('isClosureAsync returns false for sync closure', () {
|
test('isClosureAsync returns false for sync closure', () {
|
||||||
final closure = () {};
|
final closure = () {};
|
||||||
Reflector.register(closure.runtimeType);
|
ReflectionRegistry.register(closure.runtimeType);
|
||||||
Reflector.registerMethod(
|
ReflectionRegistry.registerMethod(
|
||||||
closure.runtimeType,
|
closure.runtimeType,
|
||||||
'call',
|
'call',
|
||||||
[],
|
[],
|
||||||
|
|
Loading…
Reference in a new issue