Skip to content

Import path's affect class definitions? #31230

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
jxson opened this issue Oct 26, 2017 · 11 comments
Closed

Import path's affect class definitions? #31230

jxson opened this issue Oct 26, 2017 · 11 comments
Assignees
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).

Comments

@jxson
Copy link

jxson commented Oct 26, 2017

While working on some Flutter code in Fuchsia I noticed some weird behavior, it took some head scratching to figure out a bug that was caused by it.

If you import the same file using different paths it changes the class/type definition:

import 'package:hello/models.dart' as pkg;
import 'models.dart';

void main() {
    pkg.HelloModel a = new pkg.HelloModel();
    HelloModel b = new HelloModel();

    assert(b is pkg.HelloModel);
    assert(a is HelloModel);
}

The asserts above will fail.

@bwilkerson
Copy link
Member

That is correct. Library equality in Dart is defined in terms of the URI used to reference the library rather than the path to the file containing the library. The code above is loading two different libraries (that happen to be defined by the same file), and hence two different classes (that happen to have the same name).

I've been advising people for a long time to always use a package: URI to import libraries defined in the lib directory and to use a relative URI to import any other libraries (other than dart: libraries, of course). This minimizes the chance of running into this kind of issue.

@yjbanov
Copy link

yjbanov commented Oct 26, 2017

IMHO, these semantics made sense in the JITted web world, where URL, not the file, gives identity to the downloaded code. In AOT (dart4web, Flutter) and command-line Dart VM, it's just confusing.

@bwilkerson bwilkerson added the area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language). label Oct 26, 2017
@kevmoo
Copy link
Member

kevmoo commented Oct 27, 2017

But if you get a class via an export, it's the same as getting it via the source library.

...and it shouldn't matter if the export got the type via package: or relative URI.

Feel very much like a bug!

@bwilkerson
Copy link
Member

But if you get a class via an export, it's the same as getting it via the source library.

I don't know what you mean by "source library". When you import library A, and library A exports a class from library B, the class is still defined in library B, and the URI used to reference the library (in the export directive) is still used to identify the library.

Feel very much like a bug!

The description above is the way I read the current specification. I'd be happy to find out I'm wrong.

Personally, I think we should change the specification to use file paths rather than URI's, because I think the days of loading code into a VM running in the browser are gone. That's why I marked this as a language issue.

@kevmoo
Copy link
Member

kevmoo commented Oct 27, 2017

Actually, @jxson – I have a question.

It looks like you put this file in lib/main.dart (or something) and running it from there?

Try moving it to bin/main.dart and run it then.

If it works, I'm with Brian. I'm arguing for semantics that I'm about 98% are valid. If you're in file X and you're resolved as a package: reference, any relative paths are also treated as a package: reference.

If you're running dart lib/main.dart then you're treating model.dart in two ways:

  1. as file:///my_pkg_dir/lib/model.dart
  2. as package:hello/model.dart

@zoechi
Copy link
Contributor

zoechi commented Jul 17, 2018

dup of #33076

@matanlurey
Copy link
Contributor

Duplicate of #33076.

@avi-mastov
Copy link

I had this issue in Dart 2.8.4. when the 2 URLs were practically the same, but one of them didn't have a canonical path:

import 'package:lumen/widgets/questions_flow/pages/select/presenter.dart';
import 'package:lumen/widgets/questions_flow//pages/select/presenter.dart';

See the extra slash in the 2nd URL? I would expect the Dart VM/Compiler to canonise it or issue a warning and/or have the "Optimize imports" command in Android Studio canonise it, but none of these happened/worked. I just got a runtime error. Should I open a new issue on it @matanlurey ?

@natebosch
Copy link
Member

@bwilkerson - would it be appropriate to add a hint in the analyzer when a URI should be canonicalized in an import?

@bwilkerson
Copy link
Member

I would say, yes. I doubt that anyone is intentionally using URIs that are not canonical in order to prevent a file from being seen as being the same, so I expect there'd be zero false positives.

@natebosch
Copy link
Member

Filed as a new feature request: #42829

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-language Dart language related items (some items might be better tracked at github.com/dart-lang/language).
Projects
None yet
Development

No branches or pull requests

8 participants