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

[analyzer] DartObjectImpl#value loses generics and Symbols #24490

Open
a14n opened this issue Oct 2, 2015 · 4 comments
Open

[analyzer] DartObjectImpl#value loses generics and Symbols #24490

a14n opened this issue Oct 2, 2015 · 4 comments
Labels
analyzer-api Issues that impact the public API of the analyzer package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug

Comments

@a14n
Copy link
Contributor

a14n commented Oct 2, 2015

With analyzer-0.26.1+6 DartObjectImpl#value seems to not return the good thing:

  • generics are lost : List<Object> instead of List<Symbol>
  • symbols are transformed into String: #a becomes "a"
final testSource = new StringSource('''
class A {
  final List l;
  const A({this.l});
}
@A(l:const <Symbol>[#a])
class B{}
''', 'test.dart');
context.applyChanges(new ChangeSet()..addedSource(testSource));
final lib = context.computeLibraryElement(testSource);
final ann = lib.getType('B').metadata[0] as ElementAnnotationImpl;
final val = ann.evaluationResult.value;

print(val);
// A (l = List<Symbol> ([Symbol (#a)]))

print(val.fields['l']);
// List<Symbol> ([Symbol (#a)])

print(val.fields['l'].runtimeType);
// DartObjectImpl

print(val.fields['l'].value);
// [a]

print(val.fields['l'].value.runtimeType);
// List<Object>

print(val.fields['l'].value[0].runtimeType);
// String
@a14n
Copy link
Contributor Author

a14n commented Oct 2, 2015

I faced this issue inside source_gen (/cc @kevmoo)

@kevmoo kevmoo added the area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. label Oct 3, 2015
@bwilkerson
Copy link
Member

There are two things to note.

The first is that EvaluationResultImpl and all of the objects reachable from it are internal implementation classes that are not intended to be used. I understand that we need to provide a public API for this and that you're stuck using the implementation classes until we do (and don't blame you at all for doing so), but they will likely change a fair bit when we do design a public interface.

The second in that the getter value is extremely poorly named (and will be changed when we get a public API) because it implies that you can get back the actual value of the object. But we cannot provide an actual value in all cases, so we don't do a very complete job of trying to emulate that behavior even when it is possible. If you're depending on things like the type of the value being returned or the reified type of things like lists, you might be expecting something that we can't deliver. I'd be interested to understand your use case a little better.

@a14n
Copy link
Contributor Author

a14n commented Oct 5, 2015

It's used to create an instance of the annotation that triggers the call to the generator (see https://github.com/dart-lang/source_gen/blob/master/lib/src/annotation.dart#L41-L96 for the instantiation).
This is mainly used to configure the code generation. For instance you can have a look at this json example that uses JsonSerializable annotation and its generator

@bwilkerson
Copy link
Member

Ok. I think I understand at least part of what you're trying to do here.

A better API would make that easier, but it still only works for a subset of possible use cases. Consider, for example, an annotation defined using other user-defined classes:

class Path {
  final List<String> components;
  const Path(this.components);
}

class Annotation {
  final Path path;
  const Annotation(this.path);
}

@Annotation(const Path([]))
class Target {}

The analyzer is never going to be able to provide an instance of Path as the value of the argument to the annotation on Target. So while it's convenient to create an instance of JsonSerializable for use in the generator, that approach basically means that someone has to effectively write a limited purpose Dart interpreter for a subset of constant evaluation.

Returning a Symbol rather than a String might make a tiny difference in the difficulty of writing that interpreter, but I guess I'm not convinced that it's a huge problem.

@bwilkerson bwilkerson added Type-Enhancement P3 A lower priority bug or feature request labels Oct 6, 2015
@kevmoo kevmoo added type-enhancement A request for a change that isn't a bug and removed type-enhancement labels Mar 1, 2016
@srawlins srawlins added the analyzer-api Issues that impact the public API of the analyzer package label Jun 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
analyzer-api Issues that impact the public API of the analyzer package area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. P3 A lower priority bug or feature request type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants