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

Adds support for config specific imports #1793

Merged
merged 13 commits into from
Aug 29, 2018
Merged

Conversation

jakemac53
Copy link
Contributor

Most of the changes are to the build_modules package, and there is now a separate set of module files per platform.

  • Each platform is set up with a builder in the build_modules package - but they are not applied by default. Any new platforms should also be configured in the build_modules package.
  • Individual compiler packages (or other consumers of modules) must apply the module builder for the platforms they care about, using applies_builders config.

cc @pulyaevskiy the build_node_compilers package will need an update as well - see the build_web_compilers package updates here.

@googlebot googlebot added the cla: yes Google is happy with the PR contributors label Aug 27, 2018
@@ -0,0 +1,5 @@
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] 2018

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


import 'package:test/test.dart';

// ignore: uri_does_not_exist
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we always going to need these ignore comments? That's quite annoying.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


main() {
test('Message matches expected', () {
if (1.0 is int) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We really need to provide support for this in a better way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ya, its really weird how the dart.library.* things aren't real constants just some special identifier thing that compilers know about?

strategy: fine
```

The supported platforms are currently `dart2js`, `dartdevc`, and `vm`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't we support flutter?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it can't be discovered in the same libraries.json file 😢

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boo

var id = AssetId(buildStep.inputId.package, 'lib/$metaModuleExtension');
var platformLoader = await buildStep.fetchResource(platformsLoaderResource);
var platforms = await platformLoader.load(buildStep);
var platform = platforms[_platform];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we wrap this logic up in a method? It took a while to parse what was going on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

'dart.library.<name> constants are supported.');
}
var library = condition.substring('dart.library.'.length);
var coreLibSupport = platform.libraries[library];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what's going on here with coreLibSupport.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically just checking if the current platform explicitly supports the core library that is being referenced in the conditional import. It might either omit the library entirely or explicitly have it marked as unsupported.

PlatformsLoader._();

Future<Platforms> load(AssetReader reader) async {
if (_invalidated) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[optional - not worth a rebase if you planned on merging instead of squashing] invert the condition and bail out early to reduce 1 level of nesting?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

var conditions = <String, AssetId>{r'$default': linkedId};
for (var condition in conditionalDirectiveConfigurations) {
if (Uri.parse(condition.uri.stringValue).scheme == 'dart') {
throw 'Unsupported conditional import of '
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this unsupported?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it has any value (you can't use things from them anyways) - tracking it would have meant tracking sdk deps per platform which complicates things unnecessarily.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can't use things from them anyways

I don't understand, this seems valid:

import 'fake_io.dart'
  if (dart.library.io) 'dart:io';

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I guess in that sense you could use it, I hadn't considered the fake io case but I don't think that is a common use case anyways?

My thoughts regarding this were that the different libraries don't have any overlapping types, so directly doing this would not have any value:

import 'default.dart'
  if (dart.library.io) 'dart:io'
  if (dart.library.html) 'dart:html';

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think the fake_io, fake_html thing is going to be a real use case...

I agree that there isn't much value in tracking it, and we can probably assume that they are "correct" in that you won't have something like if (dart.library.io) 'dart:html' - and let the failure be late if you do.

Is it OK to ignore them instead of throw here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't actually think the fake_io case would be common though - in what scenario would that actually be a good pattern?

Primarily this feature is meant to be used by libraries I think, where they are going to want some real implementation and not just fall back on a fake. I don't think it is particularly cumbersome to simply force people to come up with a more generic api and have their actual platform specific imports hidden behind a conditional import.

In theory you could use a fake within a test but I don't understand the value that the feature provides there since you are typically only running on one platform or always running with a fake/mock.

### Improvements

- Modules are now platform specific, and config specific imports are supported,
but only for `dart.library.*` constants.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is already an constraint on conditional imports in the CFE (though it's maybe not documented super well?)

I don't think we should phrase this as if it's a limitation. "config specific imports against dart.library.* constants are supported"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

though it's maybe not documented super well?

or at all ;)

dartdevc:
import: "package:build_modules/builders.dart"
builder_factories:
- metaModuleBuilderFactoryForPlatform('dartdevc')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[aside] If we had union types I would totally make the BuilderFactory typedef be Builder|List<Builder> Function()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, would clean this up a bunch

strategy: fine
```

The supported platforms are currently `dart2js`, `dartdevc`, and `vm`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it can't be discovered in the same libraries.json file 😢

@pulyaevskiy
Copy link
Contributor

Thanks for tagging me @natebosch! Will make sure to update when this lands.

@jakemac53
Copy link
Contributor Author

@natebosch @grouma I am reconsidering using the libraries.json file for a couple reasons, curious what you think.

  • It is unlikely that a platform changes its dart: library support any time soon
  • Flutter doesn't ship a libraries.json file in the same place
  • It makes the tests easier to write (don't have to mock the file)

@grouma
Copy link
Member

grouma commented Aug 28, 2018

I'm in favor of hard coding the mapping. As you said, it is unlikely that specific imports are added regularly. If that situation changes we can easily adjust the solution. I'd rather reduce the complexity for now.

@natebosch
Copy link
Member

@vsmenon - can we expect stability in inclusion/exclusion of dart.library.* for each platform throughout the lifetime of Dart 2.x?

I'm OK with hardcoding this if we are reasonably confident that it's not going to allow for incompatibilities against newer SDKs before there is a breaking version bump. I was more nervous about this before stable.

Other than old versions existing which are possible to pub solve against - do we think there are any reasons this isn't an easily reversible choice? We can hardcode for now and add back libraries.json parsing in the future if we decide it's warranted right?

@jakemac53
Copy link
Contributor Author

We can hardcode for now and add back libraries.json parsing in the future if we decide it's warranted right?

Right, it should be a transparent change.

@vsmenon
Copy link
Member

vsmenon commented Aug 28, 2018

can we expect stability in inclusion/exclusion of dart.library.* for each platform throughout the lifetime of Dart 2.x?

@natebosch Yes, I think so. We're not making breaking changes in 2.x here - and removing would clearly be breaking. We might consider new libraries / platform.

We're hardcoding what's true and false in DDC today.

@jakemac53
Copy link
Contributor Author

Ok, refactored the platform support handling:

  • hardcoded now instead of read from libraries.json
  • renamed Platform to DartPlatform to not conflict with dart:io's Platform
  • most apis now take a DartPlatform instead of a string
  • only specific top level constants are exposed for platforms, constructor is private

@jakemac53
Copy link
Contributor Author

Looks like the build_script_generate test is getting flaky (timeouts) - submitting with red appveyor

@jakemac53 jakemac53 merged commit ba5641f into master Aug 29, 2018
@jakemac53 jakemac53 deleted the config-specific-imports branch August 29, 2018 19:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Google is happy with the PR contributors
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants