Skip to content

Resolve Dart Protobuf imports#524

Merged
dmdashenkov merged 10 commits intomasterfrom
dart-pb-imports-tool
Apr 9, 2020
Merged

Resolve Dart Protobuf imports#524
dmdashenkov merged 10 commits intomasterfrom
dart-pb-imports-tool

Conversation

@dmdashenkov
Copy link
Contributor

The problem

Dart, just like JavaScript, has a file-based import system (as opposed to class-based in Java).

When compiling Protobuf into Dart, we have to compile all the accessible .proto files, including those from the project's dependencies. Otherwise, the compiled files would have broken imports pointing at third-party types which are not there.

Example

Module my-app uses library my-lib. Both my-app and my-lib declare Protobuf types and add utilities for working with those types.

If my-app types use my-lib types, the imports generated in my-app will point to relative paths where the my-lib generated Dart classes should be. So, if we don't compile my-lib types in my-app, my-app types contain broken imports.

Solution

Just like in JS, we fix the imports in the generated Dart code. For that, we require the user to construct a map of all the known Dart modules with generated code to their Protobuf packages (or package prefixes).

protoDart {
    modules = [
            'spine-client' : ['spine/*', 'google/*'],
            'spine-users'  : ['spine/users/*']
    ]
}

@dmdashenkov dmdashenkov self-assigned this Apr 8, 2020
@dmdashenkov dmdashenkov requested a review from armiol April 8, 2020 15:14
@dmdashenkov
Copy link
Contributor Author

@armiol, PTAL.

@codecov
Copy link

codecov bot commented Apr 8, 2020

Codecov Report

Merging #524 into master will decrease coverage by 0.45%.
The diff coverage is 14.77%.

@@             Coverage Diff              @@
##             master     #524      +/-   ##
============================================
- Coverage     74.16%   73.71%   -0.46%     
- Complexity     2935     2936       +1     
============================================
  Files           502      503       +1     
  Lines         11787    11869      +82     
  Branches        661      671      +10     
============================================
+ Hits           8742     8749       +7     
- Misses         2823     2898      +75     
  Partials        222      222              

Copy link
Collaborator

@armiol armiol left a comment

Choose a reason for hiding this comment

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

@dmdashenkov please see my comments.

*/

package io.spine.js.generate.resolve;
package io.spine.tools.code;
Copy link
Collaborator

Choose a reason for hiding this comment

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

According to the class-level comment, this is a JavaScript module. However, as you move it out from the JS-specific package, it no longer looks as such. NPM reference is also misleading to me.

private final DirectoryProperty testGeneratedDir;

/**
* Names of JavaScript modules and directories they provide.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand why it is a JavaScript module you speak about.

* modules = [
* // The module provides `company/client` directory (not including subdirectories).
* // So, an import path like {@code ../company/client/file.js}
* // becomes {@code client/company/client/file.js}.
Copy link
Collaborator

Choose a reason for hiding this comment

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

And .js files in the reference.

}

/**
* Reads the file from disc.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's from "a local filesystem".

void resolveImports(ImmutableList<ExternalModule> modules, Path libPath) {
lines = lines.stream()
.map(line -> resolveImportInLine(line, modules, libPath))
.collect(toList());
Copy link
Collaborator

Choose a reason for hiding this comment

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

This one is confusing. So you could just call the method for each of the modules, but instead, you are collecting them into a redundant list to invoke the methods.


@CheckReturnValue
@ParametersAreNonnullByDefault
package io.spine.js.generate.imports;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please document the package.

return new ResolveImports(generatedProtoDir, ImmutableList.of(module));
}

private static ExternalModule newModule(String moduleName, String directoryPattern) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

It's weird that this file has just this one private static method appended. Please review.

@ParametersAreNonnullByDefault
package io.spine.js.generate.imports.given;

import com.google.errorprone.annotations.CheckReturnValue;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please document this package, for consistency sake.

@dmdashenkov
Copy link
Contributor Author

@armiol, PTAL again.

@dmdashenkov dmdashenkov requested a review from armiol April 9, 2020 08:03
@dmdashenkov dmdashenkov merged commit 09a9d5c into master Apr 9, 2020
@dmdashenkov dmdashenkov deleted the dart-pb-imports-tool branch April 9, 2020 11:57
@dmitrykuzmin dmitrykuzmin mentioned this pull request Sep 8, 2020
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

Successfully merging this pull request may close these issues.

2 participants