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

chore(jsii): better errors around use of hidden types #1861

Merged

Conversation

RomainMuller
Copy link
Contributor

When a hidden (that is, @internal or not exported) type is used in a
visible (public or protected on an exported type) API, the error
produced would refer to the unusable type, but would not give any
indication of where it was being used from.

This makes several enhancements to this process:

  • Qualify the kind of use for the type (return, parameter, ...)
  • Attach the error to the resolving node (usage location)
  • Provide a related message with the unusable type's declaration
  • Specifically message around "this" (used or inferred as a return type)

This is going to particularly enhance the experience of folks extending
internal base types, where those internal base types declare members
that return hidden types (or "this").

Fixes #1860


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@RomainMuller RomainMuller requested a review from a team August 7, 2020 13:46
@RomainMuller RomainMuller self-assigned this Aug 7, 2020
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Aug 7, 2020
@RomainMuller RomainMuller added effort/small Small work item – less than a day of effort module/compiler Issues affecting the JSII compiler labels Aug 7, 2020
@RomainMuller
Copy link
Contributor Author

RomainMuller commented Aug 7, 2020

Added another commit to actually switch the way we test for errors in the "negatives" to actually look at the rendered error entirely (thanks to jest snapshots) in order to have a better picture of the error UX we are offering.

Marked pr/no-squash to preserve the two separate commits.

@RomainMuller RomainMuller added the pr/no-squash This PR should be merged instead of squash-merging it label Aug 10, 2020
packages/jsii/lib/assembler.ts Outdated Show resolved Hide resolved
packages/jsii/lib/assembler.ts Outdated Show resolved Hide resolved
packages/jsii/lib/assembler.ts Outdated Show resolved Hide resolved
packages/jsii/lib/assembler.ts Outdated Show resolved Hide resolved
packages/jsii/lib/assembler.ts Show resolved Hide resolved
@@ -1,5 +1,3 @@
///!MATCH_ERROR: Interface contains behavior: name should be "ISomething"
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not seeing this error (or equivalent) in the snapshot. Am I missing it, or did this get dropped somehow?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😨 OMG good catch. I guess I was never asserting there is > 0 problems found...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh and the issue turned out to be essentially that location-less problem markers are NOT rendered with the API style I was going for... Dun dun dun!

RomainMuller and others added 2 commits August 10, 2020 15:42
When a hidden (that is, `@internal` or not exported) type is used in a
visible (`public` or `protected` on an exported type) API, the error
produced would refer to the unusable type, but would not give any
indication of where it was being used from.

This makes several enhancements to this process:
- Qualify the kind of use for the type (return, parameter, ...)
- Attach the error to the resolving node (usage location)
- Provide a related message with the unusable type's declaration
- Specifically message around "this" (used or inferred as a return type)

This is going to particularly enhance the experience of folks extending
internal base types, where those internal base types declare members
that return hidden types (or "this").

Fixes #1860
Makes it easier to review the actual, complete, user experience (including error locality).
@RomainMuller RomainMuller force-pushed the rmuller/better-errors-reutrning-this-from-internal-type branch from baeebbe to d7d1d1b Compare August 10, 2020 14:08
@RomainMuller RomainMuller requested a review from njlynch August 10, 2020 14:08
@RomainMuller RomainMuller added pr/do-not-merge This PR should not be merged at this time. and removed pr/do-not-merge This PR should not be merged at this time. labels Aug 10, 2020
@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject6AEA49D1-Blkkw9bQFn8A
  • Commit ID: d7d1d1b
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@RomainMuller RomainMuller merged commit 31ec095 into master Aug 10, 2020
@RomainMuller RomainMuller deleted the rmuller/better-errors-reutrning-this-from-internal-type branch August 10, 2020 14:52
RomainMuller added a commit that referenced this pull request Aug 10, 2020
Using `--project-references`, nested types from dependencies could not
be used as they would result in the following `jsii` error:

```
Type "<type name>" cannot be used as the return type because it is private or @internal
```

THis is because in `--project-references` mode, the ambient declaration
for the nested type is the declaration that gets resolved to, and those
cannot have the `export` keyword: instead, the surrounding module
declaration is annotated with `export ambient`.

This adds the necessary code path to actually identify this scenario and
to appropriately detect the type is actually visible and exported.

The check that was failing had been added in #1861 as a way to provide a
more helpful error message when private or `@internal` types are
mistakenly used on exported APIs; which explains why this situation did
not previously occur.
RomainMuller added a commit that referenced this pull request Aug 12, 2020
Using `--project-references`, nested types from dependencies could not
be used as they would result in the following `jsii` error:

```
Type "<type name>" cannot be used as the return type because it is private or @internal
```

This is because in `--project-references` mode, the ambient declaration
for the nested type is the declaration that gets resolved to, and those
cannot have the `export` keyword: instead, the surrounding module
declaration is annotated with `export ambient`.

This adds the necessary code path to actually identify this scenario and
to appropriately detect the type is actually visible and exported.

The check that was failing had been added in #1861 as a way to provide a
more helpful error message when private or `@internal` types are
mistakenly used on exported APIs; which explains why this situation did
not previously occur.

> Hidden gem: we were previously adding the `static` keyword when
> generating nested classes in **C#**. This is a **Java**-ism and results
> in code that won't compile, since **C#** does not allow `static` nested
> classes to declare `protected` members (which we actually emit some
> of).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS. effort/small Small work item – less than a day of effort module/compiler Issues affecting the JSII compiler pr/no-squash This PR should be merged instead of squash-merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

How to keep base classes private?
4 participants