Skip to content

Commit

Permalink
v2.2.4 - Basic support for record types
Browse files Browse the repository at this point in the history
 - Added basic support for Records types.
   - Added logic to handle record types and generate typedefs for record declarations.
 - Added new tests for Records and generics in `test/reflection_factory_build_test.dart`.

 - test: ^1.24.9
 - coverage: ^1.6.4
 - data_serializer: ^1.0.12
  • Loading branch information
gmpassos authored Nov 14, 2023
2 parents 592ec0e + f82b088 commit 276eee0
Show file tree
Hide file tree
Showing 10 changed files with 257 additions and 35 deletions.
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
## 2.2.4

- Added basic support for Records types.
- Added logic to handle record types and generate typedefs for record declarations.
- Added new tests for Records and generics in `test/reflection_factory_build_test.dart`.

- test: ^1.24.9
- coverage: ^1.6.4
- data_serializer: ^1.0.12

## 2.2.3

- Added `ClassProxy.ignoreMethods2`.
Expand Down
4 changes: 2 additions & 2 deletions example/reflection_factory_bridge_example.reflection.g.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// GENERATED CODE - DO NOT MODIFY BY HAND!
// BUILDER: reflection_factory/2.2.3
// BUILDER: reflection_factory/2.2.4
// BUILD COMMAND: dart run build_runner build
//

Expand All @@ -20,7 +20,7 @@ typedef __TI<T> = TypeInfo<T>;
typedef __PR = ParameterReflection;

mixin __ReflectionMixin {
static final Version _version = Version.parse('2.2.3');
static final Version _version = Version.parse('2.2.4');

Version get reflectionFactoryVersion => _version;

Expand Down
4 changes: 2 additions & 2 deletions example/reflection_factory_example.reflection.g.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//
// GENERATED CODE - DO NOT MODIFY BY HAND!
// BUILDER: reflection_factory/2.2.3
// BUILDER: reflection_factory/2.2.4
// BUILD COMMAND: dart run build_runner build
//

Expand All @@ -20,7 +20,7 @@ typedef __TI<T> = TypeInfo<T>;
typedef __PR = ParameterReflection;

mixin __ReflectionMixin {
static final Version _version = Version.parse('2.2.3');
static final Version _version = Version.parse('2.2.4');

Version get reflectionFactoryVersion => _version;

Expand Down
6 changes: 3 additions & 3 deletions lib/src/reflection_factory_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import 'reflection_factory_utils.dart';
/// Class with all registered reflections ([ClassReflection]).
class ReflectionFactory {
// ignore: constant_identifier_names
static const String VERSION = '2.2.3';
static const String VERSION = '2.2.4';

static final ReflectionFactory _instance = ReflectionFactory._();

Expand Down Expand Up @@ -2506,8 +2506,8 @@ class TypeReflection<T> {
}

var typeStr = type.toString();
var idx = typeStr.indexOf('<');
if (idx > 0) typeStr = typeStr.substring(0, idx);
typeStr = TypeInfo.removeTypeGenerics(typeStr);

return typeStr;
}

Expand Down
89 changes: 72 additions & 17 deletions lib/src/reflection_factory_builder.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'dart:async';
import 'dart:collection';
import 'dart:io';

Expand All @@ -14,13 +13,10 @@ import 'package:build/build.dart';
import 'package:collection/collection.dart';
import 'package:dart_style/dart_style.dart';
import 'package:path/path.dart' as pack_path;
import 'package:pub_semver/pub_semver.dart';
import 'package:reflection_factory/reflection_factory.dart';

import 'analyzer/library.dart';
import 'analyzer/type_checker.dart';
import 'reflection_factory_annotation.dart';
import 'reflection_factory_base.dart';
import 'reflection_factory_extension.dart';

/// The reflection builder.
class ReflectionBuilder implements Builder {
Expand Down Expand Up @@ -263,6 +259,8 @@ class ReflectionBuilder implements Builder {
fullCode.write("part of '${genPart.partOf}';\n\n");

fullCode.write(codeTable.typeAliasTable.code);
fullCode.write('\n');

fullCode.write(codeTable.codeReflectionMixin);

var codeKeys = codeTable.allKeys.toList();
Expand Down Expand Up @@ -978,7 +976,7 @@ class _TypeAliasTable {
late final String fReturnValue;
late final String fReturnFuture;
late final String fReturnFutureOr;
late final String code;
late final StringBuffer code;

int fReturnValueUseCount = 0;

Expand All @@ -992,22 +990,39 @@ class _TypeAliasTable {
return _TypeAliasTable(privateNames);
}

_TypeAliasTable(List<String> privateNames) {
final List<String> privateNames;

_TypeAliasTable(this.privateNames) {
trName = _buildAliasName('__TR', privateNames);
tiName = _buildAliasName('__TI', privateNames);
prName = _buildAliasName('__PR', privateNames);

reflectionMixinName = _buildAliasName('__ReflectionMixin', privateNames);
fReturnValue = _buildAliasName('__retVal\$', privateNames);
fReturnFuture = _buildAliasName('__retFut\$', privateNames);
fReturnFutureOr = _buildAliasName('__retFutOr\$', privateNames);

var str = StringBuffer();
code = StringBuffer();

code.write('typedef $trName<T> = TypeReflection<T>;\n');
code.write('typedef $tiName<T> = TypeInfo<T>;\n');
code.write('typedef $prName = ParameterReflection;\n\n');
}

final Map<String, String> _recordsAliases = {};

str.write('typedef $trName<T> = TypeReflection<T>;\n');
str.write('typedef $tiName<T> = TypeInfo<T>;\n');
str.write('typedef $prName = ParameterReflection;\n\n');
String aliasForRecordType(String recordDeclaration) {
var alias = _recordsAliases[recordDeclaration];
if (alias != null) return alias;

code = str.toString();
var nextID = _recordsAliases.length + 1;
alias = _buildAliasName('__RCD$nextID', privateNames);

_recordsAliases[recordDeclaration] = alias;

code.write('typedef $alias = $recordDeclaration;\n');

return alias;
}

String _buildAliasName(String prefix, Iterable<String> usedNames) {
Expand Down Expand Up @@ -2185,7 +2200,9 @@ class _ClassTree<T> extends RecursiveElementVisitor<T> {

var declaringType = method.declaringType!.typeNameResolvable;
var returnType = method.returnTypeNameAsCode;

var returnTypeAsCode = method.returnTypeAsCode;

var nullable = method.returnNullable ? 'true' : 'false';

return "MethodReflection<$className,$returnType>("
Expand Down Expand Up @@ -3006,6 +3023,8 @@ class _Method extends _Element {

bool get isStatic => methodElement.isStatic;

DartType get returnType => methodElement.returnType;

String get returnTypeNameAsCode =>
methodElement.returnType.typeNameAsNullableCode;

Expand Down Expand Up @@ -3142,6 +3161,10 @@ extension _DartTypeExtension on DartType {
String get typeNameResolvable => resolveTypeName();

String resolveTypeName({Iterable<String>? typeParameters}) {
if (isRecordType) {
return recordDeclaration(typeParameters: typeParameters)!;
}

if (typeParameters != null &&
isParameterType &&
typeParameters.isNotEmpty) {
Expand Down Expand Up @@ -3170,7 +3193,39 @@ extension _DartTypeExtension on DartType {
return withNullability && isNullable ? '$name<$args>?' : '$name<$args>';
}

bool get isRecordType => this is RecordType;

String? recordDeclaration({Iterable<String>? typeParameters}) {
if (!isRecordType) return null;

var recordType = this as RecordType;

var recordTypesNamesPos = recordType.positionalFields
.map((t) => t.type.resolveTypeName(typeParameters: typeParameters));

var recordTypesNamesNamed = recordType.namedFields.map((t) =>
'${t.name} ${t.type.resolveTypeName(typeParameters: typeParameters)}');

var recordDeclaration = [
'(',
recordTypesNamesPos.join(', '),
if (recordTypesNamesNamed.isNotEmpty)
{
'{',
recordTypesNamesNamed.join(', '),
'}',
},
')',
].join();

return recordDeclaration;
}

String get typeName {
if (isRecordType) {
return recordDeclaration()!;
}

var name = elementDeclaration?.name;

if (name == null) {
Expand All @@ -3182,10 +3237,7 @@ extension _DartTypeExtension on DartType {
(idx > 0 && name.substring(idx - 1, idx).trim().isEmpty)) {
name = 'Function';
} else {
idx = name.indexOf('<');
if (idx > 0) {
name = name.substring(0, idx);
}
name = TypeInfo.removeTypeGenerics(name);
}
}

Expand Down Expand Up @@ -3351,7 +3403,10 @@ extension _DartTypeExtension on DartType {
if (constName != null) {
return '$tr.$constName';
} else {
if (this is TypeParameterType) {
if (isRecordType) {
var typeAlias = typeAliasTable.aliasForRecordType(name);
return '$tr<$typeAlias>($typeAlias)';
} else if (this is TypeParameterType) {
return '$tr.tDynamic';
} else {
return '$tr<$name>($name)';
Expand Down
19 changes: 16 additions & 3 deletions lib/src/reflection_factory_type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';

import 'package:collection/collection.dart';
import 'package:base_codecs/base_codecs.dart' as base_codecs;
import 'package:collection/collection.dart';

import 'reflection_factory_base.dart';
import 'reflection_factory_json.dart';
Expand Down Expand Up @@ -1250,11 +1250,24 @@ class TypeInfo<T> {
}

var typeStr = type.toString();
var idx = typeStr.indexOf('<');
if (idx > 0) typeStr = typeStr.substring(0, idx);
typeStr = removeTypeGenerics(typeStr);

return typeStr;
}

/// Removes generics from the type or record type string.
static String removeTypeGenerics(String type) {
while (true) {
var type2 = type.replaceAll(RegExp(r"<[^<>]+>"), '');

if (type2.length == type.length) {
return type;
} else {
type = type2;
}
}
}

/// The [type] arguments (generics).
final List<TypeInfo> _arguments;

Expand Down
8 changes: 4 additions & 4 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: reflection_factory
description: Allows Dart reflection with an easy approach, even for third-party classes, using code generation portable for all Dart platforms.
version: 2.2.3
version: 2.2.4
homepage: https://github.com/gmpassos/reflection_factory

environment:
Expand All @@ -24,8 +24,8 @@ dev_dependencies:
build_test: ^2.2.0
lints: ^2.1.1
pubspec: ^2.3.0
data_serializer: ^1.0.10
data_serializer: ^1.0.12
dependency_validator: ^3.2.2
test: ^1.24.6
coverage: ^1.6.3
test: ^1.24.9
coverage: ^1.6.4
benchmark: ^0.3.0
Loading

0 comments on commit 276eee0

Please sign in to comment.