Skip to content

Provide type support to linker.ts #604

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

Merged
merged 1 commit into from
Mar 23, 2022
Merged

Provide type support to linker.ts #604

merged 1 commit into from
Mar 23, 2022

Conversation

stephen-slm
Copy link
Contributor

@stephen-slm stephen-slm commented Feb 15, 2022

Why

This change provides some basic type support for the internal and exported methods within linker.ts, includes support documentation where missing for the consumer. The target result of this PR is to increase readability, maintainability and start the introduction of types.

This is the continuous development happening on top of #566 to improve user consumption, and development experience.

Depends on #603 and #594

Note

This is currently rebased on #603 so just validate the latest commit.

@stephen-slm stephen-slm changed the title Types/linker Provide type support to linker.ts Feb 15, 2022
@coveralls
Copy link

coveralls commented Feb 15, 2022

Coverage Status

Coverage remained the same at 83.721% when pulling 6409860 on stephensli:types/linker into f54dabf on ethereum:master.

@cameel cameel mentioned this pull request Feb 15, 2022
common/types.ts Outdated
* Containing support for two level configuration.
*/
export interface LibraryPlaceholdersMapping {
[libraryName: string]: string | { [location: string]: string };
Copy link
Member

Choose a reason for hiding this comment

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

Let's call it fullyQualifiedLibraryName to avoid any confusion. I.e. it's supposed to include the file name and the library name joined with :.

Also, by two-level configuration you mean {"lib.sol": {"L": "0x..."}}? Then the names don't really match. I.e. then the first level is not really a library name but the file name (or source unit name to be precise).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The type is to support both methods which are currently passed in.

{"lib.sol": {"L": "0x..."}}
and
{"lib.sol": "0x..."}

which I experienced and gained from writing the changes the tests. If i'm wrong we can correct the names.

Copy link
Member

Choose a reason for hiding this comment

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

The second should be: {"lib.sol:L": "0x..."}.

Well, technically {"lib.sol": "0x..."} will still work but only if you have a placeholder with lib.sol in it. Which you won't get from actual compilation but tests could be set up with a situation like this. lib.sol here would be interpreted as library name, i.e. as if you wrote library lib.sol {} in your code, which is forbidden due to the dot.

Copy link
Contributor Author

@stephen-slm stephen-slm Feb 15, 2022

Choose a reason for hiding this comment

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

thoughts?

// kind 1: {"lib.sol:L": "0x..."}
// kind 2: {"lib.sol": {"L": "0x..."}}

// we can specify the requirement for `L` if its always going to be `L` or change it to `[x: string]`
type: { [x: string]: string } | { [x: string]: { "L": string }  } 

Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately the current code supports mixing the two. E.g. this is valid input:

{
    "lib.sol:L1": "0x...",
    "lib.sol:L2": "0x...",
    "lib.sol": {"L3": "0x..."}
}

On the other hand, we don't even support the first kind in Standard JSON and I doubt any compiler version supported both so we might be fine changing it. It's technically a breaking change for solc-js though. @axic what do you think?

So yeah, what you did in the PR is correct, just names are a bit misleading. We could do this but it's a bit ugly:

export interface LibraryAddresses {
  [qualifiedNameOrSourceUnit: string]: string | { [unqualifiedLibraryName: string]: string };

On the other hand the ugliness at least does let you know that there's something wonky going on here and you should watch your step :)

The only other idea that comes to mind is to give the first level some generic name not to suggest it's necessarily one or the other:

export interface LibraryAddresses {
  [firstLevelID: string]: string | { [unqualifiedLibraryName: string]: string };

Copy link
Member

Choose a reason for hiding this comment

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

Can you explain how it supports both?

type: { [x: string]: string } | { [x: string]: { [x: string]: string }  } 

Doesn't the | here mean that it must have one signature or the other and not that you can mix and match fields allowed in both?

In any case, unless it supports both, that suggestion does not match what the library supports.

The problem still stands, names and the docstring here are ambiguous and need to be adjusted.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the libraries: LibraryAddresses is an object, it's stating that the content of each item within that object can be one or the other. A single item cannot be both so this is fine. In any case, unless it supports both, that suggestion does not match what the library supports. - you will have to be more clean on this since I have made all the required changes

Copy link
Member

Choose a reason for hiding this comment

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

Since the libraries: LibraryAddresses is an object, it's stating that the content of each item within that object can be one or the other. A single item cannot be both so this is fine.

I think we might be talking about different things here. I get the feeling you're commenting on the form you used in the PR and not on the one I cited. But no matter, that's not all that important so let's drop it. Perhaps I'm just misunderstanding this. I was just giving feedback on your suggestion from #604 (comment) because you asked for it.

The version in the PR is fine. I'd just replace the two level configuration part in the docstring with the example of two kinds you have above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sounds good,

i'll add this example

{
    "lib.sol:L1": "0x...",
    "lib.sol:L2": "0x...",
    "lib.sol": {"L3": "0x..."}
}

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

@stephen-slm stephen-slm requested a review from cameel February 16, 2022 08:54
common/types.ts Outdated
* Containing support for two level configuration.
*/
export interface LibraryPlaceholdersMapping {
[libraryName: string]: string | { [location: string]: string };
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately the current code supports mixing the two. E.g. this is valid input:

{
    "lib.sol:L1": "0x...",
    "lib.sol:L2": "0x...",
    "lib.sol": {"L3": "0x..."}
}

On the other hand, we don't even support the first kind in Standard JSON and I doubt any compiler version supported both so we might be fine changing it. It's technically a breaking change for solc-js though. @axic what do you think?

So yeah, what you did in the PR is correct, just names are a bit misleading. We could do this but it's a bit ugly:

export interface LibraryAddresses {
  [qualifiedNameOrSourceUnit: string]: string | { [unqualifiedLibraryName: string]: string };

On the other hand the ugliness at least does let you know that there's something wonky going on here and you should watch your step :)

The only other idea that comes to mind is to give the first level some generic name not to suggest it's necessarily one or the other:

export interface LibraryAddresses {
  [firstLevelID: string]: string | { [unqualifiedLibraryName: string]: string };

@stephen-slm stephen-slm requested a review from cameel February 28, 2022 08:18
@cameel cameel added the has dependencies The PR depends on other PRs that must be merged first label Mar 7, 2022
Copy link
Member

@cameel cameel left a comment

Choose a reason for hiding this comment

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

I think that one of the docstrings still needs small adjustments but this is not a critical issue so I'm approving already.

@axic Could you take a final look at this?

@cameel cameel merged commit 99eafc2 into ethereum:master Mar 23, 2022
@stephen-slm stephen-slm deleted the types/linker branch March 23, 2022 17:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
has dependencies The PR depends on other PRs that must be merged first
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants