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

api_analysis_exploration: add "Top-level member list" feature proposal #222

Open
wants to merge 1 commit into
base: api_analysis_exploration
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 219 additions & 5 deletions api_analysis/lib/r4/shape-format.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Proposal for package shape format

Idea:
## Idea
* Use lists of stuff, let the index in the list act as an ID number. Then we
can just reference the ID number when we reference the thing.
* Include:
Expand All @@ -11,10 +11,224 @@ Idea:
* Exclude:
* Return types and argument types (maybe we add this later?)

Undecided: (added in draft 2)
* Imports
* "extends" and "mixin"
* "implements"
## Undecided
### Imports
See draft 1 -> draft 2.

### `extends` and `mixin`
See draft 1 -> draft 2.

### `implements`
See draft 1 -> draft 2.

### Top-level member list
We could collect all the member shapes (defined across all libraries), and store them all together in one list. We could then refer to the members exported in a given library by their indexes in this list.

This can also allow us to no longer store `.identifiers` of shapes defined and exported in the same package, but note that we still need to record identifiers of any exported external top-level members, since we cannot produce summaries of them.

#### Example

In this example, we encode the member index as a tuple, where the first element is 0 if the member being exported has been defined in this package, and 1 if it is an external member.

Alternatively, we can use one integer as an index, rolling over the count from `.members` into `.externalIdentifiers` (for example, in this case, the index of "Bar" would be 1, because `.members` contains 1 element).

<details>
<summary>Full example</summary>

```js
{
"verison": 1,
"package": "foo",
"version": "1.0.0",
// Shapes of top-level members defined in any library in this package.
"members": [
// This is the 0th top-level member defined in this package.
{
"name": "Foo",
"kind": "class",
"members": [
{
"name": "sayHello",
"kind": "method",
"params": [
{
"name": ...,
"kind": "positional" | "named",
"required": true | false,
},
...
],
},
...
],
},
...
],
// Identifiers of top-level members which are defined in a different package,
// but exported in this one.
"externalIdentifiers": [
// This is the 0th external top-level member.
"Bar"
],
"libraries": [
// library 0:
{
"uri": "package:foo/foo.dart",
// Propogated exports, with this we can easily compute the set of exported
// members.
"exports": [
{
"library": 1, // library 1 is "package:foo/src/bar.dart"
"show": [
[1, 0], // the 0th external member is "Bar"
],
},
{
"library": 2, // library 2 is "package:bar/bar.dart"
"hide": [
[0, 0], // the 0th member defined in this package is "Foo"
],
}
],
},
// library 1:
{
"uri": "package:foo/src/bar.dart",
"exports": [
{
"id": 0, // library 0 is "package:foo/foo.dart"
"hide": [
[0, 0], // the 0th member defined in this package is "Foo"
],
},
],
},
// library 2:
{
// TODO: Is this a good way to do external libraries?
"uri": "package:bar/bar.dart",
// We know nothing about external libraries, so there no data here.
// We have an entry in "libraries" such that they have an identifier.
},
],
}
```
</details>

<details>
<summary>Diff from draft 1</summary>

```diff
{
"verison": 1,
"package": "foo",
"version": "1.0.0",
- "identifiers": [
- "Foo", // 0
- "sayHello", // 1
- "Bar", // 2
+ // Shapes of top-level members defined in any library in this package.
+ "members": [
+ // This is the 0th top-level member defined in this package.
+ {
+ "name": "Foo",
+ "kind": "class",
+ "members": [
+ {
+ "name": "sayHello",
+ "kind": "method",
+ "params": [
+ {
+ "name": ...,
+ "kind": "positional" | "named",
+ "required": true | false,
+ },
+ ...
+ ],
+ },
+ ...
+ ],
+ },
+ ...
+ ],
+ // Identifiers of top-level members which are defined in a different package,
+ // but exported in this one.
+ "externalIdentifiers": [
+ // This is the 0th external top-level member.
+ "Bar"
],
"libraries": [
// library 0:
{
"uri": "package:foo/foo.dart",
// Propogated exports, with this we can easily compute the set of exported
// members.
"exports": [
{
"library": 1, // library 1 is "package:foo/src/bar.dart"
- "show": [
- 2, // identifier 2 is "Bar"
+ "show": [
+ [1, 0], // the 0th external member is "Bar"
],
},
{
"library": 2, // library 2 is "package:bar/bar.dart"
"hide": [
- 0, // identifier 0 is "Foo"
+ [0, 0], // the 0th member defined in this package is "Foo"
],
}
],
- // Top-level things defined in the library
- // Not everything exported, this can be easily computed by using the
- // "exports" maps.
- "members": [
- {
- "name": 0 // identifier 0 is "Foo"
- "kind": "class",
- "members": [
- {
- "name": 1, // identifier 1 is "sayHello"
- "kind": "method",
- "params": [
- {
- "name": ...,
- "kind": "positional" | "named",
- "required": true | false,
- },
- ...
- ],
- },
- ...
- ],
- },
- ],
},
// library 1:
{
"uri": "package:foo/src/bar.dart",
"exports": [
{
"id": 0, // library 0 is "package:foo/foo.dart"
"hide": [
- 0, // identifier 0 is "Foo"
+ [0, 0], // the 0th member defined in this package is "Foo"
],
},
],
},
// library 2:
{
// TODO: Is this a good way to do external libraries?
"uri": "package:bar/bar.dart",
// We know nothing about external libraries, so there no data here.
// We have an entry in "libraries" such that they have an identifier.
},
],
}
```
</details>

## Draft 1

Expand Down
Loading