Skip to content
This repository has been archived by the owner on Jan 24, 2022. It is now read-only.

Rework compiler imports #1411

Merged
merged 8 commits into from
Jan 28, 2020
Merged

Rework compiler imports #1411

merged 8 commits into from
Jan 28, 2020

Conversation

spalladino
Copy link
Contributor

@spalladino spalladino commented Jan 24, 2020

This PR reworks how Solidity imports are resolved. It removes the dependency on resolver-engine for simplicity, and moves all logic to the SourcesGatherer module, and includes a few refactors along the way. I suggest reviewing commit by commit.

The most important change is that only a subset of import formats are now supported:

  • An absolute path: /foo/bar/baz.sol
  • A path relative to the current file: ../foo/bar.sol
  • A path relative to the current project root: contracts/foo/bar.sol
  • A path to a dependency: @openzeppelin/contracts/foo/bar.sol

Note that a path relative to the current project root is only supported for project contracts, not in a dependency. This is because we reserve the contracts/foo/bar.sol name for a bar.sol within the project, and we could have clashes if we also use it for a dependency. Dependencies should only use relative paths.

This PR also ensures that there are no repeated artifact names. If there are, a warning is emitted, and only one of them is written to disk, to prevent corruption of the generated JSON files by concurrent writes.

Fixes #1404

- Move mock project to compile to test/mocks
- Remove stdlib-with-deps as it is already covered in mock-project-to-compile
- Add package.json where missing
- Remove invalid import statements
All cases are now manually handled without a dependency to resolver-engine. Support for relative imports not starting with '.' is removed, unless they are relative to the project root, like 'contracts/foo/bar.sol'. Note that these are not supported for dependencies, only for project contracts.

A new compiler setting, workingDir, is added. All relative imports not starting with '.' are resolved on this directory.
@spalladino spalladino changed the title Fix compiler imports Rework compiler imports Jan 24, 2020
@spalladino spalladino requested a review from ylv-io January 24, 2020 23:47
@spalladino
Copy link
Contributor Author

@ylv-io I'd appreciate a review! The PR is still in draft since I want to make a few more manual tests to see if everything is working fine.

@spalladino spalladino changed the base branch from master to release/2.7 January 24, 2020 23:49
ylv-io
ylv-io previously approved these changes Jan 27, 2020
Copy link
Contributor

@ylv-io ylv-io left a comment

Choose a reason for hiding this comment

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

Small and tidy PR. Love it. 🚢
PS I found that SDK missing typings for a lot of lodash methods and fail to compile with them. I'll address that in a separate PR.

public async call(): Promise<void> {
await this._loadSoliditySourcesFromDir();
await this._loadDependencies();
const roots = await this.loadProjectSoliditySources();
Copy link
Contributor

Choose a reason for hiding this comment

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

Love removing _ and more explicit flow of data.

private async loadProjectSoliditySources(): Promise<string[]> {
const dir = this.inputDir;
if (!existsSync(dir) || !lstatSync(dir).isDirectory) return [];
return promisify(glob)('**/*.sol', { cwd: dir, absolute: true });
Copy link
Contributor

Choose a reason for hiding this comment

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

More libs, less code!


async function fileExists(file: string): Promise<boolean> {
try {
return (await promisify(fs.stat)(file)).isFile();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why we are so concerned about it being a file rather than just checking with pathExists?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It could be a directory instead of a file

`
pragma solidity ^0.5.0;
import "./subfolder/GreeterLib.sol";
import "contracts/subfolder/GreeterLib2.sol";
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is it GreeterLib2.sol? Shouldn't it be GreeterLib.sol?

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 wanted to test importing each with a different format from root

Copy link
Contributor

Choose a reason for hiding this comment

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

Test name says compiles including more than one import to the **same file**. I don't see here two imports of the same file. What I am missing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@spalladino spalladino marked this pull request as ready for review January 27, 2020 18:48
@ylv-io ylv-io self-requested a review January 28, 2020 14:07
Copy link
Contributor

@ylv-io ylv-io left a comment

Choose a reason for hiding this comment

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

This is a proper PR 🚢

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants