Skip to content

Fix use-before-def errors for ESNext property declarations #36465

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
Jan 30, 2020

Conversation

sandersn
Copy link
Member

Fixes #36441
Fixes #36442

}
else if (isParameterPropertyDeclaration(declaration, declaration.parent)) {
const container = getEnclosingBlockScopeContainer(declaration.parent);
// foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
return !(compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields
Copy link
Member

Choose a reason for hiding this comment

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

For some reason my brain wants this expression to be De Morgan’d, or maybe for whole function itself to return use-before-declared, not declared-before-used. Oh well.

Copy link
Member Author

Choose a reason for hiding this comment

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

the WHOLE time I was working on this, except every change made things harder to read.

|| isInTypeQuery(usage)
|| isUsedInFunctionOrInstanceProperty(usage, declaration, container)
&& !(compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions.useDefineForClassFields);
if (!!(usage.flags & NodeFlags.JSDoc) || isInTypeQuery(usage)) {
Copy link
Member

Choose a reason for hiding this comment

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

I bet this condition actually could be the same as isValidTypeOnlyAliasUseSite. But probably not worth changing.

return true;
case SyntaxKind.PropertyDeclaration:
return stopAtAllPropertyDeclarations ? "quit": true;
Copy link
Member

Choose a reason for hiding this comment

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

I can’t quite figure out what this means without stepping through one case that needs stopAtAllPropertyDeclarations as true and one that needs false, but are there any tests with a class expression as the initializer of a property declaration?

class Foo {
  Bar = class extends Foo {
    p2 = this.p1
  }
  p1 = 0
}

(I don’t know, maybe there’s a more creative combo of these horrors)

Copy link
Member Author

Choose a reason for hiding this comment

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

There is one:

class B2<V> {
    anon = class extends A<V> { }
}

Your example works on 3.7, so needs to keep working on 3.8:

https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAECC0G8BQ1XQELQLzVJGApgB4AuBAdgCYzzJr3QAOATNtCQBYCWEAdIwEYUaAL7DUgtgAYkYgG5gATtDBtyBAO5wAFAEokwAPbkIhkAV4hDAc21h+A-QuVgARms0re6PQeOnzSxs7Vwd9IA

Back to the drawing board I guess. What a test case!

Copy link
Member

Choose a reason for hiding this comment

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

Commit to fix this looks good 👍

@sandersn sandersn merged commit c1e45ac into master Jan 30, 2020
@sandersn sandersn deleted the fix-use-before-def-esnext-property-decls branch January 30, 2020 18:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants