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

Use goog.requireType when importing interfaces (etc.) #5343

Merged
merged 4 commits into from
Aug 11, 2021

Conversation

cpcallen
Copy link
Contributor

@cpcallen cpcallen commented Aug 10, 2021

The basics

  • I branched from goog_module
  • My pull request is against goog_module
  • My code follows the style guide
  • I have run npm test.

The details

Resolves

Related to #5026

Proposed Changes

Use goog.requireType instead of goog.require when:

  • importing modules containing only interfaces and
  • Importing any other names used only in type annotations.

Also ensure that an import is marked /* eslint-disable-next-line no-unused-vars */ if and only if it is a goog.requireType.

Reason for Changes

Interfaces have no code, so should never be referred to outside of (JSDoc) comments, and so the modules that define only interfaces never need to be goog.require'd—goog.requireType is always sufficient. This is also true of other non-interface types which appear only in comments.

Test Coverage

  • Ran npm test; all tests passed.
  • Ran npm run test:compile:advanced (with some local temporary fixes to un-break it); no increase in number of warnings generated.

Additional Information

I've applied this change to all the I* modules (hungarian notation FTW!)

@cpcallen cpcallen added this to the 2021_q3_release milestone Aug 10, 2021
@cpcallen cpcallen requested a review from moniika August 10, 2021 18:56
@cpcallen cpcallen requested a review from a team as a code owner August 10, 2021 18:56
@google-cla google-cla bot added the cla: yes Used by Google's CLA checker. label Aug 10, 2021
Interfaces have no code, so should never be referred to outside of
(JSDoc) comments, and so the modules that define only interfaces never
need to be goog.require'd - goog.requireType is always sufficient.

This commit fixes imports of all modules whose name matches
/(.*\.)?I[A-Z]*/ - i.e., the hungarian-notation named ones in
core/interfaces/.
Where a module is imported only to used in JSDoc comments it can
(and should) be goog.requireType'd instead of goog.require'd.
There were a few cases where modules were being imported with
goog.require (because they are referred to in code, not just JSDoc
comments) but were prefaced by a spurious eslint suppress.

Remove these, restoring the invariant that an import gets an eslint
if and only if it is a requireType.
@cpcallen
Copy link
Contributor Author

cpcallen commented Aug 10, 2021

Rebased to fix conflicts in core/workspace.js, .../workspace_svg.js and tests/deps.js due to migration of workspace.js.

@rachel-fenichel
Copy link
Collaborator

Continuation of a conversation from #5317:

Monica: Interfaces that are implemented need to be require'd explicitely.

Chris: I'm not aware of any such requirement. Can you direct me to more information about this? As far as I knew interfaces are nothing but a type—the only code is an empty function () {}—so the interface name should only appear in comments and so there ought not to be any reason to require it.

(Things are different in TypeScript, of course, where interface names appear outside of comments.)

Monica got this requirement from me. I know that I said this because of compiler errors or warnings that I was getting from using requireType instead of require.

I think that those were warnings that I got when I added the stricterMissingRequires flag to our error list in gulpfiles/build_tasks.js and then ran npm run build:strict:log and looked at the results.

stricterMissingRequire has been superceded by missingRequire, and now
causes a Java null pointer exception if supplied.
@cpcallen
Copy link
Contributor Author

@rachel-fenichel: thanks for copying over the discussion.

Monica got this requirement from me. I know that I said this because of compiler errors or warnings that I was getting from using requireType instead of require.

I think that those were warnings that I got when I added the stricterMissingRequires flag to our error list in gulpfiles/build_tasks.js and then ran npm run build:strict:log and looked at the results.

That is super interesting. Ok, short summary of what I have learned this morning:

  • According to the comment by @samelhusseini in build_tasks.js the flag is now just missingRequire, and indeed the stricterMissingRequire flag now causes an error:
    gulp-google-closure-compiler: java.lang.NullPointerException: No warning class for name: stricterMissingRequire
    
  • Enabling missingRequire for the code in this PR cause just three additional errors to be emitted by npm build:strict:
    core-bubble.js:45:16: ERROR - [JSC_MISSING_REQUIRE_IN_PROVIDES_FILE] 'Blockly.IBubble' references a namespace which was not required by this file.
    Please add a goog.require.
      45|  * @implements {Blockly.IBubble}
                          ^^^^^^^^^^^^^^^
    
    core-metrics_manager.js:31:16: ERROR - [JSC_MISSING_REQUIRE_IN_PROVIDES_FILE] 'Blockly.IMetricsManager' references a namespace which was not required by this file.
    Please add a goog.require.
      31|  * @implements {Blockly.IMetricsManager}
                          ^^^^^^^^^^^^^^^^^^^^^^^
    
    core-renderers-common-renderer.js:41:16: ERROR - [JSC_MISSING_REQUIRE_IN_PROVIDES_FILE] 'Blockly.IRegistrable' references a namespace which was not required by this file.
    Please add a goog.require.
      41|  * @implements {Blockly.IRegistrable}
                          ^^^^^^^^^^^^^^^^^^^^
    
    Notably these are the only three files touched which have not yet been migrated to goog.module and named requires. I note that the error is "JSC_MISSING_REQUIRE_IN_PROVIDES_FILE", and I also see a "JSC_MISSING_REQUIRE_TYPE_IN_PROVIDES_FILE", and that these are different from "JSC_MISSING_REQUIRE" which is emitted for migrated files.
  • This makes me suspicious that the error actually in the compiler, not the code (I know… it's never a compiler error—but it's plausible, since it is specifically an error generated for goog.provides files, which is probably a much less tested code path these days).

So I think the changes to already-migrated files are fine. For the not-yet-migrated ones, I could back out the change for now, but I think it's probably better to leave it in so that whoever does the migration doesn't need to remember to do it then.

@rachel-fenichel
Copy link
Collaborator

I retain my standard skepticism about whether it's a compiler bug--but since you were able to reproduce the errors in the unconverted files, and show that they don't happen in the converted files, this seems safe. Approved.

@cpcallen cpcallen merged commit 4c40378 into google:goog_module Aug 11, 2021
@cpcallen cpcallen deleted the interface-requireType branch August 11, 2021 17:50
@cpcallen cpcallen mentioned this pull request Aug 11, 2021
4 tasks
@cpcallen
Copy link
Contributor Author

cpcallen commented Aug 12, 2021

I retain my standard skepticism about whether it's a compiler bug…

I've filed google/closure-compiler#3851; we'll see what they say.

@cpcallen
Copy link
Contributor Author

cpcallen commented Aug 24, 2021

I retain my standard skepticism about whether it's a compiler bug…

I've filed google/closure-compiler#3851; we'll see what they say.

It seems that you are correct and I am wrong: there is a compiler bug, but apparently the bug is that no error message is issued when goog.requireTypeing an interface type in a goog.module. The mind boggles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Used by Google's CLA checker. type: cleanup
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants