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

Create a method to know if a type is a Built-in type #56066

Closed
danteCarvalho opened this issue Jun 22, 2024 · 11 comments
Closed

Create a method to know if a type is a Built-in type #56066

danteCarvalho opened this issue Jun 22, 2024 · 11 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. type-enhancement A request for a change that isn't a bug

Comments

@danteCarvalho
Copy link

I would like to have a method that can tell if a type is a Built-in type like the ones here https://dart.dev/language/built-in-types.
Also on the analyzer package it would be good to have the same feature on the FieldDeclaration class, i am trying to create a code geneator to create a fromJson method, but when i get to the FieldDeclaration i can't get a way to know that.

@dart-github-bot
Copy link
Collaborator

Summary: The user requests a method to determine if a Dart type is a built-in type, like int, String, or double. They also want this functionality added to the FieldDeclaration class in the analyzer package for code generation purposes.

@dart-github-bot dart-github-bot added area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. type-enhancement A request for a change that isn't a bug labels Jun 22, 2024
@lrhn
Copy link
Member

lrhn commented Jun 22, 2024

Why?

Dart doesn't have primitive types like Java or JavaScript, built-in types are just classes that happen to be in the platform libraries.

Some of them are final or sealed and cannot be implemented. User defined types can be final or sealed too, so that's not special either.

Other platform library defined types can be subtyped, so telling you whether a type is a built-in type doesn't tell you anything about the type of an actual value of that type.

If it's for fromJson, knowing that the type is declared in the platform libraries won't help you, you still need to know how to handle it, which means you should recognize the types you support individually, no matter where they come from.

@scheglov scheglov added the P4 label Jun 22, 2024
@danteCarvalho
Copy link
Author

As of why, so many times i needed that feature, i guess the intention of dart is to facilitate things for developers .
A simple bool isBuiltIn() function would be a life saving. So that when i am analyzing the fields of a class i can differentiate what is built from a class created by me or other packages.

If its on a normal dart project (not the generator), i can do this manually

bool isBuiltIn(type){
if(type is String){
}
if(type is int){
}
//etc...
}

but i feel like that should already be a part of dart

The bigger problem for me is on the generator project
When i get to analyze the Fields of a class, i get a list of FieldDeclaration
on a class like this

class Foo{
 String desc = "";
 User user = User();
 SomeEnum thing = SomeEnum.thing;
}

i can extract the whole line of a field like this String desc = "" or User user = User()
But it only gives me the text not the actual type of the Field.
I need a way to get the type from FieldDeclaration so i can analyze it.

@bwilkerson
Copy link
Member

As for the analyzer side of the question, given a resolved instance of FieldDeclaration named declaration, you ought to be able to access the type of the ith field by using declaration.fields[i].type.type. You can then use getters like isDartCoreBool to determine whether the type is one of the types you're interested in.

So that when i am analyzing the fields of a class i can differentiate what is built from a class created by me or other packages.

Knowing whether the type is from an SDK library doesn't really answer the question of whether the type is defined in the package being analyzed (unless you can assume that the package being analyzed does not depend on any other packages). For that you really need to ask the type for its element.source.uri, then check to see whether that's a package: uri for the package being analyzed.

@danteCarvalho
Copy link
Author

danteCarvalho commented Jun 22, 2024

@bwilkerson
Weird, declaration.fields.type?.type always returns null for me.
Does it have something to do with the way i get the fields?

class MyCustomGenerator extends GeneratorForAnnotation<SerialAnnotation> {
  @override
  generateForAnnotatedElement( Element element, ConstantReader annotation, BuildStep buildStep) async {
    var list = fields(element);
    //...
  }
}
List<FieldDeclaration> fields(Element element) {
  AnalysisSession? session = element.session;
  var library = element.library;
  if (library != null) {
    var parsedLibraryByElement = session?.getParsedLibraryByElement(library);
    if (parsedLibraryByElement != null) {
      parsedLibraryByElement as ParsedLibraryResult;
      var elementDeclaration = parsedLibraryByElement.getElementDeclaration(
          element);
      if (elementDeclaration != null) {
        var node = elementDeclaration.node;
        var childEntities = node.childEntities;
        List<FieldDeclaration> fields = [];
        for (var obj in childEntities) {
          if (obj is FieldDeclaration) {
            fields.add(obj);
          }
        }
        return fields;
      }
    }
  }

  final libraryCompilationUnit = (element.library!.session
      .getParsedLibraryByElement(element.library!) as ParsedLibraryResult)
      .units[0]
      .unit;
  Iterable<SyntacticEntity> childEntities =
      libraryCompilationUnit.declarations.first.childEntities;

  List<FieldDeclaration> fields = [];
  for (var obj in childEntities) {
    if (obj is FieldDeclaration) {
      fields.add(obj);
    }
  }
  return fields;
}



i got this method from https://stackoverflow.com/questions/57030992/how-do-i-get-the-astnode-from-some-element-in-dart-analyzer-source-gen

@bwilkerson
Copy link
Member

Yes. You need to use AnalysisSession.getResolvedLibraryByElement rather than AnalysisSession.getParsedLibraryByElement.

See https://github.com/dart-lang/sdk/blob/main/pkg/analyzer/doc/tutorial/ast.md#the-states-of-an-ast for a description of the difference between a parsed and a resolved AST.

@danteCarvalho
Copy link
Author

danteCarvalho commented Jun 24, 2024

Thanks! its working now with the getResolvedLibraryByElement.
Now regarding the first part o the issue, i still feel like there should be a isBuiltin method or a isDartCore method.
Whatever you guys think its best : isBuiltin(Type) or type.isBuiltin.

@bwilkerson bwilkerson added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. and removed area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P4 labels Jun 24, 2024
@lrhn
Copy link
Member

lrhn commented Jun 24, 2024

You could (perhaps, if I understood the explanation) do type.element.library?.isInSdk ?? false.
It's a little longer, but something you could easily make your own extension getter for:

extension on DartType {
  bool isPlatformType => this.element.library?.isInSdk ?? false;
}

(Completely untested.)

@danteCarvalho
Copy link
Author

danteCarvalho commented Jun 24, 2024

i tried the type.element.library?.isInSdk, but for enums i created it returns false,. Also i guess it should have a way on a normal project too.where i could get a object.runtimeType and maybe have isInSdk or isDartCore.
...maybe i am just beeing lazy as it can be done manually

@lrhn
Copy link
Member

lrhn commented Jun 24, 2024

i could get a object.runtimeType and maybe have isInSdk or isDartCore.

Absolutely won't happen, you'll have to use dart:mirrors to get information out of a Type object.
Dart Type objects don't know anything other than whether they're == to another Type object, and being able to do more than that requires retaining more information in the program than necessary.
Generally that kind of runtime reflection of source properties interact very badly with AoT compilation and tree shaking, and it's something the language actively tries to avoid.

@bwilkerson
Copy link
Member

Given that the analyzer is able to answer the question, and that the sdk libraries won't be enhanced, I think we can close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

5 participants