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

Denoting members by name in a library augmentation or a library that has augmentations #3717

Open
eernstg opened this issue Apr 23, 2024 · 1 comment
Labels
augmentation-libraries question Further information is requested

Comments

@eernstg
Copy link
Member

eernstg commented Apr 23, 2024

Thanks to @sgrekhov for bringing up this issue. Consider the following situation:

// --- Library augmentation 'augment.dart'.
augment library 'main.dart';

augment int foo(int i) => i > 2 ? foo(i - 1) : augmented(i - 1);

// --- Library 'main.dart'.
import augment 'augment.dart';

int foo(int i) {
  if (i > 0) return foo(i);
  return i;
}

It is my understanding that foo(...) in every location denotes an invocation the final, merged result of introducing the declaration named foo in main.dart and augmenting it in some number of steps (in this case just once). In general, a named reference to an instance member is always the post-merge member (the "end result"), never a single augmentation, not even when it occurs in the original (non-augmenting) declaration (here: the declaration in main.dart).

In particular, the invocation of foo(i) in the original declaration is not an infinite loop.

I couldn't find an explicit answer to this question in the feature specification. It is possible that it is considered obvious, but it is still useful to get it clarified, and we might also add a couple of sentences to the feature specification about it.

@eernstg eernstg added question Further information is requested augmentation-libraries labels Apr 23, 2024
@lrhn
Copy link
Member

lrhn commented Apr 23, 2024

foo(...) in every location denotes an invocation the final, merged result 

Agree.
There is only one way to refer to a specific base or augmentation declaration, the augmented invocation in an immediately augmenting declaration body.

Any reference by name will refer to that name in the declaration scope, or any other relevant scope, and that scope only contains one entry. An entry that is declared by a base declaration and zero or more augmenting declarations in a specific order.

The example foo function will return 0 if called with 0,
If called with a positive value, it'll recurse with i - 1 until reaching zero.
If called with a negative number, it'll recurse with i - 1 until overflowing into a positive number (if on native) then continue as above and eventually return zero (long after a stack overflow).

It's just like the functions

int foo(int i) => i > 0 ? foo(i - 1) : _$augmented$foo(i);

int _$augmented$foo(int i) {
  if (i < 0) return foo(i - 1);
  return i;
}

where nothing else can refer to the fresh name _$augmented$foo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
augmentation-libraries question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants