Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Macro - Augment class with generic #3922

Closed
LeadcodeDev opened this issue Jun 19, 2024 · 7 comments
Closed

Macro - Augment class with generic #3922

LeadcodeDev opened this issue Jun 19, 2024 · 7 comments
Labels
static-metaprogramming Issues related to static metaprogramming

Comments

@LeadcodeDev
Copy link

Hi, I'm trying to apply a macro to a class that has a generic.

To experiment a little with the meta-programming approach, I set myself the goal of creating a mini ORM based on models such as Symfony or Adonis.

I have one model, that represent database table in Dart context.

@Model()
final class MyModel implements BaseModel {
  @Column()
  external String _firstname;

  @Column()
  external String _lastname;
}

The macro @Model() provides a static function for obtaining an instance of my query builder.

macro class QueryBuilderMacro implements ClassDeclarationsMacro {
  const QueryBuilderMacro();

  @override
  FutureOr<void> buildDeclarationsForClass(ClassDeclaration clazz, MemberDeclarationBuilder builder) async {
    final fields = await builder.fieldsOf(clazz);
    print(clazz.typeParameters.map((e) => e.name));

    final availableFields = fields
        .where((element) => !element.identifier.name.startsWith("_"))
        .toList();

    final List<Object> parts = [];
    for (final field in availableFields) {
      final paramName = field.identifier.name.replaceAll('_', '')[0].toUpperCase() + field.identifier.name.substring(1);
      final type = field.type.code.parts.first as Identifier;
      parts.addAll([
        'QueryBuilder<${clazz.identifier.name}> where$paramName($type value) {',
          'return this.where("$field", value);',
        '}',
      ]);
    }

    builder.declareInType(DeclarationCode.fromParts(parts));
  }
}
@QueryBuilderMacro()
final class QueryBuilder<T extends BaseModel> {
}

Then my main

Future<void> main(List<String> arguments) async {
  final myModel = await MyModel
    .query()
    .firstOrFail();

  print([myModel.firstname, myModel.lastname]); // prints [John, Doe]
}

I have this error in my console when I run my application 👀

macros ../sdk/dart-sdk/bin/dart run --enable-experiment=macros bin/main.dart
org-dartlang-augmentation:/Development/pocs/macros/lib/query_builder.dart-0:3:21: Error: A patch class must have the same number of type variables as its origin class.
augment final class QueryBuilder {
                    ^
lib/query_builder.dart:6:13: Context: This is the origin class.
final class QueryBuilder<T extends BaseModel> {
            ^

I'd like to know whether this problem is actually a limitation to the use of macros or whether I'm doing it wrong. If so, could you give me some alternatives?

@davidmorgan davidmorgan added the static-metaprogramming Issues related to static metaprogramming label Jun 19, 2024
@davidmorgan
Copy link
Contributor

I think getting the generics right here is simply not implemented yet.

See also #3879 for discussion as to whether it might be useful augmentation libraries were less strict here.

@LeadcodeDev
Copy link
Author

Hello @davidmorgan, thank you for your reply!
I'll be following this thread closely 🙂

@jakemac53
Copy link
Contributor

Yeah this just seems like a bug in the code producing the augmentation for types with generics.

@jakemac53
Copy link
Contributor

Fix out here https://dart-review.googlesource.com/c/sdk/+/372580

@LeadcodeDev
Copy link
Author

Thanks you so much 🙏

copybara-service bot pushed a commit to dart-lang/sdk that referenced this issue Jun 21, 2024
Bug: dart-lang/language#3922
Change-Id: I9d9f6ce898e16e2ed393ae77f0dbcbf9c75fb56d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/372580
Auto-Submit: Jake Macdonald <jakemac@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
@jakemac53
Copy link
Contributor

This should be resolved, but you may need to wait a bit for a dev SDK to be released that includes the fix (needs to be >= 3.5.0-288.0.dev)

@LeadcodeDev
Copy link
Author

No problem, thank you.
Thank you for your efforts, keep up the good work !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
static-metaprogramming Issues related to static metaprogramming
Projects
Development

No branches or pull requests

3 participants