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

Add logical assignment operator #37727

Merged
merged 25 commits into from
Jun 9, 2020

Conversation

Kingwl
Copy link
Contributor

@Kingwl Kingwl commented Apr 1, 2020

Fixes #37255

@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Apr 1, 2020

The GitHub app is terrible so I can't review properly, but test 5 uses a function type returning void | undefined. That's probably a mistake.

Resolved

}

function foo2 (f?: (a: number) => void) {
f ||= (a => a)
Copy link
Member

Choose a reason for hiding this comment

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

Great test!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

😉

if (thing &&= thing.original) {
console.log(thing.name);
~~~~~
!!! error TS2532: Object is possibly 'undefined'.
Copy link
Member

Choose a reason for hiding this comment

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

Glad the test caught this - that was part of my intent when I wrote it. As you probably know, this needs to be fixed because thing.original should be defined. Let @ahejlsberg or @rbuckton know if you need help with that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I spent all afternoon And evening in this one😂

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, the code can be hard to get through, and I've honestly never wired up the CFG. Also, binary expressions recently changed to use a "trampolining" approach to avoid stack overflows on deep traversals. You can ask @weswigham about that.

If you want to play around to see if you can get it working, I'll provide a few tips and @weswigham and @ahejlsberg can weigh in case I'm totally off.

First take a look at some of the logic at

const preRightLabel = createBranchLabel();

and

if (operator === SyntaxKind.AmpersandAmpersandToken || operator === SyntaxKind.BarBarToken || operator === SyntaxKind.QuestionQuestionToken) {

The binder needs to create branch labels for these new compound assignment operators (similar to in bindLogicalExpression) while creating at least one flow node that's considered an assignment after the expression (as in bindAssignmentTargetFlow). At a glance, I think that a lot of the logic can be reused and the changes can be added around here

Eventually in getTypeAtFlowNode in the type-checker, you need to try to find a way to combine the logic when flags & FlowFlags.Assignment and flags & FlowFlags.Label both apply. To start, I'd just get something working, then worry about how to share the code.

Feel free to ask some questions if you need help. If you'd prefer, I'm also sure we could send a PR if you'd like, but it's up to you.

@@ -4355,6 +4365,12 @@ namespace ts {
|| token === SyntaxKind.ExclamationToken;
}

export function isLogicalAssignmentOperator(token: SyntaxKind): boolean {
Copy link
Member

Choose a reason for hiding this comment

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

Consider isShortCircuitingAssignmentOperator or isLogicalOrCoalescingAssignmentOperator

@@ -3334,6 +3340,10 @@ namespace ts {
return 14;
case SyntaxKind.AsteriskAsteriskToken:
return 15;
case SyntaxKind.BarBarEqualsToken:
Copy link
Member

Choose a reason for hiding this comment

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

This section doesn't seem to cover any of the assignment or compound assignment operators. I'd get clarity from whoever originally wrote this function whether this should be here, because I think these 3 cases don't belong here.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, it seems to be caught by getOperatorPrecedence above.

src/compiler/checker.ts Outdated Show resolved Hide resolved
src/compiler/checker.ts Outdated Show resolved Hide resolved
@Kingwl
Copy link
Contributor Author

Kingwl commented Apr 2, 2020

It seems works, but i don't know why.🤷🏻‍♂️

@DanielRosenwasser
Copy link
Member

@typescript-bot pack this

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 2, 2020

Heya @DanielRosenwasser, I've started to run the tarball bundle task on this PR at 1c92781. You can monitor the build here.

@Kingwl
Copy link
Contributor Author

Kingwl commented Apr 2, 2020

Current CFG is

"
Call (results.push(100)) ─ ArrayMutation (results.push(100)) ─ Branch ┬ True (results) ─────────────────────────────────────────────────┬ Start  
                                                                      ├ True (results ||= []) ─┬ Assignment (results) ─ False (results) ╯   
                                                                      ╰ False (results ||= []) ╯                                            
"

the same as downlevel result

"
Call (results.push(100)) ─ ArrayMutation (results.push(100)) ─ Branch ┬ True (results) ─────────────────────────────────────────────────┬ Start  
                                                                      ├ True ((results = [])) ─┬ Assignment (results) ─ False (results) ╯   
                                                                      ╰ False ((results = [])) ╯                                            
"

@Kingwl
Copy link
Contributor Author

Kingwl commented Apr 2, 2020

@typescript-bot pack this.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 2, 2020

Heya @Kingwl, I've started to run the tarball bundle task on this PR at a6e0086. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

Hey @Kingwl, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/70160/artifacts?artifactName=tgz&fileId=686926927B2177B6DF8E5E65AF663CA3F21F8E4A6BB13BA2F0D55123942814F102&fileName=/typescript-3.9.0-insiders.20200402.tgz"
    }
}

and then running npm install.

@Kingwl Kingwl marked this pull request as ready for review April 4, 2020 14:32
@Kingwl
Copy link
Contributor Author

Kingwl commented Apr 4, 2020

@typescript-bot pack this.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 4, 2020

Heya @Kingwl, I've started to run the tarball bundle task on this PR at 8a9e234. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

Hey @Kingwl, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/70428/artifacts?artifactName=tgz&fileId=0F5F796F0B11C552E9CE937F66A4E8AFB940559C729165A9D4B3FAFEB190B56302&fileName=/typescript-3.9.0-insiders.20200404.tgz"
    }
}

and then running npm install.

@Kingwl
Copy link
Contributor Author

Kingwl commented Apr 7, 2020

Does the playground not supported pull request build now?🤷🏻‍♂️

@DanielRosenwasser
Copy link
Member

Does the playground not supported pull request build now?

@weswigham or @orta might know

@orta
Copy link
Contributor

orta commented Apr 7, 2020

Thanks for the ping, looks like I need to dig into the playground builder - been red for a week
https://github.com/orta/make-monaco-builds/actions - looks like a master build of TS gives a new error in the monaco-typescript codebase

@orta
Copy link
Contributor

orta commented Apr 7, 2020

Made a PR: microsoft/monaco-typescript#59

@orta
Copy link
Contributor

orta commented Apr 7, 2020

and with orta/make-monaco-builds@f17ca4a in

I can request a playground again - @typescript-bot pack this.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 7, 2020

Heya @orta, I've started to run the tarball bundle task on this PR at 8a9e234. You can monitor the build here.

@typescript-bot
Copy link
Collaborator

typescript-bot commented Apr 7, 2020

Hey @orta, I've packed this into an installable tgz. You can install it for testing by referencing it in your package.json like so:

{
    "devDependencies": {
        "typescript": "https://typescript.visualstudio.com/cf7ac146-d525-443c-b23c-0d58337efebc/_apis/build/builds/70644/artifacts?artifactName=tgz&fileId=C1043CC14B2BF52EEC192CF7805DCDB9972F4A315657B65C7F9096429256B57A02&fileName=/typescript-3.9.0-insiders.20200407.tgz"
    }
}

and then running npm install.


There is also a playground for this build.

@Kingwl
Copy link
Contributor Author

Kingwl commented May 16, 2020

Only one pipeline failed with ECONNRESET.

@DanielRosenwasser
Copy link
Member

Looks like this needs to be rebased onto the latest master.

src/compiler/parser.ts Outdated Show resolved Hide resolved
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented May 20, 2020

One more review?

src/compiler/transformers/esnext.ts Outdated Show resolved Hide resolved
src/compiler/transformers/esnext.ts Outdated Show resolved Hide resolved
src/compiler/transformers/esnext.ts Outdated Show resolved Hide resolved
src/compiler/transformers/esnext.ts Outdated Show resolved Hide resolved
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented May 27, 2020

One more peek @rbuckton?

@Kingwl
Copy link
Contributor Author

Kingwl commented Jun 3, 2020

up👆

PR Backlog automation moved this from Waiting on author to Needs merge Jun 9, 2020
@DanielRosenwasser DanielRosenwasser merged commit e832e04 into microsoft:master Jun 9, 2020
PR Backlog automation moved this from Needs merge to Done Jun 9, 2020
@Kingwl Kingwl deleted the logical_assignment branch June 10, 2020 00:35
@aminpaks
Copy link
Contributor

@Kingwl I mentioned a case in here. Would you confirm that this is not a bug?

@Xample
Copy link

Xample commented Jul 24, 2020

Glad to see things moved since #20378 😀

@g-patel
Copy link

g-patel commented Sep 3, 2020

What version of typescript will this be available in?

@ExE-Boss
Copy link
Contributor

ExE-Boss commented Sep 3, 2020

@g-patel This shipped in TypeScript 4.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Milestone Bug PRs that fix a bug with a specific milestone
Projects
Archived in project
PR Backlog
  
Done
Development

Successfully merging this pull request may close these issues.

Nullish Coalescing and Logical Compound Assignments (??=, ||=, &&=)