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

API for "reviving" DartObject #178

Closed
matanlurey opened this issue Jun 21, 2017 · 13 comments
Closed

API for "reviving" DartObject #178

matanlurey opened this issue Jun 21, 2017 · 13 comments
Labels
type-enhancement A request for a change that isn't a bug

Comments

@matanlurey
Copy link
Contributor

One of the hardest and most brittle parts of the AngularDart compiler...

Basically, we need to go from a computed DartObject to some sort of model class that enables code generation of an identical object. Here are some simple (trivial) examples that are solvable with ConstantReader today:

  • String
  • int / double
  • bool
  • null
  • List<...> or Map<...> of these types, recursively

However, it's much harder with classes and enums. Consider these:

  • const Duration(seconds: 5)
  • const SomeClass._privateConstructor()
  • Enum.someValue

We could do this with ConstantReader, if we add a few more methods:

abstract class ConstantReader {
  bool get isEnum;
  RevivableEnum get enumValue;

  bool get isInstance;
  RevivableInstance get instanceValue;
}

abstract class RevivableEnum implements ConstantReader {
  Uri get uri;
  String get name;
  int get index;
}

abstract class RevivableInstance implements ConstantReader {
  Uri get uri;
  String get name;
  String get constructor;
  List<ConstantReader> get positionalArguments;
  Map<String, ConstantReader> get namedArguments;
}

We could also do error handling, i.e., a flag for checking if it is revivable (visible):

abstract class RevivableInstance implements ConstantReader {
  ...
  bool get isVisible;
}

This isn't a perfect API, but it is probably better for some of this to live in source_gen (and have closer watch by the ecosystem team and analysis team) than buried in the AngularDart compiler.

/cc @jakemac53 @alorenzen @kevmoo

@matanlurey matanlurey added the type-enhancement A request for a change that isn't a bug label Jun 21, 2017
@jakemac53
Copy link
Contributor

I am not 100% sure about the Revivable* names but generally this SGTM.

We probably also want to probably add a base class, something similar to this:

abstract RevivableBase<T> {
  String toCodeString();
  T toInstance();
}

@matanlurey
Copy link
Contributor Author

matanlurey commented Jun 22, 2017

I mostly agree - except the toCodeString - this seems too difficult to get right for all users, and then we are sort of duplicating logic for from code_builder. I'd be OK with doing this in toString() mostly for debugging though.

@matanlurey
Copy link
Contributor Author

I'm OK with the progress here so far.

@bitsydarel
Copy link

Hi guys, so what's the current api to get the value of a enum using constantReader ?

@bitsydarel
Copy link

is their a toInstance ?

@natebosch
Copy link
Member

what's the current api to get the value of a enum using constantReader ?

I don't think we have one. We could review a contribution adding an API to ConstantReader for this.

is their a toInstance ?

No, it's not feasible to implement since it depends on statically importing the class that needs to be constructed. Most likely the best we can do is something like T enumValue<T>(Iterable<T> selectFrom) with usage like reader.enumValue(SomeEnum.values);

One concern is we can't statically know that T is an enum, so it would be easy to misuse with "enum like" classes that might not fit our assumptions...

@bitsydarel
Copy link

Can dart allow us to bound generic type?

@bitsydarel
Copy link

Currently I'm doing this like that :

        .firstAnnotationOfExact(field, throwOnUnresolved: false);

    if (annotation == null) {
      return null;
    } else {
      final columnTypeValue = ColumnType.values.firstWhere(
        (columnType) =>
            annotation
                .getField("type")
                .getField(columnType.toString().split('.')[1]) !=
            null,
        orElse: () => null,
      );```

@lukepighetti
Copy link

Hey all, I'm trying to take @MyAnnotation("") and get the String r'""', or @MyAnnotation(["Foo"]) and get the string r'["Foo"]'. Basically I'm trying to recreate the value.

I tried this with no luck final nullValue = annotation.read("nullValue").revive().toString();, does this issue cover this use case or am I misunderstanding this issue?

@kevmoo
Copy link
Member

kevmoo commented Mar 26, 2020

You can write code to handle this.

See

https://github.com/dart-lang/json_serializable/blob/3ea5351cb73f1e1131a252533276e1887bb883c8/json_serializable/lib/src/json_key_utils.dart#L52-L112

@lukepighetti
Copy link

@kevmoo any reason why this hasn't been contributed to source_gen or whichever package would typically contain this type of utility method?

@kevmoo
Copy link
Member

kevmoo commented Mar 27, 2020

@lukepighetti – time/priority

Doing it for simple things is easy, but you fall off a cliff pretty quick.

PR welcome!

@lukepighetti
Copy link

@kevmoo I don't feel qualified to contribute your source to a package like source_gen. I don't even know if that's the appropriate location for that utility method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

6 participants