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

Get AST of annotation #527

Closed
stargazing-dino opened this issue Apr 12, 2021 · 3 comments
Closed

Get AST of annotation #527

stargazing-dino opened this issue Apr 12, 2021 · 3 comments
Labels
type-question A question about expected behavior or functionality

Comments

@stargazing-dino
Copy link

Hi ! I've been using the workaround described here to type my annotation but now I'm having trouble trying to get the ast of my annotation. For example say I have the user define the root of a firebase collection

part 'root.fire.dart';

// UndefinedType is not created until I generate output in my `root.fire.dart` file
const _UsersCollection = Collection<UndefinedType>(name: 'users');

@root
class Database with _$Database {
  // TODO: This should have the option to pass in an app
  @_UsersCollection
  Database._();

  static final instance = Database._();
}

I can get annotations over the named constructor _ but how do I then get the non-synthetic element declaration const _UsersCollection.

I tried this but because I always get back a synthetic element from declaration calling getElementDeclaration by design returns null

@override
FutureOr<String> generateForAnnotatedElement(
  Element element,
  ConstantReader annotation,
  BuildStep buildStep,
) async {
  if (element is! ClassElement) {
    // ...
  }

  final stringBuffer = StringBuffer();
  final constructor = element.constructors.singleWhere(
    (constructor) => constructor.displayName == '_',
    orElse: () {
      // ...
    },
  );

  for (final annotation in constructor.metadata) {
    final annotationElement = annotation.element!.declaration!;

    final elementDecleration = element.library.session
        .getParsedLibraryByElement(element.library)
        .getElementDeclaration(annotationElement);

    // elementDecleration is null i think because annotationElement is synthetic

    final node = element.node; // throws

    final String type = _getUndefinedType(node);

    _createClassWithName(type);
  }
}

I want to get the ast because I need to get the undefined type on Collection<T> so I can use that name to build it. Any help is much appreciated.

@natebosch
Copy link
Member

@scheglov, @devoncarew - Do we have a support path for questions on using the Analyzer APIs like this?

@devoncarew
Copy link
Member

The best place to ask is likely the analyzer-discuss list, referenced from here: https://dart.dev/community.

@natebosch
Copy link
Member

In this case I think the following will get you close

final annotationElement = annotation.element;
// note, the following may not work if the code has a different pattern
// for example if the annotation isn't a top level variable...
final variable = (annotationElement as PropertyAccessorElement).variable;
final astNode = await buildStep.resolver.astNodeFor(variable);

@natebosch natebosch added the type-question A question about expected behavior or functionality label Jul 16, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-question A question about expected behavior or functionality
Projects
None yet
Development

No branches or pull requests

3 participants