Skip to content

Import path's affect class definitions? #31230

Closed
@jxson

Description

@jxson

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.

Activity

bwilkerson

bwilkerson commented on Oct 26, 2017

@bwilkerson
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

yjbanov commented on Oct 26, 2017

@yjbanov

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.

added
area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).
on Oct 26, 2017
kevmoo

kevmoo commented on Oct 27, 2017

@kevmoo
Member

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

bwilkerson commented on Oct 27, 2017

@bwilkerson
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

kevmoo commented on Oct 27, 2017

@kevmoo
Member

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

zoechi commented on Jul 17, 2018

@zoechi
Contributor

dup of #33076

matanlurey

matanlurey commented on Jul 18, 2018

@matanlurey
Contributor

Duplicate of #33076.

avi-mastov

avi-mastov commented on Jul 23, 2020

@avi-mastov

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

natebosch commented on Jul 24, 2020

@natebosch
Member

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

bwilkerson

bwilkerson commented on Jul 24, 2020

@bwilkerson
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

natebosch commented on Jul 24, 2020

@natebosch
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

Metadata

Metadata

Assignees

Labels

area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @jxson@kevmoo@matanlurey@yjbanov@zoechi

      Issue actions

        Import path's affect class definitions? · Issue #31230 · dart-lang/sdk