Skip to content

Restore delayed merge check to getTypeFromJSDocValueReference #34706

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

Merged
merged 2 commits into from
Oct 24, 2019

Conversation

sandersn
Copy link
Member

@sandersn sandersn commented Oct 24, 2019

This is needed when a function merges with a prototype assignment. The resulting merged symbol is a constructor function marked with SymbolFlags.Class. However, the merge doesn't happen until getTypeOfFuncClassEnumModule is called, which, in the getTypeReferenceType code path, doesn't happen until getTypeFromJSDocValueReference. That means the check for SymbolFlags.Class is missed.

Previously, getTypeFromJSDocValueReference had a weird check symbol !== getTypeOfSymbol(symbol).symbol, which, if true, ran getTypeReferenceType again on getTypeOfSymbol(symbol).symbol. For JS "aliases", this had the effect of dereferencing the alias, and for
function-prototype merges, this had the effect of ... just trying again sfter the merge had happened.

This is a confusing way to run things. getTypeReferenceType should instead detect a function-prototype merge, cause it to happen, and then run the rest of its code instead of relying on try-again logic at
the very end. However, for the RC, I want to fix this code by restoring the old check, with an additional check to make sure that #33106 doesn't break again:

const valueType = getTypeOfSymbol(symbol)
symbol !== valueType.symbol && getMergedSymbol(symbol) === valueType.symbol

I'll work on the real fix afterwards and put it into 3.8.

Fixes #34685

This is needed when a function merges with a prototype assignment. The
resulting *merged* symbol is a constructor function marked with
SymbolFlags.Class. However, the merge doesn't happen until
getTypeOfFuncClassEnumModule is called, which, in the
getTypeReferenceType code path, doesn't happen until
getTypeFromJSDocValueReference. That means the check for
SymbolFlags.Class is missed.

Previously, getTypeFromJSDocValueReference had a weird check
`symbol !== getTypeOfSymbol(symbol).symbol`, which, if true, ran
getTypeReferenceType again on `getTypeOfSymbol(symbol).symbol`. For
JS "aliases", this had the effect of dereferencing the alias, and for
function-prototype merges, this had the effect of ... just trying again
after the merge had happened.

This is a confusing way to run things. getTypeReferenceType should
instead detect a function-prototype merge, cause it to happen, and
*then* run the rest of its code instead of relying on try-again logic at
the very end. However, for the RC, I want to fix this code by restoring
the old check, with an additional check to make sure that #33106 doesn't
break again:

```ts
const valueType = getTypeOfSymbol(symbol)
symbol !== valueType.symbol && getMergedSymbol(symbol) === valueType.symbol
```

I'll work on the real fix afterwards and put it into 3.8.
Copy link
Member

@weswigham weswigham left a comment

Choose a reason for hiding this comment

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

Have you opened an issue to track applying a better fix yet?

@sandersn
Copy link
Member Author

Not yet!

@sandersn
Copy link
Member Author

#34707

@sandersn sandersn changed the title Fix speculative js namespace crossfile merge Restore delayed merge check to getTypeFromJSDocValueReference Oct 24, 2019
@sandersn sandersn merged commit 969634b into master Oct 24, 2019
@sandersn sandersn deleted the fix-speculative-js-namespace-crossfile-merge branch October 24, 2019 16:25
@sandersn
Copy link
Member Author

@typescript-bot cherry-pick this to release-3.7

typescript-bot pushed a commit to typescript-bot/TypeScript that referenced this pull request Oct 24, 2019
Component commits:
056a656 Restore delayed merge check to getTypeFromJSDocValueReference
This is needed when a function merges with a prototype assignment. The
resulting *merged* symbol is a constructor function marked with
SymbolFlags.Class. However, the merge doesn't happen until
getTypeOfFuncClassEnumModule is called, which, in the
getTypeReferenceType code path, doesn't happen until
getTypeFromJSDocValueReference. That means the check for
SymbolFlags.Class is missed.

Previously, getTypeFromJSDocValueReference had a weird check
`symbol !== getTypeOfSymbol(symbol).symbol`, which, if true, ran
getTypeReferenceType again on `getTypeOfSymbol(symbol).symbol`. For
JS "aliases", this had the effect of dereferencing the alias, and for
function-prototype merges, this had the effect of ... just trying again
after the merge had happened.

This is a confusing way to run things. getTypeReferenceType should
instead detect a function-prototype merge, cause it to happen, and
*then* run the rest of its code instead of relying on try-again logic at
the very end. However, for the RC, I want to fix this code by restoring
the old check, with an additional check to make sure that microsoft#33106 doesn't
break again:

```ts
const valueType = getTypeOfSymbol(symbol)
symbol !== valueType.symbol && getMergedSymbol(symbol) === valueType.symbol
```

I'll work on the real fix afterwards and put it into 3.8.

d1515f4 Add bug number
@typescript-bot
Copy link
Collaborator

Hey @sandersn, I've opened #34708 for you.

sandersn pushed a commit that referenced this pull request Oct 24, 2019
Component commits:
056a656 Restore delayed merge check to getTypeFromJSDocValueReference
This is needed when a function merges with a prototype assignment. The
resulting *merged* symbol is a constructor function marked with
SymbolFlags.Class. However, the merge doesn't happen until
getTypeOfFuncClassEnumModule is called, which, in the
getTypeReferenceType code path, doesn't happen until
getTypeFromJSDocValueReference. That means the check for
SymbolFlags.Class is missed.

Previously, getTypeFromJSDocValueReference had a weird check
`symbol !== getTypeOfSymbol(symbol).symbol`, which, if true, ran
getTypeReferenceType again on `getTypeOfSymbol(symbol).symbol`. For
JS "aliases", this had the effect of dereferencing the alias, and for
function-prototype merges, this had the effect of ... just trying again
after the merge had happened.

This is a confusing way to run things. getTypeReferenceType should
instead detect a function-prototype merge, cause it to happen, and
*then* run the rest of its code instead of relying on try-again logic at
the very end. However, for the RC, I want to fix this code by restoring
the old check, with an additional check to make sure that #33106 doesn't
break again:

```ts
const valueType = getTypeOfSymbol(symbol)
symbol !== valueType.symbol && getMergedSymbol(symbol) === valueType.symbol
```

I'll work on the real fix afterwards and put it into 3.8.

d1515f4 Add bug number
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.

JSDoc type reference resolves incorrectly if checked before the constructor function it refers to
3 participants