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

Closure warnings #4684

Merged
merged 54 commits into from
Jul 13, 2017
Merged

Closure warnings #4684

merged 54 commits into from
Jul 13, 2017

Conversation

dfreedm
Copy link
Member

@dfreedm dfreedm commented Jun 12, 2017

Full support for Closure Compiler

Steven Orvell and others added 30 commits April 26, 2017 14:07
…t picked up as proto property (avoids initial binding value)
…ctor` (allows work to be done before `_initializeProperties` and is needed for proto/instance property initialization .
Copy link
Contributor

@sorvell sorvell left a comment

Choose a reason for hiding this comment

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

Generally seems ok. We're inconsistent about when we're putting stuff in polymer-externs.js v. inline which is not ideal. I think we also need to add at least some comments somewhere about why/when we're using @suppress.

@kevinpschaaf
Copy link
Member

What exactly is the difference between the type of warnings that go away with @unrestricted vs @suppress(missingProperties)?

* @extends {superClass}
* @implements {Polymer_PropertyEffects}
*/
let propertyEffectsBase = Polymer.PropertyEffects(superClass);
Copy link
Member

Choose a reason for hiding this comment

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

This actually seems like a bug, since the mixin implements static get properties()... it should extend Polymer.ElementMixin I think (and revert the <link rel="import" href="../../polymer-element.html">)

Copy link
Member Author

Choose a reason for hiding this comment

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

Seems reasonable to me. That seems like a bug in master as well then.

@@ -188,7 +210,7 @@
* @return {string} Serialized value
*/
serialize(value) {
return this._serializeValue(value);
return this._serializeValue(value) || '';
Copy link
Member

Choose a reason for hiding this comment

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

This only exists for legacy usage (isn't called directly anymore), but technically speaking, it used to return undefined for false boolean properties, null, or undefined. So probably best to just make the return type {string|undefined}.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok.

if (window.ShadyDOM && this.shadowRoot) {
this.shadowRoot.forceRender();
if (window.ShadyDOM) {
window.ShadyDOM.flush();
Copy link
Member

Choose a reason for hiding this comment

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

Curious why this is showing as a change? Just wasn't rebased recently?

Copy link
Member Author

Choose a reason for hiding this comment

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

This must have been missed in a merge conflict. I'll pull the master branch version.

@@ -86,7 +89,7 @@
* Runs all effects of a given type for the given set of property changes
* on an instance.
*
* @param {Object} inst The instance with effects to run
* @param {PropertyEffectsInstance | Polymer_PropertyEffects} inst The instance with effects to run
Copy link
Member

Choose a reason for hiding this comment

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

What does this mean? Seems like one or the other, no? Why doesn't it need to be a union of those two things?

Copy link
Member Author

Choose a reason for hiding this comment

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

Actually, PropertyEffectsInstance already extends Polymer_PropertyEffects so I can probably remove the type union here.

In general though, I would have to make a new type to do a union like you would want.

Copy link
Member Author

@dfreedm dfreedm Jun 16, 2017

Choose a reason for hiding this comment

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

Looks like I need a bunch of casts now because a lot of methods in PropertyEffects class call out to these functions and the type doesn't exist in that scope.

@dfreedm
Copy link
Member Author

dfreedm commented Jun 16, 2017

@unrestricted allows for adding instance properties outside of constructor().

@suppress {missingProperties} suppresses the warnings generated by accessing properties that the compiler does not know that the class has.
Good examples include anywhere a class is dynamically assigned a property, or a type interface doesn't include private properties.

@ChadKillingsworth
Copy link
Contributor

Man I'm glad to see this PR.

@Suppress {missingProperties} suppresses the warnings generated by accessing properties that the compiler does not know that the class has.
Good examples include anywhere a class is dynamically assigned a property, or a type interface doesn't include private properties.

Be careful when you do this that you don't inadvertently lie to the compiler about types. The type based optimizations will create some really hard to debug issues with blatantly wrong type information. Missing type information is not a problem for this though.

@dfreedm
Copy link
Member Author

dfreedm commented Jun 16, 2017

@ChadKillingsworth good points. I've been trying to use suppressions sparingly, mostly around edges where the lazy instantiation of class properties, but this is a good time to maybe try to shape the classes with nulls for those properties ahead of time.

@ChadKillingsworth
Copy link
Contributor

ChadKillingsworth commented Jun 16, 2017

@azakus You can also just add a stub definition for the compiler:

constructor() {
  /** @type {number} */
  this.myPropThatIsNotInitialized;
}

It may break stuff in closure to use this much, so try to shape classes
for closure directly.

Use polymer pass v2 to remove warnings for properties defined in
`properties` block
@@ -119,6 +120,28 @@

constructor() {
super();
/** @type {boolean} */
Copy link
Member

Choose a reason for hiding this comment

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

Try moving out to polymer-closure-types.html. The rule will be mixin property interface needs to be defined there, since it can't (easily) be auto-generated like the methods can.

* @unrestricted
*/
class PropertyEffects extends propertyEffectsBase {

constructor() {
super();
/** @type {boolean} */
Copy link
Member

Choose a reason for hiding this comment

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

Investigate moving these definitions out to the extern HTML file, and then go back to using Polymer_PropertyEffects as the inst type in the private methods

Copy link
Member Author

Choose a reason for hiding this comment

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

This is hung up by some sort of internal compiler error :/

Copy link
Member Author

Choose a reason for hiding this comment

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

Polymer_PropertyEffects.prototype.__computeEffects;
Copy link
Member

Choose a reason for hiding this comment

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

Consider:

  • use this['__computeEffects'] in code instead of enum to keep them from being renamed, so that these don't have to be externed
  • that allows these and __dataHost to be moved to polymer-closure-types.html
  • which then allows closure-types.js to not need to be externed, and instead lumped alongside polymer-closure-types.html

@@ -61,53 +64,20 @@ Polymer.sanitizeDOMValue;
*/
function JSCompiler_renameProperty(string, obj) {}

/** @record */
function PolymerTelemetry(){}
Copy link
Member

Choose a reason for hiding this comment

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

Leave this externed

@@ -1614,7 +1671,7 @@
if (this.__propagateEffects) {
runEffects(this, this.__propagateEffects, changedProps, oldProps, hasPaths);
}
let templateInfo = this.__templateInfo;
let templateInfo = /** @type {TemplateInfo} */(this.__templateInfo);
Copy link
Member

Choose a reason for hiding this comment

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

Can remove cast since it's typed in ctor right now (to be moved to types file)

*/
notifySplices(path, splices) {
let info = {};
let /** PathInfo */ info = {path: ''};
Copy link
Member

Choose a reason for hiding this comment

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

Can eliminate the type info here since it should be structural.

* @param {Object} templateInfo Template metadata for current template
* @param {Object} nodeInfo Node metadata for current template.
* @param {!TemplateInfo} templateInfo Template metadata for current template
* @param {!NodeInfo} nodeInfo Node metadata for current template.
* @param {string} name Attribute name
* @param {*} value Attribute value
Copy link
Member

Choose a reason for hiding this comment

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

value arg should always be string; can remove cast below

@ChadKillingsworth
Copy link
Contributor

I worked with this branch a bit over the weekend. A few notes:

  • Moving the interfaces from externs to source works great - except for the static properties. Since the compiler doesn't properly model static inheritance yet, leaving the static properties as externs seems appropriate to me.
  • Any extern or interface function that takes no arguments and returns nothing (it's only used for side effects) needs an @return {undefined} annotation. Otherwise, the compiler assumes it's of type function(...?):? - which is pretty horrible.
  • I recommend switching from @record to @interface. I had no problems doing that myself. @record doesn't get near the renaming that @interface does and you aren't currently using structural type checking.

Here's an example of the changes I made: ChadKillingsworth@6f27764

@dfreedm
Copy link
Member Author

dfreedm commented Jul 10, 2017

@ChadKillingsworth thanks!

@dfreedm
Copy link
Member Author

dfreedm commented Jul 11, 2017

Looks like the difference between putting all interfaces into externs and splitting statics out into externs is around 2kb in binary size.
Worthwhile, but not 100% necessary in my mind.
I think this can merge to master with the last two modifications described in #4684 (comment)

@dfreedm
Copy link
Member Author

dfreedm commented Jul 12, 2017

google/closure-compiler#2338 has merged, so now we can go ahead and merge this branch!

@sorvell sorvell merged commit 0b23e74 into master Jul 13, 2017
@sorvell sorvell deleted the closure-warnings branch July 13, 2017 19:21
@ChadKillingsworth
Copy link
Contributor

Yay!

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

Successfully merging this pull request may close these issues.

5 participants