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: cleaned up several type cases in core/field.ts and impacted files #6363

Merged
merged 10 commits into from
Sep 30, 2022

Conversation

btw17
Copy link
Member

@btw17 btw17 commented Aug 19, 2022

The basics

  • I branched from develop
  • My pull request is against develop
  • My code follows the style guide
  • I ran npm run format and npm run lint

The details

Resolves

This resolves several AnyDuringMigration type cases in core/field.ts.

Proposed Changes

  • Updates nullable types, when set, to be <OriginalType>|null to properly reflect its possible state
  • Updates usage of those nullable types to assert they're available in core/field.ts and impacted descendants
  • Added type information for callingClass which uses Field's prototype
  • Updates numbers which are expected to be strings to be cast to strings in core/field.ts

Behavior Before Change

  • Less precise type information.
  • SVGTextElement.setAttribute passed in numbers as attribute values instead of strings in core/field.ts

Behavior After Change

  • More precise type information.
  • SVGTextElement.setAttribute always passes in strings now in core/field.ts

Reason for Changes

Simplifying the information space by offloading type juggling to the compiler.

@btw17 btw17 requested a review from a team as a code owner August 19, 2022 23:03
@btw17 btw17 requested a review from maribethb August 19, 2022 23:03
Copy link
Collaborator

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

LGTM! It is frustrating that so many of these things have to be nullable, but I think that's a problem with the design of the field, not with this change.

One question: How would you feel about changing instances of sourceBlock_! to use getSourceBlock() instead (which already includes the assertion).

@btw17
Copy link
Member Author

btw17 commented Aug 24, 2022

One question: How would you feel about changing instances of sourceBlock_! to use getSourceBlock() instead (which already includes the assertion).

I'm 100% for it! With that in mind, can I update sourceBlock_ from protected to private as well? It would force those inheriting from field to use getSourceBlock, though since sourceBlock_ isn't expected to be null most of the time anyway, it could save with some confusion on handling the null case. Edit: there are some existing cases, such as in field_variable.ts in getVariableTypes_, that utilize the base sourceBlock_ and check for null, so I'll leave it protected and just update the sourceBlock_! cases as you mentioned.

@btw17
Copy link
Member Author

btw17 commented Aug 24, 2022

@BeksOmega all set! I updated fieldGroup_! to use getSvgRoot() as well. They're split into separate commits, so it should be pretty straightforward to verify.

Copy link
Collaborator

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Thanks for your work on this dude!

core/field.ts Show resolved Hide resolved
core/field.ts Outdated Show resolved Hide resolved
core/field.ts Show resolved Hide resolved
core/field_angle.ts Outdated Show resolved Hide resolved
@BeksOmega BeksOmega requested review from BeksOmega and removed request for maribethb August 25, 2022 16:22
@BeksOmega BeksOmega assigned BeksOmega and unassigned maribethb Aug 25, 2022
Copy link
Collaborator

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Rebase/merge (your preference) to resolve conflicts, then I think this is gtg.

@BeksOmega BeksOmega changed the title Chore: cleaned up several type cases in core/field.ts and impacted files chore: cleaned up several type cases in core/field.ts and impacted files Aug 25, 2022
@btw17
Copy link
Member Author

btw17 commented Aug 26, 2022

My tests are broken locally even at origin/develop so I'm not able to verify this locally, though it looks like the tests are running into an issue with getSvgRoot throwing an error for falsy values of fieldGroup_. I'm assuming that could be fixed by reverting getSvgRoot to return this.fieldGroup_!, though this might be more of a sign that getSvgRoot should actually be returning SVGElement|null. What do you think @BeksOmega?

@@ -202,7 +202,7 @@ export class FieldAngle extends FieldTextInput {
// #2380)
this.symbol_ = dom.createSvgElement(Svg.TSPAN, {});
this.symbol_.appendChild(document.createTextNode('\u00B0'));
this.textElement_.appendChild(this.symbol_);
this.getTextElement().appendChild(this.symbol_);
Copy link
Member Author

@btw17 btw17 Aug 26, 2022

Choose a reason for hiding this comment

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

Hey @maribethb & @BeksOmega - I went ahead and created getTextElement and other wrapper functions to handle encapsulating the null error check. What do you think about utilizing it in this context, though? Earlier, it was mentioned using this.textElement_! made sense here since it was just defined in initView. The trade off here I think is 'runtime compute' vs 'developer compute', so to speak 😂

Runtime Compute - In cases like this where the null check is so minor, it would take an extreme number of runs for it to impact runtime performance.

Developer Compute - It might be obvious that after initView the textElement_ should be set, though it's just one less thing a developer has to juggle when looking through this code.

Edit: The main purpose of asking here is the conceptual discussion of how to handle cases like this rather than specifically whether or not I need to correct this case (though I will correct it if this.textElement_! would be preferred!)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think either option makes sense in situations like this where we never expect developers to be interacting with these properties while they're null =)

Copy link
Contributor

Choose a reason for hiding this comment

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

We discussed this earlier this week and this is one of those cases where it's acceptable because it's easily verified that textElement is set directly beforehand in initView. The property is set and then used in the same method so there is no room for developer error - compare that to fieldGroup_ where it could be set in multiple places and an error like forgetting to call an init method would result in the value being unexpectedly null.

There is no hard and fast rule I can give you but that's why this particular case the ! is fine, though using the method is also fine.

Copy link
Collaborator

@BeksOmega BeksOmega left a comment

Choose a reason for hiding this comment

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

Just gonna wait for @maribethb 's quick lgtm as well.

Copy link
Contributor

@maribethb maribethb left a comment

Choose a reason for hiding this comment

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

in general, I would prefer more descriptive error messages that might give you a hint about what has done wrong like "fieldGroup_ is null. Has this field been initialized?" or "You may need to initialize this field first" or something, but that isn't always easy to tell. so don't necessarily need to change these, just something to think about whenever we add these.

@@ -1217,19 +1228,20 @@ export abstract class Field implements IASTNodeLocationSvg,
*/
setMarkerSvg(markerSvg: SVGElement) {
if (!markerSvg) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the parameter to this function needs to be nullable, otherwise this check doesn't make sense. some of our other setMarkerSvg methods have the same logic and the parameter is nullable there. I wonder if this was created from our closure code where we didn't always use ? consistently

@@ -202,7 +202,7 @@ export class FieldAngle extends FieldTextInput {
// #2380)
this.symbol_ = dom.createSvgElement(Svg.TSPAN, {});
this.symbol_.appendChild(document.createTextNode('\u00B0'));
this.textElement_.appendChild(this.symbol_);
this.getTextElement().appendChild(this.symbol_);
Copy link
Contributor

Choose a reason for hiding this comment

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

We discussed this earlier this week and this is one of those cases where it's acceptable because it's easily verified that textElement is set directly beforehand in initView. The property is set and then used in the same method so there is no room for developer error - compare that to fieldGroup_ where it could be set in multiple places and an error like forgetting to call an init method would result in the value being unexpectedly null.

There is no hard and fast rule I can give you but that's why this particular case the ! is fine, though using the method is also fine.

core/field.ts Show resolved Hide resolved
@BeksOmega
Copy link
Collaborator

@btw17 give me a ping when this is ready for another look =)

@btw17
Copy link
Member Author

btw17 commented Sep 23, 2022

@btw17 give me a ping when this is ready for another look =)

All set now! Just updated this PR to include the latest updates from the develop branch.

@BeksOmega
Copy link
Collaborator

LGTM after the build passes! If you want to work on this I'll baby sit it to rerun the CI. But don't feel the need to work on it before Friday.

@BeksOmega BeksOmega merged commit fa925e8 into google:develop Sep 30, 2022
@btw17 btw17 deleted the chore/cleanup-any-types branch September 30, 2022 15:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants