Skip to content

Why do we need to import an augmentation if the augmentation refers to the augmented library? #1958

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

Closed
mateusfccp opened this issue Nov 3, 2021 · 7 comments

Comments

@mateusfccp
Copy link
Contributor

In the Augmentation Libraries specification, we have the following:

  • In the augmentation library side, we must declare it as a library augment <main library url>;
  • In the augmented (main) library side, we must import the augmentation with import <augmentation library url>;
  • A given augmentation file can only be used to augment a single library.

This structure is similar with what we have today (part and part of).

However, isn't it redundant to have to import an augmentation if the augmentation can only refer to a single library? In the current proposal, it is possible that an augmentation library exist but the main library does not import it. Does it makes sense? Considering that an augmentation library refer to specifically a single main library, this augmentation library would be completely useless.

For me, the following makes sense:

  • An augmentation library does not need to declare the main library it augments. Instead, any library may import it as an augmentation, as long as the declaration rules are followed;
  • An augmentation library must declare the main library it augments. The main library does not need to import the augmentation library, as it is obviously intended that it should be applied;

I am in favor of the seconds, as the first one would be considerably confusing and it would be fairly rare the cases where an augmentation library would be applicable from more than one main library.

@jakemac53
Copy link
Contributor

In general you should be able to understand how these files are linked together whenever you are looking at just one of them, so they both need to point at each other.

Beyond that there are some more pragmatic concerns as well with either of the suggested approaches:

An augmentation library does not need to declare the main library it augments. Instead, any library may import it as an augmentation, as long as the declaration rules are followed;

We don't want any arbitrary library to be able to augment any other library. This would break modular compilation and also generally enable a lot of "action at a distance".

An augmentation library must declare the main library it augments. The main library does not need to import the augmentation library, as it is obviously intended that it should be applied

All files required for a program should be reachable through the import graph, you shouldn't have to arbitrarily search the file system for all Dart files just to check if they augment any library in your program.

@mateusfccp
Copy link
Contributor Author

mateusfccp commented Nov 3, 2021

In general you should be able to understand how these files are linked together whenever you are looking at just one of them, so they both need to point at each other.

IMO, this is not always the case. Considering macros, that is what I think is the most common case for augmentation libraries, I think referring to the augmentation library is not what most users would expect. Instead, they would expect that simply by having an annotation in the class, function or whatever declaration it is, would be enough to make things happen.

Indeed, in current meta programming system (build_runner) we already have to declare part 'library.g.dart', and in my experience this is both cumbersome and error prone. There were many times where I forgot to include the part directive, or where I included only one of them (included .freezed.dart but forgot .g.dart, for example) , making the build process to simply not build what was being expected, but succeeding even so.

That being said, I think in terms of user experience, it is must more expected that the macro's augmentation library will refer to the main library and the user won't have to do nothing more.

All files required for a program should be reachable through the import graph, you shouldn't have to arbitrarily search the file system for all Dart files just to check if they augment any library in your program.

I though that this would be one possible limitation, but is this an arbitrary choice? Couldn't we simply search through the files? And probably there is even better solutions that we didn't think of that would make this search less arbitrary...

Also, is this a valid trade-off to make user experience worse in this specific case to avoid searching the filesystem?

@bwilkerson
Copy link
Member

Couldn't we simply search through the files? And probably there is even better solutions that we didn't think of that would make this search less arbitrary...

Opening and parsing every .dart file in the file system would be prohibitively expensive in some environments. We could limit where we needed to search (where augmentations can be located relative to the main library), but those limitations would themselves be rather arbitrary.

Also, is this a valid trade-off to make user experience worse in this specific case to avoid searching the filesystem?

The speed with which IDEs and some other tools can respond is a huge part of the UX, so ensuring that they can be performant is actually ensuring that we don't make the UX worse.

@jakemac53
Copy link
Contributor

Note that macros are intended to use this system generally but users might not be required to explicitly point at an augmentation file - in fact I would likely push for there being an implicit augmentation library for any file that uses any macros.

@mateusfccp
Copy link
Contributor Author

mateusfccp commented Nov 3, 2021

The speed with which IDEs and some other tools can respond is a huge part of the UX, so ensuring that they can be performant is actually ensuring that we don't make the UX worse.

Yes, this is why I think we could search for a middle-ground, maybe...

Note that macros are intended to use this system generally but users might not be required to explicitly point at an augmentation file - in fact I would likely push for there being an implicit augmentation library for any file that uses any macros.

If this is the case, most of my worries in this question are solved. When we go to hand-written augmentation libraries, importing them manually is not that bad.

@munificent
Copy link
Member

Note that macros are intended to use this system generally but users might not be required to explicitly point at an augmentation file

Yup, this is my intention. Augmentation libraries are a general purpose Dart feature. And when augmentations are hand-authored or created by separate code generation tools, users will be required to explicitly import them and apply them to the main library.

Then macros are a separate feature layered on top. One of the special powers of that feature is that the library augmentation that macros are compiled to gets automatically applied to the main library. Users won't have to author an augmentation import just to hook up macros.

@mateusfccp
Copy link
Contributor Author

Thanks, @munificent @jakemac53.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants